Completed
Branch fix-spco-form-hanlder (8db777)
by
unknown
13:41 queued 11:20
created
core/services/json/JsonDataNode.php 2 patches
Indentation   +246 added lines, -246 removed lines patch added patch discarded remove patch
@@ -19,250 +19,250 @@
 block discarded – undo
19 19
 abstract class JsonDataNode implements JsonDataNodeInterface
20 20
 {
21 21
 
22
-    /**
23
-     * @var JsonDataNodeValidator
24
-     */
25
-    protected $validator;
26
-
27
-    /**
28
-     * @var array
29
-     */
30
-    private $data = [];
31
-
32
-    /**
33
-     * @var string
34
-     */
35
-    private $domain = '';
36
-
37
-    /**
38
-     * @var boolean
39
-     */
40
-    private $initialized = false;
41
-
42
-    /**
43
-     * @var string
44
-     */
45
-    private $node_name = '';
46
-
47
-    /**
48
-     * @var int
49
-     */
50
-    private $order = 50;
51
-
52
-
53
-    /**
54
-     * @param JsonDataNodeValidator $validator
55
-     * @throws DomainException
56
-     */
57
-    public function __construct(JsonDataNodeValidator $validator)
58
-    {
59
-        $this->validator = $validator;
60
-    }
61
-
62
-
63
-    /**
64
-     * for adding primitive data like arrays, integers, or strings
65
-     *
66
-     * @param string $key
67
-     * @param mixed  $data
68
-     * @throws DomainException
69
-     */
70
-    protected function addData(string $key, $data)
71
-    {
72
-        if ($this->validator->propertyNotSet($this->data, $key)) {
73
-            $this->data[ $key ] = $data;
74
-        }
75
-    }
76
-
77
-
78
-    /**
79
-     * for setting value of the entire data array for the node
80
-     *
81
-     * @param array $data
82
-     * @throws DomainException
83
-     */
84
-    protected function setDataArray(array $data)
85
-    {
86
-        if ($this->validator->dataArrayEmpty($this)) {
87
-            $this->data = $data;
88
-        }
89
-    }
90
-
91
-
92
-    /**
93
-     * for embedding other JsonDataNode objects within this one
94
-     *
95
-     * @param JsonDataNode $data_node
96
-     * @throws DomainException
97
-     */
98
-    public function addDataNode(JsonDataNode $data_node)
99
-    {
100
-        if ($data_node->isNotInitialized()) {
101
-            // $data_node->initialize();
102
-            $key = $data_node->nodeName();
103
-            $this->addData($key, $data_node);
104
-            // if the node being added specifies a domain (use case)
105
-            // and this is the primary data node, then set the domain
106
-            if ($this instanceof PrimaryJsonDataNode && $data_node->domain()) {
107
-                $this->setDomain($data_node->domain());
108
-            }
109
-        }
110
-    }
111
-
112
-
113
-    /**
114
-     * sets the domain (use case) that this data node provides data for
115
-     *
116
-     * @param string $domain
117
-     * @throws DomainException
118
-     */
119
-    protected function setDomain(string $domain)
120
-    {
121
-        if ($this->domain !== '') {
122
-            $this->validator->overwriteError($domain, 'domain route');
123
-        }
124
-        $this->domain = $domain;
125
-    }
126
-
127
-
128
-    /**
129
-     * used to mark the data node as having been processed
130
-     *
131
-     * @param bool $initialized
132
-     */
133
-    protected function setInitialized(bool $initialized)
134
-    {
135
-        $this->initialized = filter_var($initialized, FILTER_VALIDATE_BOOLEAN);
136
-    }
137
-
138
-
139
-    /**
140
-     * self explanatory (i hope)
141
-     *
142
-     * @param string $node_name
143
-     * @throws DomainException
144
-     */
145
-    protected function setNodeName(string $node_name)
146
-    {
147
-        $this->validator->validateCriticalProperty($node_name, 'node name');
148
-        $this->node_name = $node_name;
149
-        // by default set the data node order property by the alphabetical position of the first letter of its name
150
-        // we do this by passing the node name (in UPPERCASE) to ord() to get its ASCII position
151
-        // then we subtract 64 (cuz A has a position of 65) then multiply by 10 just to space things out a bit.
152
-        // this allows a data node to set its order upon construction to some other value
153
-        // so that it can squeak into whatever position it needs to be in, like 55
154
-        $this->setOrder((ord(strtoupper($this->node_name)) - 64) * 10);
155
-    }
156
-
157
-
158
-    /**
159
-     * the actual data in key value array format
160
-     *
161
-     * @param bool $sort
162
-     * @return array
163
-     */
164
-    public function data(bool $sort = false): array
165
-    {
166
-        if ($sort) {
167
-            // check if data array has non-numerical keys and use a custom sort algorithm, else sort by keys
168
-            EEH_Array::is_associative_array($this->data)
169
-                ? uasort(
170
-                    $this->data,
171
-                    function ($a, $b) {
172
-                        // check if each incoming argument is a node and if they have an order set
173
-                        // if so, then use that for our sorting comparison. otherwise use the node's name...
174
-                        // unless it's NOT a node, in which case use the arg value if it is scalar, or 0 if not.
175
-                        if ($a instanceof JsonDataNode) {
176
-                            $a_ord = $a->order() ?: $a->nodeName();
177
-                        } else {
178
-                            $a_ord = is_scalar($a) ?: 0;
179
-                        }
180
-                        if ($b instanceof JsonDataNode) {
181
-                            $b_ord = $b->order() ?: $b->nodeName();
182
-                        } else {
183
-                            $b_ord = is_scalar($b) ?: 0;
184
-                        }
185
-                        return $a_ord <=> $b_ord;
186
-                    }
187
-                )
188
-                // sort numerically indexed arrays by their keys
189
-                : ksort($this->data);
190
-        }
191
-        return $this->data;
192
-    }
193
-
194
-
195
-    /**
196
-     * the domain (use case) that this data node provides data for
197
-     *
198
-     * @return string
199
-     */
200
-    public function domain(): string
201
-    {
202
-        return $this->domain;
203
-    }
204
-
205
-
206
-    /**
207
-     * true if the data node has been initialized,
208
-     * which entails retrieving the required data and adding it to the data node data array
209
-     *
210
-     * @return bool
211
-     */
212
-    public function isInitialized(): bool
213
-    {
214
-        return $this->initialized;
215
-    }
216
-
217
-
218
-    /**
219
-     * true if the data node has NOT been initialized
220
-     *
221
-     * @return bool
222
-     */
223
-    public function isNotInitialized(): bool
224
-    {
225
-        return ! $this->initialized;
226
-    }
227
-
228
-
229
-    /**
230
-     * Specify data which should be serialized to JSON
231
-     *
232
-     * @link  https://php.net/manual/en/jsonserializable.jsonserialize.php
233
-     * @return array data which can be serialized by json_encode
234
-     */
235
-    public function jsonSerialize(): array
236
-    {
237
-        return $this->data;
238
-    }
239
-
240
-
241
-    /**
242
-     * self explanatory (i hope)
243
-     *
244
-     * @return string
245
-     */
246
-    public function nodeName(): string
247
-    {
248
-        return $this->node_name;
249
-    }
250
-
251
-
252
-    /**
253
-     * @return int
254
-     */
255
-    public function order(): ?int
256
-    {
257
-        return $this->order;
258
-    }
259
-
260
-
261
-    /**
262
-     * @param int $order
263
-     */
264
-    protected function setOrder(int $order): void
265
-    {
266
-        $this->order = absint($order);
267
-    }
22
+	/**
23
+	 * @var JsonDataNodeValidator
24
+	 */
25
+	protected $validator;
26
+
27
+	/**
28
+	 * @var array
29
+	 */
30
+	private $data = [];
31
+
32
+	/**
33
+	 * @var string
34
+	 */
35
+	private $domain = '';
36
+
37
+	/**
38
+	 * @var boolean
39
+	 */
40
+	private $initialized = false;
41
+
42
+	/**
43
+	 * @var string
44
+	 */
45
+	private $node_name = '';
46
+
47
+	/**
48
+	 * @var int
49
+	 */
50
+	private $order = 50;
51
+
52
+
53
+	/**
54
+	 * @param JsonDataNodeValidator $validator
55
+	 * @throws DomainException
56
+	 */
57
+	public function __construct(JsonDataNodeValidator $validator)
58
+	{
59
+		$this->validator = $validator;
60
+	}
61
+
62
+
63
+	/**
64
+	 * for adding primitive data like arrays, integers, or strings
65
+	 *
66
+	 * @param string $key
67
+	 * @param mixed  $data
68
+	 * @throws DomainException
69
+	 */
70
+	protected function addData(string $key, $data)
71
+	{
72
+		if ($this->validator->propertyNotSet($this->data, $key)) {
73
+			$this->data[ $key ] = $data;
74
+		}
75
+	}
76
+
77
+
78
+	/**
79
+	 * for setting value of the entire data array for the node
80
+	 *
81
+	 * @param array $data
82
+	 * @throws DomainException
83
+	 */
84
+	protected function setDataArray(array $data)
85
+	{
86
+		if ($this->validator->dataArrayEmpty($this)) {
87
+			$this->data = $data;
88
+		}
89
+	}
90
+
91
+
92
+	/**
93
+	 * for embedding other JsonDataNode objects within this one
94
+	 *
95
+	 * @param JsonDataNode $data_node
96
+	 * @throws DomainException
97
+	 */
98
+	public function addDataNode(JsonDataNode $data_node)
99
+	{
100
+		if ($data_node->isNotInitialized()) {
101
+			// $data_node->initialize();
102
+			$key = $data_node->nodeName();
103
+			$this->addData($key, $data_node);
104
+			// if the node being added specifies a domain (use case)
105
+			// and this is the primary data node, then set the domain
106
+			if ($this instanceof PrimaryJsonDataNode && $data_node->domain()) {
107
+				$this->setDomain($data_node->domain());
108
+			}
109
+		}
110
+	}
111
+
112
+
113
+	/**
114
+	 * sets the domain (use case) that this data node provides data for
115
+	 *
116
+	 * @param string $domain
117
+	 * @throws DomainException
118
+	 */
119
+	protected function setDomain(string $domain)
120
+	{
121
+		if ($this->domain !== '') {
122
+			$this->validator->overwriteError($domain, 'domain route');
123
+		}
124
+		$this->domain = $domain;
125
+	}
126
+
127
+
128
+	/**
129
+	 * used to mark the data node as having been processed
130
+	 *
131
+	 * @param bool $initialized
132
+	 */
133
+	protected function setInitialized(bool $initialized)
134
+	{
135
+		$this->initialized = filter_var($initialized, FILTER_VALIDATE_BOOLEAN);
136
+	}
137
+
138
+
139
+	/**
140
+	 * self explanatory (i hope)
141
+	 *
142
+	 * @param string $node_name
143
+	 * @throws DomainException
144
+	 */
145
+	protected function setNodeName(string $node_name)
146
+	{
147
+		$this->validator->validateCriticalProperty($node_name, 'node name');
148
+		$this->node_name = $node_name;
149
+		// by default set the data node order property by the alphabetical position of the first letter of its name
150
+		// we do this by passing the node name (in UPPERCASE) to ord() to get its ASCII position
151
+		// then we subtract 64 (cuz A has a position of 65) then multiply by 10 just to space things out a bit.
152
+		// this allows a data node to set its order upon construction to some other value
153
+		// so that it can squeak into whatever position it needs to be in, like 55
154
+		$this->setOrder((ord(strtoupper($this->node_name)) - 64) * 10);
155
+	}
156
+
157
+
158
+	/**
159
+	 * the actual data in key value array format
160
+	 *
161
+	 * @param bool $sort
162
+	 * @return array
163
+	 */
164
+	public function data(bool $sort = false): array
165
+	{
166
+		if ($sort) {
167
+			// check if data array has non-numerical keys and use a custom sort algorithm, else sort by keys
168
+			EEH_Array::is_associative_array($this->data)
169
+				? uasort(
170
+					$this->data,
171
+					function ($a, $b) {
172
+						// check if each incoming argument is a node and if they have an order set
173
+						// if so, then use that for our sorting comparison. otherwise use the node's name...
174
+						// unless it's NOT a node, in which case use the arg value if it is scalar, or 0 if not.
175
+						if ($a instanceof JsonDataNode) {
176
+							$a_ord = $a->order() ?: $a->nodeName();
177
+						} else {
178
+							$a_ord = is_scalar($a) ?: 0;
179
+						}
180
+						if ($b instanceof JsonDataNode) {
181
+							$b_ord = $b->order() ?: $b->nodeName();
182
+						} else {
183
+							$b_ord = is_scalar($b) ?: 0;
184
+						}
185
+						return $a_ord <=> $b_ord;
186
+					}
187
+				)
188
+				// sort numerically indexed arrays by their keys
189
+				: ksort($this->data);
190
+		}
191
+		return $this->data;
192
+	}
193
+
194
+
195
+	/**
196
+	 * the domain (use case) that this data node provides data for
197
+	 *
198
+	 * @return string
199
+	 */
200
+	public function domain(): string
201
+	{
202
+		return $this->domain;
203
+	}
204
+
205
+
206
+	/**
207
+	 * true if the data node has been initialized,
208
+	 * which entails retrieving the required data and adding it to the data node data array
209
+	 *
210
+	 * @return bool
211
+	 */
212
+	public function isInitialized(): bool
213
+	{
214
+		return $this->initialized;
215
+	}
216
+
217
+
218
+	/**
219
+	 * true if the data node has NOT been initialized
220
+	 *
221
+	 * @return bool
222
+	 */
223
+	public function isNotInitialized(): bool
224
+	{
225
+		return ! $this->initialized;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Specify data which should be serialized to JSON
231
+	 *
232
+	 * @link  https://php.net/manual/en/jsonserializable.jsonserialize.php
233
+	 * @return array data which can be serialized by json_encode
234
+	 */
235
+	public function jsonSerialize(): array
236
+	{
237
+		return $this->data;
238
+	}
239
+
240
+
241
+	/**
242
+	 * self explanatory (i hope)
243
+	 *
244
+	 * @return string
245
+	 */
246
+	public function nodeName(): string
247
+	{
248
+		return $this->node_name;
249
+	}
250
+
251
+
252
+	/**
253
+	 * @return int
254
+	 */
255
+	public function order(): ?int
256
+	{
257
+		return $this->order;
258
+	}
259
+
260
+
261
+	/**
262
+	 * @param int $order
263
+	 */
264
+	protected function setOrder(int $order): void
265
+	{
266
+		$this->order = absint($order);
267
+	}
268 268
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
     protected function addData(string $key, $data)
71 71
     {
72 72
         if ($this->validator->propertyNotSet($this->data, $key)) {
73
-            $this->data[ $key ] = $data;
73
+            $this->data[$key] = $data;
74 74
         }
75 75
     }
76 76
 
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
             EEH_Array::is_associative_array($this->data)
169 169
                 ? uasort(
170 170
                     $this->data,
171
-                    function ($a, $b) {
171
+                    function($a, $b) {
172 172
                         // check if each incoming argument is a node and if they have an order set
173 173
                         // if so, then use that for our sorting comparison. otherwise use the node's name...
174 174
                         // unless it's NOT a node, in which case use the arg value if it is scalar, or 0 if not.
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegFormHandler.php 1 patch
Indentation   +278 added lines, -278 removed lines patch added patch discarded remove patch
@@ -18,309 +18,309 @@
 block discarded – undo
18 18
 class RegFormHandler
19 19
 {
20 20
 
21
-    /**
22
-     * @var EE_Checkout
23
-     */
24
-    public $checkout;
21
+	/**
22
+	 * @var EE_Checkout
23
+	 */
24
+	public $checkout;
25 25
 
26
-    /**
27
-     * @var RegFormInputHandler
28
-     */
29
-    public $input_handler;
26
+	/**
27
+	 * @var RegFormInputHandler
28
+	 */
29
+	public $input_handler;
30 30
 
31
-    /**
32
-     * @var array
33
-     */
34
-    private $non_input_form_sections;
31
+	/**
32
+	 * @var array
33
+	 */
34
+	private $non_input_form_sections;
35 35
 
36
-    /**
37
-     * @var RegFormAttendeeFactory
38
-     */
39
-    private $attendee_factory;
36
+	/**
37
+	 * @var RegFormAttendeeFactory
38
+	 */
39
+	private $attendee_factory;
40 40
 
41
-    /**
42
-     * @var RegistrantData
43
-     */
44
-    private $registrant_data;
41
+	/**
42
+	 * @var RegistrantData
43
+	 */
44
+	private $registrant_data;
45 45
 
46
-    /**
47
-     * @var EE_Registration_Processor
48
-     */
49
-    private $registration_processor;
46
+	/**
47
+	 * @var EE_Registration_Processor
48
+	 */
49
+	private $registration_processor;
50 50
 
51
-    /**
52
-     * @var bool
53
-     */
54
-    private $valid;
51
+	/**
52
+	 * @var bool
53
+	 */
54
+	private $valid;
55 55
 
56 56
 
57
-    /**
58
-     * RegFormHandler constructor.
59
-     */
60
-    public function __construct(
61
-        EE_Checkout $checkout,
62
-        RegistrantData $registrant_data,
63
-        RegFormAttendeeFactory $attendee_factory,
64
-        EE_Registration_Processor $registration_processor
65
-    ) {
66
-        $this->checkout                = $checkout;
67
-        $this->registrant_data         = $registrant_data;
68
-        $this->attendee_factory        = $attendee_factory;
69
-        $this->registration_processor  = $registration_processor;
70
-        // reg form sections that do not contain inputs
71
-        $this->non_input_form_sections = [
72
-            'primary_registrant',
73
-            'additional_attendee_reg_info',
74
-            'spco_copy_attendee_chk',
75
-        ];
76
-        $this->initializeInputHandler();
77
-    }
57
+	/**
58
+	 * RegFormHandler constructor.
59
+	 */
60
+	public function __construct(
61
+		EE_Checkout $checkout,
62
+		RegistrantData $registrant_data,
63
+		RegFormAttendeeFactory $attendee_factory,
64
+		EE_Registration_Processor $registration_processor
65
+	) {
66
+		$this->checkout                = $checkout;
67
+		$this->registrant_data         = $registrant_data;
68
+		$this->attendee_factory        = $attendee_factory;
69
+		$this->registration_processor  = $registration_processor;
70
+		// reg form sections that do not contain inputs
71
+		$this->non_input_form_sections = [
72
+			'primary_registrant',
73
+			'additional_attendee_reg_info',
74
+			'spco_copy_attendee_chk',
75
+		];
76
+		$this->initializeInputHandler();
77
+	}
78 78
 
79 79
 
80
-    private function initializeInputHandler()
81
-    {
82
-        $reg_form = $this->checkout->current_step->reg_form;
83
-        $required_questions = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
84
-        $this->input_handler = LoaderFactory::getShared(
85
-            RegFormInputHandler::class,
86
-            [ $this->checkout->reg_url_link, $required_questions ]
87
-        );
88
-    }
80
+	private function initializeInputHandler()
81
+	{
82
+		$reg_form = $this->checkout->current_step->reg_form;
83
+		$required_questions = $reg_form instanceof RegForm ? $reg_form->requiredQuestions() : [];
84
+		$this->input_handler = LoaderFactory::getShared(
85
+			RegFormInputHandler::class,
86
+			[ $this->checkout->reg_url_link, $required_questions ]
87
+		);
88
+	}
89 89
 
90 90
 
91
-    /**
92
-     * @return int
93
-     */
94
-    public function attendeeCount(): int
95
-    {
96
-        return $this->registrant_data->attendeeCount();
97
-    }
91
+	/**
92
+	 * @return int
93
+	 */
94
+	public function attendeeCount(): int
95
+	{
96
+		return $this->registrant_data->attendeeCount();
97
+	}
98 98
 
99 99
 
100
-    /**
101
-     * @return bool
102
-     */
103
-    private function isInvalid(): bool
104
-    {
105
-        $this->valid = false;
106
-        return $this->valid;
107
-    }
100
+	/**
101
+	 * @return bool
102
+	 */
103
+	private function isInvalid(): bool
104
+	{
105
+		$this->valid = false;
106
+		return $this->valid;
107
+	}
108 108
 
109 109
 
110
-    /**
111
-     * @param EE_Registration[] $registrations
112
-     * @param array[][]         $reg_form_data
113
-     * @return bool
114
-     * @throws EntityNotFoundException
115
-     * @throws EE_Error
116
-     * @throws InvalidArgumentException
117
-     * @throws ReflectionException
118
-     * @throws RuntimeException
119
-     * @throws InvalidDataTypeException
120
-     * @throws InvalidInterfaceException
121
-     */
122
-    public function processRegistrations(array $registrations, array $reg_form_data): bool
123
-    {
124
-        // start off optimistic, then trip this to false if anything goes wrong
125
-        $this->valid = true;
126
-        foreach ($registrations as $registration) {
127
-            // verify EE_Registration object
128
-            if (! $this->isValidRegistration($registration)) {
129
-                return $this->isInvalid();
130
-            }
131
-            $reg_url_link = $registration->reg_url_link();
132
-            // reg_url_link exists ?
133
-            if (! $this->isValidRegUrlLink($reg_url_link)) {
134
-                return $this->isInvalid();
135
-            }
136
-            // should this registration be processed during this visit ?
137
-            if (! $this->checkout->visit_allows_processing_of_this_registration($registration)) {
138
-                continue;
139
-            }
140
-            // if NOT revisiting, then let's save the registration now,
141
-            // so that we have a REG_ID to use when generating other objects
142
-            if (! $this->checkout->revisit) {
143
-                $registration->save();
144
-            }
145
-            /**
146
-             * This allows plugins to trigger a fail on processing of a
147
-             * registration for any conditions they may have for it to pass.
148
-             *
149
-             * @var bool if true is returned by the plugin then the registration processing is halted.
150
-             */
151
-            if (
152
-                apply_filters(
153
-                    'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
154
-                    false,
155
-                    $this->registrant_data->attendeeCount(),
156
-                    $registration,
157
-                    $registrations,
158
-                    $reg_form_data,
159
-                    $this
160
-                )
161
-            ) {
162
-                return $this->isInvalid();
163
-            }
110
+	/**
111
+	 * @param EE_Registration[] $registrations
112
+	 * @param array[][]         $reg_form_data
113
+	 * @return bool
114
+	 * @throws EntityNotFoundException
115
+	 * @throws EE_Error
116
+	 * @throws InvalidArgumentException
117
+	 * @throws ReflectionException
118
+	 * @throws RuntimeException
119
+	 * @throws InvalidDataTypeException
120
+	 * @throws InvalidInterfaceException
121
+	 */
122
+	public function processRegistrations(array $registrations, array $reg_form_data): bool
123
+	{
124
+		// start off optimistic, then trip this to false if anything goes wrong
125
+		$this->valid = true;
126
+		foreach ($registrations as $registration) {
127
+			// verify EE_Registration object
128
+			if (! $this->isValidRegistration($registration)) {
129
+				return $this->isInvalid();
130
+			}
131
+			$reg_url_link = $registration->reg_url_link();
132
+			// reg_url_link exists ?
133
+			if (! $this->isValidRegUrlLink($reg_url_link)) {
134
+				return $this->isInvalid();
135
+			}
136
+			// should this registration be processed during this visit ?
137
+			if (! $this->checkout->visit_allows_processing_of_this_registration($registration)) {
138
+				continue;
139
+			}
140
+			// if NOT revisiting, then let's save the registration now,
141
+			// so that we have a REG_ID to use when generating other objects
142
+			if (! $this->checkout->revisit) {
143
+				$registration->save();
144
+			}
145
+			/**
146
+			 * This allows plugins to trigger a fail on processing of a
147
+			 * registration for any conditions they may have for it to pass.
148
+			 *
149
+			 * @var bool if true is returned by the plugin then the registration processing is halted.
150
+			 */
151
+			if (
152
+				apply_filters(
153
+					'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process',
154
+					false,
155
+					$this->registrant_data->attendeeCount(),
156
+					$registration,
157
+					$registrations,
158
+					$reg_form_data,
159
+					$this
160
+				)
161
+			) {
162
+				return $this->isInvalid();
163
+			}
164 164
 
165
-            // Houston, we have a registration!
166
-            if (! $this->processRegistration($registration, $reg_url_link, $reg_form_data)) {
167
-                return $this->isInvalid();
168
-            }
169
-        }
170
-        return $this->valid;
171
-    }
165
+			// Houston, we have a registration!
166
+			if (! $this->processRegistration($registration, $reg_url_link, $reg_form_data)) {
167
+				return $this->isInvalid();
168
+			}
169
+		}
170
+		return $this->valid;
171
+	}
172 172
 
173 173
 
174
-    /**
175
-     * @param string $reg_url_link
176
-     * @return bool
177
-     */
178
-    private function isValidRegUrlLink(string $reg_url_link): bool
179
-    {
180
-        if (! empty($reg_url_link)) {
181
-            return true;
182
-        }
183
-        EE_Error::add_error(
184
-            esc_html__(
185
-                'An invalid or missing line item ID was encountered while attempting to process the registration form.',
186
-                'event_espresso'
187
-            ),
188
-            __FILE__,
189
-            __FUNCTION__,
190
-            __LINE__
191
-        );
192
-        return false;
193
-    }
174
+	/**
175
+	 * @param string $reg_url_link
176
+	 * @return bool
177
+	 */
178
+	private function isValidRegUrlLink(string $reg_url_link): bool
179
+	{
180
+		if (! empty($reg_url_link)) {
181
+			return true;
182
+		}
183
+		EE_Error::add_error(
184
+			esc_html__(
185
+				'An invalid or missing line item ID was encountered while attempting to process the registration form.',
186
+				'event_espresso'
187
+			),
188
+			__FILE__,
189
+			__FUNCTION__,
190
+			__LINE__
191
+		);
192
+		return false;
193
+	}
194 194
 
195 195
 
196
-    /**
197
-     * @param EE_Registration $registration
198
-     * @return bool
199
-     */
200
-    private function isValidRegistration(EE_Registration $registration): bool
201
-    {
202
-        // verify EE_Registration object
203
-        if ($registration instanceof EE_Registration) {
204
-            return true;
205
-        }
206
-        EE_Error::add_error(
207
-            esc_html__(
208
-                'An invalid Registration object was discovered when attempting to process your registration information.',
209
-                'event_espresso'
210
-            ),
211
-            __FILE__,
212
-            __FUNCTION__,
213
-            __LINE__
214
-        );
215
-        return false;
216
-    }
196
+	/**
197
+	 * @param EE_Registration $registration
198
+	 * @return bool
199
+	 */
200
+	private function isValidRegistration(EE_Registration $registration): bool
201
+	{
202
+		// verify EE_Registration object
203
+		if ($registration instanceof EE_Registration) {
204
+			return true;
205
+		}
206
+		EE_Error::add_error(
207
+			esc_html__(
208
+				'An invalid Registration object was discovered when attempting to process your registration information.',
209
+				'event_espresso'
210
+			),
211
+			__FILE__,
212
+			__FUNCTION__,
213
+			__LINE__
214
+		);
215
+		return false;
216
+	}
217 217
 
218 218
 
219
-    /**
220
-     * @param EE_Registration $registration
221
-     * @param string          $reg_url_link
222
-     * @param array[][]       $reg_form_data
223
-     * @return bool
224
-     * @throws EE_Error
225
-     * @throws ReflectionException
226
-     */
227
-    private function processRegistration(
228
-        EE_Registration $registration,
229
-        string $reg_url_link,
230
-        array $reg_form_data
231
-    ): bool {
232
-        $this->registrant_data->initializeRegistrantData($registration);
233
-        if (! $this->processRegFormData($registration, $reg_url_link, $reg_form_data)) {
234
-            return false;
235
-        }
236
-        // RegFormAttendeeFactory
237
-        if (! $this->attendee_factory->create($registration, $reg_url_link)) {
238
-            return false;
239
-        }
240
-        // at this point, we should have enough details about the registrant to consider the registration
241
-        // NOT incomplete
242
-        $this->registration_processor->toggle_incomplete_registration_status_to_default(
243
-            $registration,
244
-            false,
245
-            new Context(
246
-                'spco_reg_step_attendee_information_process_registrations',
247
-                esc_html__(
248
-                    'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
249
-                    'event_espresso'
250
-                )
251
-            )
252
-        );
253
-        // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
254
-        // abandoned
255
-        $this->checkout->transaction->toggle_failed_transaction_status();
256
-        // if we've gotten this far, then let's save what we have
257
-        $registration->save();
258
-        // add relation between TXN and registration
259
-        $this->associateRegistrationWithTransaction($registration);
260
-        return true;
261
-    }
219
+	/**
220
+	 * @param EE_Registration $registration
221
+	 * @param string          $reg_url_link
222
+	 * @param array[][]       $reg_form_data
223
+	 * @return bool
224
+	 * @throws EE_Error
225
+	 * @throws ReflectionException
226
+	 */
227
+	private function processRegistration(
228
+		EE_Registration $registration,
229
+		string $reg_url_link,
230
+		array $reg_form_data
231
+	): bool {
232
+		$this->registrant_data->initializeRegistrantData($registration);
233
+		if (! $this->processRegFormData($registration, $reg_url_link, $reg_form_data)) {
234
+			return false;
235
+		}
236
+		// RegFormAttendeeFactory
237
+		if (! $this->attendee_factory->create($registration, $reg_url_link)) {
238
+			return false;
239
+		}
240
+		// at this point, we should have enough details about the registrant to consider the registration
241
+		// NOT incomplete
242
+		$this->registration_processor->toggle_incomplete_registration_status_to_default(
243
+			$registration,
244
+			false,
245
+			new Context(
246
+				'spco_reg_step_attendee_information_process_registrations',
247
+				esc_html__(
248
+					'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.',
249
+					'event_espresso'
250
+				)
251
+			)
252
+		);
253
+		// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to
254
+		// abandoned
255
+		$this->checkout->transaction->toggle_failed_transaction_status();
256
+		// if we've gotten this far, then let's save what we have
257
+		$registration->save();
258
+		// add relation between TXN and registration
259
+		$this->associateRegistrationWithTransaction($registration);
260
+		return true;
261
+	}
262 262
 
263 263
 
264
-    /**
265
-     * @param EE_Registration $registration
266
-     * @param string          $reg_url_link
267
-     * @param array           $reg_form_data
268
-     * @return bool
269
-     * @throws EE_Error
270
-     * @throws ReflectionException
271
-     */
272
-    private function processRegFormData(EE_Registration $registration, string $reg_url_link, array $reg_form_data): bool
273
-    {
274
-        if (isset($reg_form_data[ $reg_url_link ])) {
275
-            // do we need to copy basic info from primary attendee ?
276
-            $copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
277
-                                  && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
278
-            $this->registrant_data->setCopyPrimary($copy_primary);
279
-            // filter form input data for this registration
280
-            $reg_form_data[ $reg_url_link ] = (array) apply_filters(
281
-                'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
282
-                $reg_form_data[ $reg_url_link ]
283
-            );
284
-            if (isset($reg_form_data['primary_attendee'])) {
285
-                $primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
286
-                $this->registrant_data->addPrimaryRegistrantDataValue('reg_url_link', $primary_reg_url_link);
287
-                unset($reg_form_data['primary_attendee']);
288
-            }
289
-            // now loop through our array of valid post data && process attendee reg forms
290
-            foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
291
-                if (in_array($form_section, $this->non_input_form_sections, true)) {
292
-                    continue;
293
-                }
294
-                foreach ($form_inputs as $form_input => $input_value) {
295
-                    $input_processed = $this->input_handler->processFormInput(
296
-                        $registration,
297
-                        $reg_url_link,
298
-                        $form_input,
299
-                        $input_value
300
-                    );
301
-                    if (! $input_processed) {
302
-                        return false;
303
-                    }
304
-                }
305
-            }
306
-        }
307
-        return true;
308
-    }
264
+	/**
265
+	 * @param EE_Registration $registration
266
+	 * @param string          $reg_url_link
267
+	 * @param array           $reg_form_data
268
+	 * @return bool
269
+	 * @throws EE_Error
270
+	 * @throws ReflectionException
271
+	 */
272
+	private function processRegFormData(EE_Registration $registration, string $reg_url_link, array $reg_form_data): bool
273
+	{
274
+		if (isset($reg_form_data[ $reg_url_link ])) {
275
+			// do we need to copy basic info from primary attendee ?
276
+			$copy_primary = isset($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info'])
277
+								  && absint($reg_form_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0;
278
+			$this->registrant_data->setCopyPrimary($copy_primary);
279
+			// filter form input data for this registration
280
+			$reg_form_data[ $reg_url_link ] = (array) apply_filters(
281
+				'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
282
+				$reg_form_data[ $reg_url_link ]
283
+			);
284
+			if (isset($reg_form_data['primary_attendee'])) {
285
+				$primary_reg_url_link = $reg_form_data['primary_attendee'] ?? '';
286
+				$this->registrant_data->addPrimaryRegistrantDataValue('reg_url_link', $primary_reg_url_link);
287
+				unset($reg_form_data['primary_attendee']);
288
+			}
289
+			// now loop through our array of valid post data && process attendee reg forms
290
+			foreach ($reg_form_data[ $reg_url_link ] as $form_section => $form_inputs) {
291
+				if (in_array($form_section, $this->non_input_form_sections, true)) {
292
+					continue;
293
+				}
294
+				foreach ($form_inputs as $form_input => $input_value) {
295
+					$input_processed = $this->input_handler->processFormInput(
296
+						$registration,
297
+						$reg_url_link,
298
+						$form_input,
299
+						$input_value
300
+					);
301
+					if (! $input_processed) {
302
+						return false;
303
+					}
304
+				}
305
+			}
306
+		}
307
+		return true;
308
+	}
309 309
 
310 310
 
311
-    /**
312
-     * @param EE_Registration $registration
313
-     * @return void
314
-     * @throws EE_Error
315
-     * @throws InvalidArgumentException
316
-     * @throws ReflectionException
317
-     * @throws InvalidDataTypeException
318
-     * @throws InvalidInterfaceException
319
-     */
320
-    private function associateRegistrationWithTransaction(EE_Registration $registration)
321
-    {
322
-        // add relation to registration
323
-        $this->checkout->transaction->_add_relation_to($registration, 'Registration');
324
-        $this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
325
-    }
311
+	/**
312
+	 * @param EE_Registration $registration
313
+	 * @return void
314
+	 * @throws EE_Error
315
+	 * @throws InvalidArgumentException
316
+	 * @throws ReflectionException
317
+	 * @throws InvalidDataTypeException
318
+	 * @throws InvalidInterfaceException
319
+	 */
320
+	private function associateRegistrationWithTransaction(EE_Registration $registration)
321
+	{
322
+		// add relation to registration
323
+		$this->checkout->transaction->_add_relation_to($registration, 'Registration');
324
+		$this->checkout->transaction->update_cache_after_object_save('Registration', $registration);
325
+	}
326 326
 }
Please login to merge, or discard this patch.
modules/single_page_checkout/inc/EE_Checkout.class.php 1 patch
Indentation   +1422 added lines, -1422 removed lines patch added patch discarded remove patch
@@ -15,1427 +15,1427 @@
 block discarded – undo
15 15
 class EE_Checkout
16 16
 {
17 17
 
18
-    /**
19
-     *    whether current request originated from the EE admin
20
-     *
21
-     * @var bool
22
-     */
23
-    public $admin_request = false;
24
-
25
-    /**
26
-     * whether returning to edit attendee information or to retry a payment
27
-     *
28
-     * @var bool
29
-     */
30
-    public $revisit = false;
31
-
32
-    /**
33
-     * whether the primary registrant is returning to edit attendee information or to retry a payment
34
-     *
35
-     * @var bool
36
-     */
37
-    public $primary_revisit = false;
38
-
39
-    /**
40
-     * is registration allowed to progress or halted for some reason such as failing to pass recaptcha?
41
-     *
42
-     * @var bool
43
-     */
44
-    public $continue_reg = true;
45
-
46
-    /**
47
-     * redirect to thank you page ?
48
-     *
49
-     * @var bool
50
-     */
51
-    public $redirect = false;
52
-
53
-    /**
54
-     * generate the reg form or not ?
55
-     *
56
-     * @var bool
57
-     */
58
-    public $generate_reg_form = true;
59
-
60
-    /**
61
-     * process a reg form submission or not ?
62
-     *
63
-     * @var bool
64
-     */
65
-    public $process_form_submission = false;
66
-
67
-    /**
68
-     * tracks whether the TXN status modified during this checkout
69
-     *
70
-     * @var bool
71
-     */
72
-    public $txn_status_updated = false;
73
-
74
-    /**
75
-     * only triggered to true after absolutely everything has finished.
76
-     *
77
-     * @var bool
78
-     */
79
-    protected $exit_spco = false;
80
-
81
-    /**
82
-     * tracks whether any of the TXN's Registrations statuses modified during this checkout
83
-     * indexed by registration ID
84
-     *
85
-     * @var array
86
-     */
87
-    protected $reg_status_updated = array();
88
-
89
-    /**
90
-     * timestamp when redirected from Ticket Selector to the checkout
91
-     *
92
-     * @var int
93
-     */
94
-    public $uts = 0;
95
-
96
-    /**
97
-     * total number of tickets that were in the cart
98
-     *
99
-     * @var int
100
-     */
101
-    public $total_ticket_count = 0;
102
-
103
-    /**
104
-     * corresponds loosely to EE_Transaction::remaining()
105
-     * but can be modified by SPCO
106
-     *
107
-     * @var float
108
-     */
109
-    public $amount_owing = 0;
110
-
111
-    /**
112
-     * the reg step slug from the incoming request
113
-     *
114
-     * @var string
115
-     */
116
-    public $step = '';
117
-
118
-    /**
119
-     * the reg step slug for a step being edited
120
-     *
121
-     * @var string
122
-     */
123
-    public $edit_step = '';
124
-
125
-    /**
126
-     * the action being performed on the current step
127
-     *
128
-     * @var string
129
-     */
130
-    public $action = '';
131
-
132
-    /**
133
-     * reg_url_link for a previously saved registration
134
-     *
135
-     * @var string
136
-     */
137
-    public $reg_url_link = '';
138
-
139
-    /**
140
-     * string slug for the payment method that was selected during the payment options step
141
-     *
142
-     * @var string
143
-     */
144
-    public $selected_method_of_payment = '';
145
-
146
-    /**
147
-     * base url for the site's registration checkout page - additional url params will be added to this
148
-     *
149
-     * @var string
150
-     */
151
-    public $reg_page_base_url = '';
152
-
153
-    /**
154
-     * base url for the site's registration cancelled page - additional url params will be added to this
155
-     *
156
-     * @var string
157
-     */
158
-    public $cancel_page_url = '';
159
-
160
-    /**
161
-     * base url for the site's thank you page - additional url params will be added to this
162
-     *
163
-     * @var string
164
-     */
165
-    public $thank_you_page_url = '';
166
-
167
-    /**
168
-     * base url for any redirects - additional url params will be added to this
169
-     *
170
-     * @var string
171
-     */
172
-    public $redirect_url = '';
173
-
174
-    /**
175
-     * form of POST data for use with off-site gateways
176
-     *
177
-     * @var string
178
-     */
179
-    public $redirect_form = '';
180
-
181
-    /**
182
-     * array of query where params to use when retrieving cached registrations from $this->checkout->transaction
183
-     *
184
-     * @var array
185
-     */
186
-    public $reg_cache_where_params = array();
187
-
188
-    /**
189
-     * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX
190
-     * requests
191
-     *
192
-     * @var EE_SPCO_JSON_Response
193
-     */
194
-    public $json_response;
195
-
196
-    /**
197
-     * where we are going next in the reg process
198
-     *
199
-     * @var EE_SPCO_Reg_Step
200
-     */
201
-    public $next_step;
202
-
203
-    /**
204
-     * where we are in the reg process
205
-     *
206
-     * @var EE_SPCO_Reg_Step
207
-     */
208
-    public $current_step;
209
-
210
-    /**
211
-     *    $_cart - the current cart object
212
-     *
213
-     * @var EE_CART
214
-     */
215
-    public $cart;
216
-
217
-    /**
218
-     *    $_transaction - the current transaction object
219
-     *
220
-     * @var EE_Transaction
221
-     */
222
-    public $transaction;
223
-
224
-    /**
225
-     *    the related attendee object for the primary registrant
226
-     *
227
-     * @var EE_Attendee
228
-     */
229
-    public $primary_attendee_obj;
230
-
231
-    /**
232
-     *    $payment_method - the payment method object for the selected method of payment
233
-     *
234
-     * @var EE_Payment_Method
235
-     */
236
-    public $payment_method;
237
-
238
-    /**
239
-     *    $payment - if a payment was successfully made during the reg process,
240
-     *    then here it is !!!
241
-     *
242
-     * @var EE_Payment
243
-     */
244
-    public $payment;
245
-
246
-    /**
247
-     *    if a payment method was selected that uses an on-site gateway, then this is the billing form
248
-     *
249
-     * @var EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form
250
-     */
251
-    public $billing_form;
252
-
253
-    /**
254
-     *    the entire registration form composed of ALL of the subsections generated by the various reg steps
255
-     *
256
-     * @var EE_Form_Section_Proper
257
-     */
258
-    public $registration_form;
259
-
260
-    /**
261
-     * array of EE_SPCO_Reg_Step objects
262
-     *
263
-     * @var EE_SPCO_Reg_Step[]
264
-     */
265
-    public $reg_steps = array();
266
-
267
-    /**
268
-     * array of EE_Payment_Method objects
269
-     *
270
-     * @var EE_Payment_Method[]
271
-     */
272
-    public $available_payment_methods = array();
273
-
274
-
275
-    /**
276
-     *    class constructor
277
-     *
278
-     * @access    public
279
-     */
280
-    public function __construct()
281
-    {
282
-        $this->reg_page_base_url = EE_Registry::instance()->CFG->core->reg_page_url();
283
-        $this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
284
-        $this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
285
-        $this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
286
-        $this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
287
-        $this->reg_cache_where_params = array(
288
-            0          => array('REG_deleted' => false),
289
-            'order_by' => array('REG_count' => 'ASC'),
290
-        );
291
-    }
292
-
293
-
294
-    /**
295
-     * returns true if ANY reg status was updated during checkout
296
-     *
297
-     * @return boolean
298
-     */
299
-    public function any_reg_status_updated()
300
-    {
301
-        foreach ($this->reg_status_updated as $reg_status) {
302
-            if ($reg_status) {
303
-                return true;
304
-            }
305
-        }
306
-        return false;
307
-    }
308
-
309
-
310
-    /**
311
-     * @param $REG_ID
312
-     * @return boolean
313
-     */
314
-    public function reg_status_updated($REG_ID)
315
-    {
316
-        return isset($this->reg_status_updated[ $REG_ID ]) ? $this->reg_status_updated[ $REG_ID ] : false;
317
-    }
318
-
319
-
320
-    /**
321
-     * @param $REG_ID
322
-     * @param $reg_status
323
-     */
324
-    public function set_reg_status_updated($REG_ID, $reg_status)
325
-    {
326
-        $this->reg_status_updated[ $REG_ID ] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
327
-    }
328
-
329
-
330
-    /**
331
-     * exit_spco
332
-     *
333
-     * @return bool
334
-     */
335
-    public function exit_spco()
336
-    {
337
-        return $this->exit_spco;
338
-    }
339
-
340
-
341
-    /**
342
-     * set_exit_spco
343
-     * can ONLY be set by the  Finalize_Registration reg step
344
-     */
345
-    public function set_exit_spco()
346
-    {
347
-        if ($this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
348
-            $this->exit_spco = true;
349
-        }
350
-    }
351
-
352
-
353
-    /**
354
-     *    reset_for_current_request
355
-     *
356
-     * @access    public
357
-     * @return    void
358
-     */
359
-    public function reset_for_current_request()
360
-    {
361
-        $this->process_form_submission = false;
362
-        $this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
363
-        $this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
364
-        $this->continue_reg = true;
365
-        $this->redirect = false;
366
-        // don't reset the cached redirect form if we're about to be asked to display it !!!
367
-        if (EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step') !== 'redirect_form') {
368
-            $this->redirect_form = '';
369
-        }
370
-        $this->redirect_url = '';
371
-        $this->json_response = new EE_SPCO_JSON_Response();
372
-        EE_Form_Section_Proper::reset_js_localization();
373
-    }
374
-
375
-
376
-    /**
377
-     *    add_reg_step
378
-     *
379
-     * @access    public
380
-     * @param EE_SPCO_Reg_Step $reg_step_obj
381
-     * @return    void
382
-     */
383
-    public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj)
384
-    {
385
-        $this->reg_steps[ $reg_step_obj->slug() ] = $reg_step_obj;
386
-    }
387
-
388
-
389
-    /**
390
-     * skip_reg_step
391
-     * if the current reg step does not need to run for some reason,
392
-     * then this will advance SPCO to the next reg step,
393
-     * and mark the skipped step as completed
394
-     *
395
-     * @access    public
396
-     * @param string $reg_step_slug
397
-     * @return    void
398
-     * @throws \EE_Error
399
-     */
400
-    public function skip_reg_step($reg_step_slug = '')
401
-    {
402
-        $step_to_skip = $this->find_reg_step($reg_step_slug);
403
-        if ($step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step()) {
404
-            $step_to_skip->set_is_current_step(false);
405
-            $step_to_skip->set_completed();
406
-            // advance to the next step
407
-            $this->set_current_step($this->next_step->slug());
408
-            // also reset the step param in the request in case any other code references that directly
409
-            EE_Registry::instance()->REQ->set('step', $this->current_step->slug());
410
-            // since we are skipping a step and setting the current step to be what was previously the next step,
411
-            // we need to check that the next step is now correct, and not still set to the current step.
412
-            if ($this->current_step->slug() === $this->next_step->slug()) {
413
-                // correctly setup the next step
414
-                $this->set_next_step();
415
-            }
416
-            $this->set_reg_step_initiated($this->current_step);
417
-        }
418
-    }
419
-
420
-
421
-    /**
422
-     *    remove_reg_step
423
-     *
424
-     * @access    public
425
-     * @param string $reg_step_slug
426
-     * @param bool   $reset whether to reset reg steps after removal
427
-     * @throws EE_Error
428
-     */
429
-    public function remove_reg_step($reg_step_slug = '', $reset = true)
430
-    {
431
-        unset($this->reg_steps[ $reg_step_slug ]);
432
-        if ($this->transaction instanceof EE_Transaction) {
433
-            // now remove reg step from TXN and save
434
-            $this->transaction->remove_reg_step($reg_step_slug);
435
-            $this->transaction->save();
436
-        }
437
-        if ($reset) {
438
-            $this->reset_reg_steps();
439
-        }
440
-    }
441
-
442
-
443
-    /**
444
-     *    set_reg_step_order
445
-     *
446
-     * @access    public
447
-     * @param string $reg_step_slug
448
-     * @param int    $order
449
-     * @return    void
450
-     */
451
-    public function set_reg_step_order($reg_step_slug = '', $order = 100)
452
-    {
453
-        if (isset($this->reg_steps[ $reg_step_slug ])) {
454
-            $this->reg_steps[ $reg_step_slug ]->set_order($order);
455
-        }
456
-    }
457
-
458
-
459
-    /**
460
-     *    set_current_step
461
-     *
462
-     * @access    public
463
-     * @param string $current_step
464
-     * @return    void
465
-     */
466
-    public function set_current_step($current_step)
467
-    {
468
-        // grab what step we're on
469
-        $this->current_step = isset($this->reg_steps[ $current_step ])
470
-            ? $this->reg_steps[ $current_step ]
471
-            : reset(
472
-                $this->reg_steps
473
-            );
474
-        // verify instance
475
-        if ($this->current_step instanceof EE_SPCO_Reg_Step) {
476
-            // we don't want to repeat completed steps if this is the first time through SPCO
477
-            if ($this->continue_reg && ! $this->revisit && $this->current_step->completed()) {
478
-                // so advance to the next step
479
-                $this->set_next_step();
480
-                if ($this->next_step instanceof EE_SPCO_Reg_Step) {
481
-                    // and attempt to set it as the current step
482
-                    $this->set_current_step($this->next_step->slug());
483
-                }
484
-                return;
485
-            }
486
-            $this->current_step->set_is_current_step(true);
487
-        } else {
488
-            EE_Error::add_error(
489
-                __('The current step could not be set.', 'event_espresso'),
490
-                __FILE__,
491
-                __FUNCTION__,
492
-                __LINE__
493
-            );
494
-        }
495
-    }
496
-
497
-
498
-    /**
499
-     *    set_next_step
500
-     * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step
501
-     *
502
-     * @access    public
503
-     * @return    void
504
-     */
505
-    public function set_next_step()
506
-    {
507
-        // set pointer to start of array
508
-        reset($this->reg_steps);
509
-        // if there is more than one step
510
-        if (count($this->reg_steps) > 1) {
511
-            // advance to the current step and set pointer
512
-            while (key($this->reg_steps) !== $this->current_step->slug() && key($this->reg_steps) !== '') {
513
-                next($this->reg_steps);
514
-            }
515
-        }
516
-        // advance one more spot ( if it exists )
517
-        $this->next_step = next($this->reg_steps);
518
-        // verify instance
519
-        $this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step : null;
520
-        // then back to current step to reset
521
-        prev($this->reg_steps);
522
-    }
523
-
524
-
525
-    /**
526
-     *    get_next_reg_step
527
-     *    this simply returns the next step from reg_steps array
528
-     *
529
-     * @access    public
530
-     * @return    EE_SPCO_Reg_Step | null
531
-     */
532
-    public function get_next_reg_step()
533
-    {
534
-        $next = next($this->reg_steps);
535
-        prev($this->reg_steps);
536
-        return $next instanceof EE_SPCO_Reg_Step ? $next : null;
537
-    }
538
-
539
-
540
-    /**
541
-     * get_prev_reg_step
542
-     *    this simply returns the previous step from reg_steps array
543
-     *
544
-     * @access    public
545
-     * @return    EE_SPCO_Reg_Step | null
546
-     */
547
-    public function get_prev_reg_step()
548
-    {
549
-        $prev = prev($this->reg_steps);
550
-        next($this->reg_steps);
551
-        return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
552
-    }
553
-
554
-
555
-    /**
556
-     * sort_reg_steps
557
-     *
558
-     * @access public
559
-     * @return void
560
-     */
561
-    public function sort_reg_steps()
562
-    {
563
-        $reg_step_sorting_callback = apply_filters(
564
-            'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback',
565
-            'reg_step_sorting_callback'
566
-        );
567
-        uasort($this->reg_steps, array($this, $reg_step_sorting_callback));
568
-    }
569
-
570
-
571
-    /**
572
-     * find_reg_step
573
-     * finds a reg step by the given slug
574
-     *
575
-     * @access    public
576
-     * @param string $reg_step_slug
577
-     * @return EE_SPCO_Reg_Step|null
578
-     */
579
-    public function find_reg_step($reg_step_slug = '')
580
-    {
581
-        if (! empty($reg_step_slug)) {
582
-            // copy reg step array
583
-            $reg_steps = $this->reg_steps;
584
-            // set pointer to start of array
585
-            reset($reg_steps);
586
-            // if there is more than one step
587
-            if (count($reg_steps) > 1) {
588
-                // advance to the current step and set pointer
589
-                while (key($reg_steps) !== $reg_step_slug && key($reg_steps) !== '') {
590
-                    next($reg_steps);
591
-                }
592
-                return current($reg_steps);
593
-            }
594
-        }
595
-        return null;
596
-    }
597
-
598
-
599
-    /**
600
-     * reg_step_sorting_callback
601
-     *
602
-     * @access public
603
-     * @param EE_SPCO_Reg_Step $reg_step_A
604
-     * @param EE_SPCO_Reg_Step $reg_step_B
605
-     * @return int
606
-     */
607
-    public function reg_step_sorting_callback(EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B)
608
-    {
609
-        // send finalize_registration step to the end of the array
610
-        if ($reg_step_A->slug() === 'finalize_registration') {
611
-            return 1;
612
-        } elseif ($reg_step_B->slug() === 'finalize_registration') {
613
-            return -1;
614
-        }
615
-        if ($reg_step_A->order() === $reg_step_B->order()) {
616
-            return 0;
617
-        }
618
-        return ($reg_step_A->order() > $reg_step_B->order()) ? 1 : -1;
619
-    }
620
-
621
-
622
-    /**
623
-     * set_reg_step_initiated
624
-     *
625
-     * @access    public
626
-     * @param    EE_SPCO_Reg_Step $reg_step
627
-     * @throws \EE_Error
628
-     */
629
-    public function set_reg_step_initiated(EE_SPCO_Reg_Step $reg_step)
630
-    {
631
-        // call set_reg_step_initiated ???
632
-        if (
18
+	/**
19
+	 *    whether current request originated from the EE admin
20
+	 *
21
+	 * @var bool
22
+	 */
23
+	public $admin_request = false;
24
+
25
+	/**
26
+	 * whether returning to edit attendee information or to retry a payment
27
+	 *
28
+	 * @var bool
29
+	 */
30
+	public $revisit = false;
31
+
32
+	/**
33
+	 * whether the primary registrant is returning to edit attendee information or to retry a payment
34
+	 *
35
+	 * @var bool
36
+	 */
37
+	public $primary_revisit = false;
38
+
39
+	/**
40
+	 * is registration allowed to progress or halted for some reason such as failing to pass recaptcha?
41
+	 *
42
+	 * @var bool
43
+	 */
44
+	public $continue_reg = true;
45
+
46
+	/**
47
+	 * redirect to thank you page ?
48
+	 *
49
+	 * @var bool
50
+	 */
51
+	public $redirect = false;
52
+
53
+	/**
54
+	 * generate the reg form or not ?
55
+	 *
56
+	 * @var bool
57
+	 */
58
+	public $generate_reg_form = true;
59
+
60
+	/**
61
+	 * process a reg form submission or not ?
62
+	 *
63
+	 * @var bool
64
+	 */
65
+	public $process_form_submission = false;
66
+
67
+	/**
68
+	 * tracks whether the TXN status modified during this checkout
69
+	 *
70
+	 * @var bool
71
+	 */
72
+	public $txn_status_updated = false;
73
+
74
+	/**
75
+	 * only triggered to true after absolutely everything has finished.
76
+	 *
77
+	 * @var bool
78
+	 */
79
+	protected $exit_spco = false;
80
+
81
+	/**
82
+	 * tracks whether any of the TXN's Registrations statuses modified during this checkout
83
+	 * indexed by registration ID
84
+	 *
85
+	 * @var array
86
+	 */
87
+	protected $reg_status_updated = array();
88
+
89
+	/**
90
+	 * timestamp when redirected from Ticket Selector to the checkout
91
+	 *
92
+	 * @var int
93
+	 */
94
+	public $uts = 0;
95
+
96
+	/**
97
+	 * total number of tickets that were in the cart
98
+	 *
99
+	 * @var int
100
+	 */
101
+	public $total_ticket_count = 0;
102
+
103
+	/**
104
+	 * corresponds loosely to EE_Transaction::remaining()
105
+	 * but can be modified by SPCO
106
+	 *
107
+	 * @var float
108
+	 */
109
+	public $amount_owing = 0;
110
+
111
+	/**
112
+	 * the reg step slug from the incoming request
113
+	 *
114
+	 * @var string
115
+	 */
116
+	public $step = '';
117
+
118
+	/**
119
+	 * the reg step slug for a step being edited
120
+	 *
121
+	 * @var string
122
+	 */
123
+	public $edit_step = '';
124
+
125
+	/**
126
+	 * the action being performed on the current step
127
+	 *
128
+	 * @var string
129
+	 */
130
+	public $action = '';
131
+
132
+	/**
133
+	 * reg_url_link for a previously saved registration
134
+	 *
135
+	 * @var string
136
+	 */
137
+	public $reg_url_link = '';
138
+
139
+	/**
140
+	 * string slug for the payment method that was selected during the payment options step
141
+	 *
142
+	 * @var string
143
+	 */
144
+	public $selected_method_of_payment = '';
145
+
146
+	/**
147
+	 * base url for the site's registration checkout page - additional url params will be added to this
148
+	 *
149
+	 * @var string
150
+	 */
151
+	public $reg_page_base_url = '';
152
+
153
+	/**
154
+	 * base url for the site's registration cancelled page - additional url params will be added to this
155
+	 *
156
+	 * @var string
157
+	 */
158
+	public $cancel_page_url = '';
159
+
160
+	/**
161
+	 * base url for the site's thank you page - additional url params will be added to this
162
+	 *
163
+	 * @var string
164
+	 */
165
+	public $thank_you_page_url = '';
166
+
167
+	/**
168
+	 * base url for any redirects - additional url params will be added to this
169
+	 *
170
+	 * @var string
171
+	 */
172
+	public $redirect_url = '';
173
+
174
+	/**
175
+	 * form of POST data for use with off-site gateways
176
+	 *
177
+	 * @var string
178
+	 */
179
+	public $redirect_form = '';
180
+
181
+	/**
182
+	 * array of query where params to use when retrieving cached registrations from $this->checkout->transaction
183
+	 *
184
+	 * @var array
185
+	 */
186
+	public $reg_cache_where_params = array();
187
+
188
+	/**
189
+	 * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX
190
+	 * requests
191
+	 *
192
+	 * @var EE_SPCO_JSON_Response
193
+	 */
194
+	public $json_response;
195
+
196
+	/**
197
+	 * where we are going next in the reg process
198
+	 *
199
+	 * @var EE_SPCO_Reg_Step
200
+	 */
201
+	public $next_step;
202
+
203
+	/**
204
+	 * where we are in the reg process
205
+	 *
206
+	 * @var EE_SPCO_Reg_Step
207
+	 */
208
+	public $current_step;
209
+
210
+	/**
211
+	 *    $_cart - the current cart object
212
+	 *
213
+	 * @var EE_CART
214
+	 */
215
+	public $cart;
216
+
217
+	/**
218
+	 *    $_transaction - the current transaction object
219
+	 *
220
+	 * @var EE_Transaction
221
+	 */
222
+	public $transaction;
223
+
224
+	/**
225
+	 *    the related attendee object for the primary registrant
226
+	 *
227
+	 * @var EE_Attendee
228
+	 */
229
+	public $primary_attendee_obj;
230
+
231
+	/**
232
+	 *    $payment_method - the payment method object for the selected method of payment
233
+	 *
234
+	 * @var EE_Payment_Method
235
+	 */
236
+	public $payment_method;
237
+
238
+	/**
239
+	 *    $payment - if a payment was successfully made during the reg process,
240
+	 *    then here it is !!!
241
+	 *
242
+	 * @var EE_Payment
243
+	 */
244
+	public $payment;
245
+
246
+	/**
247
+	 *    if a payment method was selected that uses an on-site gateway, then this is the billing form
248
+	 *
249
+	 * @var EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form
250
+	 */
251
+	public $billing_form;
252
+
253
+	/**
254
+	 *    the entire registration form composed of ALL of the subsections generated by the various reg steps
255
+	 *
256
+	 * @var EE_Form_Section_Proper
257
+	 */
258
+	public $registration_form;
259
+
260
+	/**
261
+	 * array of EE_SPCO_Reg_Step objects
262
+	 *
263
+	 * @var EE_SPCO_Reg_Step[]
264
+	 */
265
+	public $reg_steps = array();
266
+
267
+	/**
268
+	 * array of EE_Payment_Method objects
269
+	 *
270
+	 * @var EE_Payment_Method[]
271
+	 */
272
+	public $available_payment_methods = array();
273
+
274
+
275
+	/**
276
+	 *    class constructor
277
+	 *
278
+	 * @access    public
279
+	 */
280
+	public function __construct()
281
+	{
282
+		$this->reg_page_base_url = EE_Registry::instance()->CFG->core->reg_page_url();
283
+		$this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
284
+		$this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
285
+		$this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
286
+		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
287
+		$this->reg_cache_where_params = array(
288
+			0          => array('REG_deleted' => false),
289
+			'order_by' => array('REG_count' => 'ASC'),
290
+		);
291
+	}
292
+
293
+
294
+	/**
295
+	 * returns true if ANY reg status was updated during checkout
296
+	 *
297
+	 * @return boolean
298
+	 */
299
+	public function any_reg_status_updated()
300
+	{
301
+		foreach ($this->reg_status_updated as $reg_status) {
302
+			if ($reg_status) {
303
+				return true;
304
+			}
305
+		}
306
+		return false;
307
+	}
308
+
309
+
310
+	/**
311
+	 * @param $REG_ID
312
+	 * @return boolean
313
+	 */
314
+	public function reg_status_updated($REG_ID)
315
+	{
316
+		return isset($this->reg_status_updated[ $REG_ID ]) ? $this->reg_status_updated[ $REG_ID ] : false;
317
+	}
318
+
319
+
320
+	/**
321
+	 * @param $REG_ID
322
+	 * @param $reg_status
323
+	 */
324
+	public function set_reg_status_updated($REG_ID, $reg_status)
325
+	{
326
+		$this->reg_status_updated[ $REG_ID ] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
327
+	}
328
+
329
+
330
+	/**
331
+	 * exit_spco
332
+	 *
333
+	 * @return bool
334
+	 */
335
+	public function exit_spco()
336
+	{
337
+		return $this->exit_spco;
338
+	}
339
+
340
+
341
+	/**
342
+	 * set_exit_spco
343
+	 * can ONLY be set by the  Finalize_Registration reg step
344
+	 */
345
+	public function set_exit_spco()
346
+	{
347
+		if ($this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
348
+			$this->exit_spco = true;
349
+		}
350
+	}
351
+
352
+
353
+	/**
354
+	 *    reset_for_current_request
355
+	 *
356
+	 * @access    public
357
+	 * @return    void
358
+	 */
359
+	public function reset_for_current_request()
360
+	{
361
+		$this->process_form_submission = false;
362
+		$this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
363
+		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
364
+		$this->continue_reg = true;
365
+		$this->redirect = false;
366
+		// don't reset the cached redirect form if we're about to be asked to display it !!!
367
+		if (EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step') !== 'redirect_form') {
368
+			$this->redirect_form = '';
369
+		}
370
+		$this->redirect_url = '';
371
+		$this->json_response = new EE_SPCO_JSON_Response();
372
+		EE_Form_Section_Proper::reset_js_localization();
373
+	}
374
+
375
+
376
+	/**
377
+	 *    add_reg_step
378
+	 *
379
+	 * @access    public
380
+	 * @param EE_SPCO_Reg_Step $reg_step_obj
381
+	 * @return    void
382
+	 */
383
+	public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj)
384
+	{
385
+		$this->reg_steps[ $reg_step_obj->slug() ] = $reg_step_obj;
386
+	}
387
+
388
+
389
+	/**
390
+	 * skip_reg_step
391
+	 * if the current reg step does not need to run for some reason,
392
+	 * then this will advance SPCO to the next reg step,
393
+	 * and mark the skipped step as completed
394
+	 *
395
+	 * @access    public
396
+	 * @param string $reg_step_slug
397
+	 * @return    void
398
+	 * @throws \EE_Error
399
+	 */
400
+	public function skip_reg_step($reg_step_slug = '')
401
+	{
402
+		$step_to_skip = $this->find_reg_step($reg_step_slug);
403
+		if ($step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step()) {
404
+			$step_to_skip->set_is_current_step(false);
405
+			$step_to_skip->set_completed();
406
+			// advance to the next step
407
+			$this->set_current_step($this->next_step->slug());
408
+			// also reset the step param in the request in case any other code references that directly
409
+			EE_Registry::instance()->REQ->set('step', $this->current_step->slug());
410
+			// since we are skipping a step and setting the current step to be what was previously the next step,
411
+			// we need to check that the next step is now correct, and not still set to the current step.
412
+			if ($this->current_step->slug() === $this->next_step->slug()) {
413
+				// correctly setup the next step
414
+				$this->set_next_step();
415
+			}
416
+			$this->set_reg_step_initiated($this->current_step);
417
+		}
418
+	}
419
+
420
+
421
+	/**
422
+	 *    remove_reg_step
423
+	 *
424
+	 * @access    public
425
+	 * @param string $reg_step_slug
426
+	 * @param bool   $reset whether to reset reg steps after removal
427
+	 * @throws EE_Error
428
+	 */
429
+	public function remove_reg_step($reg_step_slug = '', $reset = true)
430
+	{
431
+		unset($this->reg_steps[ $reg_step_slug ]);
432
+		if ($this->transaction instanceof EE_Transaction) {
433
+			// now remove reg step from TXN and save
434
+			$this->transaction->remove_reg_step($reg_step_slug);
435
+			$this->transaction->save();
436
+		}
437
+		if ($reset) {
438
+			$this->reset_reg_steps();
439
+		}
440
+	}
441
+
442
+
443
+	/**
444
+	 *    set_reg_step_order
445
+	 *
446
+	 * @access    public
447
+	 * @param string $reg_step_slug
448
+	 * @param int    $order
449
+	 * @return    void
450
+	 */
451
+	public function set_reg_step_order($reg_step_slug = '', $order = 100)
452
+	{
453
+		if (isset($this->reg_steps[ $reg_step_slug ])) {
454
+			$this->reg_steps[ $reg_step_slug ]->set_order($order);
455
+		}
456
+	}
457
+
458
+
459
+	/**
460
+	 *    set_current_step
461
+	 *
462
+	 * @access    public
463
+	 * @param string $current_step
464
+	 * @return    void
465
+	 */
466
+	public function set_current_step($current_step)
467
+	{
468
+		// grab what step we're on
469
+		$this->current_step = isset($this->reg_steps[ $current_step ])
470
+			? $this->reg_steps[ $current_step ]
471
+			: reset(
472
+				$this->reg_steps
473
+			);
474
+		// verify instance
475
+		if ($this->current_step instanceof EE_SPCO_Reg_Step) {
476
+			// we don't want to repeat completed steps if this is the first time through SPCO
477
+			if ($this->continue_reg && ! $this->revisit && $this->current_step->completed()) {
478
+				// so advance to the next step
479
+				$this->set_next_step();
480
+				if ($this->next_step instanceof EE_SPCO_Reg_Step) {
481
+					// and attempt to set it as the current step
482
+					$this->set_current_step($this->next_step->slug());
483
+				}
484
+				return;
485
+			}
486
+			$this->current_step->set_is_current_step(true);
487
+		} else {
488
+			EE_Error::add_error(
489
+				__('The current step could not be set.', 'event_espresso'),
490
+				__FILE__,
491
+				__FUNCTION__,
492
+				__LINE__
493
+			);
494
+		}
495
+	}
496
+
497
+
498
+	/**
499
+	 *    set_next_step
500
+	 * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step
501
+	 *
502
+	 * @access    public
503
+	 * @return    void
504
+	 */
505
+	public function set_next_step()
506
+	{
507
+		// set pointer to start of array
508
+		reset($this->reg_steps);
509
+		// if there is more than one step
510
+		if (count($this->reg_steps) > 1) {
511
+			// advance to the current step and set pointer
512
+			while (key($this->reg_steps) !== $this->current_step->slug() && key($this->reg_steps) !== '') {
513
+				next($this->reg_steps);
514
+			}
515
+		}
516
+		// advance one more spot ( if it exists )
517
+		$this->next_step = next($this->reg_steps);
518
+		// verify instance
519
+		$this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step : null;
520
+		// then back to current step to reset
521
+		prev($this->reg_steps);
522
+	}
523
+
524
+
525
+	/**
526
+	 *    get_next_reg_step
527
+	 *    this simply returns the next step from reg_steps array
528
+	 *
529
+	 * @access    public
530
+	 * @return    EE_SPCO_Reg_Step | null
531
+	 */
532
+	public function get_next_reg_step()
533
+	{
534
+		$next = next($this->reg_steps);
535
+		prev($this->reg_steps);
536
+		return $next instanceof EE_SPCO_Reg_Step ? $next : null;
537
+	}
538
+
539
+
540
+	/**
541
+	 * get_prev_reg_step
542
+	 *    this simply returns the previous step from reg_steps array
543
+	 *
544
+	 * @access    public
545
+	 * @return    EE_SPCO_Reg_Step | null
546
+	 */
547
+	public function get_prev_reg_step()
548
+	{
549
+		$prev = prev($this->reg_steps);
550
+		next($this->reg_steps);
551
+		return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
552
+	}
553
+
554
+
555
+	/**
556
+	 * sort_reg_steps
557
+	 *
558
+	 * @access public
559
+	 * @return void
560
+	 */
561
+	public function sort_reg_steps()
562
+	{
563
+		$reg_step_sorting_callback = apply_filters(
564
+			'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback',
565
+			'reg_step_sorting_callback'
566
+		);
567
+		uasort($this->reg_steps, array($this, $reg_step_sorting_callback));
568
+	}
569
+
570
+
571
+	/**
572
+	 * find_reg_step
573
+	 * finds a reg step by the given slug
574
+	 *
575
+	 * @access    public
576
+	 * @param string $reg_step_slug
577
+	 * @return EE_SPCO_Reg_Step|null
578
+	 */
579
+	public function find_reg_step($reg_step_slug = '')
580
+	{
581
+		if (! empty($reg_step_slug)) {
582
+			// copy reg step array
583
+			$reg_steps = $this->reg_steps;
584
+			// set pointer to start of array
585
+			reset($reg_steps);
586
+			// if there is more than one step
587
+			if (count($reg_steps) > 1) {
588
+				// advance to the current step and set pointer
589
+				while (key($reg_steps) !== $reg_step_slug && key($reg_steps) !== '') {
590
+					next($reg_steps);
591
+				}
592
+				return current($reg_steps);
593
+			}
594
+		}
595
+		return null;
596
+	}
597
+
598
+
599
+	/**
600
+	 * reg_step_sorting_callback
601
+	 *
602
+	 * @access public
603
+	 * @param EE_SPCO_Reg_Step $reg_step_A
604
+	 * @param EE_SPCO_Reg_Step $reg_step_B
605
+	 * @return int
606
+	 */
607
+	public function reg_step_sorting_callback(EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B)
608
+	{
609
+		// send finalize_registration step to the end of the array
610
+		if ($reg_step_A->slug() === 'finalize_registration') {
611
+			return 1;
612
+		} elseif ($reg_step_B->slug() === 'finalize_registration') {
613
+			return -1;
614
+		}
615
+		if ($reg_step_A->order() === $reg_step_B->order()) {
616
+			return 0;
617
+		}
618
+		return ($reg_step_A->order() > $reg_step_B->order()) ? 1 : -1;
619
+	}
620
+
621
+
622
+	/**
623
+	 * set_reg_step_initiated
624
+	 *
625
+	 * @access    public
626
+	 * @param    EE_SPCO_Reg_Step $reg_step
627
+	 * @throws \EE_Error
628
+	 */
629
+	public function set_reg_step_initiated(EE_SPCO_Reg_Step $reg_step)
630
+	{
631
+		// call set_reg_step_initiated ???
632
+		if (
633 633
 // first time visiting SPCO ?
634
-            ! $this->revisit
635
-            && (
636
-                // and displaying the reg step form for the first time ?
637
-                $this->action === 'display_spco_reg_step'
638
-                // or initializing the final step
639
-                || $reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration
640
-            )
641
-        ) {
642
-            // set the start time for this reg step
643
-            if (! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
644
-                if (WP_DEBUG) {
645
-                    EE_Error::add_error(
646
-                        sprintf(
647
-                            __('The "%1$s" registration step was not initialized properly.', 'event_espresso'),
648
-                            $reg_step->name()
649
-                        ),
650
-                        __FILE__,
651
-                        __FUNCTION__,
652
-                        __LINE__
653
-                    );
654
-                }
655
-            }
656
-        }
657
-    }
658
-
659
-
660
-    /**
661
-     *    set_reg_step_JSON_info
662
-     *
663
-     * @access public
664
-     * @return    void
665
-     */
666
-    public function set_reg_step_JSON_info()
667
-    {
668
-        EE_Registry::$i18n_js_strings['reg_steps'] = array();
669
-        // pass basic reg step data to JS
670
-        foreach ($this->reg_steps as $reg_step) {
671
-            EE_Registry::$i18n_js_strings['reg_steps'][] = $reg_step->slug();
672
-        }
673
-        // reset reg step html
674
-        // $this->json_response->set_reg_step_html('');
675
-    }
676
-
677
-
678
-    /**
679
-     *    reset_reg_steps
680
-     *
681
-     * @access public
682
-     * @return void
683
-     */
684
-    public function reset_reg_steps()
685
-    {
686
-        $this->sort_reg_steps();
687
-        $this->set_current_step(EE_Registry::instance()->REQ->get('step'));
688
-        $this->set_next_step();
689
-        // the text that appears on the reg step form submit button
690
-        $this->current_step->set_submit_button_text();
691
-        $this->set_reg_step_JSON_info();
692
-    }
693
-
694
-
695
-    /**
696
-     *    get_registration_time_limit
697
-     *
698
-     * @access    public
699
-     * @return        string
700
-     */
701
-    public function get_registration_time_limit()
702
-    {
703
-        $registration_time_limit = (float) (EE_Registry::instance()->SSN->expiration() - time());
704
-        $time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
705
-        $registration_time_limit = date($time_limit_format, $registration_time_limit);
706
-        return apply_filters(
707
-            'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
708
-            $registration_time_limit
709
-        );
710
-    }
711
-
712
-
713
-    /**
714
-     * payment_required
715
-     *
716
-     * @return boolean
717
-     */
718
-    public function payment_required()
719
-    {
720
-        // if NOT:
721
-        //     registration via admin
722
-        //      completed TXN
723
-        //      overpaid TXN
724
-        //      free TXN(total = 0.00)
725
-        //      then payment required is TRUE
726
-        return ! ($this->admin_request
727
-                  || $this->transaction->is_completed()
728
-                  || $this->transaction->is_overpaid()
729
-                  || $this->transaction->is_free()) ? true : false;
730
-    }
731
-
732
-
733
-    /**
734
-     * get_cart_for_transaction
735
-     *
736
-     * @access public
737
-     * @param EE_Transaction $transaction
738
-     * @return EE_Cart
739
-     */
740
-    public function get_cart_for_transaction($transaction)
741
-    {
742
-        $session = EE_Registry::instance()->load_core('Session');
743
-        $cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn($transaction, $session) : null;
744
-        // verify cart
745
-        if (! $cart instanceof EE_Cart) {
746
-            $cart = EE_Registry::instance()->load_core('Cart');
747
-        }
748
-
749
-        return $cart;
750
-    }
751
-
752
-
753
-    /**
754
-     *    initialize_txn_reg_steps_array
755
-     *
756
-     * @access public
757
-     * @return    array
758
-     */
759
-    public function initialize_txn_reg_steps_array()
760
-    {
761
-        $txn_reg_steps_array = array();
762
-        foreach ($this->reg_steps as $reg_step) {
763
-            $txn_reg_steps_array[ $reg_step->slug() ] = false;
764
-        }
765
-        return $txn_reg_steps_array;
766
-    }
767
-
768
-
769
-    /**
770
-     *    update_txn_reg_steps_array
771
-     *
772
-     * @access public
773
-     * @return    bool
774
-     * @throws \EE_Error
775
-     */
776
-    public function update_txn_reg_steps_array()
777
-    {
778
-        $updated = false;
779
-        foreach ($this->reg_steps as $reg_step) {
780
-            if ($reg_step->completed()) {
781
-                $updated = $this->transaction->set_reg_step_completed($reg_step->slug())
782
-                    ? true
783
-                    : $updated;
784
-            }
785
-        }
786
-        if ($updated) {
787
-            $this->transaction->save();
788
-        }
789
-        return $updated;
790
-    }
791
-
792
-
793
-    /**
794
-     *    stash_transaction_and_checkout
795
-     *
796
-     * @access public
797
-     * @return    void
798
-     * @throws \EE_Error
799
-     */
800
-    public function stash_transaction_and_checkout()
801
-    {
802
-        if (! $this->revisit) {
803
-            $this->update_txn_reg_steps_array();
804
-        }
805
-        $this->track_transaction_and_registration_status_updates();
806
-        // save all data to the db, but suppress errors
807
-        // $this->save_all_data( FALSE );
808
-        // cache the checkout in the session
809
-        EE_Registry::instance()->SSN->set_checkout($this);
810
-    }
811
-
812
-
813
-    /**
814
-     *    track_transaction_and_registration_status_updates
815
-     *    stores whether any updates were made to the TXN or it's related registrations
816
-     *
817
-     * @access public
818
-     * @return void
819
-     * @throws \EE_Error
820
-     */
821
-    public function track_transaction_and_registration_status_updates()
822
-    {
823
-        // verify the transaction
824
-        if ($this->transaction instanceof EE_Transaction) {
825
-            // has there been a TXN status change during this checkout?
826
-            $this->txn_status_updated = $this->transaction->txn_status_updated();
827
-            /** @type EE_Registration_Processor $registration_processor */
828
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
829
-            // grab the saved registrations from the transaction
830
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
831
-                if ($registration_processor->reg_status_updated($registration->ID())) {
832
-                    $this->set_reg_status_updated($registration->ID(), true);
833
-                }
834
-            }
835
-        }
836
-    }
837
-
838
-
839
-    /**
840
-     *    visit_allows_processing_of_this_registration
841
-     *    determines if the current SPCO visit should allow the passed EE_Registration to be used in processing.
842
-     *    one of the following conditions must be met:
843
-     *        EITHER:    A) first time thru SPCO -> process ALL registrations ( NOT a revisit )
844
-     *        OR :        B) primary registrant is editing info -> process ALL registrations ( primary_revisit )
845
-     *        OR :        C) another registrant is editing info -> ONLY process their registration ( revisit AND their
846
-     *        reg_url_link matches )
847
-     *
848
-     * @access public
849
-     * @param    EE_Registration $registration
850
-     * @return    bool
851
-     * @throws \EE_Error
852
-     */
853
-    public function visit_allows_processing_of_this_registration(EE_Registration $registration)
854
-    {
855
-        return ! $this->revisit
856
-               || $this->primary_revisit
857
-               || (
858
-                   $this->revisit && $this->reg_url_link === $registration->reg_url_link()
859
-               )
860
-            ? true
861
-            : false;
862
-    }
863
-
864
-
865
-    /**
866
-     *    _transaction_has_primary_registration
867
-     *
868
-     * @access        private
869
-     * @return        bool
870
-     */
871
-    public function transaction_has_primary_registrant()
872
-    {
873
-        return $this->primary_attendee_obj instanceof EE_Attendee ? true : false;
874
-    }
875
-
876
-
877
-    /**
878
-     *    save_all_data
879
-     *    simply loops through the current transaction and saves all data for each registration
880
-     *
881
-     * @access public
882
-     * @param bool $show_errors
883
-     * @return bool
884
-     * @throws \EE_Error
885
-     */
886
-    public function save_all_data($show_errors = true)
887
-    {
888
-        // verify the transaction
889
-        if ($this->transaction instanceof EE_Transaction) {
890
-            // save to ensure that TXN has ID
891
-            $this->transaction->save();
892
-            // grab the saved registrations from the transaction
893
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
894
-                $this->_save_registration($registration, $show_errors);
895
-            }
896
-        } else {
897
-            if ($show_errors) {
898
-                EE_Error::add_error(
899
-                    __(
900
-                        'A valid Transaction was not found when attempting to save your registration information.',
901
-                        'event_espresso'
902
-                    ),
903
-                    __FILE__,
904
-                    __FUNCTION__,
905
-                    __LINE__
906
-                );
907
-            }
908
-            return false;
909
-        }
910
-        return true;
911
-    }
912
-
913
-
914
-    /**
915
-     * _save_registration_attendee
916
-     *
917
-     * @param    EE_Registration $registration
918
-     * @param bool               $show_errors
919
-     * @return void
920
-     * @throws \EE_Error
921
-     */
922
-    private function _save_registration($registration, $show_errors = true)
923
-    {
924
-        // verify object
925
-        if ($registration instanceof EE_Registration) {
926
-            // should this registration be processed during this visit ?
927
-            if ($this->visit_allows_processing_of_this_registration($registration)) {
928
-                // set TXN ID
929
-                if (! $registration->transaction_ID()) {
930
-                    $registration->set_transaction_id($this->transaction->ID());
931
-                }
932
-                // verify and save the attendee
933
-                $this->_save_registration_attendee($registration, $show_errors);
934
-                // save answers to reg form questions
935
-                $this->_save_registration_answers($registration, $show_errors);
936
-                // save changes
937
-                $registration->save();
938
-                // update txn cache
939
-                if (! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
940
-                    if ($show_errors) {
941
-                        EE_Error::add_error(
942
-                            __(
943
-                                'The newly saved Registration object could not be cached on the Transaction.',
944
-                                'event_espresso'
945
-                            ),
946
-                            __FILE__,
947
-                            __FUNCTION__,
948
-                            __LINE__
949
-                        );
950
-                    }
951
-                }
952
-            }
953
-        } else {
954
-            if ($show_errors) {
955
-                EE_Error::add_error(
956
-                    __(
957
-                        'An invalid Registration object was discovered when attempting to save your registration information.',
958
-                        'event_espresso'
959
-                    ),
960
-                    __FILE__,
961
-                    __FUNCTION__,
962
-                    __LINE__
963
-                );
964
-            }
965
-        }
966
-    }
967
-
968
-
969
-    /**
970
-     * _save_registration_attendee
971
-     *
972
-     * @param    EE_Registration $registration
973
-     * @param bool               $show_errors
974
-     * @return void
975
-     * @throws \EE_Error
976
-     */
977
-    private function _save_registration_attendee($registration, $show_errors = true)
978
-    {
979
-        if ($registration->attendee() instanceof EE_Attendee) {
980
-            // save so that ATT has ID
981
-            $registration->attendee()->save();
982
-            if (! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
983
-                if ($show_errors) {
984
-                    EE_Error::add_error(
985
-                        __(
986
-                            'The newly saved Attendee object could not be cached on the registration.',
987
-                            'event_espresso'
988
-                        ),
989
-                        __FILE__,
990
-                        __FUNCTION__,
991
-                        __LINE__
992
-                    );
993
-                }
994
-            }
995
-        } else {
996
-            if ($show_errors) {
997
-                EE_Error::add_error(
998
-                    sprintf(
999
-                        '%1$s||%1$s $attendee = %2$s',
1000
-                        __(
1001
-                            'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.',
1002
-                            'event_espresso'
1003
-                        ),
1004
-                        var_export($registration->attendee(), true)
1005
-                    ),
1006
-                    __FILE__,
1007
-                    __FUNCTION__,
1008
-                    __LINE__
1009
-                );
1010
-            }
1011
-        }
1012
-    }
1013
-
1014
-
1015
-    /**
1016
-     * _save_question_answers
1017
-     *
1018
-     * @param    EE_Registration $registration
1019
-     * @param bool               $show_errors
1020
-     * @return void
1021
-     * @throws \EE_Error
1022
-     */
1023
-    private function _save_registration_answers($registration, $show_errors = true)
1024
-    {
1025
-        // now save the answers
1026
-        foreach ($registration->answers() as $cache_key => $answer) {
1027
-            // verify object
1028
-            if ($answer instanceof EE_Answer) {
1029
-                $answer->set_registration($registration->ID());
1030
-                $answer->save();
1031
-                if (! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
1032
-                    if ($show_errors) {
1033
-                        EE_Error::add_error(
1034
-                            __(
1035
-                                'The newly saved Answer object could not be cached on the registration.',
1036
-                                'event_espresso'
1037
-                            ),
1038
-                            __FILE__,
1039
-                            __FUNCTION__,
1040
-                            __LINE__
1041
-                        );
1042
-                    }
1043
-                }
1044
-            } else {
1045
-                if ($show_errors) {
1046
-                    EE_Error::add_error(
1047
-                        __(
1048
-                            'An invalid Answer object was discovered when attempting to save your registration information.',
1049
-                            'event_espresso'
1050
-                        ),
1051
-                        __FILE__,
1052
-                        __FUNCTION__,
1053
-                        __LINE__
1054
-                    );
1055
-                }
1056
-            }
1057
-        }
1058
-    }
1059
-
1060
-
1061
-    /**
1062
-     *    refresh_all_entities
1063
-     *   will either refresh the entity map with objects form the db or from the checkout cache
1064
-     *
1065
-     * @access public
1066
-     * @param bool $from_db
1067
-     * @return bool
1068
-     * @throws \EE_Error
1069
-     */
1070
-    public function refresh_all_entities($from_db = false)
1071
-    {
1072
-        $from_db = $this->current_step->is_final_step() || $this->action === 'process_gateway_response'
1073
-            ? true
1074
-            : $from_db;
1075
-        // $this->log(
1076
-        //     __CLASS__,
1077
-        //     __FUNCTION__,
1078
-        //     __LINE__,
1079
-        //     array('from_db' => $from_db)
1080
-        // );
1081
-        return $from_db ? $this->refresh_from_db() : $this->refresh_entity_map();
1082
-    }
1083
-
1084
-
1085
-    /**
1086
-     *  refresh_entity_map
1087
-     *  simply loops through the current transaction and updates each
1088
-     *  model's entity map using EEM_Base::refresh_entity_map_from_db()
1089
-     *
1090
-     * @access public
1091
-     * @return bool
1092
-     * @throws \EE_Error
1093
-     */
1094
-    protected function refresh_from_db()
1095
-    {
1096
-        // verify the transaction
1097
-        if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1098
-            // pull fresh TXN data from the db
1099
-            $this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db($this->transaction->ID());
1100
-            // update EE_Checkout's cached primary_attendee object
1101
-            $this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db($this->transaction);
1102
-            // update EE_Checkout's cached payment object
1103
-            $payment = $this->transaction->last_payment();
1104
-            $this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
1105
-            // update EE_Checkout's cached payment_method object
1106
-            $payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
1107
-            $this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method
1108
-                : $this->payment_method;
1109
-            // now refresh the cart, based on the TXN
1110
-            $this->cart = $this->get_cart_for_transaction($this->transaction);
1111
-        } else {
1112
-            EE_Error::add_error(
1113
-                __(
1114
-                    'A valid Transaction was not found when attempting to update the model entity mapper.',
1115
-                    'event_espresso'
1116
-                ),
1117
-                __FILE__,
1118
-                __FUNCTION__,
1119
-                __LINE__
1120
-            );
1121
-            return false;
1122
-        }
1123
-        return true;
1124
-    }
1125
-
1126
-
1127
-    /**
1128
-     * _refresh_primary_attendee_obj_from_db
1129
-     *
1130
-     * @param   EE_Transaction $transaction
1131
-     * @return  EE_Attendee | null
1132
-     * @throws \EE_Error
1133
-     */
1134
-    protected function _refresh_primary_attendee_obj_from_db(EE_Transaction $transaction)
1135
-    {
1136
-        $primary_attendee_obj = null;
1137
-        // grab the saved registrations from the transaction
1138
-        foreach ($transaction->registrations($this->reg_cache_where_params, true) as $registration) {
1139
-            // verify object
1140
-            if ($registration instanceof EE_Registration) {
1141
-                $attendee = $registration->attendee();
1142
-                // verify object && maybe cache primary_attendee_obj ?
1143
-                if ($attendee instanceof EE_Attendee && $registration->is_primary_registrant()) {
1144
-                    $primary_attendee_obj = $attendee;
1145
-                }
1146
-            } else {
1147
-                EE_Error::add_error(
1148
-                    __(
1149
-                        'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1150
-                        'event_espresso'
1151
-                    ),
1152
-                    __FILE__,
1153
-                    __FUNCTION__,
1154
-                    __LINE__
1155
-                );
1156
-            }
1157
-        }
1158
-        return $primary_attendee_obj;
1159
-    }
1160
-
1161
-
1162
-    /**
1163
-     *  refresh_entity_map
1164
-     *  simply loops through the current transaction and updates
1165
-     *  each model's entity map using EEM_Base::refresh_entity_map_with()
1166
-     *
1167
-     * @access public
1168
-     * @return bool
1169
-     * @throws \EE_Error
1170
-     */
1171
-    protected function refresh_entity_map()
1172
-    {
1173
-        // verify the transaction
1174
-        if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1175
-            // never cache payment info
1176
-            $this->transaction->clear_cache('Payment');
1177
-            // is the Payment Options Reg Step completed ?
1178
-            if ($this->transaction->reg_step_completed('payment_options')) {
1179
-                // then check for payments and update TXN accordingly
1180
-                /** @type EE_Transaction_Payments $transaction_payments */
1181
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1182
-                $transaction_payments->calculate_total_payments_and_update_status($this->transaction);
1183
-            }
1184
-            // grab the saved registrations from the transaction
1185
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $reg_cache_ID => $registration) {
1186
-                $this->_refresh_registration($reg_cache_ID, $registration);
1187
-            }
1188
-            // make sure our cached TXN is added to the model entity mapper
1189
-            $this->transaction = $this->transaction->get_model()->refresh_entity_map_with(
1190
-                $this->transaction->ID(),
1191
-                $this->transaction
1192
-            );
1193
-        } else {
1194
-            EE_Error::add_error(
1195
-                __(
1196
-                    'A valid Transaction was not found when attempting to update the model entity mapper.',
1197
-                    'event_espresso'
1198
-                ),
1199
-                __FILE__,
1200
-                __FUNCTION__,
1201
-                __LINE__
1202
-            );
1203
-            return false;
1204
-        }
1205
-        // verify and update the cart because inaccurate totals are not so much fun
1206
-        if ($this->cart instanceof EE_Cart) {
1207
-            $grand_total = $this->cart->get_grand_total();
1208
-            if ($grand_total instanceof EE_Line_Item && $grand_total->ID()) {
1209
-                $grand_total->recalculate_total_including_taxes();
1210
-                $grand_total = $grand_total->get_model()->refresh_entity_map_with(
1211
-                    $this->cart->get_grand_total()->ID(),
1212
-                    $this->cart->get_grand_total()
1213
-                );
1214
-            }
1215
-            if ($grand_total instanceof EE_Line_Item) {
1216
-                $this->cart = EE_Cart::instance($grand_total);
1217
-            } else {
1218
-                EE_Error::add_error(
1219
-                    __(
1220
-                        'A valid Cart was not found when attempting to update the model entity mapper.',
1221
-                        'event_espresso'
1222
-                    ),
1223
-                    __FILE__,
1224
-                    __FUNCTION__,
1225
-                    __LINE__
1226
-                );
1227
-                return false;
1228
-            }
1229
-        }
1230
-        return true;
1231
-    }
1232
-
1233
-
1234
-    /**
1235
-     * _refresh_registration
1236
-     *
1237
-     * @param    string | int    $reg_cache_ID
1238
-     * @param    EE_Registration $registration
1239
-     * @return void
1240
-     * @throws \EE_Error
1241
-     */
1242
-    protected function _refresh_registration($reg_cache_ID, $registration)
1243
-    {
1244
-
1245
-        // verify object
1246
-        if ($registration instanceof EE_Registration) {
1247
-            // update the entity mapper attendee
1248
-            $this->_refresh_registration_attendee($registration);
1249
-            // update the entity mapper answers for reg form questions
1250
-            $this->_refresh_registration_answers($registration);
1251
-            // make sure the cached registration is added to the model entity mapper
1252
-            $registration->get_model()->refresh_entity_map_with($reg_cache_ID, $registration);
1253
-        } else {
1254
-            EE_Error::add_error(
1255
-                __(
1256
-                    'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1257
-                    'event_espresso'
1258
-                ),
1259
-                __FILE__,
1260
-                __FUNCTION__,
1261
-                __LINE__
1262
-            );
1263
-        }
1264
-    }
1265
-
1266
-
1267
-    /**
1268
-     * _save_registration_attendee
1269
-     *
1270
-     * @param    EE_Registration $registration
1271
-     * @return void
1272
-     * @throws \EE_Error
1273
-     */
1274
-    protected function _refresh_registration_attendee($registration)
1275
-    {
1276
-        $attendee = $registration->attendee();
1277
-        // verify object
1278
-        if ($attendee instanceof EE_Attendee && $attendee->ID()) {
1279
-            // make sure the cached attendee is added to the model entity mapper
1280
-            $registration->attendee()->get_model()->refresh_entity_map_with($attendee->ID(), $attendee);
1281
-            // maybe cache primary_attendee_obj ?
1282
-            if ($registration->is_primary_registrant()) {
1283
-                $this->primary_attendee_obj = $attendee;
1284
-            }
1285
-        }
1286
-    }
1287
-
1288
-
1289
-    /**
1290
-     * _refresh_registration_answers
1291
-     *
1292
-     * @param    EE_Registration $registration
1293
-     * @return void
1294
-     * @throws \EE_Error
1295
-     */
1296
-    protected function _refresh_registration_answers($registration)
1297
-    {
1298
-
1299
-        // now update the answers
1300
-        foreach ($registration->answers() as $cache_key => $answer) {
1301
-            // verify object
1302
-            if ($answer instanceof EE_Answer) {
1303
-                if ($answer->ID()) {
1304
-                    // make sure the cached answer is added to the model entity mapper
1305
-                    $answer->get_model()->refresh_entity_map_with($answer->ID(), $answer);
1306
-                }
1307
-            } else {
1308
-                EE_Error::add_error(
1309
-                    __(
1310
-                        'An invalid Answer object was discovered when attempting to update the model entity mapper.',
1311
-                        'event_espresso'
1312
-                    ),
1313
-                    __FILE__,
1314
-                    __FUNCTION__,
1315
-                    __LINE__
1316
-                );
1317
-            }
1318
-        }
1319
-    }
1320
-
1321
-
1322
-    /**
1323
-     *    __sleep
1324
-     * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
1325
-     * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
1326
-     * reg form, because if needed, it will be regenerated anyways
1327
-     *
1328
-     * @return array
1329
-     * @throws \EE_Error
1330
-     */
1331
-    public function __sleep()
1332
-    {
1333
-        if ($this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID()) {
1334
-            $this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1335
-        }        // remove the reg form and the checkout
1336
-        if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1337
-            $this->transaction = $this->transaction->ID();
1338
-        }        // remove the reg form and the checkout
1339
-        return array_diff(array_keys(get_object_vars($this)), array('billing_form', 'registration_form'));
1340
-    }
1341
-
1342
-
1343
-    /**
1344
-     *    __wakeup
1345
-     * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1346
-     * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1347
-     */
1348
-    public function __wakeup()
1349
-    {
1350
-        if (! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1351
-            // $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1352
-            $this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID($this->primary_attendee_obj);
1353
-        }
1354
-        if (! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1355
-            // $this->transaction is actually just an ID, so use it to get the object from the db
1356
-            $this->transaction = EEM_Transaction::instance()->get_one_by_ID($this->transaction);
1357
-        }
1358
-        foreach ($this->reg_steps as $reg_step) {
1359
-            $reg_step->checkout = $this;
1360
-        }
1361
-    }
1362
-
1363
-
1364
-    /**
1365
-     * debug
1366
-     *
1367
-     * @param string $class
1368
-     * @param string $func
1369
-     * @param string $line
1370
-     * @param array  $info
1371
-     * @param bool   $display_request
1372
-     * @throws \EE_Error
1373
-     */
1374
-    public function log($class = '', $func = '', $line = '', $info = array(), $display_request = false)
1375
-    {
1376
-        $disabled = true;
1377
-        if (WP_DEBUG && ! $disabled) {
1378
-            $debug_data = get_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array());
1379
-            $default_data = array(
1380
-                $class                    => $func . '() : ' . $line,
1381
-                'request->step'           => $this->step,
1382
-                'request->action'         => $this->action,
1383
-                'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step ?
1384
-                    $this->current_step->slug() : '',
1385
-                'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1386
-                    $this->current_step->completed() : '',
1387
-                'txn_status_updated'      => $this->transaction->txn_status_updated(),
1388
-                'reg_status_updated'      => $this->reg_status_updated,
1389
-                'reg_url_link'            => $this->reg_url_link,
1390
-                'REQ'                     => $display_request ? $_REQUEST : '',
1391
-            );
1392
-            if ($this->transaction instanceof EE_Transaction) {
1393
-                $default_data['TXN_status'] = $this->transaction->status_ID();
1394
-                $default_data['TXN_reg_steps'] = $this->transaction->reg_steps();
1395
-                foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1396
-                    $default_data['registrations'][ $REG_ID ] = $registration->status_ID();
1397
-                }
1398
-                if ($this->transaction->ID()) {
1399
-                    $TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1400
-                    // don't serialize objects
1401
-                    $info = $this->_strip_objects($info);
1402
-                    if (! isset($debug_data[ $TXN_ID ])) {
1403
-                        $debug_data[ $TXN_ID ] = array();
1404
-                    }
1405
-                    $debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1406
-                        $default_data,
1407
-                        $info
1408
-                    );
1409
-                    update_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data);
1410
-                }
1411
-            }
1412
-        }
1413
-    }
1414
-
1415
-
1416
-    /**
1417
-     * _strip_objects
1418
-     *
1419
-     * @param array $info
1420
-     * @return array
1421
-     */
1422
-    public function _strip_objects($info = array())
1423
-    {
1424
-        foreach ((array) $info as $key => $value) {
1425
-            if (is_array($value)) {
1426
-                $info[ $key ] = $this->_strip_objects($value);
1427
-            } elseif (is_object($value)) {
1428
-                $object_class = get_class($value);
1429
-                $info[ $object_class ] = array();
1430
-                $info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
1431
-                if (method_exists($value, 'status')) {
1432
-                    $info[ $object_class ]['status'] = $value->status();
1433
-                } elseif (method_exists($value, 'status_ID')) {
1434
-                    $info[ $object_class ]['status'] = $value->status_ID();
1435
-                }
1436
-                unset($info[ $key ]);
1437
-            }
1438
-        }
1439
-        return (array) $info;
1440
-    }
634
+			! $this->revisit
635
+			&& (
636
+				// and displaying the reg step form for the first time ?
637
+				$this->action === 'display_spco_reg_step'
638
+				// or initializing the final step
639
+				|| $reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration
640
+			)
641
+		) {
642
+			// set the start time for this reg step
643
+			if (! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
644
+				if (WP_DEBUG) {
645
+					EE_Error::add_error(
646
+						sprintf(
647
+							__('The "%1$s" registration step was not initialized properly.', 'event_espresso'),
648
+							$reg_step->name()
649
+						),
650
+						__FILE__,
651
+						__FUNCTION__,
652
+						__LINE__
653
+					);
654
+				}
655
+			}
656
+		}
657
+	}
658
+
659
+
660
+	/**
661
+	 *    set_reg_step_JSON_info
662
+	 *
663
+	 * @access public
664
+	 * @return    void
665
+	 */
666
+	public function set_reg_step_JSON_info()
667
+	{
668
+		EE_Registry::$i18n_js_strings['reg_steps'] = array();
669
+		// pass basic reg step data to JS
670
+		foreach ($this->reg_steps as $reg_step) {
671
+			EE_Registry::$i18n_js_strings['reg_steps'][] = $reg_step->slug();
672
+		}
673
+		// reset reg step html
674
+		// $this->json_response->set_reg_step_html('');
675
+	}
676
+
677
+
678
+	/**
679
+	 *    reset_reg_steps
680
+	 *
681
+	 * @access public
682
+	 * @return void
683
+	 */
684
+	public function reset_reg_steps()
685
+	{
686
+		$this->sort_reg_steps();
687
+		$this->set_current_step(EE_Registry::instance()->REQ->get('step'));
688
+		$this->set_next_step();
689
+		// the text that appears on the reg step form submit button
690
+		$this->current_step->set_submit_button_text();
691
+		$this->set_reg_step_JSON_info();
692
+	}
693
+
694
+
695
+	/**
696
+	 *    get_registration_time_limit
697
+	 *
698
+	 * @access    public
699
+	 * @return        string
700
+	 */
701
+	public function get_registration_time_limit()
702
+	{
703
+		$registration_time_limit = (float) (EE_Registry::instance()->SSN->expiration() - time());
704
+		$time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
705
+		$registration_time_limit = date($time_limit_format, $registration_time_limit);
706
+		return apply_filters(
707
+			'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
708
+			$registration_time_limit
709
+		);
710
+	}
711
+
712
+
713
+	/**
714
+	 * payment_required
715
+	 *
716
+	 * @return boolean
717
+	 */
718
+	public function payment_required()
719
+	{
720
+		// if NOT:
721
+		//     registration via admin
722
+		//      completed TXN
723
+		//      overpaid TXN
724
+		//      free TXN(total = 0.00)
725
+		//      then payment required is TRUE
726
+		return ! ($this->admin_request
727
+				  || $this->transaction->is_completed()
728
+				  || $this->transaction->is_overpaid()
729
+				  || $this->transaction->is_free()) ? true : false;
730
+	}
731
+
732
+
733
+	/**
734
+	 * get_cart_for_transaction
735
+	 *
736
+	 * @access public
737
+	 * @param EE_Transaction $transaction
738
+	 * @return EE_Cart
739
+	 */
740
+	public function get_cart_for_transaction($transaction)
741
+	{
742
+		$session = EE_Registry::instance()->load_core('Session');
743
+		$cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn($transaction, $session) : null;
744
+		// verify cart
745
+		if (! $cart instanceof EE_Cart) {
746
+			$cart = EE_Registry::instance()->load_core('Cart');
747
+		}
748
+
749
+		return $cart;
750
+	}
751
+
752
+
753
+	/**
754
+	 *    initialize_txn_reg_steps_array
755
+	 *
756
+	 * @access public
757
+	 * @return    array
758
+	 */
759
+	public function initialize_txn_reg_steps_array()
760
+	{
761
+		$txn_reg_steps_array = array();
762
+		foreach ($this->reg_steps as $reg_step) {
763
+			$txn_reg_steps_array[ $reg_step->slug() ] = false;
764
+		}
765
+		return $txn_reg_steps_array;
766
+	}
767
+
768
+
769
+	/**
770
+	 *    update_txn_reg_steps_array
771
+	 *
772
+	 * @access public
773
+	 * @return    bool
774
+	 * @throws \EE_Error
775
+	 */
776
+	public function update_txn_reg_steps_array()
777
+	{
778
+		$updated = false;
779
+		foreach ($this->reg_steps as $reg_step) {
780
+			if ($reg_step->completed()) {
781
+				$updated = $this->transaction->set_reg_step_completed($reg_step->slug())
782
+					? true
783
+					: $updated;
784
+			}
785
+		}
786
+		if ($updated) {
787
+			$this->transaction->save();
788
+		}
789
+		return $updated;
790
+	}
791
+
792
+
793
+	/**
794
+	 *    stash_transaction_and_checkout
795
+	 *
796
+	 * @access public
797
+	 * @return    void
798
+	 * @throws \EE_Error
799
+	 */
800
+	public function stash_transaction_and_checkout()
801
+	{
802
+		if (! $this->revisit) {
803
+			$this->update_txn_reg_steps_array();
804
+		}
805
+		$this->track_transaction_and_registration_status_updates();
806
+		// save all data to the db, but suppress errors
807
+		// $this->save_all_data( FALSE );
808
+		// cache the checkout in the session
809
+		EE_Registry::instance()->SSN->set_checkout($this);
810
+	}
811
+
812
+
813
+	/**
814
+	 *    track_transaction_and_registration_status_updates
815
+	 *    stores whether any updates were made to the TXN or it's related registrations
816
+	 *
817
+	 * @access public
818
+	 * @return void
819
+	 * @throws \EE_Error
820
+	 */
821
+	public function track_transaction_and_registration_status_updates()
822
+	{
823
+		// verify the transaction
824
+		if ($this->transaction instanceof EE_Transaction) {
825
+			// has there been a TXN status change during this checkout?
826
+			$this->txn_status_updated = $this->transaction->txn_status_updated();
827
+			/** @type EE_Registration_Processor $registration_processor */
828
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
829
+			// grab the saved registrations from the transaction
830
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
831
+				if ($registration_processor->reg_status_updated($registration->ID())) {
832
+					$this->set_reg_status_updated($registration->ID(), true);
833
+				}
834
+			}
835
+		}
836
+	}
837
+
838
+
839
+	/**
840
+	 *    visit_allows_processing_of_this_registration
841
+	 *    determines if the current SPCO visit should allow the passed EE_Registration to be used in processing.
842
+	 *    one of the following conditions must be met:
843
+	 *        EITHER:    A) first time thru SPCO -> process ALL registrations ( NOT a revisit )
844
+	 *        OR :        B) primary registrant is editing info -> process ALL registrations ( primary_revisit )
845
+	 *        OR :        C) another registrant is editing info -> ONLY process their registration ( revisit AND their
846
+	 *        reg_url_link matches )
847
+	 *
848
+	 * @access public
849
+	 * @param    EE_Registration $registration
850
+	 * @return    bool
851
+	 * @throws \EE_Error
852
+	 */
853
+	public function visit_allows_processing_of_this_registration(EE_Registration $registration)
854
+	{
855
+		return ! $this->revisit
856
+			   || $this->primary_revisit
857
+			   || (
858
+				   $this->revisit && $this->reg_url_link === $registration->reg_url_link()
859
+			   )
860
+			? true
861
+			: false;
862
+	}
863
+
864
+
865
+	/**
866
+	 *    _transaction_has_primary_registration
867
+	 *
868
+	 * @access        private
869
+	 * @return        bool
870
+	 */
871
+	public function transaction_has_primary_registrant()
872
+	{
873
+		return $this->primary_attendee_obj instanceof EE_Attendee ? true : false;
874
+	}
875
+
876
+
877
+	/**
878
+	 *    save_all_data
879
+	 *    simply loops through the current transaction and saves all data for each registration
880
+	 *
881
+	 * @access public
882
+	 * @param bool $show_errors
883
+	 * @return bool
884
+	 * @throws \EE_Error
885
+	 */
886
+	public function save_all_data($show_errors = true)
887
+	{
888
+		// verify the transaction
889
+		if ($this->transaction instanceof EE_Transaction) {
890
+			// save to ensure that TXN has ID
891
+			$this->transaction->save();
892
+			// grab the saved registrations from the transaction
893
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
894
+				$this->_save_registration($registration, $show_errors);
895
+			}
896
+		} else {
897
+			if ($show_errors) {
898
+				EE_Error::add_error(
899
+					__(
900
+						'A valid Transaction was not found when attempting to save your registration information.',
901
+						'event_espresso'
902
+					),
903
+					__FILE__,
904
+					__FUNCTION__,
905
+					__LINE__
906
+				);
907
+			}
908
+			return false;
909
+		}
910
+		return true;
911
+	}
912
+
913
+
914
+	/**
915
+	 * _save_registration_attendee
916
+	 *
917
+	 * @param    EE_Registration $registration
918
+	 * @param bool               $show_errors
919
+	 * @return void
920
+	 * @throws \EE_Error
921
+	 */
922
+	private function _save_registration($registration, $show_errors = true)
923
+	{
924
+		// verify object
925
+		if ($registration instanceof EE_Registration) {
926
+			// should this registration be processed during this visit ?
927
+			if ($this->visit_allows_processing_of_this_registration($registration)) {
928
+				// set TXN ID
929
+				if (! $registration->transaction_ID()) {
930
+					$registration->set_transaction_id($this->transaction->ID());
931
+				}
932
+				// verify and save the attendee
933
+				$this->_save_registration_attendee($registration, $show_errors);
934
+				// save answers to reg form questions
935
+				$this->_save_registration_answers($registration, $show_errors);
936
+				// save changes
937
+				$registration->save();
938
+				// update txn cache
939
+				if (! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
940
+					if ($show_errors) {
941
+						EE_Error::add_error(
942
+							__(
943
+								'The newly saved Registration object could not be cached on the Transaction.',
944
+								'event_espresso'
945
+							),
946
+							__FILE__,
947
+							__FUNCTION__,
948
+							__LINE__
949
+						);
950
+					}
951
+				}
952
+			}
953
+		} else {
954
+			if ($show_errors) {
955
+				EE_Error::add_error(
956
+					__(
957
+						'An invalid Registration object was discovered when attempting to save your registration information.',
958
+						'event_espresso'
959
+					),
960
+					__FILE__,
961
+					__FUNCTION__,
962
+					__LINE__
963
+				);
964
+			}
965
+		}
966
+	}
967
+
968
+
969
+	/**
970
+	 * _save_registration_attendee
971
+	 *
972
+	 * @param    EE_Registration $registration
973
+	 * @param bool               $show_errors
974
+	 * @return void
975
+	 * @throws \EE_Error
976
+	 */
977
+	private function _save_registration_attendee($registration, $show_errors = true)
978
+	{
979
+		if ($registration->attendee() instanceof EE_Attendee) {
980
+			// save so that ATT has ID
981
+			$registration->attendee()->save();
982
+			if (! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
983
+				if ($show_errors) {
984
+					EE_Error::add_error(
985
+						__(
986
+							'The newly saved Attendee object could not be cached on the registration.',
987
+							'event_espresso'
988
+						),
989
+						__FILE__,
990
+						__FUNCTION__,
991
+						__LINE__
992
+					);
993
+				}
994
+			}
995
+		} else {
996
+			if ($show_errors) {
997
+				EE_Error::add_error(
998
+					sprintf(
999
+						'%1$s||%1$s $attendee = %2$s',
1000
+						__(
1001
+							'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.',
1002
+							'event_espresso'
1003
+						),
1004
+						var_export($registration->attendee(), true)
1005
+					),
1006
+					__FILE__,
1007
+					__FUNCTION__,
1008
+					__LINE__
1009
+				);
1010
+			}
1011
+		}
1012
+	}
1013
+
1014
+
1015
+	/**
1016
+	 * _save_question_answers
1017
+	 *
1018
+	 * @param    EE_Registration $registration
1019
+	 * @param bool               $show_errors
1020
+	 * @return void
1021
+	 * @throws \EE_Error
1022
+	 */
1023
+	private function _save_registration_answers($registration, $show_errors = true)
1024
+	{
1025
+		// now save the answers
1026
+		foreach ($registration->answers() as $cache_key => $answer) {
1027
+			// verify object
1028
+			if ($answer instanceof EE_Answer) {
1029
+				$answer->set_registration($registration->ID());
1030
+				$answer->save();
1031
+				if (! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
1032
+					if ($show_errors) {
1033
+						EE_Error::add_error(
1034
+							__(
1035
+								'The newly saved Answer object could not be cached on the registration.',
1036
+								'event_espresso'
1037
+							),
1038
+							__FILE__,
1039
+							__FUNCTION__,
1040
+							__LINE__
1041
+						);
1042
+					}
1043
+				}
1044
+			} else {
1045
+				if ($show_errors) {
1046
+					EE_Error::add_error(
1047
+						__(
1048
+							'An invalid Answer object was discovered when attempting to save your registration information.',
1049
+							'event_espresso'
1050
+						),
1051
+						__FILE__,
1052
+						__FUNCTION__,
1053
+						__LINE__
1054
+					);
1055
+				}
1056
+			}
1057
+		}
1058
+	}
1059
+
1060
+
1061
+	/**
1062
+	 *    refresh_all_entities
1063
+	 *   will either refresh the entity map with objects form the db or from the checkout cache
1064
+	 *
1065
+	 * @access public
1066
+	 * @param bool $from_db
1067
+	 * @return bool
1068
+	 * @throws \EE_Error
1069
+	 */
1070
+	public function refresh_all_entities($from_db = false)
1071
+	{
1072
+		$from_db = $this->current_step->is_final_step() || $this->action === 'process_gateway_response'
1073
+			? true
1074
+			: $from_db;
1075
+		// $this->log(
1076
+		//     __CLASS__,
1077
+		//     __FUNCTION__,
1078
+		//     __LINE__,
1079
+		//     array('from_db' => $from_db)
1080
+		// );
1081
+		return $from_db ? $this->refresh_from_db() : $this->refresh_entity_map();
1082
+	}
1083
+
1084
+
1085
+	/**
1086
+	 *  refresh_entity_map
1087
+	 *  simply loops through the current transaction and updates each
1088
+	 *  model's entity map using EEM_Base::refresh_entity_map_from_db()
1089
+	 *
1090
+	 * @access public
1091
+	 * @return bool
1092
+	 * @throws \EE_Error
1093
+	 */
1094
+	protected function refresh_from_db()
1095
+	{
1096
+		// verify the transaction
1097
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1098
+			// pull fresh TXN data from the db
1099
+			$this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db($this->transaction->ID());
1100
+			// update EE_Checkout's cached primary_attendee object
1101
+			$this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db($this->transaction);
1102
+			// update EE_Checkout's cached payment object
1103
+			$payment = $this->transaction->last_payment();
1104
+			$this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
1105
+			// update EE_Checkout's cached payment_method object
1106
+			$payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
1107
+			$this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method
1108
+				: $this->payment_method;
1109
+			// now refresh the cart, based on the TXN
1110
+			$this->cart = $this->get_cart_for_transaction($this->transaction);
1111
+		} else {
1112
+			EE_Error::add_error(
1113
+				__(
1114
+					'A valid Transaction was not found when attempting to update the model entity mapper.',
1115
+					'event_espresso'
1116
+				),
1117
+				__FILE__,
1118
+				__FUNCTION__,
1119
+				__LINE__
1120
+			);
1121
+			return false;
1122
+		}
1123
+		return true;
1124
+	}
1125
+
1126
+
1127
+	/**
1128
+	 * _refresh_primary_attendee_obj_from_db
1129
+	 *
1130
+	 * @param   EE_Transaction $transaction
1131
+	 * @return  EE_Attendee | null
1132
+	 * @throws \EE_Error
1133
+	 */
1134
+	protected function _refresh_primary_attendee_obj_from_db(EE_Transaction $transaction)
1135
+	{
1136
+		$primary_attendee_obj = null;
1137
+		// grab the saved registrations from the transaction
1138
+		foreach ($transaction->registrations($this->reg_cache_where_params, true) as $registration) {
1139
+			// verify object
1140
+			if ($registration instanceof EE_Registration) {
1141
+				$attendee = $registration->attendee();
1142
+				// verify object && maybe cache primary_attendee_obj ?
1143
+				if ($attendee instanceof EE_Attendee && $registration->is_primary_registrant()) {
1144
+					$primary_attendee_obj = $attendee;
1145
+				}
1146
+			} else {
1147
+				EE_Error::add_error(
1148
+					__(
1149
+						'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1150
+						'event_espresso'
1151
+					),
1152
+					__FILE__,
1153
+					__FUNCTION__,
1154
+					__LINE__
1155
+				);
1156
+			}
1157
+		}
1158
+		return $primary_attendee_obj;
1159
+	}
1160
+
1161
+
1162
+	/**
1163
+	 *  refresh_entity_map
1164
+	 *  simply loops through the current transaction and updates
1165
+	 *  each model's entity map using EEM_Base::refresh_entity_map_with()
1166
+	 *
1167
+	 * @access public
1168
+	 * @return bool
1169
+	 * @throws \EE_Error
1170
+	 */
1171
+	protected function refresh_entity_map()
1172
+	{
1173
+		// verify the transaction
1174
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1175
+			// never cache payment info
1176
+			$this->transaction->clear_cache('Payment');
1177
+			// is the Payment Options Reg Step completed ?
1178
+			if ($this->transaction->reg_step_completed('payment_options')) {
1179
+				// then check for payments and update TXN accordingly
1180
+				/** @type EE_Transaction_Payments $transaction_payments */
1181
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1182
+				$transaction_payments->calculate_total_payments_and_update_status($this->transaction);
1183
+			}
1184
+			// grab the saved registrations from the transaction
1185
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $reg_cache_ID => $registration) {
1186
+				$this->_refresh_registration($reg_cache_ID, $registration);
1187
+			}
1188
+			// make sure our cached TXN is added to the model entity mapper
1189
+			$this->transaction = $this->transaction->get_model()->refresh_entity_map_with(
1190
+				$this->transaction->ID(),
1191
+				$this->transaction
1192
+			);
1193
+		} else {
1194
+			EE_Error::add_error(
1195
+				__(
1196
+					'A valid Transaction was not found when attempting to update the model entity mapper.',
1197
+					'event_espresso'
1198
+				),
1199
+				__FILE__,
1200
+				__FUNCTION__,
1201
+				__LINE__
1202
+			);
1203
+			return false;
1204
+		}
1205
+		// verify and update the cart because inaccurate totals are not so much fun
1206
+		if ($this->cart instanceof EE_Cart) {
1207
+			$grand_total = $this->cart->get_grand_total();
1208
+			if ($grand_total instanceof EE_Line_Item && $grand_total->ID()) {
1209
+				$grand_total->recalculate_total_including_taxes();
1210
+				$grand_total = $grand_total->get_model()->refresh_entity_map_with(
1211
+					$this->cart->get_grand_total()->ID(),
1212
+					$this->cart->get_grand_total()
1213
+				);
1214
+			}
1215
+			if ($grand_total instanceof EE_Line_Item) {
1216
+				$this->cart = EE_Cart::instance($grand_total);
1217
+			} else {
1218
+				EE_Error::add_error(
1219
+					__(
1220
+						'A valid Cart was not found when attempting to update the model entity mapper.',
1221
+						'event_espresso'
1222
+					),
1223
+					__FILE__,
1224
+					__FUNCTION__,
1225
+					__LINE__
1226
+				);
1227
+				return false;
1228
+			}
1229
+		}
1230
+		return true;
1231
+	}
1232
+
1233
+
1234
+	/**
1235
+	 * _refresh_registration
1236
+	 *
1237
+	 * @param    string | int    $reg_cache_ID
1238
+	 * @param    EE_Registration $registration
1239
+	 * @return void
1240
+	 * @throws \EE_Error
1241
+	 */
1242
+	protected function _refresh_registration($reg_cache_ID, $registration)
1243
+	{
1244
+
1245
+		// verify object
1246
+		if ($registration instanceof EE_Registration) {
1247
+			// update the entity mapper attendee
1248
+			$this->_refresh_registration_attendee($registration);
1249
+			// update the entity mapper answers for reg form questions
1250
+			$this->_refresh_registration_answers($registration);
1251
+			// make sure the cached registration is added to the model entity mapper
1252
+			$registration->get_model()->refresh_entity_map_with($reg_cache_ID, $registration);
1253
+		} else {
1254
+			EE_Error::add_error(
1255
+				__(
1256
+					'An invalid Registration object was discovered when attempting to update the model entity mapper.',
1257
+					'event_espresso'
1258
+				),
1259
+				__FILE__,
1260
+				__FUNCTION__,
1261
+				__LINE__
1262
+			);
1263
+		}
1264
+	}
1265
+
1266
+
1267
+	/**
1268
+	 * _save_registration_attendee
1269
+	 *
1270
+	 * @param    EE_Registration $registration
1271
+	 * @return void
1272
+	 * @throws \EE_Error
1273
+	 */
1274
+	protected function _refresh_registration_attendee($registration)
1275
+	{
1276
+		$attendee = $registration->attendee();
1277
+		// verify object
1278
+		if ($attendee instanceof EE_Attendee && $attendee->ID()) {
1279
+			// make sure the cached attendee is added to the model entity mapper
1280
+			$registration->attendee()->get_model()->refresh_entity_map_with($attendee->ID(), $attendee);
1281
+			// maybe cache primary_attendee_obj ?
1282
+			if ($registration->is_primary_registrant()) {
1283
+				$this->primary_attendee_obj = $attendee;
1284
+			}
1285
+		}
1286
+	}
1287
+
1288
+
1289
+	/**
1290
+	 * _refresh_registration_answers
1291
+	 *
1292
+	 * @param    EE_Registration $registration
1293
+	 * @return void
1294
+	 * @throws \EE_Error
1295
+	 */
1296
+	protected function _refresh_registration_answers($registration)
1297
+	{
1298
+
1299
+		// now update the answers
1300
+		foreach ($registration->answers() as $cache_key => $answer) {
1301
+			// verify object
1302
+			if ($answer instanceof EE_Answer) {
1303
+				if ($answer->ID()) {
1304
+					// make sure the cached answer is added to the model entity mapper
1305
+					$answer->get_model()->refresh_entity_map_with($answer->ID(), $answer);
1306
+				}
1307
+			} else {
1308
+				EE_Error::add_error(
1309
+					__(
1310
+						'An invalid Answer object was discovered when attempting to update the model entity mapper.',
1311
+						'event_espresso'
1312
+					),
1313
+					__FILE__,
1314
+					__FUNCTION__,
1315
+					__LINE__
1316
+				);
1317
+			}
1318
+		}
1319
+	}
1320
+
1321
+
1322
+	/**
1323
+	 *    __sleep
1324
+	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
1325
+	 * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
1326
+	 * reg form, because if needed, it will be regenerated anyways
1327
+	 *
1328
+	 * @return array
1329
+	 * @throws \EE_Error
1330
+	 */
1331
+	public function __sleep()
1332
+	{
1333
+		if ($this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID()) {
1334
+			$this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1335
+		}        // remove the reg form and the checkout
1336
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1337
+			$this->transaction = $this->transaction->ID();
1338
+		}        // remove the reg form and the checkout
1339
+		return array_diff(array_keys(get_object_vars($this)), array('billing_form', 'registration_form'));
1340
+	}
1341
+
1342
+
1343
+	/**
1344
+	 *    __wakeup
1345
+	 * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1346
+	 * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1347
+	 */
1348
+	public function __wakeup()
1349
+	{
1350
+		if (! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1351
+			// $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1352
+			$this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID($this->primary_attendee_obj);
1353
+		}
1354
+		if (! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1355
+			// $this->transaction is actually just an ID, so use it to get the object from the db
1356
+			$this->transaction = EEM_Transaction::instance()->get_one_by_ID($this->transaction);
1357
+		}
1358
+		foreach ($this->reg_steps as $reg_step) {
1359
+			$reg_step->checkout = $this;
1360
+		}
1361
+	}
1362
+
1363
+
1364
+	/**
1365
+	 * debug
1366
+	 *
1367
+	 * @param string $class
1368
+	 * @param string $func
1369
+	 * @param string $line
1370
+	 * @param array  $info
1371
+	 * @param bool   $display_request
1372
+	 * @throws \EE_Error
1373
+	 */
1374
+	public function log($class = '', $func = '', $line = '', $info = array(), $display_request = false)
1375
+	{
1376
+		$disabled = true;
1377
+		if (WP_DEBUG && ! $disabled) {
1378
+			$debug_data = get_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array());
1379
+			$default_data = array(
1380
+				$class                    => $func . '() : ' . $line,
1381
+				'request->step'           => $this->step,
1382
+				'request->action'         => $this->action,
1383
+				'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step ?
1384
+					$this->current_step->slug() : '',
1385
+				'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1386
+					$this->current_step->completed() : '',
1387
+				'txn_status_updated'      => $this->transaction->txn_status_updated(),
1388
+				'reg_status_updated'      => $this->reg_status_updated,
1389
+				'reg_url_link'            => $this->reg_url_link,
1390
+				'REQ'                     => $display_request ? $_REQUEST : '',
1391
+			);
1392
+			if ($this->transaction instanceof EE_Transaction) {
1393
+				$default_data['TXN_status'] = $this->transaction->status_ID();
1394
+				$default_data['TXN_reg_steps'] = $this->transaction->reg_steps();
1395
+				foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1396
+					$default_data['registrations'][ $REG_ID ] = $registration->status_ID();
1397
+				}
1398
+				if ($this->transaction->ID()) {
1399
+					$TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1400
+					// don't serialize objects
1401
+					$info = $this->_strip_objects($info);
1402
+					if (! isset($debug_data[ $TXN_ID ])) {
1403
+						$debug_data[ $TXN_ID ] = array();
1404
+					}
1405
+					$debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1406
+						$default_data,
1407
+						$info
1408
+					);
1409
+					update_option('EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data);
1410
+				}
1411
+			}
1412
+		}
1413
+	}
1414
+
1415
+
1416
+	/**
1417
+	 * _strip_objects
1418
+	 *
1419
+	 * @param array $info
1420
+	 * @return array
1421
+	 */
1422
+	public function _strip_objects($info = array())
1423
+	{
1424
+		foreach ((array) $info as $key => $value) {
1425
+			if (is_array($value)) {
1426
+				$info[ $key ] = $this->_strip_objects($value);
1427
+			} elseif (is_object($value)) {
1428
+				$object_class = get_class($value);
1429
+				$info[ $object_class ] = array();
1430
+				$info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
1431
+				if (method_exists($value, 'status')) {
1432
+					$info[ $object_class ]['status'] = $value->status();
1433
+				} elseif (method_exists($value, 'status_ID')) {
1434
+					$info[ $object_class ]['status'] = $value->status_ID();
1435
+				}
1436
+				unset($info[ $key ]);
1437
+			}
1438
+		}
1439
+		return (array) $info;
1440
+	}
1441 1441
 }
Please login to merge, or discard this patch.