Completed
Branch BUG-10202-persistent-admin-not... (4ac09f)
by
unknown
23:47 queued 12:18
created
core/libraries/batch/JobHandlers/DatetimeOffsetFix.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -158,19 +158,19 @@  discard block
 block discarded – undo
158 158
         $date_ranges = array();
159 159
         //since some affected models might have two tables, we have to get our tables and set up a query for each table.
160 160
         foreach ($model->get_tables() as $table) {
161
-            $query = 'UPDATE ' . $table->get_table_name();
161
+            $query = 'UPDATE '.$table->get_table_name();
162 162
             $fields_affected = array();
163 163
             $inner_query = array();
164 164
             foreach ($model->_get_fields_for_table($table->get_table_alias()) as $model_field) {
165 165
                 if ($model_field instanceof EE_Datetime_Field) {
166
-                    $inner_query[$model_field->get_table_column()] = $model_field->get_table_column() . ' = '
167
-                                     . $sql_date_function . '('
166
+                    $inner_query[$model_field->get_table_column()] = $model_field->get_table_column().' = '
167
+                                     . $sql_date_function.'('
168 168
                                      . $model_field->get_table_column()
169 169
                                      . ", INTERVAL {$offset} MINUTE)";
170 170
                     $fields_affected[] = $model_field;
171 171
                 }
172 172
             }
173
-            if (! $fields_affected) {
173
+            if ( ! $fields_affected) {
174 174
                 continue;
175 175
             }
176 176
             //do we do one query per column/field or one query for all fields on the model? It all depends on whether
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
                     //record error.
188 188
                     $error_message = $wpdb->last_error;
189 189
                     //handle the edgecases where last_error might be empty.
190
-                    if (! $error_message) {
190
+                    if ( ! $error_message) {
191 191
                         $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
192 192
                     }
193 193
                     $this->recordChangeLog($model, $original_offset, $table, $fields_affected, $error_message);
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
         foreach ($inner_query as $field_name => $field_query) {
221 221
             $query_to_run = $query;
222 222
             $where_conditions = array();
223
-            $query_to_run .= ' SET ' . $field_query;
223
+            $query_to_run .= ' SET '.$field_query;
224 224
             if ($start_date_range instanceof DbSafeDateTime) {
225 225
                 $start_date = $start_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
226 226
                 $where_conditions[] = "{$field_name} > '{$start_date}'";
@@ -230,14 +230,14 @@  discard block
 block discarded – undo
230 230
                 $where_conditions[] = "{$field_name} < '{$end_date}'";
231 231
             }
232 232
             if ($where_conditions) {
233
-                $query_to_run .= ' WHERE ' . implode(' AND ', $where_conditions);
233
+                $query_to_run .= ' WHERE '.implode(' AND ', $where_conditions);
234 234
             }
235 235
             $result = $wpdb->query($query_to_run);
236 236
             if ($result === false) {
237 237
                 //record error.
238 238
                 $error_message = $wpdb->last_error;
239 239
                 //handle the edgecases where last_error might be empty.
240
-                if (! $error_message) {
240
+                if ( ! $error_message) {
241 241
                     $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
242 242
                 }
243 243
                 $errors[$field_name] = $error_message;
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
     private function doQueryForAllFields($query, array $inner_query)
258 258
     {
259 259
         global $wpdb;
260
-        $query .= ' SET ' . implode(',', $inner_query);
260
+        $query .= ' SET '.implode(',', $inner_query);
261 261
         return $wpdb->query($query);
262 262
     }
263 263
 
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
         $fields = array();
284 284
         /** @var EE_Datetime_Field $model_field */
285 285
         foreach ($model_fields_affected as $model_field) {
286
-            if (! $model_field instanceof EE_Datetime_Field) {
286
+            if ( ! $model_field instanceof EE_Datetime_Field) {
287 287
                 continue;
288 288
             }
289 289
             $fields[] = $model_field->get_name();
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
     private function getModelsWithDatetimeFields()
336 336
     {
337 337
         $this->getModelsToProcess();
338
-        if (! empty($this->models_with_datetime_fields)) {
338
+        if ( ! empty($this->models_with_datetime_fields)) {
339 339
             return $this->models_with_datetime_fields;
340 340
         }
341 341
 
Please login to merge, or discard this patch.
Indentation   +458 added lines, -458 removed lines patch added patch discarded remove patch
@@ -26,462 +26,462 @@
 block discarded – undo
26 26
 class DatetimeOffsetFix extends JobHandler
27 27
 {
28 28
 
29
-    /**
30
-     * Key for the option used to track which models have been processed when doing the batches.
31
-     */
32
-    const MODELS_TO_PROCESS_OPTION_KEY = 'ee_models_processed_for_datetime_offset_fix';
33
-
34
-
35
-    const COUNT_OF_MODELS_PROCESSED = 'ee_count_of_ee_models_processed_for_datetime_offset_fixed';
36
-
37
-    /**
38
-     * Key for the option used to track what the current offset is that will be applied when this tool is executed.
39
-     */
40
-    const OFFSET_TO_APPLY_OPTION_KEY = 'ee_datetime_offset_fix_offset_to_apply';
41
-
42
-
43
-    const OPTION_KEY_OFFSET_RANGE_START_DATE = 'ee_datetime_offset_start_date_range';
44
-
45
-
46
-    const OPTION_KEY_OFFSET_RANGE_END_DATE = 'ee_datetime_offset_end_date_range';
47
-
48
-
49
-    /**
50
-     * String labelling the datetime offset fix type for change-log entries.
51
-     */
52
-    const DATETIME_OFFSET_FIX_CHANGELOG_TYPE = 'datetime_offset_fix';
53
-
54
-
55
-    /**
56
-     * String labelling a datetime offset fix error for change-log entries.
57
-     */
58
-    const DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE = 'datetime_offset_fix_error';
59
-
60
-    /**
61
-     * @var EEM_Base[]
62
-     */
63
-    protected $models_with_datetime_fields = array();
64
-
65
-
66
-    /**
67
-     * Performs any necessary setup for starting the job. This is also a good
68
-     * place to setup the $job_arguments which will be used for subsequent HTTP requests
69
-     * when continue_job will be called
70
-     *
71
-     * @param JobParameters $job_parameters
72
-     * @return JobStepResponse
73
-     * @throws EE_Error
74
-     * @throws InvalidArgumentException
75
-     * @throws InvalidDataTypeException
76
-     * @throws InvalidInterfaceException
77
-     */
78
-    public function create_job(JobParameters $job_parameters)
79
-    {
80
-        $models_with_datetime_fields = $this->getModelsWithDatetimeFields();
81
-        //we'll be doing each model as a batch.
82
-        $job_parameters->set_job_size(count($models_with_datetime_fields));
83
-        return new JobStepResponse(
84
-            $job_parameters,
85
-            esc_html__('Starting Datetime Offset Fix', 'event_espresso')
86
-        );
87
-    }
88
-
89
-    /**
90
-     * Performs another step of the job
91
-     *
92
-     * @param JobParameters $job_parameters
93
-     * @param int           $batch_size
94
-     * @return JobStepResponse
95
-     * @throws EE_Error
96
-     * @throws InvalidArgumentException
97
-     * @throws InvalidDataTypeException
98
-     * @throws InvalidInterfaceException
99
-     */
100
-    public function continue_job(JobParameters $job_parameters, $batch_size = 50)
101
-    {
102
-        $models_to_process = $this->getModelsWithDatetimeFields();
103
-        //let's pop off the a model and do the query to apply the offset.
104
-        $model_to_process = array_pop($models_to_process);
105
-        //update our record
106
-        $this->setModelsToProcess($models_to_process);
107
-        $this->processModel($model_to_process);
108
-        $this->updateCountOfModelsProcessed();
109
-        $job_parameters->set_units_processed($this->getCountOfModelsProcessed());
110
-        if (count($models_to_process) > 0) {
111
-            $job_parameters->set_status(JobParameters::status_continue);
112
-        } else {
113
-            $job_parameters->set_status(JobParameters::status_complete);
114
-        }
115
-        return new JobStepResponse(
116
-            $job_parameters,
117
-            sprintf(
118
-                esc_html__('Updated the offset for all datetime fields on the %s model.', 'event_espresso'),
119
-                $model_to_process
120
-            )
121
-        );
122
-    }
123
-
124
-    /**
125
-     * Performs any clean-up logic when we know the job is completed
126
-     *
127
-     * @param JobParameters $job_parameters
128
-     * @return JobStepResponse
129
-     * @throws BatchRequestException
130
-     */
131
-    public function cleanup_job(JobParameters $job_parameters)
132
-    {
133
-        //delete important saved options.
134
-        delete_option(self::MODELS_TO_PROCESS_OPTION_KEY);
135
-        delete_option(self::COUNT_OF_MODELS_PROCESSED);
136
-        delete_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE);
137
-        delete_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE);
138
-        return new JobStepResponse($job_parameters, esc_html__(
139
-            'Offset has been applied to all affected fields.',
140
-            'event_espresso'
141
-        ));
142
-    }
143
-
144
-
145
-    /**
146
-     * Contains the logic for processing a model and applying the datetime offset to affected fields on that model.
147
-     * @param string $model_class_name
148
-     * @throws EE_Error
149
-     */
150
-    protected function processModel($model_class_name)
151
-    {
152
-        global $wpdb;
153
-        /** @var EEM_Base $model */
154
-        $model = $model_class_name::instance();
155
-        $original_offset = self::getOffset();
156
-        $start_date_range = self::getStartDateRange();
157
-        $end_date_range = self::getEndDateRange();
158
-        $sql_date_function = $original_offset > 0 ? 'DATE_ADD' : 'DATE_SUB';
159
-        $offset = abs($original_offset) * 60;
160
-        $date_ranges = array();
161
-        //since some affected models might have two tables, we have to get our tables and set up a query for each table.
162
-        foreach ($model->get_tables() as $table) {
163
-            $query = 'UPDATE ' . $table->get_table_name();
164
-            $fields_affected = array();
165
-            $inner_query = array();
166
-            foreach ($model->_get_fields_for_table($table->get_table_alias()) as $model_field) {
167
-                if ($model_field instanceof EE_Datetime_Field) {
168
-                    $inner_query[$model_field->get_table_column()] = $model_field->get_table_column() . ' = '
169
-                                     . $sql_date_function . '('
170
-                                     . $model_field->get_table_column()
171
-                                     . ", INTERVAL {$offset} MINUTE)";
172
-                    $fields_affected[] = $model_field;
173
-                }
174
-            }
175
-            if (! $fields_affected) {
176
-                continue;
177
-            }
178
-            //do we do one query per column/field or one query for all fields on the model? It all depends on whether
179
-            //there is a date range applied or not.
180
-            if ($start_date_range instanceof DbSafeDateTime || $end_date_range instanceof DbSafeDateTime) {
181
-                $result = $this->doQueryForEachField($query, $inner_query, $start_date_range, $end_date_range);
182
-            } else {
183
-                $result = $this->doQueryForAllFields($query, $inner_query);
184
-            }
185
-
186
-            //record appropriate logs for the query
187
-            switch (true) {
188
-                case $result === false:
189
-                    //record error.
190
-                    $error_message = $wpdb->last_error;
191
-                    //handle the edgecases where last_error might be empty.
192
-                    if (! $error_message) {
193
-                        $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
194
-                    }
195
-                    $this->recordChangeLog($model, $original_offset, $table, $fields_affected, $error_message);
196
-                    break;
197
-                case is_array($result) && ! empty($result):
198
-                    foreach ($result as $field_name => $error_message) {
199
-                        $this->recordChangeLog($model, $original_offset, $table, array($field_name), $error_message);
200
-                    }
201
-                    break;
202
-                default:
203
-                    $this->recordChangeLog($model, $original_offset, $table, $fields_affected);
204
-            }
205
-        }
206
-    }
207
-
208
-
209
-    /**
210
-     * Does the query on each $inner_query individually.
211
-     *
212
-     * @param string              $query
213
-     * @param array               $inner_query
214
-     * @param DbSafeDateTime|null $start_date_range
215
-     * @param DbSafeDateTime|null $end_date_range
216
-     * @return array  An array of any errors encountered and the fields they were for.
217
-     */
218
-    private function doQueryForEachField($query, array $inner_query, $start_date_range, $end_date_range)
219
-    {
220
-        global $wpdb;
221
-        $errors = array();
222
-        foreach ($inner_query as $field_name => $field_query) {
223
-            $query_to_run = $query;
224
-            $where_conditions = array();
225
-            $query_to_run .= ' SET ' . $field_query;
226
-            if ($start_date_range instanceof DbSafeDateTime) {
227
-                $start_date = $start_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
228
-                $where_conditions[] = "{$field_name} > '{$start_date}'";
229
-            }
230
-            if ($end_date_range instanceof DbSafeDateTime) {
231
-                $end_date = $end_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
232
-                $where_conditions[] = "{$field_name} < '{$end_date}'";
233
-            }
234
-            if ($where_conditions) {
235
-                $query_to_run .= ' WHERE ' . implode(' AND ', $where_conditions);
236
-            }
237
-            $result = $wpdb->query($query_to_run);
238
-            if ($result === false) {
239
-                //record error.
240
-                $error_message = $wpdb->last_error;
241
-                //handle the edgecases where last_error might be empty.
242
-                if (! $error_message) {
243
-                    $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
244
-                }
245
-                $errors[$field_name] = $error_message;
246
-            }
247
-        }
248
-        return $errors;
249
-    }
250
-
251
-
252
-    /**
253
-     * Performs the query for all fields within the inner_query
254
-     *
255
-     * @param string $query
256
-     * @param array  $inner_query
257
-     * @return false|int
258
-     */
259
-    private function doQueryForAllFields($query, array $inner_query)
260
-    {
261
-        global $wpdb;
262
-        $query .= ' SET ' . implode(',', $inner_query);
263
-        return $wpdb->query($query);
264
-    }
265
-
266
-
267
-    /**
268
-     * Records a changelog entry using the given information.
269
-     *
270
-     * @param EEM_Base              $model
271
-     * @param float                 $offset
272
-     * @param EE_Table_Base         $table
273
-     * @param EE_Model_Field_Base[] $model_fields_affected
274
-     * @param string                $error_message   If present then there was an error so let's record that instead.
275
-     * @throws EE_Error
276
-     */
277
-    private function recordChangeLog(
278
-        EEM_Base $model,
279
-        $offset,
280
-        EE_Table_Base $table,
281
-        $model_fields_affected,
282
-        $error_message = ''
283
-    ) {
284
-        //setup $fields list.
285
-        $fields = array();
286
-        /** @var EE_Datetime_Field $model_field */
287
-        foreach ($model_fields_affected as $model_field) {
288
-            if (! $model_field instanceof EE_Datetime_Field) {
289
-                continue;
290
-            }
291
-            $fields[] = $model_field->get_name();
292
-        }
293
-        //setup the message for the changelog entry.
294
-        $message = $error_message
295
-            ? sprintf(
296
-                esc_html__(
297
-                    'The %1$s table for the %2$s model did not have the offset of %3$f applied to its fields (%4$s), because of the following error:%5$s',
298
-                    'event_espresso'
299
-                ),
300
-                $table->get_table_name(),
301
-                $model->get_this_model_name(),
302
-                $offset,
303
-                implode(',', $fields),
304
-                $error_message
305
-            )
306
-            : sprintf(
307
-                esc_html__(
308
-                    'The %1$s table for the %2$s model has had the offset of %3$f applied to its following fields: %4$s',
309
-                    'event_espresso'
310
-                ),
311
-                $table->get_table_name(),
312
-                $model->get_this_model_name(),
313
-                $offset,
314
-                implode(',', $fields)
315
-            );
316
-        //write to the log
317
-        $changelog = EE_Change_Log::new_instance(array(
318
-            'LOG_type' => $error_message
319
-                ? self::DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE
320
-                : self::DATETIME_OFFSET_FIX_CHANGELOG_TYPE,
321
-            'LOG_message' => $message
322
-        ));
323
-        $changelog->save();
324
-    }
325
-
326
-
327
-    /**
328
-     * Returns an array of models that have datetime fields.
329
-     * This array is added to a short lived transient cache to keep having to build this list to a minimum.
330
-     *
331
-     * @return array an array of model class names.
332
-     * @throws EE_Error
333
-     * @throws InvalidDataTypeException
334
-     * @throws InvalidInterfaceException
335
-     * @throws InvalidArgumentException
336
-     */
337
-    private function getModelsWithDatetimeFields()
338
-    {
339
-        $this->getModelsToProcess();
340
-        if (! empty($this->models_with_datetime_fields)) {
341
-            return $this->models_with_datetime_fields;
342
-        }
343
-
344
-        $all_non_abstract_models = EE_Registry::instance()->non_abstract_db_models;
345
-        foreach ($all_non_abstract_models as $non_abstract_model) {
346
-            //get model instance
347
-            /** @var EEM_Base $non_abstract_model */
348
-            $non_abstract_model = $non_abstract_model::instance();
349
-            if ($non_abstract_model->get_a_field_of_type('EE_Datetime_Field') instanceof EE_Datetime_Field) {
350
-                $this->models_with_datetime_fields[] = get_class($non_abstract_model);
351
-            }
352
-        }
353
-        $this->setModelsToProcess($this->models_with_datetime_fields);
354
-        return $this->models_with_datetime_fields;
355
-    }
356
-
357
-
358
-    /**
359
-     * This simply records the models that have been processed with our tracking option.
360
-     * @param array $models_to_set  array of model class names.
361
-     */
362
-    private function setModelsToProcess($models_to_set)
363
-    {
364
-        update_option(self::MODELS_TO_PROCESS_OPTION_KEY, $models_to_set);
365
-    }
366
-
367
-
368
-    /**
369
-     * Used to keep track of how many models have been processed for the batch
370
-     * @param $count
371
-     */
372
-    private function updateCountOfModelsProcessed($count = 1)
373
-    {
374
-        $count = $this->getCountOfModelsProcessed() + (int) $count;
375
-        update_option(self::COUNT_OF_MODELS_PROCESSED, $count);
376
-    }
377
-
378
-
379
-    /**
380
-     * Retrieve the tracked number of models processed between requests.
381
-     * @return int
382
-     */
383
-    private function getCountOfModelsProcessed()
384
-    {
385
-        return (int) get_option(self::COUNT_OF_MODELS_PROCESSED, 0);
386
-    }
387
-
388
-
389
-    /**
390
-     * Returns the models that are left to process.
391
-     * @return array  an array of model class names.
392
-     */
393
-    private function getModelsToProcess()
394
-    {
395
-        if (empty($this->models_with_datetime_fields)) {
396
-            $this->models_with_datetime_fields = get_option(self::MODELS_TO_PROCESS_OPTION_KEY, array());
397
-        }
398
-        return $this->models_with_datetime_fields;
399
-    }
400
-
401
-
402
-    /**
403
-     * Used to record the offset that will be applied to dates and times for EE_Datetime_Field columns.
404
-     * @param float $offset
405
-     */
406
-    public static function updateOffset($offset)
407
-    {
408
-        update_option(self::OFFSET_TO_APPLY_OPTION_KEY, $offset);
409
-    }
410
-
411
-
412
-    /**
413
-     * Used to retrieve the saved offset that will be applied to dates and times for EE_Datetime_Field columns.
414
-     *
415
-     * @return float
416
-     */
417
-    public static function getOffset()
418
-    {
419
-        return (float) get_option(self::OFFSET_TO_APPLY_OPTION_KEY, 0);
420
-    }
421
-
422
-
423
-    /**
424
-     * Used to set the saved offset range start date.
425
-     * @param DbSafeDateTime|null $start_date
426
-     */
427
-    public static function updateStartDateRange(DbSafeDateTime $start_date = null)
428
-    {
429
-        $date_to_save = $start_date instanceof DbSafeDateTime
430
-            ? $start_date->format('U')
431
-            : '';
432
-        update_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, $date_to_save);
433
-    }
434
-
435
-
436
-    /**
437
-     * Used to get the saved offset range start date.
438
-     * @return DbSafeDateTime|null
439
-     */
440
-    public static function getStartDateRange()
441
-    {
442
-        $start_date = get_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, null);
443
-        try {
444
-            $datetime = DateTime::createFromFormat('U', $start_date, new DateTimeZone('UTC'));
445
-            $start_date = $datetime instanceof DateTime
446
-                ? DbSafeDateTime::createFromDateTime($datetime)
447
-                : null;
448
-
449
-        } catch (Exception $e) {
450
-            $start_date = null;
451
-        }
452
-        return $start_date;
453
-    }
454
-
455
-
456
-
457
-    /**
458
-     * Used to set the saved offset range end date.
459
-     * @param DbSafeDateTime|null $end_date
460
-     */
461
-    public static function updateEndDateRange(DbSafeDateTime $end_date = null)
462
-    {
463
-        $date_to_save = $end_date instanceof DbSafeDateTime
464
-            ? $end_date->format('U')
465
-            : '';
466
-        update_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, $date_to_save);
467
-    }
468
-
469
-
470
-    /**
471
-     * Used to get the saved offset range end date.
472
-     * @return DbSafeDateTime|null
473
-     */
474
-    public static function getEndDateRange()
475
-    {
476
-        $end_date = get_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, null);
477
-        try {
478
-            $datetime = DateTime::createFromFormat('U', $end_date, new DateTimeZone('UTC'));
479
-            $end_date = $datetime instanceof Datetime
480
-                ? DbSafeDateTime::createFromDateTime($datetime)
481
-                : null;
482
-        } catch (Exception $e) {
483
-            $end_date = null;
484
-        }
485
-        return $end_date;
486
-    }
29
+	/**
30
+	 * Key for the option used to track which models have been processed when doing the batches.
31
+	 */
32
+	const MODELS_TO_PROCESS_OPTION_KEY = 'ee_models_processed_for_datetime_offset_fix';
33
+
34
+
35
+	const COUNT_OF_MODELS_PROCESSED = 'ee_count_of_ee_models_processed_for_datetime_offset_fixed';
36
+
37
+	/**
38
+	 * Key for the option used to track what the current offset is that will be applied when this tool is executed.
39
+	 */
40
+	const OFFSET_TO_APPLY_OPTION_KEY = 'ee_datetime_offset_fix_offset_to_apply';
41
+
42
+
43
+	const OPTION_KEY_OFFSET_RANGE_START_DATE = 'ee_datetime_offset_start_date_range';
44
+
45
+
46
+	const OPTION_KEY_OFFSET_RANGE_END_DATE = 'ee_datetime_offset_end_date_range';
47
+
48
+
49
+	/**
50
+	 * String labelling the datetime offset fix type for change-log entries.
51
+	 */
52
+	const DATETIME_OFFSET_FIX_CHANGELOG_TYPE = 'datetime_offset_fix';
53
+
54
+
55
+	/**
56
+	 * String labelling a datetime offset fix error for change-log entries.
57
+	 */
58
+	const DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE = 'datetime_offset_fix_error';
59
+
60
+	/**
61
+	 * @var EEM_Base[]
62
+	 */
63
+	protected $models_with_datetime_fields = array();
64
+
65
+
66
+	/**
67
+	 * Performs any necessary setup for starting the job. This is also a good
68
+	 * place to setup the $job_arguments which will be used for subsequent HTTP requests
69
+	 * when continue_job will be called
70
+	 *
71
+	 * @param JobParameters $job_parameters
72
+	 * @return JobStepResponse
73
+	 * @throws EE_Error
74
+	 * @throws InvalidArgumentException
75
+	 * @throws InvalidDataTypeException
76
+	 * @throws InvalidInterfaceException
77
+	 */
78
+	public function create_job(JobParameters $job_parameters)
79
+	{
80
+		$models_with_datetime_fields = $this->getModelsWithDatetimeFields();
81
+		//we'll be doing each model as a batch.
82
+		$job_parameters->set_job_size(count($models_with_datetime_fields));
83
+		return new JobStepResponse(
84
+			$job_parameters,
85
+			esc_html__('Starting Datetime Offset Fix', 'event_espresso')
86
+		);
87
+	}
88
+
89
+	/**
90
+	 * Performs another step of the job
91
+	 *
92
+	 * @param JobParameters $job_parameters
93
+	 * @param int           $batch_size
94
+	 * @return JobStepResponse
95
+	 * @throws EE_Error
96
+	 * @throws InvalidArgumentException
97
+	 * @throws InvalidDataTypeException
98
+	 * @throws InvalidInterfaceException
99
+	 */
100
+	public function continue_job(JobParameters $job_parameters, $batch_size = 50)
101
+	{
102
+		$models_to_process = $this->getModelsWithDatetimeFields();
103
+		//let's pop off the a model and do the query to apply the offset.
104
+		$model_to_process = array_pop($models_to_process);
105
+		//update our record
106
+		$this->setModelsToProcess($models_to_process);
107
+		$this->processModel($model_to_process);
108
+		$this->updateCountOfModelsProcessed();
109
+		$job_parameters->set_units_processed($this->getCountOfModelsProcessed());
110
+		if (count($models_to_process) > 0) {
111
+			$job_parameters->set_status(JobParameters::status_continue);
112
+		} else {
113
+			$job_parameters->set_status(JobParameters::status_complete);
114
+		}
115
+		return new JobStepResponse(
116
+			$job_parameters,
117
+			sprintf(
118
+				esc_html__('Updated the offset for all datetime fields on the %s model.', 'event_espresso'),
119
+				$model_to_process
120
+			)
121
+		);
122
+	}
123
+
124
+	/**
125
+	 * Performs any clean-up logic when we know the job is completed
126
+	 *
127
+	 * @param JobParameters $job_parameters
128
+	 * @return JobStepResponse
129
+	 * @throws BatchRequestException
130
+	 */
131
+	public function cleanup_job(JobParameters $job_parameters)
132
+	{
133
+		//delete important saved options.
134
+		delete_option(self::MODELS_TO_PROCESS_OPTION_KEY);
135
+		delete_option(self::COUNT_OF_MODELS_PROCESSED);
136
+		delete_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE);
137
+		delete_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE);
138
+		return new JobStepResponse($job_parameters, esc_html__(
139
+			'Offset has been applied to all affected fields.',
140
+			'event_espresso'
141
+		));
142
+	}
143
+
144
+
145
+	/**
146
+	 * Contains the logic for processing a model and applying the datetime offset to affected fields on that model.
147
+	 * @param string $model_class_name
148
+	 * @throws EE_Error
149
+	 */
150
+	protected function processModel($model_class_name)
151
+	{
152
+		global $wpdb;
153
+		/** @var EEM_Base $model */
154
+		$model = $model_class_name::instance();
155
+		$original_offset = self::getOffset();
156
+		$start_date_range = self::getStartDateRange();
157
+		$end_date_range = self::getEndDateRange();
158
+		$sql_date_function = $original_offset > 0 ? 'DATE_ADD' : 'DATE_SUB';
159
+		$offset = abs($original_offset) * 60;
160
+		$date_ranges = array();
161
+		//since some affected models might have two tables, we have to get our tables and set up a query for each table.
162
+		foreach ($model->get_tables() as $table) {
163
+			$query = 'UPDATE ' . $table->get_table_name();
164
+			$fields_affected = array();
165
+			$inner_query = array();
166
+			foreach ($model->_get_fields_for_table($table->get_table_alias()) as $model_field) {
167
+				if ($model_field instanceof EE_Datetime_Field) {
168
+					$inner_query[$model_field->get_table_column()] = $model_field->get_table_column() . ' = '
169
+									 . $sql_date_function . '('
170
+									 . $model_field->get_table_column()
171
+									 . ", INTERVAL {$offset} MINUTE)";
172
+					$fields_affected[] = $model_field;
173
+				}
174
+			}
175
+			if (! $fields_affected) {
176
+				continue;
177
+			}
178
+			//do we do one query per column/field or one query for all fields on the model? It all depends on whether
179
+			//there is a date range applied or not.
180
+			if ($start_date_range instanceof DbSafeDateTime || $end_date_range instanceof DbSafeDateTime) {
181
+				$result = $this->doQueryForEachField($query, $inner_query, $start_date_range, $end_date_range);
182
+			} else {
183
+				$result = $this->doQueryForAllFields($query, $inner_query);
184
+			}
185
+
186
+			//record appropriate logs for the query
187
+			switch (true) {
188
+				case $result === false:
189
+					//record error.
190
+					$error_message = $wpdb->last_error;
191
+					//handle the edgecases where last_error might be empty.
192
+					if (! $error_message) {
193
+						$error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
194
+					}
195
+					$this->recordChangeLog($model, $original_offset, $table, $fields_affected, $error_message);
196
+					break;
197
+				case is_array($result) && ! empty($result):
198
+					foreach ($result as $field_name => $error_message) {
199
+						$this->recordChangeLog($model, $original_offset, $table, array($field_name), $error_message);
200
+					}
201
+					break;
202
+				default:
203
+					$this->recordChangeLog($model, $original_offset, $table, $fields_affected);
204
+			}
205
+		}
206
+	}
207
+
208
+
209
+	/**
210
+	 * Does the query on each $inner_query individually.
211
+	 *
212
+	 * @param string              $query
213
+	 * @param array               $inner_query
214
+	 * @param DbSafeDateTime|null $start_date_range
215
+	 * @param DbSafeDateTime|null $end_date_range
216
+	 * @return array  An array of any errors encountered and the fields they were for.
217
+	 */
218
+	private function doQueryForEachField($query, array $inner_query, $start_date_range, $end_date_range)
219
+	{
220
+		global $wpdb;
221
+		$errors = array();
222
+		foreach ($inner_query as $field_name => $field_query) {
223
+			$query_to_run = $query;
224
+			$where_conditions = array();
225
+			$query_to_run .= ' SET ' . $field_query;
226
+			if ($start_date_range instanceof DbSafeDateTime) {
227
+				$start_date = $start_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
228
+				$where_conditions[] = "{$field_name} > '{$start_date}'";
229
+			}
230
+			if ($end_date_range instanceof DbSafeDateTime) {
231
+				$end_date = $end_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
232
+				$where_conditions[] = "{$field_name} < '{$end_date}'";
233
+			}
234
+			if ($where_conditions) {
235
+				$query_to_run .= ' WHERE ' . implode(' AND ', $where_conditions);
236
+			}
237
+			$result = $wpdb->query($query_to_run);
238
+			if ($result === false) {
239
+				//record error.
240
+				$error_message = $wpdb->last_error;
241
+				//handle the edgecases where last_error might be empty.
242
+				if (! $error_message) {
243
+					$error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
244
+				}
245
+				$errors[$field_name] = $error_message;
246
+			}
247
+		}
248
+		return $errors;
249
+	}
250
+
251
+
252
+	/**
253
+	 * Performs the query for all fields within the inner_query
254
+	 *
255
+	 * @param string $query
256
+	 * @param array  $inner_query
257
+	 * @return false|int
258
+	 */
259
+	private function doQueryForAllFields($query, array $inner_query)
260
+	{
261
+		global $wpdb;
262
+		$query .= ' SET ' . implode(',', $inner_query);
263
+		return $wpdb->query($query);
264
+	}
265
+
266
+
267
+	/**
268
+	 * Records a changelog entry using the given information.
269
+	 *
270
+	 * @param EEM_Base              $model
271
+	 * @param float                 $offset
272
+	 * @param EE_Table_Base         $table
273
+	 * @param EE_Model_Field_Base[] $model_fields_affected
274
+	 * @param string                $error_message   If present then there was an error so let's record that instead.
275
+	 * @throws EE_Error
276
+	 */
277
+	private function recordChangeLog(
278
+		EEM_Base $model,
279
+		$offset,
280
+		EE_Table_Base $table,
281
+		$model_fields_affected,
282
+		$error_message = ''
283
+	) {
284
+		//setup $fields list.
285
+		$fields = array();
286
+		/** @var EE_Datetime_Field $model_field */
287
+		foreach ($model_fields_affected as $model_field) {
288
+			if (! $model_field instanceof EE_Datetime_Field) {
289
+				continue;
290
+			}
291
+			$fields[] = $model_field->get_name();
292
+		}
293
+		//setup the message for the changelog entry.
294
+		$message = $error_message
295
+			? sprintf(
296
+				esc_html__(
297
+					'The %1$s table for the %2$s model did not have the offset of %3$f applied to its fields (%4$s), because of the following error:%5$s',
298
+					'event_espresso'
299
+				),
300
+				$table->get_table_name(),
301
+				$model->get_this_model_name(),
302
+				$offset,
303
+				implode(',', $fields),
304
+				$error_message
305
+			)
306
+			: sprintf(
307
+				esc_html__(
308
+					'The %1$s table for the %2$s model has had the offset of %3$f applied to its following fields: %4$s',
309
+					'event_espresso'
310
+				),
311
+				$table->get_table_name(),
312
+				$model->get_this_model_name(),
313
+				$offset,
314
+				implode(',', $fields)
315
+			);
316
+		//write to the log
317
+		$changelog = EE_Change_Log::new_instance(array(
318
+			'LOG_type' => $error_message
319
+				? self::DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE
320
+				: self::DATETIME_OFFSET_FIX_CHANGELOG_TYPE,
321
+			'LOG_message' => $message
322
+		));
323
+		$changelog->save();
324
+	}
325
+
326
+
327
+	/**
328
+	 * Returns an array of models that have datetime fields.
329
+	 * This array is added to a short lived transient cache to keep having to build this list to a minimum.
330
+	 *
331
+	 * @return array an array of model class names.
332
+	 * @throws EE_Error
333
+	 * @throws InvalidDataTypeException
334
+	 * @throws InvalidInterfaceException
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	private function getModelsWithDatetimeFields()
338
+	{
339
+		$this->getModelsToProcess();
340
+		if (! empty($this->models_with_datetime_fields)) {
341
+			return $this->models_with_datetime_fields;
342
+		}
343
+
344
+		$all_non_abstract_models = EE_Registry::instance()->non_abstract_db_models;
345
+		foreach ($all_non_abstract_models as $non_abstract_model) {
346
+			//get model instance
347
+			/** @var EEM_Base $non_abstract_model */
348
+			$non_abstract_model = $non_abstract_model::instance();
349
+			if ($non_abstract_model->get_a_field_of_type('EE_Datetime_Field') instanceof EE_Datetime_Field) {
350
+				$this->models_with_datetime_fields[] = get_class($non_abstract_model);
351
+			}
352
+		}
353
+		$this->setModelsToProcess($this->models_with_datetime_fields);
354
+		return $this->models_with_datetime_fields;
355
+	}
356
+
357
+
358
+	/**
359
+	 * This simply records the models that have been processed with our tracking option.
360
+	 * @param array $models_to_set  array of model class names.
361
+	 */
362
+	private function setModelsToProcess($models_to_set)
363
+	{
364
+		update_option(self::MODELS_TO_PROCESS_OPTION_KEY, $models_to_set);
365
+	}
366
+
367
+
368
+	/**
369
+	 * Used to keep track of how many models have been processed for the batch
370
+	 * @param $count
371
+	 */
372
+	private function updateCountOfModelsProcessed($count = 1)
373
+	{
374
+		$count = $this->getCountOfModelsProcessed() + (int) $count;
375
+		update_option(self::COUNT_OF_MODELS_PROCESSED, $count);
376
+	}
377
+
378
+
379
+	/**
380
+	 * Retrieve the tracked number of models processed between requests.
381
+	 * @return int
382
+	 */
383
+	private function getCountOfModelsProcessed()
384
+	{
385
+		return (int) get_option(self::COUNT_OF_MODELS_PROCESSED, 0);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Returns the models that are left to process.
391
+	 * @return array  an array of model class names.
392
+	 */
393
+	private function getModelsToProcess()
394
+	{
395
+		if (empty($this->models_with_datetime_fields)) {
396
+			$this->models_with_datetime_fields = get_option(self::MODELS_TO_PROCESS_OPTION_KEY, array());
397
+		}
398
+		return $this->models_with_datetime_fields;
399
+	}
400
+
401
+
402
+	/**
403
+	 * Used to record the offset that will be applied to dates and times for EE_Datetime_Field columns.
404
+	 * @param float $offset
405
+	 */
406
+	public static function updateOffset($offset)
407
+	{
408
+		update_option(self::OFFSET_TO_APPLY_OPTION_KEY, $offset);
409
+	}
410
+
411
+
412
+	/**
413
+	 * Used to retrieve the saved offset that will be applied to dates and times for EE_Datetime_Field columns.
414
+	 *
415
+	 * @return float
416
+	 */
417
+	public static function getOffset()
418
+	{
419
+		return (float) get_option(self::OFFSET_TO_APPLY_OPTION_KEY, 0);
420
+	}
421
+
422
+
423
+	/**
424
+	 * Used to set the saved offset range start date.
425
+	 * @param DbSafeDateTime|null $start_date
426
+	 */
427
+	public static function updateStartDateRange(DbSafeDateTime $start_date = null)
428
+	{
429
+		$date_to_save = $start_date instanceof DbSafeDateTime
430
+			? $start_date->format('U')
431
+			: '';
432
+		update_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, $date_to_save);
433
+	}
434
+
435
+
436
+	/**
437
+	 * Used to get the saved offset range start date.
438
+	 * @return DbSafeDateTime|null
439
+	 */
440
+	public static function getStartDateRange()
441
+	{
442
+		$start_date = get_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, null);
443
+		try {
444
+			$datetime = DateTime::createFromFormat('U', $start_date, new DateTimeZone('UTC'));
445
+			$start_date = $datetime instanceof DateTime
446
+				? DbSafeDateTime::createFromDateTime($datetime)
447
+				: null;
448
+
449
+		} catch (Exception $e) {
450
+			$start_date = null;
451
+		}
452
+		return $start_date;
453
+	}
454
+
455
+
456
+
457
+	/**
458
+	 * Used to set the saved offset range end date.
459
+	 * @param DbSafeDateTime|null $end_date
460
+	 */
461
+	public static function updateEndDateRange(DbSafeDateTime $end_date = null)
462
+	{
463
+		$date_to_save = $end_date instanceof DbSafeDateTime
464
+			? $end_date->format('U')
465
+			: '';
466
+		update_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, $date_to_save);
467
+	}
468
+
469
+
470
+	/**
471
+	 * Used to get the saved offset range end date.
472
+	 * @return DbSafeDateTime|null
473
+	 */
474
+	public static function getEndDateRange()
475
+	{
476
+		$end_date = get_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, null);
477
+		try {
478
+			$datetime = DateTime::createFromFormat('U', $end_date, new DateTimeZone('UTC'));
479
+			$end_date = $datetime instanceof Datetime
480
+				? DbSafeDateTime::createFromDateTime($datetime)
481
+				: null;
482
+		} catch (Exception $e) {
483
+			$end_date = null;
484
+		}
485
+		return $end_date;
486
+	}
487 487
 }
Please login to merge, or discard this patch.
core/domain/services/event/EventSpacesCalculator.php 2 patches
Indentation   +660 added lines, -660 removed lines patch added patch discarded remove patch
@@ -31,666 +31,666 @@
 block discarded – undo
31 31
 class EventSpacesCalculator
32 32
 {
33 33
 
34
-    /**
35
-     * @var EE_Event $event
36
-     */
37
-    private $event;
38
-
39
-    /**
40
-     * @var array $datetime_query_params
41
-     */
42
-    private $datetime_query_params;
43
-
44
-    /**
45
-     * @var EE_Ticket[] $active_tickets
46
-     */
47
-    private $active_tickets = array();
48
-
49
-    /**
50
-     * @var EE_Datetime[] $datetimes
51
-     */
52
-    private $datetimes = array();
53
-
54
-    /**
55
-     * Array of Ticket IDs grouped by Datetime
56
-     *
57
-     * @var array $datetimes
58
-     */
59
-    private $datetime_tickets = array();
60
-
61
-    /**
62
-     * Max spaces for each Datetime (reg limit - previous sold)
63
-     *
64
-     * @var array $datetime_spaces
65
-     */
66
-    private $datetime_spaces = array();
67
-
68
-    /**
69
-     * Array of Datetime IDs grouped by Ticket
70
-     *
71
-     * @var array[] $ticket_datetimes
72
-     */
73
-    private $ticket_datetimes = array();
74
-
75
-    /**
76
-     * maximum ticket quantities for each ticket (adjusted for reg limit)
77
-     *
78
-     * @var array $ticket_quantities
79
-     */
80
-    private $ticket_quantities = array();
81
-
82
-    /**
83
-     * total quantity of sold and reserved for each ticket
84
-     *
85
-     * @var array $tickets_sold
86
-     */
87
-    private $tickets_sold = array();
88
-
89
-    /**
90
-     * total spaces available across all datetimes
91
-     *
92
-     * @var array $total_spaces
93
-     */
94
-    private $total_spaces = array();
95
-
96
-    /**
97
-     * @var boolean $debug
98
-     */
99
-    private $debug = false;
100
-
101
-    /**
102
-     * @var null|int $spaces_remaining
103
-     */
104
-    private $spaces_remaining;
105
-
106
-    /**
107
-     * @var null|int $total_spaces_available
108
-     */
109
-    private $total_spaces_available;
110
-
111
-
112
-
113
-    /**
114
-     * EventSpacesCalculator constructor.
115
-     *
116
-     * @param EE_Event $event
117
-     * @param array    $datetime_query_params
118
-     * @throws EE_Error
119
-     */
120
-    public function __construct(EE_Event $event, array $datetime_query_params = array())
121
-    {
122
-        $this->event                 = $event;
123
-        $this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
124
-        $this->setHooks();
125
-    }
126
-
127
-
128
-
129
-    /**
130
-     * @return void
131
-     */
132
-    private function setHooks()
133
-    {
134
-        add_action( 'AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
-        add_action( 'AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
-        add_action( 'AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
-        add_action( 'AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
-        add_action( 'AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
-        add_action( 'AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
-        add_action( 'AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
-        add_action( 'AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     * @return void
148
-     */
149
-    public function clearResults()
150
-    {
151
-        $this->spaces_remaining = null;
152
-        $this->total_spaces_available = null;
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     * @return EE_Ticket[]
159
-     * @throws EE_Error
160
-     * @throws InvalidDataTypeException
161
-     * @throws InvalidInterfaceException
162
-     * @throws InvalidArgumentException
163
-     */
164
-    public function getActiveTickets()
165
-    {
166
-        if (empty($this->active_tickets)) {
167
-            $this->active_tickets = $this->event->tickets(
168
-                array(
169
-                    array(
170
-                        'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
171
-                        'TKT_deleted'  => false,
172
-                    ),
173
-                    'order_by' => array('TKT_qty' => 'ASC'),
174
-                )
175
-            );
176
-        }
177
-        return $this->active_tickets;
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     * @param EE_Ticket[] $active_tickets
184
-     * @throws EE_Error
185
-     * @throws DomainException
186
-     * @throws UnexpectedEntityException
187
-     */
188
-    public function setActiveTickets(array $active_tickets = array())
189
-    {
190
-        if ( ! empty($active_tickets)) {
191
-            foreach ($active_tickets as $active_ticket) {
192
-                $this->validateTicket($active_ticket);
193
-            }
194
-            // sort incoming array by ticket quantity (asc)
195
-            usort(
196
-                $active_tickets,
197
-                function (EE_Ticket $a, EE_Ticket $b) {
198
-                    if ($a->qty() === $b->qty()) {
199
-                        return 0;
200
-                    }
201
-                    return ($a->qty() < $b->qty())
202
-                        ? -1
203
-                        : 1;
204
-                }
205
-            );
206
-        }
207
-        $this->active_tickets = $active_tickets;
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     * @param $ticket
214
-     * @throws DomainException
215
-     * @throws EE_Error
216
-     * @throws UnexpectedEntityException
217
-     */
218
-    private function validateTicket($ticket)
219
-    {
220
-        if ( ! $ticket instanceof EE_Ticket) {
221
-            throw new DomainException(
222
-                esc_html__(
223
-                    'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
224
-                    'event_espresso'
225
-                )
226
-            );
227
-        }
228
-        if ($ticket->get_event_ID() !== $this->event->ID()) {
229
-            throw new DomainException(
230
-                sprintf(
231
-                    esc_html__(
232
-                        'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
233
-                        'event_espresso'
234
-                    ),
235
-                    $ticket->get_event_ID(),
236
-                    $this->event->ID()
237
-                )
238
-            );
239
-        }
240
-    }
241
-
242
-
243
-
244
-    /**
245
-     * @return EE_Datetime[]
246
-     */
247
-    public function getDatetimes()
248
-    {
249
-        return $this->datetimes;
250
-    }
251
-
252
-
253
-
254
-    /**
255
-     * @param EE_Datetime $datetime
256
-     * @throws EE_Error
257
-     * @throws DomainException
258
-     */
259
-    public function setDatetime(EE_Datetime $datetime)
260
-    {
261
-        if ($datetime->event()->ID() !== $this->event->ID()) {
262
-            throw new DomainException(
263
-                sprintf(
264
-                    esc_html__(
265
-                        'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
266
-                        'event_espresso'
267
-                    ),
268
-                    $datetime->event()->ID(),
269
-                    $this->event->ID()
270
-                )
271
-            );
272
-        }
273
-        $this->datetimes[ $datetime->ID() ] = $datetime;
274
-    }
275
-
276
-
277
-
278
-    /**
279
-     * calculate spaces remaining based on "saleable" tickets
280
-     *
281
-     * @return float|int
282
-     * @throws EE_Error
283
-     * @throws DomainException
284
-     * @throws UnexpectedEntityException
285
-     * @throws InvalidDataTypeException
286
-     * @throws InvalidInterfaceException
287
-     * @throws InvalidArgumentException
288
-     */
289
-    public function spacesRemaining()
290
-    {
291
-        if ($this->spaces_remaining === null) {
292
-            $this->initialize();
293
-            $this->spaces_remaining = $this->calculate();
294
-        }
295
-        return $this->spaces_remaining;
296
-    }
297
-
298
-
299
-
300
-    /**
301
-     * calculates total available spaces for an event with no regard for sold tickets
302
-     *
303
-     * @return int|float
304
-     * @throws EE_Error
305
-     * @throws DomainException
306
-     * @throws UnexpectedEntityException
307
-     * @throws InvalidDataTypeException
308
-     * @throws InvalidInterfaceException
309
-     * @throws InvalidArgumentException
310
-     */
311
-    public function totalSpacesAvailable()
312
-    {
313
-        if($this->total_spaces_available === null) {
314
-            $this->initialize();
315
-            $this->total_spaces_available = $this->calculate(false);
316
-        }
317
-        return $this->total_spaces_available;
318
-    }
319
-
320
-
321
-
322
-    /**
323
-     * Loops through the active tickets for the event
324
-     * and builds a series of data arrays that will be used for calculating
325
-     * the total maximum available spaces, as well as the spaces remaining.
326
-     * Because ticket quantities affect datetime spaces and vice versa,
327
-     * we need to be constantly updating these data arrays as things change,
328
-     * which is the entire reason for their existence.
329
-     *
330
-     * @throws EE_Error
331
-     * @throws DomainException
332
-     * @throws UnexpectedEntityException
333
-     * @throws InvalidDataTypeException
334
-     * @throws InvalidInterfaceException
335
-     * @throws InvalidArgumentException
336
-     */
337
-    private function initialize()
338
-    {
339
-        if ($this->debug) {
340
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
341
-        }
342
-        $this->datetime_tickets  = array();
343
-        $this->datetime_spaces   = array();
344
-        $this->ticket_datetimes  = array();
345
-        $this->ticket_quantities = array();
346
-        $this->tickets_sold      = array();
347
-        $this->total_spaces      = array();
348
-        $active_tickets          = $this->getActiveTickets();
349
-        if ( ! empty($active_tickets)) {
350
-            foreach ($active_tickets as $ticket) {
351
-                $this->validateTicket($ticket);
352
-                // we need to index our data arrays using strings for the purpose of sorting,
353
-                // but we also need them to be unique, so  we'll just prepend a letter T to the ID
354
-                $ticket_identifier = "T{$ticket->ID()}";
355
-                // to start, we'll just consider the raw qty to be the maximum availability for this ticket
356
-                $max_tickets = $ticket->qty();
357
-                // but we'll adjust that after looping over each datetime for the ticket and checking reg limits
358
-                $ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
359
-                foreach ($ticket_datetimes as $datetime) {
360
-                    // save all datetimes
361
-                    $this->setDatetime($datetime);
362
-                    $datetime_identifier = "D{$datetime->ID()}";
363
-                    $reg_limit           = $datetime->reg_limit();
364
-                    // ticket quantity can not exceed datetime reg limit
365
-                    $max_tickets = min($max_tickets, $reg_limit);
366
-                    // as described earlier, because we need to be able to constantly adjust numbers for things,
367
-                    // we are going to move all of our data into the following arrays:
368
-                    // datetime spaces initially represents the reg limit for each datetime,
369
-                    // but this will get adjusted as tickets are accounted for
370
-                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
371
-                    // just an array of ticket IDs grouped by datetime
372
-                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
373
-                    // and an array of datetime IDs grouped by ticket
374
-                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
375
-                }
376
-                // total quantity of sold and reserved for each ticket
377
-                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
378
-                // and the maximum ticket quantities for each ticket (adjusted for reg limit)
379
-                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
380
-            }
381
-        }
382
-        // sort datetime spaces by reg limit, but maintain our string indexes
383
-        asort($this->datetime_spaces, SORT_NUMERIC);
384
-        // datetime tickets need to be sorted in the SAME order as the above array...
385
-        // so we'll just use array_merge() to take the structure of datetime_spaces
386
-        // but overwrite all of the data with that from datetime_tickets
387
-        $this->datetime_tickets = array_merge(
388
-            $this->datetime_spaces,
389
-            $this->datetime_tickets
390
-        );
391
-        if ($this->debug) {
392
-            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
393
-            \EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
394
-            \EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
395
-        }
396
-    }
397
-
398
-
399
-
400
-    /**
401
-     * performs calculations on initialized data
402
-     *
403
-     * @param bool $consider_sold
404
-     * @return int|float
405
-     */
406
-    private function calculate($consider_sold = true)
407
-    {
408
-        if ($this->debug) {
409
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
410
-        }
411
-        if ($consider_sold) {
412
-            // subtract amounts sold from all ticket quantities and datetime spaces
413
-            $this->adjustTicketQuantitiesDueToSales();
414
-        }
415
-        foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
416
-            $this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
417
-        }
418
-        // total spaces available is just the sum of the spaces available for each datetime
419
-        $spaces_remaining = array_sum($this->total_spaces);
420
-        if ($this->debug) {
421
-            \EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
422
-            \EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
423
-            \EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
424
-        }
425
-        return $spaces_remaining;
426
-    }
427
-
428
-
429
-    /**
430
-     * subtracts amount of  tickets sold from ticket quantities and datetime spaces
431
-     */
432
-    private function adjustTicketQuantitiesDueToSales()
433
-    {
434
-        if ($this->debug) {
435
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
436
-        }
437
-        foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
438
-            if (isset($this->ticket_quantities[ $ticket_identifier ])){
439
-                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
440
-                if ($this->debug) {
441
-                    \EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
442
-                }
443
-            }
444
-            if (
445
-                isset($this->ticket_datetimes[ $ticket_identifier ])
446
-                && is_array($this->ticket_datetimes[ $ticket_identifier ])
447
-            ){
448
-                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
449
-                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
450
-                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
451
-                        if ($this->debug) {
452
-                            \EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
453
-                                'subtracting', __FILE__, __LINE__);
454
-                        }
455
-                    }
456
-                }
457
-            }
458
-        }
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     * @param string $datetime_identifier
465
-     * @param array  $tickets
466
-     */
467
-    private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
468
-    {
469
-        // make sure a reg limit is set for the datetime
470
-        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
471
-            ? $this->datetime_spaces[ $datetime_identifier ]
472
-            : 0;
473
-        // and bail if it is not
474
-        if ( ! $reg_limit) {
475
-            if ($this->debug) {
476
-                \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
477
-            }
478
-            return;
479
-        }
480
-        if ($this->debug) {
481
-            \EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
482
-            \EEH_Debug_Tools::printr("{$reg_limit}", 'REG LIMIT', __FILE__, __LINE__);
483
-        }
484
-        // number of allocated spaces always starts at zero
485
-        $spaces_allocated                           = 0;
486
-        $this->total_spaces[ $datetime_identifier ] = 0;
487
-        foreach ($tickets as $ticket_identifier) {
488
-            $spaces_allocated = $this->calculateAvailableSpacesForTicket(
489
-                $datetime_identifier,
490
-                $reg_limit,
491
-                $ticket_identifier,
492
-                $spaces_allocated
493
-            );
494
-        }
495
-        // spaces can't be negative
496
-        $spaces_allocated = max($spaces_allocated, 0);
497
-        if ($spaces_allocated) {
498
-            // track any non-zero values
499
-            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
500
-            if ($this->debug) {
501
-                \EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
502
-            }
503
-        } else {
504
-            if ($this->debug) {
505
-                \EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
506
-            }
507
-        }
508
-        if ($this->debug) {
509
-            \EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
510
-                __LINE__);
511
-            \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
512
-            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
513
-        }
514
-    }
515
-
516
-
517
-
518
-    /**
519
-     * @param string $datetime_identifier
520
-     * @param int    $reg_limit
521
-     * @param string $ticket_identifier
522
-     * @param int    $spaces_allocated
523
-     * @return int
524
-     */
525
-    private function calculateAvailableSpacesForTicket(
526
-        $datetime_identifier,
527
-        $reg_limit,
528
-        $ticket_identifier,
529
-        $spaces_allocated
530
-    ) {
531
-        // make sure ticket quantity is set
532
-        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
533
-            ? $this->ticket_quantities[ $ticket_identifier ]
534
-            : 0;
535
-        if ($this->debug) {
536
-            \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
537
-            \EEH_Debug_Tools::printr("{$ticket_quantity}", "ticket $ticket_identifier quantity: ",
538
-                __FILE__, __LINE__, 2);
539
-        }
540
-        if ($ticket_quantity) {
541
-            if ($this->debug) {
542
-                \EEH_Debug_Tools::printr(
543
-                    ($spaces_allocated <= $reg_limit)
544
-                        ? 'true'
545
-                        : 'false',
546
-                    ' . spaces_allocated <= reg_limit = ',
547
-                    __FILE__, __LINE__
548
-                );
549
-            }
550
-            // if the datetime is NOT at full capacity yet
551
-            if ($spaces_allocated <= $reg_limit) {
552
-                // then the maximum ticket quantity we can allocate is the lowest value of either:
553
-                //  the number of remaining spaces for the datetime, which is the limit - spaces already taken
554
-                //  or the maximum ticket quantity
555
-                $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
556
-                // adjust the available quantity in our tracking array
557
-                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
558
-                // and increment spaces allocated for this datetime
559
-                $spaces_allocated += $ticket_quantity;
560
-                $at_capacity = $spaces_allocated >= $reg_limit;
561
-                if ($this->debug) {
562
-                    \EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
563
-                        __FILE__, __LINE__,   3);
564
-                    if ($at_capacity) {
565
-                        \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
566
-                    }
567
-                }
568
-                // now adjust all other datetimes that allow access to this ticket
569
-                $this->adjustDatetimes(
570
-                    $datetime_identifier,
571
-                    $ticket_identifier,
572
-                    $ticket_quantity,
573
-                    $at_capacity
574
-                );
575
-            }
576
-        }
577
-        return $spaces_allocated;
578
-    }
579
-
580
-
581
-
582
-    /**
583
-     * subtracts ticket amounts from all datetime reg limits
584
-     * that allow access to the ticket specified,
585
-     * because that ticket could be used
586
-     * to attend any of the datetimes it has access to
587
-     *
588
-     * @param string $datetime_identifier
589
-     * @param string $ticket_identifier
590
-     * @param bool   $at_capacity
591
-     * @param int    $ticket_quantity
592
-     */
593
-    private function adjustDatetimes(
594
-        $datetime_identifier,
595
-        $ticket_identifier,
596
-        $ticket_quantity,
597
-        $at_capacity
598
-    ) {
599
-        /** @var array $datetime_tickets */
600
-        foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
601
-            if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
602
-                continue;
603
-            }
604
-            $adjusted = $this->adjustDatetimeSpaces(
605
-                $datetime_ID,
606
-                $ticket_identifier,
607
-                $ticket_quantity
608
-            );
609
-            // skip to next ticket if nothing changed
610
-            if (! ($adjusted || $at_capacity)) {
611
-                continue;
612
-            }
613
-            // then all of it's tickets are now unavailable
614
-            foreach ($datetime_tickets as $datetime_ticket) {
615
-                if (
616
-                    ($ticket_identifier === $datetime_ticket || $at_capacity)
617
-                    && isset($this->ticket_quantities[ $datetime_ticket ])
618
-                    && $this->ticket_quantities[ $datetime_ticket ] > 0
619
-                ) {
620
-                    if ($this->debug) {
621
-                        \EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
622
-                            __LINE__);
623
-                    }
624
-                    // if this datetime is at full capacity, set any tracked available quantities to zero
625
-                    // otherwise just subtract the ticket quantity
626
-                    $new_quantity = $at_capacity
627
-                        ? 0
628
-                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
629
-                    // don't let ticket quantity go below zero
630
-                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
631
-                    if ($this->debug) {
632
-                        \EEH_Debug_Tools::printr(
633
-                            $at_capacity
634
-                                ? "0 because Datetime {$datetime_identifier} is at capacity"
635
-                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
636
-                            " . . . . {$datetime_ticket} quantity set to ",
637
-                            __FILE__, __LINE__
638
-                        );
639
-                    }
640
-                }
641
-                // but we also need to adjust spaces for any other datetimes this ticket has access to
642
-                if ($datetime_ticket === $ticket_identifier) {
643
-                    if (isset($this->ticket_datetimes[ $datetime_ticket ])
644
-                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
645
-                    ) {
646
-                        if ($this->debug) {
647
-                            \EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
648
-                                __LINE__);
649
-                        }
650
-                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
651
-                            // don't adjust the current datetime twice
652
-                            if ($datetime !== $datetime_identifier) {
653
-                                $this->adjustDatetimeSpaces(
654
-                                    $datetime,
655
-                                    $datetime_ticket,
656
-                                    $ticket_quantity
657
-                                );
658
-                            }
659
-                        }
660
-                    }
661
-                }
662
-            }
663
-        }
664
-    }
665
-
666
-    private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
667
-    {
668
-        // does datetime have spaces available?
669
-        // and does the supplied ticket have access to this datetime ?
670
-        if (
671
-            $this->datetime_spaces[ $datetime_identifier ] > 0
672
-            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
673
-            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
674
-            ) {
675
-            if ($this->debug) {
676
-                \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
677
-                \EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
678
-            }
679
-            // then decrement the available spaces for the datetime
680
-            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
681
-            // but don't let quantities go below zero
682
-            $this->datetime_spaces[ $datetime_identifier ] = max(
683
-                $this->datetime_spaces[ $datetime_identifier ],
684
-                0
685
-            );
686
-            if ($this->debug) {
687
-                \EEH_Debug_Tools::printr("{$ticket_quantity}",
688
-                    " . . . {$datetime_identifier} capacity reduced by", __FILE__, __LINE__);
689
-            }
690
-            return true;
691
-        }
692
-        return false;
693
-    }
34
+	/**
35
+	 * @var EE_Event $event
36
+	 */
37
+	private $event;
38
+
39
+	/**
40
+	 * @var array $datetime_query_params
41
+	 */
42
+	private $datetime_query_params;
43
+
44
+	/**
45
+	 * @var EE_Ticket[] $active_tickets
46
+	 */
47
+	private $active_tickets = array();
48
+
49
+	/**
50
+	 * @var EE_Datetime[] $datetimes
51
+	 */
52
+	private $datetimes = array();
53
+
54
+	/**
55
+	 * Array of Ticket IDs grouped by Datetime
56
+	 *
57
+	 * @var array $datetimes
58
+	 */
59
+	private $datetime_tickets = array();
60
+
61
+	/**
62
+	 * Max spaces for each Datetime (reg limit - previous sold)
63
+	 *
64
+	 * @var array $datetime_spaces
65
+	 */
66
+	private $datetime_spaces = array();
67
+
68
+	/**
69
+	 * Array of Datetime IDs grouped by Ticket
70
+	 *
71
+	 * @var array[] $ticket_datetimes
72
+	 */
73
+	private $ticket_datetimes = array();
74
+
75
+	/**
76
+	 * maximum ticket quantities for each ticket (adjusted for reg limit)
77
+	 *
78
+	 * @var array $ticket_quantities
79
+	 */
80
+	private $ticket_quantities = array();
81
+
82
+	/**
83
+	 * total quantity of sold and reserved for each ticket
84
+	 *
85
+	 * @var array $tickets_sold
86
+	 */
87
+	private $tickets_sold = array();
88
+
89
+	/**
90
+	 * total spaces available across all datetimes
91
+	 *
92
+	 * @var array $total_spaces
93
+	 */
94
+	private $total_spaces = array();
95
+
96
+	/**
97
+	 * @var boolean $debug
98
+	 */
99
+	private $debug = false;
100
+
101
+	/**
102
+	 * @var null|int $spaces_remaining
103
+	 */
104
+	private $spaces_remaining;
105
+
106
+	/**
107
+	 * @var null|int $total_spaces_available
108
+	 */
109
+	private $total_spaces_available;
110
+
111
+
112
+
113
+	/**
114
+	 * EventSpacesCalculator constructor.
115
+	 *
116
+	 * @param EE_Event $event
117
+	 * @param array    $datetime_query_params
118
+	 * @throws EE_Error
119
+	 */
120
+	public function __construct(EE_Event $event, array $datetime_query_params = array())
121
+	{
122
+		$this->event                 = $event;
123
+		$this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
124
+		$this->setHooks();
125
+	}
126
+
127
+
128
+
129
+	/**
130
+	 * @return void
131
+	 */
132
+	private function setHooks()
133
+	{
134
+		add_action( 'AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
+		add_action( 'AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
+		add_action( 'AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
+		add_action( 'AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
+		add_action( 'AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
+		add_action( 'AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
+		add_action( 'AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
+		add_action( 'AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 * @return void
148
+	 */
149
+	public function clearResults()
150
+	{
151
+		$this->spaces_remaining = null;
152
+		$this->total_spaces_available = null;
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 * @return EE_Ticket[]
159
+	 * @throws EE_Error
160
+	 * @throws InvalidDataTypeException
161
+	 * @throws InvalidInterfaceException
162
+	 * @throws InvalidArgumentException
163
+	 */
164
+	public function getActiveTickets()
165
+	{
166
+		if (empty($this->active_tickets)) {
167
+			$this->active_tickets = $this->event->tickets(
168
+				array(
169
+					array(
170
+						'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
171
+						'TKT_deleted'  => false,
172
+					),
173
+					'order_by' => array('TKT_qty' => 'ASC'),
174
+				)
175
+			);
176
+		}
177
+		return $this->active_tickets;
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 * @param EE_Ticket[] $active_tickets
184
+	 * @throws EE_Error
185
+	 * @throws DomainException
186
+	 * @throws UnexpectedEntityException
187
+	 */
188
+	public function setActiveTickets(array $active_tickets = array())
189
+	{
190
+		if ( ! empty($active_tickets)) {
191
+			foreach ($active_tickets as $active_ticket) {
192
+				$this->validateTicket($active_ticket);
193
+			}
194
+			// sort incoming array by ticket quantity (asc)
195
+			usort(
196
+				$active_tickets,
197
+				function (EE_Ticket $a, EE_Ticket $b) {
198
+					if ($a->qty() === $b->qty()) {
199
+						return 0;
200
+					}
201
+					return ($a->qty() < $b->qty())
202
+						? -1
203
+						: 1;
204
+				}
205
+			);
206
+		}
207
+		$this->active_tickets = $active_tickets;
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 * @param $ticket
214
+	 * @throws DomainException
215
+	 * @throws EE_Error
216
+	 * @throws UnexpectedEntityException
217
+	 */
218
+	private function validateTicket($ticket)
219
+	{
220
+		if ( ! $ticket instanceof EE_Ticket) {
221
+			throw new DomainException(
222
+				esc_html__(
223
+					'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
224
+					'event_espresso'
225
+				)
226
+			);
227
+		}
228
+		if ($ticket->get_event_ID() !== $this->event->ID()) {
229
+			throw new DomainException(
230
+				sprintf(
231
+					esc_html__(
232
+						'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
233
+						'event_espresso'
234
+					),
235
+					$ticket->get_event_ID(),
236
+					$this->event->ID()
237
+				)
238
+			);
239
+		}
240
+	}
241
+
242
+
243
+
244
+	/**
245
+	 * @return EE_Datetime[]
246
+	 */
247
+	public function getDatetimes()
248
+	{
249
+		return $this->datetimes;
250
+	}
251
+
252
+
253
+
254
+	/**
255
+	 * @param EE_Datetime $datetime
256
+	 * @throws EE_Error
257
+	 * @throws DomainException
258
+	 */
259
+	public function setDatetime(EE_Datetime $datetime)
260
+	{
261
+		if ($datetime->event()->ID() !== $this->event->ID()) {
262
+			throw new DomainException(
263
+				sprintf(
264
+					esc_html__(
265
+						'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
266
+						'event_espresso'
267
+					),
268
+					$datetime->event()->ID(),
269
+					$this->event->ID()
270
+				)
271
+			);
272
+		}
273
+		$this->datetimes[ $datetime->ID() ] = $datetime;
274
+	}
275
+
276
+
277
+
278
+	/**
279
+	 * calculate spaces remaining based on "saleable" tickets
280
+	 *
281
+	 * @return float|int
282
+	 * @throws EE_Error
283
+	 * @throws DomainException
284
+	 * @throws UnexpectedEntityException
285
+	 * @throws InvalidDataTypeException
286
+	 * @throws InvalidInterfaceException
287
+	 * @throws InvalidArgumentException
288
+	 */
289
+	public function spacesRemaining()
290
+	{
291
+		if ($this->spaces_remaining === null) {
292
+			$this->initialize();
293
+			$this->spaces_remaining = $this->calculate();
294
+		}
295
+		return $this->spaces_remaining;
296
+	}
297
+
298
+
299
+
300
+	/**
301
+	 * calculates total available spaces for an event with no regard for sold tickets
302
+	 *
303
+	 * @return int|float
304
+	 * @throws EE_Error
305
+	 * @throws DomainException
306
+	 * @throws UnexpectedEntityException
307
+	 * @throws InvalidDataTypeException
308
+	 * @throws InvalidInterfaceException
309
+	 * @throws InvalidArgumentException
310
+	 */
311
+	public function totalSpacesAvailable()
312
+	{
313
+		if($this->total_spaces_available === null) {
314
+			$this->initialize();
315
+			$this->total_spaces_available = $this->calculate(false);
316
+		}
317
+		return $this->total_spaces_available;
318
+	}
319
+
320
+
321
+
322
+	/**
323
+	 * Loops through the active tickets for the event
324
+	 * and builds a series of data arrays that will be used for calculating
325
+	 * the total maximum available spaces, as well as the spaces remaining.
326
+	 * Because ticket quantities affect datetime spaces and vice versa,
327
+	 * we need to be constantly updating these data arrays as things change,
328
+	 * which is the entire reason for their existence.
329
+	 *
330
+	 * @throws EE_Error
331
+	 * @throws DomainException
332
+	 * @throws UnexpectedEntityException
333
+	 * @throws InvalidDataTypeException
334
+	 * @throws InvalidInterfaceException
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	private function initialize()
338
+	{
339
+		if ($this->debug) {
340
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
341
+		}
342
+		$this->datetime_tickets  = array();
343
+		$this->datetime_spaces   = array();
344
+		$this->ticket_datetimes  = array();
345
+		$this->ticket_quantities = array();
346
+		$this->tickets_sold      = array();
347
+		$this->total_spaces      = array();
348
+		$active_tickets          = $this->getActiveTickets();
349
+		if ( ! empty($active_tickets)) {
350
+			foreach ($active_tickets as $ticket) {
351
+				$this->validateTicket($ticket);
352
+				// we need to index our data arrays using strings for the purpose of sorting,
353
+				// but we also need them to be unique, so  we'll just prepend a letter T to the ID
354
+				$ticket_identifier = "T{$ticket->ID()}";
355
+				// to start, we'll just consider the raw qty to be the maximum availability for this ticket
356
+				$max_tickets = $ticket->qty();
357
+				// but we'll adjust that after looping over each datetime for the ticket and checking reg limits
358
+				$ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
359
+				foreach ($ticket_datetimes as $datetime) {
360
+					// save all datetimes
361
+					$this->setDatetime($datetime);
362
+					$datetime_identifier = "D{$datetime->ID()}";
363
+					$reg_limit           = $datetime->reg_limit();
364
+					// ticket quantity can not exceed datetime reg limit
365
+					$max_tickets = min($max_tickets, $reg_limit);
366
+					// as described earlier, because we need to be able to constantly adjust numbers for things,
367
+					// we are going to move all of our data into the following arrays:
368
+					// datetime spaces initially represents the reg limit for each datetime,
369
+					// but this will get adjusted as tickets are accounted for
370
+					$this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
371
+					// just an array of ticket IDs grouped by datetime
372
+					$this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
373
+					// and an array of datetime IDs grouped by ticket
374
+					$this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
375
+				}
376
+				// total quantity of sold and reserved for each ticket
377
+				$this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
378
+				// and the maximum ticket quantities for each ticket (adjusted for reg limit)
379
+				$this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
380
+			}
381
+		}
382
+		// sort datetime spaces by reg limit, but maintain our string indexes
383
+		asort($this->datetime_spaces, SORT_NUMERIC);
384
+		// datetime tickets need to be sorted in the SAME order as the above array...
385
+		// so we'll just use array_merge() to take the structure of datetime_spaces
386
+		// but overwrite all of the data with that from datetime_tickets
387
+		$this->datetime_tickets = array_merge(
388
+			$this->datetime_spaces,
389
+			$this->datetime_tickets
390
+		);
391
+		if ($this->debug) {
392
+			\EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
393
+			\EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
394
+			\EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
395
+		}
396
+	}
397
+
398
+
399
+
400
+	/**
401
+	 * performs calculations on initialized data
402
+	 *
403
+	 * @param bool $consider_sold
404
+	 * @return int|float
405
+	 */
406
+	private function calculate($consider_sold = true)
407
+	{
408
+		if ($this->debug) {
409
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
410
+		}
411
+		if ($consider_sold) {
412
+			// subtract amounts sold from all ticket quantities and datetime spaces
413
+			$this->adjustTicketQuantitiesDueToSales();
414
+		}
415
+		foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
416
+			$this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
417
+		}
418
+		// total spaces available is just the sum of the spaces available for each datetime
419
+		$spaces_remaining = array_sum($this->total_spaces);
420
+		if ($this->debug) {
421
+			\EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
422
+			\EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
423
+			\EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
424
+		}
425
+		return $spaces_remaining;
426
+	}
427
+
428
+
429
+	/**
430
+	 * subtracts amount of  tickets sold from ticket quantities and datetime spaces
431
+	 */
432
+	private function adjustTicketQuantitiesDueToSales()
433
+	{
434
+		if ($this->debug) {
435
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
436
+		}
437
+		foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
438
+			if (isset($this->ticket_quantities[ $ticket_identifier ])){
439
+				$this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
440
+				if ($this->debug) {
441
+					\EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
442
+				}
443
+			}
444
+			if (
445
+				isset($this->ticket_datetimes[ $ticket_identifier ])
446
+				&& is_array($this->ticket_datetimes[ $ticket_identifier ])
447
+			){
448
+				foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
449
+					if (isset($this->ticket_quantities[ $ticket_identifier ])) {
450
+						$this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
451
+						if ($this->debug) {
452
+							\EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
453
+								'subtracting', __FILE__, __LINE__);
454
+						}
455
+					}
456
+				}
457
+			}
458
+		}
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 * @param string $datetime_identifier
465
+	 * @param array  $tickets
466
+	 */
467
+	private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
468
+	{
469
+		// make sure a reg limit is set for the datetime
470
+		$reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
471
+			? $this->datetime_spaces[ $datetime_identifier ]
472
+			: 0;
473
+		// and bail if it is not
474
+		if ( ! $reg_limit) {
475
+			if ($this->debug) {
476
+				\EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
477
+			}
478
+			return;
479
+		}
480
+		if ($this->debug) {
481
+			\EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
482
+			\EEH_Debug_Tools::printr("{$reg_limit}", 'REG LIMIT', __FILE__, __LINE__);
483
+		}
484
+		// number of allocated spaces always starts at zero
485
+		$spaces_allocated                           = 0;
486
+		$this->total_spaces[ $datetime_identifier ] = 0;
487
+		foreach ($tickets as $ticket_identifier) {
488
+			$spaces_allocated = $this->calculateAvailableSpacesForTicket(
489
+				$datetime_identifier,
490
+				$reg_limit,
491
+				$ticket_identifier,
492
+				$spaces_allocated
493
+			);
494
+		}
495
+		// spaces can't be negative
496
+		$spaces_allocated = max($spaces_allocated, 0);
497
+		if ($spaces_allocated) {
498
+			// track any non-zero values
499
+			$this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
500
+			if ($this->debug) {
501
+				\EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
502
+			}
503
+		} else {
504
+			if ($this->debug) {
505
+				\EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
506
+			}
507
+		}
508
+		if ($this->debug) {
509
+			\EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
510
+				__LINE__);
511
+			\EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
512
+			\EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
513
+		}
514
+	}
515
+
516
+
517
+
518
+	/**
519
+	 * @param string $datetime_identifier
520
+	 * @param int    $reg_limit
521
+	 * @param string $ticket_identifier
522
+	 * @param int    $spaces_allocated
523
+	 * @return int
524
+	 */
525
+	private function calculateAvailableSpacesForTicket(
526
+		$datetime_identifier,
527
+		$reg_limit,
528
+		$ticket_identifier,
529
+		$spaces_allocated
530
+	) {
531
+		// make sure ticket quantity is set
532
+		$ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
533
+			? $this->ticket_quantities[ $ticket_identifier ]
534
+			: 0;
535
+		if ($this->debug) {
536
+			\EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
537
+			\EEH_Debug_Tools::printr("{$ticket_quantity}", "ticket $ticket_identifier quantity: ",
538
+				__FILE__, __LINE__, 2);
539
+		}
540
+		if ($ticket_quantity) {
541
+			if ($this->debug) {
542
+				\EEH_Debug_Tools::printr(
543
+					($spaces_allocated <= $reg_limit)
544
+						? 'true'
545
+						: 'false',
546
+					' . spaces_allocated <= reg_limit = ',
547
+					__FILE__, __LINE__
548
+				);
549
+			}
550
+			// if the datetime is NOT at full capacity yet
551
+			if ($spaces_allocated <= $reg_limit) {
552
+				// then the maximum ticket quantity we can allocate is the lowest value of either:
553
+				//  the number of remaining spaces for the datetime, which is the limit - spaces already taken
554
+				//  or the maximum ticket quantity
555
+				$ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
556
+				// adjust the available quantity in our tracking array
557
+				$this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
558
+				// and increment spaces allocated for this datetime
559
+				$spaces_allocated += $ticket_quantity;
560
+				$at_capacity = $spaces_allocated >= $reg_limit;
561
+				if ($this->debug) {
562
+					\EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
563
+						__FILE__, __LINE__,   3);
564
+					if ($at_capacity) {
565
+						\EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
566
+					}
567
+				}
568
+				// now adjust all other datetimes that allow access to this ticket
569
+				$this->adjustDatetimes(
570
+					$datetime_identifier,
571
+					$ticket_identifier,
572
+					$ticket_quantity,
573
+					$at_capacity
574
+				);
575
+			}
576
+		}
577
+		return $spaces_allocated;
578
+	}
579
+
580
+
581
+
582
+	/**
583
+	 * subtracts ticket amounts from all datetime reg limits
584
+	 * that allow access to the ticket specified,
585
+	 * because that ticket could be used
586
+	 * to attend any of the datetimes it has access to
587
+	 *
588
+	 * @param string $datetime_identifier
589
+	 * @param string $ticket_identifier
590
+	 * @param bool   $at_capacity
591
+	 * @param int    $ticket_quantity
592
+	 */
593
+	private function adjustDatetimes(
594
+		$datetime_identifier,
595
+		$ticket_identifier,
596
+		$ticket_quantity,
597
+		$at_capacity
598
+	) {
599
+		/** @var array $datetime_tickets */
600
+		foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
601
+			if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
602
+				continue;
603
+			}
604
+			$adjusted = $this->adjustDatetimeSpaces(
605
+				$datetime_ID,
606
+				$ticket_identifier,
607
+				$ticket_quantity
608
+			);
609
+			// skip to next ticket if nothing changed
610
+			if (! ($adjusted || $at_capacity)) {
611
+				continue;
612
+			}
613
+			// then all of it's tickets are now unavailable
614
+			foreach ($datetime_tickets as $datetime_ticket) {
615
+				if (
616
+					($ticket_identifier === $datetime_ticket || $at_capacity)
617
+					&& isset($this->ticket_quantities[ $datetime_ticket ])
618
+					&& $this->ticket_quantities[ $datetime_ticket ] > 0
619
+				) {
620
+					if ($this->debug) {
621
+						\EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
622
+							__LINE__);
623
+					}
624
+					// if this datetime is at full capacity, set any tracked available quantities to zero
625
+					// otherwise just subtract the ticket quantity
626
+					$new_quantity = $at_capacity
627
+						? 0
628
+						: $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
629
+					// don't let ticket quantity go below zero
630
+					$this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
631
+					if ($this->debug) {
632
+						\EEH_Debug_Tools::printr(
633
+							$at_capacity
634
+								? "0 because Datetime {$datetime_identifier} is at capacity"
635
+								: "{$this->ticket_quantities[ $datetime_ticket ]}",
636
+							" . . . . {$datetime_ticket} quantity set to ",
637
+							__FILE__, __LINE__
638
+						);
639
+					}
640
+				}
641
+				// but we also need to adjust spaces for any other datetimes this ticket has access to
642
+				if ($datetime_ticket === $ticket_identifier) {
643
+					if (isset($this->ticket_datetimes[ $datetime_ticket ])
644
+						&& is_array($this->ticket_datetimes[ $datetime_ticket ])
645
+					) {
646
+						if ($this->debug) {
647
+							\EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
648
+								__LINE__);
649
+						}
650
+						foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
651
+							// don't adjust the current datetime twice
652
+							if ($datetime !== $datetime_identifier) {
653
+								$this->adjustDatetimeSpaces(
654
+									$datetime,
655
+									$datetime_ticket,
656
+									$ticket_quantity
657
+								);
658
+							}
659
+						}
660
+					}
661
+				}
662
+			}
663
+		}
664
+	}
665
+
666
+	private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
667
+	{
668
+		// does datetime have spaces available?
669
+		// and does the supplied ticket have access to this datetime ?
670
+		if (
671
+			$this->datetime_spaces[ $datetime_identifier ] > 0
672
+			&& isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
673
+			&& in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
674
+			) {
675
+			if ($this->debug) {
676
+				\EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
677
+				\EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
678
+			}
679
+			// then decrement the available spaces for the datetime
680
+			$this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
681
+			// but don't let quantities go below zero
682
+			$this->datetime_spaces[ $datetime_identifier ] = max(
683
+				$this->datetime_spaces[ $datetime_identifier ],
684
+				0
685
+			);
686
+			if ($this->debug) {
687
+				\EEH_Debug_Tools::printr("{$ticket_quantity}",
688
+					" . . . {$datetime_identifier} capacity reduced by", __FILE__, __LINE__);
689
+			}
690
+			return true;
691
+		}
692
+		return false;
693
+	}
694 694
 
695 695
 }
696 696
 // Location: EventSpacesCalculator.php
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -131,14 +131,14 @@  discard block
 block discarded – undo
131 131
      */
132 132
     private function setHooks()
133 133
     {
134
-        add_action( 'AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
-        add_action( 'AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
-        add_action( 'AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
-        add_action( 'AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
-        add_action( 'AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
-        add_action( 'AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
-        add_action( 'AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
-        add_action( 'AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
134
+        add_action('AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
+        add_action('AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
+        add_action('AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
+        add_action('AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
+        add_action('AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
+        add_action('AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
+        add_action('AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
+        add_action('AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
142 142
     }
143 143
 
144 144
 
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
             // sort incoming array by ticket quantity (asc)
195 195
             usort(
196 196
                 $active_tickets,
197
-                function (EE_Ticket $a, EE_Ticket $b) {
197
+                function(EE_Ticket $a, EE_Ticket $b) {
198 198
                     if ($a->qty() === $b->qty()) {
199 199
                         return 0;
200 200
                     }
@@ -270,7 +270,7 @@  discard block
 block discarded – undo
270 270
                 )
271 271
             );
272 272
         }
273
-        $this->datetimes[ $datetime->ID() ] = $datetime;
273
+        $this->datetimes[$datetime->ID()] = $datetime;
274 274
     }
275 275
 
276 276
 
@@ -310,7 +310,7 @@  discard block
 block discarded – undo
310 310
      */
311 311
     public function totalSpacesAvailable()
312 312
     {
313
-        if($this->total_spaces_available === null) {
313
+        if ($this->total_spaces_available === null) {
314 314
             $this->initialize();
315 315
             $this->total_spaces_available = $this->calculate(false);
316 316
         }
@@ -367,16 +367,16 @@  discard block
 block discarded – undo
367 367
                     // we are going to move all of our data into the following arrays:
368 368
                     // datetime spaces initially represents the reg limit for each datetime,
369 369
                     // but this will get adjusted as tickets are accounted for
370
-                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
370
+                    $this->datetime_spaces[$datetime_identifier] = $reg_limit;
371 371
                     // just an array of ticket IDs grouped by datetime
372
-                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
372
+                    $this->datetime_tickets[$datetime_identifier][] = $ticket_identifier;
373 373
                     // and an array of datetime IDs grouped by ticket
374
-                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
374
+                    $this->ticket_datetimes[$ticket_identifier][] = $datetime_identifier;
375 375
                 }
376 376
                 // total quantity of sold and reserved for each ticket
377
-                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
377
+                $this->tickets_sold[$ticket_identifier] = $ticket->sold() + $ticket->reserved();
378 378
                 // and the maximum ticket quantities for each ticket (adjusted for reg limit)
379
-                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
379
+                $this->ticket_quantities[$ticket_identifier] = $max_tickets;
380 380
             }
381 381
         }
382 382
         // sort datetime spaces by reg limit, but maintain our string indexes
@@ -435,19 +435,19 @@  discard block
 block discarded – undo
435 435
             \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
436 436
         }
437 437
         foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
438
-            if (isset($this->ticket_quantities[ $ticket_identifier ])){
439
-                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
438
+            if (isset($this->ticket_quantities[$ticket_identifier])) {
439
+                $this->ticket_quantities[$ticket_identifier] -= $tickets_sold;
440 440
                 if ($this->debug) {
441 441
                     \EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
442 442
                 }
443 443
             }
444 444
             if (
445
-                isset($this->ticket_datetimes[ $ticket_identifier ])
446
-                && is_array($this->ticket_datetimes[ $ticket_identifier ])
447
-            ){
448
-                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
449
-                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
450
-                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
445
+                isset($this->ticket_datetimes[$ticket_identifier])
446
+                && is_array($this->ticket_datetimes[$ticket_identifier])
447
+            ) {
448
+                foreach ($this->ticket_datetimes[$ticket_identifier] as $ticket_datetime) {
449
+                    if (isset($this->ticket_quantities[$ticket_identifier])) {
450
+                        $this->datetime_spaces[$ticket_datetime] -= $tickets_sold;
451 451
                         if ($this->debug) {
452 452
                             \EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
453 453
                                 'subtracting', __FILE__, __LINE__);
@@ -467,8 +467,8 @@  discard block
 block discarded – undo
467 467
     private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
468 468
     {
469 469
         // make sure a reg limit is set for the datetime
470
-        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
471
-            ? $this->datetime_spaces[ $datetime_identifier ]
470
+        $reg_limit = isset($this->datetime_spaces[$datetime_identifier])
471
+            ? $this->datetime_spaces[$datetime_identifier]
472 472
             : 0;
473 473
         // and bail if it is not
474 474
         if ( ! $reg_limit) {
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
         }
484 484
         // number of allocated spaces always starts at zero
485 485
         $spaces_allocated                           = 0;
486
-        $this->total_spaces[ $datetime_identifier ] = 0;
486
+        $this->total_spaces[$datetime_identifier] = 0;
487 487
         foreach ($tickets as $ticket_identifier) {
488 488
             $spaces_allocated = $this->calculateAvailableSpacesForTicket(
489 489
                 $datetime_identifier,
@@ -496,9 +496,9 @@  discard block
 block discarded – undo
496 496
         $spaces_allocated = max($spaces_allocated, 0);
497 497
         if ($spaces_allocated) {
498 498
             // track any non-zero values
499
-            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
499
+            $this->total_spaces[$datetime_identifier] += $spaces_allocated;
500 500
             if ($this->debug) {
501
-                \EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
501
+                \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
502 502
             }
503 503
         } else {
504 504
             if ($this->debug) {
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
             }
507 507
         }
508 508
         if ($this->debug) {
509
-            \EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
509
+            \EEH_Debug_Tools::printr($this->total_spaces[$datetime_identifier], '$total_spaces', __FILE__,
510 510
                 __LINE__);
511 511
             \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
512 512
             \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
@@ -529,8 +529,8 @@  discard block
 block discarded – undo
529 529
         $spaces_allocated
530 530
     ) {
531 531
         // make sure ticket quantity is set
532
-        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
533
-            ? $this->ticket_quantities[ $ticket_identifier ]
532
+        $ticket_quantity = isset($this->ticket_quantities[$ticket_identifier])
533
+            ? $this->ticket_quantities[$ticket_identifier]
534 534
             : 0;
535 535
         if ($this->debug) {
536 536
             \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
@@ -554,13 +554,13 @@  discard block
 block discarded – undo
554 554
                 //  or the maximum ticket quantity
555 555
                 $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
556 556
                 // adjust the available quantity in our tracking array
557
-                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
557
+                $this->ticket_quantities[$ticket_identifier] -= $ticket_quantity;
558 558
                 // and increment spaces allocated for this datetime
559 559
                 $spaces_allocated += $ticket_quantity;
560 560
                 $at_capacity = $spaces_allocated >= $reg_limit;
561 561
                 if ($this->debug) {
562 562
                     \EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
563
-                        __FILE__, __LINE__,   3);
563
+                        __FILE__, __LINE__, 3);
564 564
                     if ($at_capacity) {
565 565
                         \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
566 566
                     }
@@ -607,15 +607,15 @@  discard block
 block discarded – undo
607 607
                 $ticket_quantity
608 608
             );
609 609
             // skip to next ticket if nothing changed
610
-            if (! ($adjusted || $at_capacity)) {
610
+            if ( ! ($adjusted || $at_capacity)) {
611 611
                 continue;
612 612
             }
613 613
             // then all of it's tickets are now unavailable
614 614
             foreach ($datetime_tickets as $datetime_ticket) {
615 615
                 if (
616 616
                     ($ticket_identifier === $datetime_ticket || $at_capacity)
617
-                    && isset($this->ticket_quantities[ $datetime_ticket ])
618
-                    && $this->ticket_quantities[ $datetime_ticket ] > 0
617
+                    && isset($this->ticket_quantities[$datetime_ticket])
618
+                    && $this->ticket_quantities[$datetime_ticket] > 0
619 619
                 ) {
620 620
                     if ($this->debug) {
621 621
                         \EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
@@ -625,14 +625,14 @@  discard block
 block discarded – undo
625 625
                     // otherwise just subtract the ticket quantity
626 626
                     $new_quantity = $at_capacity
627 627
                         ? 0
628
-                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
628
+                        : $this->ticket_quantities[$datetime_ticket] - $ticket_quantity;
629 629
                     // don't let ticket quantity go below zero
630
-                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
630
+                    $this->ticket_quantities[$datetime_ticket] = max($new_quantity, 0);
631 631
                     if ($this->debug) {
632 632
                         \EEH_Debug_Tools::printr(
633 633
                             $at_capacity
634 634
                                 ? "0 because Datetime {$datetime_identifier} is at capacity"
635
-                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
635
+                                : "{$this->ticket_quantities[$datetime_ticket]}",
636 636
                             " . . . . {$datetime_ticket} quantity set to ",
637 637
                             __FILE__, __LINE__
638 638
                         );
@@ -640,14 +640,14 @@  discard block
 block discarded – undo
640 640
                 }
641 641
                 // but we also need to adjust spaces for any other datetimes this ticket has access to
642 642
                 if ($datetime_ticket === $ticket_identifier) {
643
-                    if (isset($this->ticket_datetimes[ $datetime_ticket ])
644
-                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
643
+                    if (isset($this->ticket_datetimes[$datetime_ticket])
644
+                        && is_array($this->ticket_datetimes[$datetime_ticket])
645 645
                     ) {
646 646
                         if ($this->debug) {
647 647
                             \EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
648 648
                                 __LINE__);
649 649
                         }
650
-                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
650
+                        foreach ($this->ticket_datetimes[$datetime_ticket] as $datetime) {
651 651
                             // don't adjust the current datetime twice
652 652
                             if ($datetime !== $datetime_identifier) {
653 653
                                 $this->adjustDatetimeSpaces(
@@ -668,19 +668,19 @@  discard block
 block discarded – undo
668 668
         // does datetime have spaces available?
669 669
         // and does the supplied ticket have access to this datetime ?
670 670
         if (
671
-            $this->datetime_spaces[ $datetime_identifier ] > 0
672
-            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
673
-            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
671
+            $this->datetime_spaces[$datetime_identifier] > 0
672
+            && isset($this->datetime_spaces[$datetime_identifier], $this->datetime_tickets[$datetime_identifier])
673
+            && in_array($ticket_identifier, $this->datetime_tickets[$datetime_identifier], true)
674 674
             ) {
675 675
             if ($this->debug) {
676 676
                 \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
677
-                \EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
677
+                \EEH_Debug_Tools::printr("{$this->datetime_spaces[$datetime_identifier]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
678 678
             }
679 679
             // then decrement the available spaces for the datetime
680
-            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
680
+            $this->datetime_spaces[$datetime_identifier] -= $ticket_quantity;
681 681
             // but don't let quantities go below zero
682
-            $this->datetime_spaces[ $datetime_identifier ] = max(
683
-                $this->datetime_spaces[ $datetime_identifier ],
682
+            $this->datetime_spaces[$datetime_identifier] = max(
683
+                $this->datetime_spaces[$datetime_identifier],
684 684
                 0
685 685
             );
686 686
             if ($this->debug) {
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket.class.php 2 patches
Indentation   +626 added lines, -626 removed lines patch added patch discarded remove patch
@@ -61,15 +61,15 @@  discard block
 block discarded – undo
61 61
 
62 62
 
63 63
 
64
-    /**
65
-     * @param array  $props_n_values          incoming values
66
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
67
-     *                                        used.)
68
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
69
-     *                                        date_format and the second value is the time format
70
-     * @return EE_Ticket
71
-     * @throws \EE_Error
72
-     */
64
+	/**
65
+	 * @param array  $props_n_values          incoming values
66
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
67
+	 *                                        used.)
68
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
69
+	 *                                        date_format and the second value is the time format
70
+	 * @return EE_Ticket
71
+	 * @throws \EE_Error
72
+	 */
73 73
 	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
74 74
 		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
75 75
 		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
@@ -77,36 +77,36 @@  discard block
 block discarded – undo
77 77
 
78 78
 
79 79
 
80
-    /**
81
-     * @param array  $props_n_values  incoming values from the database
82
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
83
-     *                                the website will be used.
84
-     * @return EE_Ticket
85
-     * @throws \EE_Error
86
-     */
80
+	/**
81
+	 * @param array  $props_n_values  incoming values from the database
82
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
83
+	 *                                the website will be used.
84
+	 * @return EE_Ticket
85
+	 * @throws \EE_Error
86
+	 */
87 87
 	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
88 88
 		return new self( $props_n_values, TRUE, $timezone );
89 89
 	}
90 90
 
91 91
 
92 92
 
93
-    /**
94
-     * @return bool
95
-     * @throws \EE_Error
96
-     */
93
+	/**
94
+	 * @return bool
95
+	 * @throws \EE_Error
96
+	 */
97 97
 	public function parent() {
98 98
 		return $this->get( 'TKT_parent' );
99 99
 	}
100 100
 
101 101
 
102 102
 
103
-    /**
104
-     * return if a ticket has quantities available for purchase
105
-     *
106
-     * @param  int $DTT_ID the primary key for a particular datetime
107
-     * @return boolean
108
-     * @throws \EE_Error
109
-     */
103
+	/**
104
+	 * return if a ticket has quantities available for purchase
105
+	 *
106
+	 * @param  int $DTT_ID the primary key for a particular datetime
107
+	 * @return boolean
108
+	 * @throws \EE_Error
109
+	 */
110 110
 	public function available( $DTT_ID = 0 ) {
111 111
 		// are we checking availability for a particular datetime ?
112 112
 		if ( $DTT_ID ) {
@@ -123,14 +123,14 @@  discard block
 block discarded – undo
123 123
 
124 124
 
125 125
 
126
-    /**
127
-     * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
128
-     *
129
-     * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the relevant status const
130
-     * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save further processing
131
-     * @return mixed status int if the display string isn't requested
132
-     * @throws \EE_Error
133
-     */
126
+	/**
127
+	 * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
128
+	 *
129
+	 * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the relevant status const
130
+	 * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save further processing
131
+	 * @return mixed status int if the display string isn't requested
132
+	 * @throws \EE_Error
133
+	 */
134 134
 	public function ticket_status( $display = FALSE, $remaining = null ) {
135 135
 		$remaining = is_bool( $remaining ) ? $remaining : $this->is_remaining();
136 136
 		if ( ! $remaining ) {
@@ -153,14 +153,14 @@  discard block
 block discarded – undo
153 153
 
154 154
 
155 155
 
156
-    /**
157
-     * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale considering ALL the factors used for figuring that out.
158
-     *
159
-     * @access public
160
-     * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
161
-     * @return boolean         true = tickets remaining, false not.
162
-     * @throws \EE_Error
163
-     */
156
+	/**
157
+	 * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale considering ALL the factors used for figuring that out.
158
+	 *
159
+	 * @access public
160
+	 * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
161
+	 * @return boolean         true = tickets remaining, false not.
162
+	 * @throws \EE_Error
163
+	 */
164 164
 	public function is_remaining( $DTT_ID = 0 ) {
165 165
 		$num_remaining = $this->remaining( $DTT_ID );
166 166
 		if ( $num_remaining === 0 ) {
@@ -174,76 +174,76 @@  discard block
 block discarded – undo
174 174
 
175 175
 
176 176
 
177
-    /**
178
-     * return the total number of tickets available for purchase
179
-     *
180
-     * @param  int $DTT_ID the primary key for a particular datetime.
181
-     *                     set to 0 for all related datetimes
182
-     * @return int
183
-     * @throws \EE_Error
184
-     */
177
+	/**
178
+	 * return the total number of tickets available for purchase
179
+	 *
180
+	 * @param  int $DTT_ID the primary key for a particular datetime.
181
+	 *                     set to 0 for all related datetimes
182
+	 * @return int
183
+	 * @throws \EE_Error
184
+	 */
185 185
 	public function remaining( $DTT_ID = 0 ) {
186 186
 		return $this->real_quantity_on_ticket('saleable', $DTT_ID );
187 187
 	}
188 188
 
189 189
 
190 190
 
191
-    /**
192
-     * Gets min
193
-     *
194
-     * @return int
195
-     * @throws \EE_Error
196
-     */
191
+	/**
192
+	 * Gets min
193
+	 *
194
+	 * @return int
195
+	 * @throws \EE_Error
196
+	 */
197 197
 	public function min() {
198 198
 		return $this->get( 'TKT_min' );
199 199
 	}
200 200
 
201 201
 
202 202
 
203
-    /**
204
-     * return if a ticket is no longer available cause its available dates have expired.
205
-     *
206
-     * @return boolean
207
-     * @throws \EE_Error
208
-     */
203
+	/**
204
+	 * return if a ticket is no longer available cause its available dates have expired.
205
+	 *
206
+	 * @return boolean
207
+	 * @throws \EE_Error
208
+	 */
209 209
 	public function is_expired() {
210 210
 		return ( $this->get_raw( 'TKT_end_date' ) < time() );
211 211
 	}
212 212
 
213 213
 
214 214
 
215
-    /**
216
-     * Return if a ticket is yet to go on sale or not
217
-     *
218
-     * @return boolean
219
-     * @throws \EE_Error
220
-     */
215
+	/**
216
+	 * Return if a ticket is yet to go on sale or not
217
+	 *
218
+	 * @return boolean
219
+	 * @throws \EE_Error
220
+	 */
221 221
 	public function is_pending() {
222 222
 		return ( $this->get_raw( 'TKT_start_date' ) > time() );
223 223
 	}
224 224
 
225 225
 
226 226
 
227
-    /**
228
-     * Return if a ticket is on sale or not
229
-     *
230
-     * @return boolean
231
-     * @throws \EE_Error
232
-     */
227
+	/**
228
+	 * Return if a ticket is on sale or not
229
+	 *
230
+	 * @return boolean
231
+	 * @throws \EE_Error
232
+	 */
233 233
 	public function is_on_sale() {
234 234
 		return ( $this->get_raw( 'TKT_start_date' ) < time() && $this->get_raw( 'TKT_end_date' ) > time() );
235 235
 	}
236 236
 
237 237
 
238 238
 
239
-    /**
240
-     * This returns the chronologically last datetime that this ticket is associated with
241
-     *
242
-     * @param string $dt_frmt
243
-     * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with the end date ie: Jan 01 "to" Dec 31
244
-     * @return string
245
-     * @throws \EE_Error
246
-     */
239
+	/**
240
+	 * This returns the chronologically last datetime that this ticket is associated with
241
+	 *
242
+	 * @param string $dt_frmt
243
+	 * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with the end date ie: Jan 01 "to" Dec 31
244
+	 * @return string
245
+	 * @throws \EE_Error
246
+	 */
247 247
 	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
248 248
 		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date( $dt_frmt ) : '';
249 249
 		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date( $dt_frmt ) : '';
@@ -253,12 +253,12 @@  discard block
 block discarded – undo
253 253
 
254 254
 
255 255
 
256
-    /**
257
-     * This returns the chronologically first datetime that this ticket is associated with
258
-     *
259
-     * @return EE_Datetime
260
-     * @throws \EE_Error
261
-     */
256
+	/**
257
+	 * This returns the chronologically first datetime that this ticket is associated with
258
+	 *
259
+	 * @return EE_Datetime
260
+	 * @throws \EE_Error
261
+	 */
262 262
 	public function first_datetime() {
263 263
 		$datetimes = $this->datetimes( array( 'limit' => 1 ) );
264 264
 		return reset( $datetimes );
@@ -266,14 +266,14 @@  discard block
 block discarded – undo
266 266
 
267 267
 
268 268
 
269
-    /**
270
-     * Gets all the datetimes this ticket can be used for attending.
271
-     * Unless otherwise specified, orders datetimes by start date.
272
-     *
273
-     * @param array $query_params see EEM_Base::get_all()
274
-     * @return EE_Datetime[]|EE_Base_Class[]
275
-     * @throws \EE_Error
276
-     */
269
+	/**
270
+	 * Gets all the datetimes this ticket can be used for attending.
271
+	 * Unless otherwise specified, orders datetimes by start date.
272
+	 *
273
+	 * @param array $query_params see EEM_Base::get_all()
274
+	 * @return EE_Datetime[]|EE_Base_Class[]
275
+	 * @throws \EE_Error
276
+	 */
277 277
 	public function datetimes( $query_params = array() ) {
278 278
 		if ( ! isset( $query_params[ 'order_by' ] ) ) {
279 279
 			$query_params[ 'order_by' ][ 'DTT_order' ] = 'ASC';
@@ -283,12 +283,12 @@  discard block
 block discarded – undo
283 283
 
284 284
 
285 285
 
286
-    /**
287
-     * This returns the chronologically last datetime that this ticket is associated with
288
-     *
289
-     * @return EE_Datetime
290
-     * @throws \EE_Error
291
-     */
286
+	/**
287
+	 * This returns the chronologically last datetime that this ticket is associated with
288
+	 *
289
+	 * @return EE_Datetime
290
+	 * @throws \EE_Error
291
+	 */
292 292
 	public function last_datetime() {
293 293
 		$datetimes = $this->datetimes( array( 'limit' => 1, 'order_by' => array( 'DTT_EVT_start' => 'DESC' ) ) );
294 294
 		return end( $datetimes );
@@ -296,19 +296,19 @@  discard block
 block discarded – undo
296 296
 
297 297
 
298 298
 
299
-    /**
300
-     * This returns the total tickets sold depending on the given parameters.
301
-     *
302
-     * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
303
-     *                        'ticket' = total ticket sales for all datetimes this ticket is related to
304
-     *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
305
-     *                        'datetime' = total ticket sales in the datetime_ticket table.
306
-     *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
307
-     *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
308
-     * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
309
-     * @return mixed (array|int)          how many tickets have sold
310
-     * @throws \EE_Error
311
-     */
299
+	/**
300
+	 * This returns the total tickets sold depending on the given parameters.
301
+	 *
302
+	 * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
303
+	 *                        'ticket' = total ticket sales for all datetimes this ticket is related to
304
+	 *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
305
+	 *                        'datetime' = total ticket sales in the datetime_ticket table.
306
+	 *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
307
+	 *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
308
+	 * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
309
+	 * @return mixed (array|int)          how many tickets have sold
310
+	 * @throws \EE_Error
311
+	 */
312 312
 	public function tickets_sold( $what = 'ticket', $dtt_id = NULL ) {
313 313
 		$total = 0;
314 314
 		$tickets_sold = $this->_all_tickets_sold();
@@ -333,12 +333,12 @@  discard block
 block discarded – undo
333 333
 
334 334
 
335 335
 
336
-    /**
337
-     * This returns an array indexed by datetime_id for tickets sold with this ticket.
338
-     *
339
-     * @return EE_Ticket[]
340
-     * @throws \EE_Error
341
-     */
336
+	/**
337
+	 * This returns an array indexed by datetime_id for tickets sold with this ticket.
338
+	 *
339
+	 * @return EE_Ticket[]
340
+	 * @throws \EE_Error
341
+	 */
342 342
 	protected function _all_tickets_sold() {
343 343
 		$datetimes = $this->get_many_related( 'Datetime' );
344 344
 		$tickets_sold = array();
@@ -354,29 +354,29 @@  discard block
 block discarded – undo
354 354
 
355 355
 
356 356
 
357
-    /**
358
-     * This returns the base price object for the ticket.
359
-     *
360
-     * @param  bool $return_array whether to return as an array indexed by price id or just the object.
361
-     * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362
-     * @throws \EE_Error
363
-     */
357
+	/**
358
+	 * This returns the base price object for the ticket.
359
+	 *
360
+	 * @param  bool $return_array whether to return as an array indexed by price id or just the object.
361
+	 * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362
+	 * @throws \EE_Error
363
+	 */
364 364
 	public function base_price( $return_array = FALSE ) {
365 365
 		$_where = array( 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price );
366 366
 		return $return_array
367
-            ? $this->get_many_related( 'Price', array( $_where ) )
368
-            : $this->get_first_related( 'Price', array( $_where ) );
367
+			? $this->get_many_related( 'Price', array( $_where ) )
368
+			: $this->get_first_related( 'Price', array( $_where ) );
369 369
 	}
370 370
 
371 371
 
372 372
 
373
-    /**
374
-     * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
375
-     *
376
-     * @access public
377
-     * @return EE_Price[]
378
-     * @throws \EE_Error
379
-     */
373
+	/**
374
+	 * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
375
+	 *
376
+	 * @access public
377
+	 * @return EE_Price[]
378
+	 * @throws \EE_Error
379
+	 */
380 380
 	public function price_modifiers() {
381 381
 		$query_params = array( 0 => array( 'Price_Type.PBT_ID' => array( 'NOT IN', array( EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax ) ) ) );
382 382
 		return $this->prices( $query_params );
@@ -384,132 +384,132 @@  discard block
 block discarded – undo
384 384
 
385 385
 
386 386
 
387
-    /**
388
-     * Gets all the prices that combine to form the final price of this ticket
389
-     *
390
-     * @param array $query_params like EEM_Base::get_all
391
-     * @return EE_Price[]|EE_Base_Class[]
392
-     * @throws \EE_Error
393
-     */
387
+	/**
388
+	 * Gets all the prices that combine to form the final price of this ticket
389
+	 *
390
+	 * @param array $query_params like EEM_Base::get_all
391
+	 * @return EE_Price[]|EE_Base_Class[]
392
+	 * @throws \EE_Error
393
+	 */
394 394
 	public function prices( $query_params = array() ) {
395 395
 		return $this->get_many_related( 'Price', $query_params );
396 396
 	}
397 397
 
398 398
 
399 399
 
400
-    /**
401
-     * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
402
-     *
403
-     * @param array $query_params see EEM_Base::get_all()
404
-     * @return EE_Datetime_Ticket|EE_Base_Class[]
405
-     * @throws \EE_Error
406
-     */
400
+	/**
401
+	 * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
402
+	 *
403
+	 * @param array $query_params see EEM_Base::get_all()
404
+	 * @return EE_Datetime_Ticket|EE_Base_Class[]
405
+	 * @throws \EE_Error
406
+	 */
407 407
 	public function datetime_tickets( $query_params = array() ) {
408 408
 		return $this->get_many_related( 'Datetime_Ticket', $query_params );
409 409
 	}
410 410
 
411 411
 
412 412
 
413
-    /**
414
-     * Gets all the datetimes from the db ordered by DTT_order
415
-     *
416
-     * @param boolean $show_expired
417
-     * @param boolean $show_deleted
418
-     * @return EE_Datetime[]
419
-     * @throws \EE_Error
420
-     */
413
+	/**
414
+	 * Gets all the datetimes from the db ordered by DTT_order
415
+	 *
416
+	 * @param boolean $show_expired
417
+	 * @param boolean $show_deleted
418
+	 * @return EE_Datetime[]
419
+	 * @throws \EE_Error
420
+	 */
421 421
 	public function datetimes_ordered( $show_expired = TRUE, $show_deleted = FALSE ) {
422 422
 		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_ticket_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted );
423 423
 	}
424 424
 
425 425
 
426 426
 
427
-    /**
428
-     * Gets ID
429
-     *
430
-     * @return string
431
-     * @throws \EE_Error
432
-     */
427
+	/**
428
+	 * Gets ID
429
+	 *
430
+	 * @return string
431
+	 * @throws \EE_Error
432
+	 */
433 433
 	public function ID() {
434 434
 		return $this->get( 'TKT_ID' );
435 435
 	}
436 436
 
437 437
 
438 438
 
439
-    /**
440
-     * get the author of the ticket.
441
-     *
442
-     * @since 4.5.0
443
-     * @return int
444
-     * @throws \EE_Error
445
-     */
439
+	/**
440
+	 * get the author of the ticket.
441
+	 *
442
+	 * @since 4.5.0
443
+	 * @return int
444
+	 * @throws \EE_Error
445
+	 */
446 446
 	public function wp_user() {
447 447
 		return $this->get('TKT_wp_user');
448 448
 	}
449 449
 
450 450
 
451 451
 
452
-    /**
453
-     * Gets the template for the ticket
454
-     *
455
-     * @return EE_Ticket_Template|EE_Base_Class
456
-     * @throws \EE_Error
457
-     */
452
+	/**
453
+	 * Gets the template for the ticket
454
+	 *
455
+	 * @return EE_Ticket_Template|EE_Base_Class
456
+	 * @throws \EE_Error
457
+	 */
458 458
 	public function template() {
459 459
 		return $this->get_first_related( 'Ticket_Template' );
460 460
 	}
461 461
 
462 462
 
463 463
 
464
-    /**
465
-     * Simply returns an array of EE_Price objects that are taxes.
466
-     *
467
-     * @return EE_Price[]
468
-     * @throws \EE_Error
469
-     */
464
+	/**
465
+	 * Simply returns an array of EE_Price objects that are taxes.
466
+	 *
467
+	 * @return EE_Price[]
468
+	 * @throws \EE_Error
469
+	 */
470 470
 	public function get_ticket_taxes_for_admin() {
471 471
 		return EE_Taxes::get_taxes_for_admin();
472 472
 	}
473 473
 
474 474
 
475 475
 
476
-    /**
477
-     * @return float
478
-     * @throws \EE_Error
479
-     */
476
+	/**
477
+	 * @return float
478
+	 * @throws \EE_Error
479
+	 */
480 480
 	public function ticket_price() {
481 481
 		return $this->get( 'TKT_price' );
482 482
 	}
483 483
 
484 484
 
485 485
 
486
-    /**
487
-     * @return mixed
488
-     * @throws \EE_Error
489
-     */
486
+	/**
487
+	 * @return mixed
488
+	 * @throws \EE_Error
489
+	 */
490 490
 	public function pretty_price() {
491 491
 		return $this->get_pretty( 'TKT_price' );
492 492
 	}
493 493
 
494 494
 
495 495
 
496
-    /**
497
-     * @return bool
498
-     * @throws \EE_Error
499
-     */
496
+	/**
497
+	 * @return bool
498
+	 * @throws \EE_Error
499
+	 */
500 500
 	public function is_free() {
501 501
 		return $this->get_ticket_total_with_taxes() === (float) 0;
502 502
 	}
503 503
 
504 504
 
505 505
 
506
-    /**
507
-     * get_ticket_total_with_taxes
508
-     *
509
-     * @param bool $no_cache
510
-     * @return float
511
-     * @throws \EE_Error
512
-     */
506
+	/**
507
+	 * get_ticket_total_with_taxes
508
+	 *
509
+	 * @param bool $no_cache
510
+	 * @return float
511
+	 * @throws \EE_Error
512
+	 */
513 513
 	public function get_ticket_total_with_taxes( $no_cache = FALSE ) {
514 514
 		if ($this->_ticket_total_with_taxes === null || $no_cache ) {
515 515
 			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
@@ -526,201 +526,201 @@  discard block
 block discarded – undo
526 526
 
527 527
 
528 528
 
529
-    /**
530
-     * @return float
531
-     * @throws \EE_Error
532
-     */
529
+	/**
530
+	 * @return float
531
+	 * @throws \EE_Error
532
+	 */
533 533
 	public function get_ticket_subtotal() {
534 534
 		return EE_Taxes::get_subtotal_for_admin( $this );
535 535
 	}
536 536
 
537 537
 
538 538
 
539
-    /**
540
-     * Returns the total taxes applied to this ticket
541
-     *
542
-     * @return float
543
-     * @throws \EE_Error
544
-     */
539
+	/**
540
+	 * Returns the total taxes applied to this ticket
541
+	 *
542
+	 * @return float
543
+	 * @throws \EE_Error
544
+	 */
545 545
 	public function get_ticket_taxes_total_for_admin() {
546 546
 		return EE_Taxes::get_total_taxes_for_admin( $this );
547 547
 	}
548 548
 
549 549
 
550 550
 
551
-    /**
552
-     * Sets name
553
-     *
554
-     * @param string $name
555
-     * @throws \EE_Error
556
-     */
551
+	/**
552
+	 * Sets name
553
+	 *
554
+	 * @param string $name
555
+	 * @throws \EE_Error
556
+	 */
557 557
 	public function set_name( $name ) {
558 558
 		$this->set( 'TKT_name', $name );
559 559
 	}
560 560
 
561 561
 
562 562
 
563
-    /**
564
-     * Gets description
565
-     *
566
-     * @return string
567
-     * @throws \EE_Error
568
-     */
563
+	/**
564
+	 * Gets description
565
+	 *
566
+	 * @return string
567
+	 * @throws \EE_Error
568
+	 */
569 569
 	public function description() {
570 570
 		return $this->get( 'TKT_description' );
571 571
 	}
572 572
 
573 573
 
574 574
 
575
-    /**
576
-     * Sets description
577
-     *
578
-     * @param string $description
579
-     * @throws \EE_Error
580
-     */
575
+	/**
576
+	 * Sets description
577
+	 *
578
+	 * @param string $description
579
+	 * @throws \EE_Error
580
+	 */
581 581
 	public function set_description( $description ) {
582 582
 		$this->set( 'TKT_description', $description );
583 583
 	}
584 584
 
585 585
 
586 586
 
587
-    /**
588
-     * Gets start_date
589
-     *
590
-     * @param string $dt_frmt
591
-     * @param string $tm_frmt
592
-     * @return string
593
-     * @throws \EE_Error
594
-     */
587
+	/**
588
+	 * Gets start_date
589
+	 *
590
+	 * @param string $dt_frmt
591
+	 * @param string $tm_frmt
592
+	 * @return string
593
+	 * @throws \EE_Error
594
+	 */
595 595
 	public function start_date( $dt_frmt = '', $tm_frmt = '' ) {
596 596
 		return $this->_get_datetime( 'TKT_start_date', $dt_frmt, $tm_frmt );
597 597
 	}
598 598
 
599 599
 
600 600
 
601
-    /**
602
-     * Sets start_date
603
-     *
604
-     * @param string $start_date
605
-     * @return void
606
-     * @throws \EE_Error
607
-     */
601
+	/**
602
+	 * Sets start_date
603
+	 *
604
+	 * @param string $start_date
605
+	 * @return void
606
+	 * @throws \EE_Error
607
+	 */
608 608
 	public function set_start_date( $start_date ) {
609 609
 		$this->_set_date_time( 'B', $start_date, 'TKT_start_date' );
610 610
 	}
611 611
 
612 612
 
613 613
 
614
-    /**
615
-     * Gets end_date
616
-     *
617
-     * @param string $dt_frmt
618
-     * @param string $tm_frmt
619
-     * @return string
620
-     * @throws \EE_Error
621
-     */
614
+	/**
615
+	 * Gets end_date
616
+	 *
617
+	 * @param string $dt_frmt
618
+	 * @param string $tm_frmt
619
+	 * @return string
620
+	 * @throws \EE_Error
621
+	 */
622 622
 	public function end_date( $dt_frmt = '', $tm_frmt = '' ) {
623 623
 		return $this->_get_datetime( 'TKT_end_date', $dt_frmt, $tm_frmt );
624 624
 	}
625 625
 
626 626
 
627 627
 
628
-    /**
629
-     * Sets end_date
630
-     *
631
-     * @param string $end_date
632
-     * @return void
633
-     * @throws \EE_Error
634
-     */
628
+	/**
629
+	 * Sets end_date
630
+	 *
631
+	 * @param string $end_date
632
+	 * @return void
633
+	 * @throws \EE_Error
634
+	 */
635 635
 	public function set_end_date( $end_date ) {
636 636
 		$this->_set_date_time( 'B', $end_date, 'TKT_end_date' );
637 637
 	}
638 638
 
639 639
 
640 640
 
641
-    /**
642
-     * Sets sell until time
643
-     *
644
-     * @since 4.5.0
645
-     * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646
-     * @throws \EE_Error
647
-     */
641
+	/**
642
+	 * Sets sell until time
643
+	 *
644
+	 * @since 4.5.0
645
+	 * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646
+	 * @throws \EE_Error
647
+	 */
648 648
 	public function set_end_time( $time ) {
649 649
 		$this->_set_time_for( $time, 'TKT_end_date' );
650 650
 	}
651 651
 
652 652
 
653 653
 
654
-    /**
655
-     * Sets min
656
-     *
657
-     * @param int $min
658
-     * @return void
659
-     * @throws \EE_Error
660
-     */
654
+	/**
655
+	 * Sets min
656
+	 *
657
+	 * @param int $min
658
+	 * @return void
659
+	 * @throws \EE_Error
660
+	 */
661 661
 	public function set_min( $min ) {
662 662
 		$this->set( 'TKT_min', $min );
663 663
 	}
664 664
 
665 665
 
666 666
 
667
-    /**
668
-     * Gets max
669
-     *
670
-     * @return int
671
-     * @throws \EE_Error
672
-     */
667
+	/**
668
+	 * Gets max
669
+	 *
670
+	 * @return int
671
+	 * @throws \EE_Error
672
+	 */
673 673
 	public function max() {
674 674
 		return $this->get( 'TKT_max' );
675 675
 	}
676 676
 
677 677
 
678 678
 
679
-    /**
680
-     * Sets max
681
-     *
682
-     * @param int $max
683
-     * @return void
684
-     * @throws \EE_Error
685
-     */
679
+	/**
680
+	 * Sets max
681
+	 *
682
+	 * @param int $max
683
+	 * @return void
684
+	 * @throws \EE_Error
685
+	 */
686 686
 	public function set_max( $max ) {
687 687
 		$this->set( 'TKT_max', $max );
688 688
 	}
689 689
 
690 690
 
691 691
 
692
-    /**
693
-     * Sets price
694
-     *
695
-     * @param float $price
696
-     * @return void
697
-     * @throws \EE_Error
698
-     */
692
+	/**
693
+	 * Sets price
694
+	 *
695
+	 * @param float $price
696
+	 * @return void
697
+	 * @throws \EE_Error
698
+	 */
699 699
 	public function set_price( $price ) {
700 700
 		$this->set( 'TKT_price', $price );
701 701
 	}
702 702
 
703 703
 
704 704
 
705
-    /**
706
-     * Gets sold
707
-     *
708
-     * @return int
709
-     * @throws \EE_Error
710
-     */
705
+	/**
706
+	 * Gets sold
707
+	 *
708
+	 * @return int
709
+	 * @throws \EE_Error
710
+	 */
711 711
 	public function sold() {
712 712
 		return $this->get_raw( 'TKT_sold' );
713 713
 	}
714 714
 
715 715
 
716 716
 
717
-    /**
718
-     * Sets sold
719
-     *
720
-     * @param int $sold
721
-     * @return void
722
-     * @throws \EE_Error
723
-     */
717
+	/**
718
+	 * Sets sold
719
+	 *
720
+	 * @param int $sold
721
+	 * @return void
722
+	 * @throws \EE_Error
723
+	 */
724 724
 	public function set_sold( $sold ) {
725 725
 		// sold can not go below zero
726 726
 		$sold = max( 0, $sold );
@@ -729,13 +729,13 @@  discard block
 block discarded – undo
729 729
 
730 730
 
731 731
 
732
-    /**
733
-     * increments sold by amount passed by $qty
734
-     *
735
-     * @param int $qty
736
-     * @return void
737
-     * @throws \EE_Error
738
-     */
732
+	/**
733
+	 * increments sold by amount passed by $qty
734
+	 *
735
+	 * @param int $qty
736
+	 * @return void
737
+	 * @throws \EE_Error
738
+	 */
739 739
 	public function increase_sold( $qty = 1 ) {
740 740
 		$sold = $this->sold() + $qty;
741 741
 		// remove ticket reservation, but don't adjust datetime reservations,  because that will happen
@@ -744,22 +744,22 @@  discard block
 block discarded – undo
744 744
 		$this->_increase_sold_for_datetimes( $qty );
745 745
 		$this->set_sold( $sold );
746 746
 		do_action(
747
-		    'AHEE__EE_Ticket__increase_sold',
748
-            $this,
749
-            $qty,
750
-            $sold
751
-        );
747
+			'AHEE__EE_Ticket__increase_sold',
748
+			$this,
749
+			$qty,
750
+			$sold
751
+		);
752 752
 	}
753 753
 
754 754
 
755 755
 
756
-    /**
757
-     * Increases sold on related datetimes
758
-     *
759
-     * @param int $qty
760
-     * @return void
761
-     * @throws \EE_Error
762
-     */
756
+	/**
757
+	 * Increases sold on related datetimes
758
+	 *
759
+	 * @param int $qty
760
+	 * @return void
761
+	 * @throws \EE_Error
762
+	 */
763 763
 	protected function _increase_sold_for_datetimes( $qty = 1 ) {
764 764
 		$datetimes = $this->datetimes();
765 765
 		if ( is_array( $datetimes ) ) {
@@ -774,34 +774,34 @@  discard block
 block discarded – undo
774 774
 
775 775
 
776 776
 
777
-    /**
778
-     * decrements (subtracts) sold by amount passed by $qty
779
-     *
780
-     * @param int $qty
781
-     * @return void
782
-     * @throws \EE_Error
783
-     */
777
+	/**
778
+	 * decrements (subtracts) sold by amount passed by $qty
779
+	 *
780
+	 * @param int $qty
781
+	 * @return void
782
+	 * @throws \EE_Error
783
+	 */
784 784
 	public function decrease_sold( $qty = 1 ) {
785 785
 		$sold = $this->sold() - $qty;
786 786
 		$this->_decrease_sold_for_datetimes( $qty );
787 787
 		$this->set_sold( $sold );
788
-        do_action(
789
-            'AHEE__EE_Ticket__decrease_sold',
790
-            $this,
791
-            $qty,
792
-            $sold
793
-        );
794
-    }
795
-
796
-
797
-
798
-    /**
799
-     * Decreases sold on related datetimes
800
-     *
801
-     * @param int $qty
802
-     * @return void
803
-     * @throws \EE_Error
804
-     */
788
+		do_action(
789
+			'AHEE__EE_Ticket__decrease_sold',
790
+			$this,
791
+			$qty,
792
+			$sold
793
+		);
794
+	}
795
+
796
+
797
+
798
+	/**
799
+	 * Decreases sold on related datetimes
800
+	 *
801
+	 * @param int $qty
802
+	 * @return void
803
+	 * @throws \EE_Error
804
+	 */
805 805
 	protected function _decrease_sold_for_datetimes( $qty = 1 ) {
806 806
 		$datetimes = $this->datetimes();
807 807
 		if ( is_array( $datetimes ) ) {
@@ -816,25 +816,25 @@  discard block
 block discarded – undo
816 816
 
817 817
 
818 818
 
819
-    /**
820
-     * Gets qty of reserved tickets
821
-     *
822
-     * @return int
823
-     * @throws \EE_Error
824
-     */
819
+	/**
820
+	 * Gets qty of reserved tickets
821
+	 *
822
+	 * @return int
823
+	 * @throws \EE_Error
824
+	 */
825 825
 	public function reserved() {
826 826
 		return $this->get_raw( 'TKT_reserved' );
827 827
 	}
828 828
 
829 829
 
830 830
 
831
-    /**
832
-     * Sets reserved
833
-     *
834
-     * @param int $reserved
835
-     * @return void
836
-     * @throws \EE_Error
837
-     */
831
+	/**
832
+	 * Sets reserved
833
+	 *
834
+	 * @param int $reserved
835
+	 * @return void
836
+	 * @throws \EE_Error
837
+	 */
838 838
 	public function set_reserved( $reserved ) {
839 839
 		// reserved can not go below zero
840 840
 		$reserved = max( 0, (int) $reserved );
@@ -843,35 +843,35 @@  discard block
 block discarded – undo
843 843
 
844 844
 
845 845
 
846
-    /**
847
-     * increments reserved by amount passed by $qty
848
-     *
849
-     * @param int $qty
850
-     * @return void
851
-     * @throws \EE_Error
852
-     */
846
+	/**
847
+	 * increments reserved by amount passed by $qty
848
+	 *
849
+	 * @param int $qty
850
+	 * @return void
851
+	 * @throws \EE_Error
852
+	 */
853 853
 	public function increase_reserved( $qty = 1 ) {
854 854
 		$qty = absint( $qty );
855 855
 		$reserved = $this->reserved() + $qty;
856 856
 		$this->_increase_reserved_for_datetimes( $qty );
857 857
 		$this->set_reserved( $reserved );
858
-        do_action(
859
-            'AHEE__EE_Ticket__increase_reserved',
860
-            $this,
861
-            $qty,
862
-            $reserved
863
-        );
864
-    }
865
-
866
-
867
-
868
-    /**
869
-     * Increases sold on related datetimes
870
-     *
871
-     * @param int $qty
872
-     * @return void
873
-     * @throws \EE_Error
874
-     */
858
+		do_action(
859
+			'AHEE__EE_Ticket__increase_reserved',
860
+			$this,
861
+			$qty,
862
+			$reserved
863
+		);
864
+	}
865
+
866
+
867
+
868
+	/**
869
+	 * Increases sold on related datetimes
870
+	 *
871
+	 * @param int $qty
872
+	 * @return void
873
+	 * @throws \EE_Error
874
+	 */
875 875
 	protected function _increase_reserved_for_datetimes( $qty = 1 ) {
876 876
 		$datetimes = $this->datetimes();
877 877
 		if ( is_array( $datetimes ) ) {
@@ -886,37 +886,37 @@  discard block
 block discarded – undo
886 886
 
887 887
 
888 888
 
889
-    /**
890
-     * decrements (subtracts) reserved by amount passed by $qty
891
-     *
892
-     * @param int  $qty
893
-     * @param bool $adjust_datetimes
894
-     * @return void
895
-     * @throws \EE_Error
896
-     */
889
+	/**
890
+	 * decrements (subtracts) reserved by amount passed by $qty
891
+	 *
892
+	 * @param int  $qty
893
+	 * @param bool $adjust_datetimes
894
+	 * @return void
895
+	 * @throws \EE_Error
896
+	 */
897 897
 	public function decrease_reserved( $qty = 1, $adjust_datetimes = true ) {
898 898
 		$reserved = $this->reserved() - absint( $qty );
899 899
 		if ( $adjust_datetimes ) {
900 900
 			$this->_decrease_reserved_for_datetimes( $qty );
901 901
 		}
902 902
 		$this->set_reserved( $reserved );
903
-        do_action(
904
-            'AHEE__EE_Ticket__decrease_reserved',
905
-            $this,
906
-            $qty,
907
-            $reserved
908
-        );
909
-    }
910
-
911
-
912
-
913
-    /**
914
-     * Increases sold on related datetimes
915
-     *
916
-     * @param int $qty
917
-     * @return void
918
-     * @throws \EE_Error
919
-     */
903
+		do_action(
904
+			'AHEE__EE_Ticket__decrease_reserved',
905
+			$this,
906
+			$qty,
907
+			$reserved
908
+		);
909
+	}
910
+
911
+
912
+
913
+	/**
914
+	 * Increases sold on related datetimes
915
+	 *
916
+	 * @param int $qty
917
+	 * @return void
918
+	 * @throws \EE_Error
919
+	 */
920 920
 	protected function _decrease_reserved_for_datetimes( $qty = 1 ) {
921 921
 		$datetimes = $this->datetimes();
922 922
 		if ( is_array( $datetimes ) ) {
@@ -931,18 +931,18 @@  discard block
 block discarded – undo
931 931
 
932 932
 
933 933
 
934
-    /**
935
-     * Gets ticket quantity
936
-     *
937
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
938
-     *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
939
-     *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
940
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
941
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
942
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
943
-     * @return int
944
-     * @throws \EE_Error
945
-     */
934
+	/**
935
+	 * Gets ticket quantity
936
+	 *
937
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
938
+	 *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
939
+	 *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
940
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
941
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
942
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
943
+	 * @return int
944
+	 * @throws \EE_Error
945
+	 */
946 946
 	public function qty( $context = '' ) {
947 947
 		switch ( $context ) {
948 948
 			case 'reg_limit' :
@@ -956,19 +956,19 @@  discard block
 block discarded – undo
956 956
 
957 957
 
958 958
 
959
-    /**
960
-     * Gets ticket quantity
961
-     *
962
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
963
-     *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
964
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
965
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
966
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
967
-     * @param  int   $DTT_ID      the primary key for a particular datetime.
968
-     *                            set to 0 for all related datetimes
969
-     * @return int
970
-     * @throws \EE_Error
971
-     */
959
+	/**
960
+	 * Gets ticket quantity
961
+	 *
962
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
963
+	 *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
964
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
965
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
966
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
967
+	 * @param  int   $DTT_ID      the primary key for a particular datetime.
968
+	 *                            set to 0 for all related datetimes
969
+	 * @return int
970
+	 * @throws \EE_Error
971
+	 */
972 972
 	public function real_quantity_on_ticket( $context = 'reg_limit', $DTT_ID = 0 ) {
973 973
 		$raw = $this->get_raw( 'TKT_qty' );
974 974
 		// return immediately if it's zero
@@ -1051,212 +1051,212 @@  discard block
 block discarded – undo
1051 1051
 
1052 1052
 
1053 1053
 
1054
-    /**
1055
-     * Gets uses
1056
-     *
1057
-     * @return int
1058
-     * @throws \EE_Error
1059
-     */
1054
+	/**
1055
+	 * Gets uses
1056
+	 *
1057
+	 * @return int
1058
+	 * @throws \EE_Error
1059
+	 */
1060 1060
 	public function uses() {
1061 1061
 		return $this->get( 'TKT_uses' );
1062 1062
 	}
1063 1063
 
1064 1064
 
1065 1065
 
1066
-    /**
1067
-     * Sets uses
1068
-     *
1069
-     * @param int $uses
1070
-     * @return void
1071
-     * @throws \EE_Error
1072
-     */
1066
+	/**
1067
+	 * Sets uses
1068
+	 *
1069
+	 * @param int $uses
1070
+	 * @return void
1071
+	 * @throws \EE_Error
1072
+	 */
1073 1073
 	public function set_uses( $uses ) {
1074 1074
 		$this->set( 'TKT_uses', $uses );
1075 1075
 	}
1076 1076
 
1077 1077
 
1078 1078
 
1079
-    /**
1080
-     * returns whether ticket is required or not.
1081
-     *
1082
-     * @return boolean
1083
-     * @throws \EE_Error
1084
-     */
1079
+	/**
1080
+	 * returns whether ticket is required or not.
1081
+	 *
1082
+	 * @return boolean
1083
+	 * @throws \EE_Error
1084
+	 */
1085 1085
 	public function required() {
1086 1086
 		return $this->get( 'TKT_required' );
1087 1087
 	}
1088 1088
 
1089 1089
 
1090 1090
 
1091
-    /**
1092
-     * sets the TKT_required property
1093
-     *
1094
-     * @param boolean $required
1095
-     * @return void
1096
-     * @throws \EE_Error
1097
-     */
1091
+	/**
1092
+	 * sets the TKT_required property
1093
+	 *
1094
+	 * @param boolean $required
1095
+	 * @return void
1096
+	 * @throws \EE_Error
1097
+	 */
1098 1098
 	public function set_required( $required ) {
1099 1099
 		$this->set( 'TKT_required', $required );
1100 1100
 	}
1101 1101
 
1102 1102
 
1103 1103
 
1104
-    /**
1105
-     * Gets taxable
1106
-     *
1107
-     * @return boolean
1108
-     * @throws \EE_Error
1109
-     */
1104
+	/**
1105
+	 * Gets taxable
1106
+	 *
1107
+	 * @return boolean
1108
+	 * @throws \EE_Error
1109
+	 */
1110 1110
 	public function taxable() {
1111 1111
 		return $this->get( 'TKT_taxable' );
1112 1112
 	}
1113 1113
 
1114 1114
 
1115 1115
 
1116
-    /**
1117
-     * Sets taxable
1118
-     *
1119
-     * @param boolean $taxable
1120
-     * @return void
1121
-     * @throws \EE_Error
1122
-     */
1116
+	/**
1117
+	 * Sets taxable
1118
+	 *
1119
+	 * @param boolean $taxable
1120
+	 * @return void
1121
+	 * @throws \EE_Error
1122
+	 */
1123 1123
 	public function set_taxable( $taxable ) {
1124 1124
 		$this->set( 'TKT_taxable', $taxable );
1125 1125
 	}
1126 1126
 
1127 1127
 
1128 1128
 
1129
-    /**
1130
-     * Gets is_default
1131
-     *
1132
-     * @return boolean
1133
-     * @throws \EE_Error
1134
-     */
1129
+	/**
1130
+	 * Gets is_default
1131
+	 *
1132
+	 * @return boolean
1133
+	 * @throws \EE_Error
1134
+	 */
1135 1135
 	public function is_default() {
1136 1136
 		return $this->get( 'TKT_is_default' );
1137 1137
 	}
1138 1138
 
1139 1139
 
1140 1140
 
1141
-    /**
1142
-     * Sets is_default
1143
-     *
1144
-     * @param boolean $is_default
1145
-     * @return void
1146
-     * @throws \EE_Error
1147
-     */
1141
+	/**
1142
+	 * Sets is_default
1143
+	 *
1144
+	 * @param boolean $is_default
1145
+	 * @return void
1146
+	 * @throws \EE_Error
1147
+	 */
1148 1148
 	public function set_is_default( $is_default ) {
1149 1149
 		$this->set( 'TKT_is_default', $is_default );
1150 1150
 	}
1151 1151
 
1152 1152
 
1153 1153
 
1154
-    /**
1155
-     * Gets order
1156
-     *
1157
-     * @return int
1158
-     * @throws \EE_Error
1159
-     */
1154
+	/**
1155
+	 * Gets order
1156
+	 *
1157
+	 * @return int
1158
+	 * @throws \EE_Error
1159
+	 */
1160 1160
 	public function order() {
1161 1161
 		return $this->get( 'TKT_order' );
1162 1162
 	}
1163 1163
 
1164 1164
 
1165 1165
 
1166
-    /**
1167
-     * Sets order
1168
-     *
1169
-     * @param int $order
1170
-     * @return void
1171
-     * @throws \EE_Error
1172
-     */
1166
+	/**
1167
+	 * Sets order
1168
+	 *
1169
+	 * @param int $order
1170
+	 * @return void
1171
+	 * @throws \EE_Error
1172
+	 */
1173 1173
 	public function set_order( $order ) {
1174 1174
 		$this->set( 'TKT_order', $order );
1175 1175
 	}
1176 1176
 
1177 1177
 
1178 1178
 
1179
-    /**
1180
-     * Gets row
1181
-     *
1182
-     * @return int
1183
-     * @throws \EE_Error
1184
-     */
1179
+	/**
1180
+	 * Gets row
1181
+	 *
1182
+	 * @return int
1183
+	 * @throws \EE_Error
1184
+	 */
1185 1185
 	public function row() {
1186 1186
 		return $this->get( 'TKT_row' );
1187 1187
 	}
1188 1188
 
1189 1189
 
1190 1190
 
1191
-    /**
1192
-     * Sets row
1193
-     *
1194
-     * @param int $row
1195
-     * @return void
1196
-     * @throws \EE_Error
1197
-     */
1191
+	/**
1192
+	 * Sets row
1193
+	 *
1194
+	 * @param int $row
1195
+	 * @return void
1196
+	 * @throws \EE_Error
1197
+	 */
1198 1198
 	public function set_row( $row ) {
1199 1199
 		$this->set( 'TKT_row', $row );
1200 1200
 	}
1201 1201
 
1202 1202
 
1203 1203
 
1204
-    /**
1205
-     * Gets deleted
1206
-     *
1207
-     * @return boolean
1208
-     * @throws \EE_Error
1209
-     */
1204
+	/**
1205
+	 * Gets deleted
1206
+	 *
1207
+	 * @return boolean
1208
+	 * @throws \EE_Error
1209
+	 */
1210 1210
 	public function deleted() {
1211 1211
 		return $this->get( 'TKT_deleted' );
1212 1212
 	}
1213 1213
 
1214 1214
 
1215 1215
 
1216
-    /**
1217
-     * Sets deleted
1218
-     *
1219
-     * @param boolean $deleted
1220
-     * @return void
1221
-     * @throws \EE_Error
1222
-     */
1216
+	/**
1217
+	 * Sets deleted
1218
+	 *
1219
+	 * @param boolean $deleted
1220
+	 * @return void
1221
+	 * @throws \EE_Error
1222
+	 */
1223 1223
 	public function set_deleted( $deleted ) {
1224 1224
 		$this->set( 'TKT_deleted', $deleted );
1225 1225
 	}
1226 1226
 
1227 1227
 
1228 1228
 
1229
-    /**
1230
-     * Gets parent
1231
-     *
1232
-     * @return int
1233
-     * @throws \EE_Error
1234
-     */
1229
+	/**
1230
+	 * Gets parent
1231
+	 *
1232
+	 * @return int
1233
+	 * @throws \EE_Error
1234
+	 */
1235 1235
 	public function parent_ID() {
1236 1236
 		return $this->get( 'TKT_parent' );
1237 1237
 	}
1238 1238
 
1239 1239
 
1240 1240
 
1241
-    /**
1242
-     * Sets parent
1243
-     *
1244
-     * @param int $parent
1245
-     * @return void
1246
-     * @throws \EE_Error
1247
-     */
1241
+	/**
1242
+	 * Sets parent
1243
+	 *
1244
+	 * @param int $parent
1245
+	 * @return void
1246
+	 * @throws \EE_Error
1247
+	 */
1248 1248
 	public function set_parent_ID( $parent ) {
1249 1249
 		$this->set( 'TKT_parent', $parent );
1250 1250
 	}
1251 1251
 
1252 1252
 
1253 1253
 
1254
-    /**
1255
-     * Gets a string which is handy for showing in gateways etc that describes the ticket.
1256
-     *
1257
-     * @return string
1258
-     * @throws \EE_Error
1259
-     */
1254
+	/**
1255
+	 * Gets a string which is handy for showing in gateways etc that describes the ticket.
1256
+	 *
1257
+	 * @return string
1258
+	 * @throws \EE_Error
1259
+	 */
1260 1260
 	public function name_and_info() {
1261 1261
 		$times = array();
1262 1262
 		foreach ( $this->datetimes() as $datetime ) {
@@ -1267,67 +1267,67 @@  discard block
 block discarded – undo
1267 1267
 
1268 1268
 
1269 1269
 
1270
-    /**
1271
-     * Gets name
1272
-     *
1273
-     * @return string
1274
-     * @throws \EE_Error
1275
-     */
1270
+	/**
1271
+	 * Gets name
1272
+	 *
1273
+	 * @return string
1274
+	 * @throws \EE_Error
1275
+	 */
1276 1276
 	public function name() {
1277 1277
 		return $this->get( 'TKT_name' );
1278 1278
 	}
1279 1279
 
1280 1280
 
1281 1281
 
1282
-    /**
1283
-     * Gets price
1284
-     *
1285
-     * @return float
1286
-     * @throws \EE_Error
1287
-     */
1282
+	/**
1283
+	 * Gets price
1284
+	 *
1285
+	 * @return float
1286
+	 * @throws \EE_Error
1287
+	 */
1288 1288
 	public function price() {
1289 1289
 		return $this->get( 'TKT_price' );
1290 1290
 	}
1291 1291
 
1292 1292
 
1293 1293
 
1294
-    /**
1295
-     * Gets all the registrations for this ticket
1296
-     *
1297
-     * @param array $query_params like EEM_Base::get_all's
1298
-     * @return EE_Registration[]|EE_Base_Class[]
1299
-     * @throws \EE_Error
1300
-     */
1294
+	/**
1295
+	 * Gets all the registrations for this ticket
1296
+	 *
1297
+	 * @param array $query_params like EEM_Base::get_all's
1298
+	 * @return EE_Registration[]|EE_Base_Class[]
1299
+	 * @throws \EE_Error
1300
+	 */
1301 1301
 	public function registrations( $query_params = array() ) {
1302 1302
 		return $this->get_many_related( 'Registration', $query_params );
1303 1303
 	}
1304 1304
 
1305 1305
 
1306 1306
 
1307
-    /**
1308
-     * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1309
-     * into account
1310
-     *
1311
-     * @return int
1312
-     * @throws \EE_Error
1313
-     */
1307
+	/**
1308
+	 * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1309
+	 * into account
1310
+	 *
1311
+	 * @return int
1312
+	 * @throws \EE_Error
1313
+	 */
1314 1314
 	public function update_tickets_sold() {
1315
-        $count_regs_for_this_ticket = $this->count_registrations(
1316
-            array(
1317
-                array(
1318
-                    'STS_ID'      => EEM_Registration::status_id_approved,
1319
-                    'REG_deleted' => 0,
1320
-                ),
1321
-            )
1322
-        );
1323
-        $sold = $this->sold();
1324
-        if ($count_regs_for_this_ticket > $sold) {
1325
-            $this->increase_sold($count_regs_for_this_ticket - $sold);
1326
-            $this->save();
1327
-        } else if ($count_regs_for_this_ticket < $sold) {
1328
-            $this->decrease_sold($count_regs_for_this_ticket - $sold);
1329
-            $this->save();
1330
-        }
1315
+		$count_regs_for_this_ticket = $this->count_registrations(
1316
+			array(
1317
+				array(
1318
+					'STS_ID'      => EEM_Registration::status_id_approved,
1319
+					'REG_deleted' => 0,
1320
+				),
1321
+			)
1322
+		);
1323
+		$sold = $this->sold();
1324
+		if ($count_regs_for_this_ticket > $sold) {
1325
+			$this->increase_sold($count_regs_for_this_ticket - $sold);
1326
+			$this->save();
1327
+		} else if ($count_regs_for_this_ticket < $sold) {
1328
+			$this->decrease_sold($count_regs_for_this_ticket - $sold);
1329
+			$this->save();
1330
+		}
1331 1331
 		return $count_regs_for_this_ticket;
1332 1332
 	}
1333 1333
 
@@ -1355,21 +1355,21 @@  discard block
 block discarded – undo
1355 1355
 
1356 1356
 
1357 1357
 
1358
-    /**
1359
-     * Implementation of the EEI_Event_Relation interface method
1360
-     *
1361
-     * @see EEI_Event_Relation for comments
1362
-     * @return EE_Event
1363
-     * @throws \EE_Error
1364
-     * @throws UnexpectedEntityException
1365
-     */
1358
+	/**
1359
+	 * Implementation of the EEI_Event_Relation interface method
1360
+	 *
1361
+	 * @see EEI_Event_Relation for comments
1362
+	 * @return EE_Event
1363
+	 * @throws \EE_Error
1364
+	 * @throws UnexpectedEntityException
1365
+	 */
1366 1366
 	public function get_related_event() {
1367 1367
 		//get one datetime to use for getting the event
1368 1368
 		$datetime = $this->first_datetime();
1369 1369
 		if ( ! $datetime instanceof \EE_Datetime ) {
1370 1370
 			throw new UnexpectedEntityException(
1371 1371
 				$datetime,
1372
-                'EE_Datetime',
1372
+				'EE_Datetime',
1373 1373
 				sprintf(
1374 1374
 					__( 'The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1375 1375
 					$this->name()
@@ -1380,7 +1380,7 @@  discard block
 block discarded – undo
1380 1380
 		if ( ! $event instanceof \EE_Event ) {
1381 1381
 			throw new UnexpectedEntityException(
1382 1382
 				$event,
1383
-                'EE_Event',
1383
+				'EE_Event',
1384 1384
 				sprintf(
1385 1385
 					__( 'The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1386 1386
 					$this->name()
@@ -1392,14 +1392,14 @@  discard block
 block discarded – undo
1392 1392
 
1393 1393
 
1394 1394
 
1395
-    /**
1396
-     * Implementation of the EEI_Event_Relation interface method
1397
-     *
1398
-     * @see EEI_Event_Relation for comments
1399
-     * @return string
1400
-     * @throws UnexpectedEntityException
1401
-     * @throws \EE_Error
1402
-     */
1395
+	/**
1396
+	 * Implementation of the EEI_Event_Relation interface method
1397
+	 *
1398
+	 * @see EEI_Event_Relation for comments
1399
+	 * @return string
1400
+	 * @throws UnexpectedEntityException
1401
+	 * @throws \EE_Error
1402
+	 */
1403 1403
 	public function get_event_name() {
1404 1404
 		$event = $this->get_related_event();
1405 1405
 		return $event instanceof EE_Event ? $event->name() : '';
@@ -1407,28 +1407,28 @@  discard block
 block discarded – undo
1407 1407
 
1408 1408
 
1409 1409
 
1410
-    /**
1411
-     * Implementation of the EEI_Event_Relation interface method
1412
-     *
1413
-     * @see EEI_Event_Relation for comments
1414
-     * @return int
1415
-     * @throws UnexpectedEntityException
1416
-     * @throws \EE_Error
1417
-     */
1410
+	/**
1411
+	 * Implementation of the EEI_Event_Relation interface method
1412
+	 *
1413
+	 * @see EEI_Event_Relation for comments
1414
+	 * @return int
1415
+	 * @throws UnexpectedEntityException
1416
+	 * @throws \EE_Error
1417
+	 */
1418 1418
 	public function get_event_ID() {
1419 1419
 		$event = $this->get_related_event();
1420 1420
 		return $event instanceof EE_Event ? $event->ID() : 0;
1421 1421
 	}
1422 1422
 
1423 1423
 
1424
-    /**
1425
-     * This simply returns whether a ticket can be permanently deleted or not.
1426
-     * The criteria for determining this is whether the ticket has any related registrations.
1427
-     * If there are none then it can be permanently deleted.
1428
-     *
1429
-     * @return bool
1430
-     */
1424
+	/**
1425
+	 * This simply returns whether a ticket can be permanently deleted or not.
1426
+	 * The criteria for determining this is whether the ticket has any related registrations.
1427
+	 * If there are none then it can be permanently deleted.
1428
+	 *
1429
+	 * @return bool
1430
+	 */
1431 1431
 	public function is_permanently_deleteable() {
1432
-	    return $this->count_registrations() === 0;
1433
-    }
1432
+		return $this->count_registrations() === 0;
1433
+	}
1434 1434
 } //end EE_Ticket class
Please login to merge, or discard this patch.
Spacing   +203 added lines, -203 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php use EventEspresso\core\exceptions\UnexpectedEntityException;
2 2
 
3
-if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
4
-	exit( 'No direct script access allowed' );
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4
+	exit('No direct script access allowed');
5 5
 }
6 6
 /**
7 7
  * Event Espresso
@@ -70,9 +70,9 @@  discard block
 block discarded – undo
70 70
      * @return EE_Ticket
71 71
      * @throws \EE_Error
72 72
      */
73
-	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
74
-		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
75
-		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
73
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) {
74
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76 76
 	}
77 77
 
78 78
 
@@ -84,8 +84,8 @@  discard block
 block discarded – undo
84 84
      * @return EE_Ticket
85 85
      * @throws \EE_Error
86 86
      */
87
-	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
88
-		return new self( $props_n_values, TRUE, $timezone );
87
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null) {
88
+		return new self($props_n_values, TRUE, $timezone);
89 89
 	}
90 90
 
91 91
 
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
      * @throws \EE_Error
96 96
      */
97 97
 	public function parent() {
98
-		return $this->get( 'TKT_parent' );
98
+		return $this->get('TKT_parent');
99 99
 	}
100 100
 
101 101
 
@@ -107,13 +107,13 @@  discard block
 block discarded – undo
107 107
      * @return boolean
108 108
      * @throws \EE_Error
109 109
      */
110
-	public function available( $DTT_ID = 0 ) {
110
+	public function available($DTT_ID = 0) {
111 111
 		// are we checking availability for a particular datetime ?
112
-		if ( $DTT_ID ) {
112
+		if ($DTT_ID) {
113 113
 			// get that datetime object
114
-			$datetime = $this->get_first_related( 'Datetime', array( array( 'DTT_ID' => $DTT_ID ) ) );
114
+			$datetime = $this->get_first_related('Datetime', array(array('DTT_ID' => $DTT_ID)));
115 115
 			// if  ticket sales for this datetime have exceeded the reg limit...
116
-			if ( $datetime instanceof EE_Datetime && $datetime->sold_out() ) {
116
+			if ($datetime instanceof EE_Datetime && $datetime->sold_out()) {
117 117
 				return FALSE;
118 118
 			}
119 119
 		}
@@ -131,22 +131,22 @@  discard block
 block discarded – undo
131 131
      * @return mixed status int if the display string isn't requested
132 132
      * @throws \EE_Error
133 133
      */
134
-	public function ticket_status( $display = FALSE, $remaining = null ) {
135
-		$remaining = is_bool( $remaining ) ? $remaining : $this->is_remaining();
136
-		if ( ! $remaining ) {
137
-			return $display ? EEH_Template::pretty_status( EE_Ticket::sold_out, FALSE, 'sentence' ) : EE_Ticket::sold_out;
134
+	public function ticket_status($display = FALSE, $remaining = null) {
135
+		$remaining = is_bool($remaining) ? $remaining : $this->is_remaining();
136
+		if ( ! $remaining) {
137
+			return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, FALSE, 'sentence') : EE_Ticket::sold_out;
138 138
 		}
139
-		if ( $this->get( 'TKT_deleted' ) ) {
140
-			return $display ? EEH_Template::pretty_status( EE_Ticket::archived, FALSE, 'sentence' ) : EE_Ticket::archived;
139
+		if ($this->get('TKT_deleted')) {
140
+			return $display ? EEH_Template::pretty_status(EE_Ticket::archived, FALSE, 'sentence') : EE_Ticket::archived;
141 141
 		}
142
-		if ( $this->is_expired() ) {
143
-			return $display ? EEH_Template::pretty_status( EE_Ticket::expired, FALSE, 'sentence' ) : EE_Ticket::expired;
142
+		if ($this->is_expired()) {
143
+			return $display ? EEH_Template::pretty_status(EE_Ticket::expired, FALSE, 'sentence') : EE_Ticket::expired;
144 144
 		}
145
-		if ( $this->is_pending() ) {
146
-			return $display ? EEH_Template::pretty_status( EE_Ticket::pending, FALSE, 'sentence' ) : EE_Ticket::pending;
145
+		if ($this->is_pending()) {
146
+			return $display ? EEH_Template::pretty_status(EE_Ticket::pending, FALSE, 'sentence') : EE_Ticket::pending;
147 147
 		}
148
-		if ( $this->is_on_sale() ) {
149
-			return $display ? EEH_Template::pretty_status( EE_Ticket::onsale, FALSE, 'sentence' ) : EE_Ticket::onsale;
148
+		if ($this->is_on_sale()) {
149
+			return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, FALSE, 'sentence') : EE_Ticket::onsale;
150 150
 		}
151 151
 		return '';
152 152
 	}
@@ -161,12 +161,12 @@  discard block
 block discarded – undo
161 161
      * @return boolean         true = tickets remaining, false not.
162 162
      * @throws \EE_Error
163 163
      */
164
-	public function is_remaining( $DTT_ID = 0 ) {
165
-		$num_remaining = $this->remaining( $DTT_ID );
166
-		if ( $num_remaining === 0 ) {
164
+	public function is_remaining($DTT_ID = 0) {
165
+		$num_remaining = $this->remaining($DTT_ID);
166
+		if ($num_remaining === 0) {
167 167
 			return FALSE;
168 168
 		}
169
-		if ( $num_remaining > 0 && $num_remaining < $this->min() ) {
169
+		if ($num_remaining > 0 && $num_remaining < $this->min()) {
170 170
 			return FALSE;
171 171
 		}
172 172
 		return TRUE;
@@ -182,8 +182,8 @@  discard block
 block discarded – undo
182 182
      * @return int
183 183
      * @throws \EE_Error
184 184
      */
185
-	public function remaining( $DTT_ID = 0 ) {
186
-		return $this->real_quantity_on_ticket('saleable', $DTT_ID );
185
+	public function remaining($DTT_ID = 0) {
186
+		return $this->real_quantity_on_ticket('saleable', $DTT_ID);
187 187
 	}
188 188
 
189 189
 
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
      * @throws \EE_Error
196 196
      */
197 197
 	public function min() {
198
-		return $this->get( 'TKT_min' );
198
+		return $this->get('TKT_min');
199 199
 	}
200 200
 
201 201
 
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
      * @throws \EE_Error
208 208
      */
209 209
 	public function is_expired() {
210
-		return ( $this->get_raw( 'TKT_end_date' ) < time() );
210
+		return ($this->get_raw('TKT_end_date') < time());
211 211
 	}
212 212
 
213 213
 
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
      * @throws \EE_Error
220 220
      */
221 221
 	public function is_pending() {
222
-		return ( $this->get_raw( 'TKT_start_date' ) > time() );
222
+		return ($this->get_raw('TKT_start_date') > time());
223 223
 	}
224 224
 
225 225
 
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
      * @throws \EE_Error
232 232
      */
233 233
 	public function is_on_sale() {
234
-		return ( $this->get_raw( 'TKT_start_date' ) < time() && $this->get_raw( 'TKT_end_date' ) > time() );
234
+		return ($this->get_raw('TKT_start_date') < time() && $this->get_raw('TKT_end_date') > time());
235 235
 	}
236 236
 
237 237
 
@@ -244,11 +244,11 @@  discard block
 block discarded – undo
244 244
      * @return string
245 245
      * @throws \EE_Error
246 246
      */
247
-	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
248
-		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date( $dt_frmt ) : '';
249
-		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date( $dt_frmt ) : '';
247
+	public function date_range($dt_frmt = '', $conjunction = ' - ') {
248
+		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date($dt_frmt) : '';
249
+		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date($dt_frmt) : '';
250 250
 
251
-		return $first_date && $last_date ? $first_date . $conjunction  . $last_date : '';
251
+		return $first_date && $last_date ? $first_date.$conjunction.$last_date : '';
252 252
 	}
253 253
 
254 254
 
@@ -260,8 +260,8 @@  discard block
 block discarded – undo
260 260
      * @throws \EE_Error
261 261
      */
262 262
 	public function first_datetime() {
263
-		$datetimes = $this->datetimes( array( 'limit' => 1 ) );
264
-		return reset( $datetimes );
263
+		$datetimes = $this->datetimes(array('limit' => 1));
264
+		return reset($datetimes);
265 265
 	}
266 266
 
267 267
 
@@ -274,11 +274,11 @@  discard block
 block discarded – undo
274 274
      * @return EE_Datetime[]|EE_Base_Class[]
275 275
      * @throws \EE_Error
276 276
      */
277
-	public function datetimes( $query_params = array() ) {
278
-		if ( ! isset( $query_params[ 'order_by' ] ) ) {
279
-			$query_params[ 'order_by' ][ 'DTT_order' ] = 'ASC';
277
+	public function datetimes($query_params = array()) {
278
+		if ( ! isset($query_params['order_by'])) {
279
+			$query_params['order_by']['DTT_order'] = 'ASC';
280 280
 		}
281
-		return $this->get_many_related( 'Datetime', $query_params );
281
+		return $this->get_many_related('Datetime', $query_params);
282 282
 	}
283 283
 
284 284
 
@@ -290,8 +290,8 @@  discard block
 block discarded – undo
290 290
      * @throws \EE_Error
291 291
      */
292 292
 	public function last_datetime() {
293
-		$datetimes = $this->datetimes( array( 'limit' => 1, 'order_by' => array( 'DTT_EVT_start' => 'DESC' ) ) );
294
-		return end( $datetimes );
293
+		$datetimes = $this->datetimes(array('limit' => 1, 'order_by' => array('DTT_EVT_start' => 'DESC')));
294
+		return end($datetimes);
295 295
 	}
296 296
 
297 297
 
@@ -309,22 +309,22 @@  discard block
 block discarded – undo
309 309
      * @return mixed (array|int)          how many tickets have sold
310 310
      * @throws \EE_Error
311 311
      */
312
-	public function tickets_sold( $what = 'ticket', $dtt_id = NULL ) {
312
+	public function tickets_sold($what = 'ticket', $dtt_id = NULL) {
313 313
 		$total = 0;
314 314
 		$tickets_sold = $this->_all_tickets_sold();
315
-		switch ( $what ) {
315
+		switch ($what) {
316 316
 			case 'ticket' :
317
-				return $tickets_sold[ 'ticket' ];
317
+				return $tickets_sold['ticket'];
318 318
 				break;
319 319
 			case 'datetime' :
320
-				if ( empty( $tickets_sold[ 'datetime' ] ) ) {
320
+				if (empty($tickets_sold['datetime'])) {
321 321
 					return $total;
322 322
 				}
323
-				if ( ! empty( $dtt_id ) && ! isset( $tickets_sold[ 'datetime' ][ $dtt_id ] ) ) {
324
-					EE_Error::add_error( __( 'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
323
+				if ( ! empty($dtt_id) && ! isset($tickets_sold['datetime'][$dtt_id])) {
324
+					EE_Error::add_error(__('You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
325 325
 					return $total;
326 326
 				}
327
-				return empty( $dtt_id ) ? $tickets_sold[ 'datetime' ] : $tickets_sold[ 'datetime' ][ $dtt_id ];
327
+				return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][$dtt_id];
328 328
 				break;
329 329
 			default:
330 330
 				return $total;
@@ -340,15 +340,15 @@  discard block
 block discarded – undo
340 340
      * @throws \EE_Error
341 341
      */
342 342
 	protected function _all_tickets_sold() {
343
-		$datetimes = $this->get_many_related( 'Datetime' );
343
+		$datetimes = $this->get_many_related('Datetime');
344 344
 		$tickets_sold = array();
345
-		if ( ! empty( $datetimes ) ) {
346
-			foreach ( $datetimes as $datetime ) {
347
-				$tickets_sold[ 'datetime' ][ $datetime->ID() ] = $datetime->get( 'DTT_sold' );
345
+		if ( ! empty($datetimes)) {
346
+			foreach ($datetimes as $datetime) {
347
+				$tickets_sold['datetime'][$datetime->ID()] = $datetime->get('DTT_sold');
348 348
 			}
349 349
 		}
350 350
 		//Tickets sold
351
-		$tickets_sold[ 'ticket' ] = $this->sold();
351
+		$tickets_sold['ticket'] = $this->sold();
352 352
 		return $tickets_sold;
353 353
 	}
354 354
 
@@ -361,11 +361,11 @@  discard block
 block discarded – undo
361 361
      * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362 362
      * @throws \EE_Error
363 363
      */
364
-	public function base_price( $return_array = FALSE ) {
365
-		$_where = array( 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price );
364
+	public function base_price($return_array = FALSE) {
365
+		$_where = array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price);
366 366
 		return $return_array
367
-            ? $this->get_many_related( 'Price', array( $_where ) )
368
-            : $this->get_first_related( 'Price', array( $_where ) );
367
+            ? $this->get_many_related('Price', array($_where))
368
+            : $this->get_first_related('Price', array($_where));
369 369
 	}
370 370
 
371 371
 
@@ -378,8 +378,8 @@  discard block
 block discarded – undo
378 378
      * @throws \EE_Error
379 379
      */
380 380
 	public function price_modifiers() {
381
-		$query_params = array( 0 => array( 'Price_Type.PBT_ID' => array( 'NOT IN', array( EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax ) ) ) );
382
-		return $this->prices( $query_params );
381
+		$query_params = array(0 => array('Price_Type.PBT_ID' => array('NOT IN', array(EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax))));
382
+		return $this->prices($query_params);
383 383
 	}
384 384
 
385 385
 
@@ -391,8 +391,8 @@  discard block
 block discarded – undo
391 391
      * @return EE_Price[]|EE_Base_Class[]
392 392
      * @throws \EE_Error
393 393
      */
394
-	public function prices( $query_params = array() ) {
395
-		return $this->get_many_related( 'Price', $query_params );
394
+	public function prices($query_params = array()) {
395
+		return $this->get_many_related('Price', $query_params);
396 396
 	}
397 397
 
398 398
 
@@ -404,8 +404,8 @@  discard block
 block discarded – undo
404 404
      * @return EE_Datetime_Ticket|EE_Base_Class[]
405 405
      * @throws \EE_Error
406 406
      */
407
-	public function datetime_tickets( $query_params = array() ) {
408
-		return $this->get_many_related( 'Datetime_Ticket', $query_params );
407
+	public function datetime_tickets($query_params = array()) {
408
+		return $this->get_many_related('Datetime_Ticket', $query_params);
409 409
 	}
410 410
 
411 411
 
@@ -418,8 +418,8 @@  discard block
 block discarded – undo
418 418
      * @return EE_Datetime[]
419 419
      * @throws \EE_Error
420 420
      */
421
-	public function datetimes_ordered( $show_expired = TRUE, $show_deleted = FALSE ) {
422
-		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_ticket_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted );
421
+	public function datetimes_ordered($show_expired = TRUE, $show_deleted = FALSE) {
422
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order($this->ID(), $show_expired, $show_deleted);
423 423
 	}
424 424
 
425 425
 
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
      * @throws \EE_Error
432 432
      */
433 433
 	public function ID() {
434
-		return $this->get( 'TKT_ID' );
434
+		return $this->get('TKT_ID');
435 435
 	}
436 436
 
437 437
 
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      * @throws \EE_Error
457 457
      */
458 458
 	public function template() {
459
-		return $this->get_first_related( 'Ticket_Template' );
459
+		return $this->get_first_related('Ticket_Template');
460 460
 	}
461 461
 
462 462
 
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
      * @throws \EE_Error
479 479
      */
480 480
 	public function ticket_price() {
481
-		return $this->get( 'TKT_price' );
481
+		return $this->get('TKT_price');
482 482
 	}
483 483
 
484 484
 
@@ -488,7 +488,7 @@  discard block
 block discarded – undo
488 488
      * @throws \EE_Error
489 489
      */
490 490
 	public function pretty_price() {
491
-		return $this->get_pretty( 'TKT_price' );
491
+		return $this->get_pretty('TKT_price');
492 492
 	}
493 493
 
494 494
 
@@ -510,8 +510,8 @@  discard block
 block discarded – undo
510 510
      * @return float
511 511
      * @throws \EE_Error
512 512
      */
513
-	public function get_ticket_total_with_taxes( $no_cache = FALSE ) {
514
-		if ($this->_ticket_total_with_taxes === null || $no_cache ) {
513
+	public function get_ticket_total_with_taxes($no_cache = FALSE) {
514
+		if ($this->_ticket_total_with_taxes === null || $no_cache) {
515 515
 			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
516 516
 		}
517 517
 		return (float) $this->_ticket_total_with_taxes;
@@ -520,7 +520,7 @@  discard block
 block discarded – undo
520 520
 
521 521
 
522 522
 	public function ensure_TKT_Price_correct() {
523
-		$this->set( 'TKT_price', EE_Taxes::get_subtotal_for_admin( $this ) );
523
+		$this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this));
524 524
 		$this->save();
525 525
 	}
526 526
 
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
      * @throws \EE_Error
532 532
      */
533 533
 	public function get_ticket_subtotal() {
534
-		return EE_Taxes::get_subtotal_for_admin( $this );
534
+		return EE_Taxes::get_subtotal_for_admin($this);
535 535
 	}
536 536
 
537 537
 
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
      * @throws \EE_Error
544 544
      */
545 545
 	public function get_ticket_taxes_total_for_admin() {
546
-		return EE_Taxes::get_total_taxes_for_admin( $this );
546
+		return EE_Taxes::get_total_taxes_for_admin($this);
547 547
 	}
548 548
 
549 549
 
@@ -554,8 +554,8 @@  discard block
 block discarded – undo
554 554
      * @param string $name
555 555
      * @throws \EE_Error
556 556
      */
557
-	public function set_name( $name ) {
558
-		$this->set( 'TKT_name', $name );
557
+	public function set_name($name) {
558
+		$this->set('TKT_name', $name);
559 559
 	}
560 560
 
561 561
 
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
      * @throws \EE_Error
568 568
      */
569 569
 	public function description() {
570
-		return $this->get( 'TKT_description' );
570
+		return $this->get('TKT_description');
571 571
 	}
572 572
 
573 573
 
@@ -578,8 +578,8 @@  discard block
 block discarded – undo
578 578
      * @param string $description
579 579
      * @throws \EE_Error
580 580
      */
581
-	public function set_description( $description ) {
582
-		$this->set( 'TKT_description', $description );
581
+	public function set_description($description) {
582
+		$this->set('TKT_description', $description);
583 583
 	}
584 584
 
585 585
 
@@ -592,8 +592,8 @@  discard block
 block discarded – undo
592 592
      * @return string
593 593
      * @throws \EE_Error
594 594
      */
595
-	public function start_date( $dt_frmt = '', $tm_frmt = '' ) {
596
-		return $this->_get_datetime( 'TKT_start_date', $dt_frmt, $tm_frmt );
595
+	public function start_date($dt_frmt = '', $tm_frmt = '') {
596
+		return $this->_get_datetime('TKT_start_date', $dt_frmt, $tm_frmt);
597 597
 	}
598 598
 
599 599
 
@@ -605,8 +605,8 @@  discard block
 block discarded – undo
605 605
      * @return void
606 606
      * @throws \EE_Error
607 607
      */
608
-	public function set_start_date( $start_date ) {
609
-		$this->_set_date_time( 'B', $start_date, 'TKT_start_date' );
608
+	public function set_start_date($start_date) {
609
+		$this->_set_date_time('B', $start_date, 'TKT_start_date');
610 610
 	}
611 611
 
612 612
 
@@ -619,8 +619,8 @@  discard block
 block discarded – undo
619 619
      * @return string
620 620
      * @throws \EE_Error
621 621
      */
622
-	public function end_date( $dt_frmt = '', $tm_frmt = '' ) {
623
-		return $this->_get_datetime( 'TKT_end_date', $dt_frmt, $tm_frmt );
622
+	public function end_date($dt_frmt = '', $tm_frmt = '') {
623
+		return $this->_get_datetime('TKT_end_date', $dt_frmt, $tm_frmt);
624 624
 	}
625 625
 
626 626
 
@@ -632,8 +632,8 @@  discard block
 block discarded – undo
632 632
      * @return void
633 633
      * @throws \EE_Error
634 634
      */
635
-	public function set_end_date( $end_date ) {
636
-		$this->_set_date_time( 'B', $end_date, 'TKT_end_date' );
635
+	public function set_end_date($end_date) {
636
+		$this->_set_date_time('B', $end_date, 'TKT_end_date');
637 637
 	}
638 638
 
639 639
 
@@ -645,8 +645,8 @@  discard block
 block discarded – undo
645 645
      * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646 646
      * @throws \EE_Error
647 647
      */
648
-	public function set_end_time( $time ) {
649
-		$this->_set_time_for( $time, 'TKT_end_date' );
648
+	public function set_end_time($time) {
649
+		$this->_set_time_for($time, 'TKT_end_date');
650 650
 	}
651 651
 
652 652
 
@@ -658,8 +658,8 @@  discard block
 block discarded – undo
658 658
      * @return void
659 659
      * @throws \EE_Error
660 660
      */
661
-	public function set_min( $min ) {
662
-		$this->set( 'TKT_min', $min );
661
+	public function set_min($min) {
662
+		$this->set('TKT_min', $min);
663 663
 	}
664 664
 
665 665
 
@@ -671,7 +671,7 @@  discard block
 block discarded – undo
671 671
      * @throws \EE_Error
672 672
      */
673 673
 	public function max() {
674
-		return $this->get( 'TKT_max' );
674
+		return $this->get('TKT_max');
675 675
 	}
676 676
 
677 677
 
@@ -683,8 +683,8 @@  discard block
 block discarded – undo
683 683
      * @return void
684 684
      * @throws \EE_Error
685 685
      */
686
-	public function set_max( $max ) {
687
-		$this->set( 'TKT_max', $max );
686
+	public function set_max($max) {
687
+		$this->set('TKT_max', $max);
688 688
 	}
689 689
 
690 690
 
@@ -696,8 +696,8 @@  discard block
 block discarded – undo
696 696
      * @return void
697 697
      * @throws \EE_Error
698 698
      */
699
-	public function set_price( $price ) {
700
-		$this->set( 'TKT_price', $price );
699
+	public function set_price($price) {
700
+		$this->set('TKT_price', $price);
701 701
 	}
702 702
 
703 703
 
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
      * @throws \EE_Error
710 710
      */
711 711
 	public function sold() {
712
-		return $this->get_raw( 'TKT_sold' );
712
+		return $this->get_raw('TKT_sold');
713 713
 	}
714 714
 
715 715
 
@@ -721,10 +721,10 @@  discard block
 block discarded – undo
721 721
      * @return void
722 722
      * @throws \EE_Error
723 723
      */
724
-	public function set_sold( $sold ) {
724
+	public function set_sold($sold) {
725 725
 		// sold can not go below zero
726
-		$sold = max( 0, $sold );
727
-		$this->set( 'TKT_sold', $sold );
726
+		$sold = max(0, $sold);
727
+		$this->set('TKT_sold', $sold);
728 728
 	}
729 729
 
730 730
 
@@ -736,13 +736,13 @@  discard block
 block discarded – undo
736 736
      * @return void
737 737
      * @throws \EE_Error
738 738
      */
739
-	public function increase_sold( $qty = 1 ) {
739
+	public function increase_sold($qty = 1) {
740 740
 		$sold = $this->sold() + $qty;
741 741
 		// remove ticket reservation, but don't adjust datetime reservations,  because that will happen
742 742
 		// via \EE_Datetime::increase_sold() when \EE_Ticket::_increase_sold_for_datetimes() is called
743
-		$this->decrease_reserved( $qty, false );
744
-		$this->_increase_sold_for_datetimes( $qty );
745
-		$this->set_sold( $sold );
743
+		$this->decrease_reserved($qty, false);
744
+		$this->_increase_sold_for_datetimes($qty);
745
+		$this->set_sold($sold);
746 746
 		do_action(
747 747
 		    'AHEE__EE_Ticket__increase_sold',
748 748
             $this,
@@ -760,12 +760,12 @@  discard block
 block discarded – undo
760 760
      * @return void
761 761
      * @throws \EE_Error
762 762
      */
763
-	protected function _increase_sold_for_datetimes( $qty = 1 ) {
763
+	protected function _increase_sold_for_datetimes($qty = 1) {
764 764
 		$datetimes = $this->datetimes();
765
-		if ( is_array( $datetimes ) ) {
766
-			foreach ( $datetimes as $datetime ) {
767
-				if ( $datetime instanceof EE_Datetime ) {
768
-					$datetime->increase_sold( $qty );
765
+		if (is_array($datetimes)) {
766
+			foreach ($datetimes as $datetime) {
767
+				if ($datetime instanceof EE_Datetime) {
768
+					$datetime->increase_sold($qty);
769 769
 					$datetime->save();
770 770
 				}
771 771
 			}
@@ -781,10 +781,10 @@  discard block
 block discarded – undo
781 781
      * @return void
782 782
      * @throws \EE_Error
783 783
      */
784
-	public function decrease_sold( $qty = 1 ) {
784
+	public function decrease_sold($qty = 1) {
785 785
 		$sold = $this->sold() - $qty;
786
-		$this->_decrease_sold_for_datetimes( $qty );
787
-		$this->set_sold( $sold );
786
+		$this->_decrease_sold_for_datetimes($qty);
787
+		$this->set_sold($sold);
788 788
         do_action(
789 789
             'AHEE__EE_Ticket__decrease_sold',
790 790
             $this,
@@ -802,12 +802,12 @@  discard block
 block discarded – undo
802 802
      * @return void
803 803
      * @throws \EE_Error
804 804
      */
805
-	protected function _decrease_sold_for_datetimes( $qty = 1 ) {
805
+	protected function _decrease_sold_for_datetimes($qty = 1) {
806 806
 		$datetimes = $this->datetimes();
807
-		if ( is_array( $datetimes ) ) {
808
-			foreach ( $datetimes as $datetime ) {
809
-				if ( $datetime instanceof EE_Datetime ) {
810
-					$datetime->decrease_sold( $qty );
807
+		if (is_array($datetimes)) {
808
+			foreach ($datetimes as $datetime) {
809
+				if ($datetime instanceof EE_Datetime) {
810
+					$datetime->decrease_sold($qty);
811 811
 					$datetime->save();
812 812
 				}
813 813
 			}
@@ -823,7 +823,7 @@  discard block
 block discarded – undo
823 823
      * @throws \EE_Error
824 824
      */
825 825
 	public function reserved() {
826
-		return $this->get_raw( 'TKT_reserved' );
826
+		return $this->get_raw('TKT_reserved');
827 827
 	}
828 828
 
829 829
 
@@ -835,10 +835,10 @@  discard block
 block discarded – undo
835 835
      * @return void
836 836
      * @throws \EE_Error
837 837
      */
838
-	public function set_reserved( $reserved ) {
838
+	public function set_reserved($reserved) {
839 839
 		// reserved can not go below zero
840
-		$reserved = max( 0, (int) $reserved );
841
-		$this->set( 'TKT_reserved', $reserved );
840
+		$reserved = max(0, (int) $reserved);
841
+		$this->set('TKT_reserved', $reserved);
842 842
 	}
843 843
 
844 844
 
@@ -850,11 +850,11 @@  discard block
 block discarded – undo
850 850
      * @return void
851 851
      * @throws \EE_Error
852 852
      */
853
-	public function increase_reserved( $qty = 1 ) {
854
-		$qty = absint( $qty );
853
+	public function increase_reserved($qty = 1) {
854
+		$qty = absint($qty);
855 855
 		$reserved = $this->reserved() + $qty;
856
-		$this->_increase_reserved_for_datetimes( $qty );
857
-		$this->set_reserved( $reserved );
856
+		$this->_increase_reserved_for_datetimes($qty);
857
+		$this->set_reserved($reserved);
858 858
         do_action(
859 859
             'AHEE__EE_Ticket__increase_reserved',
860 860
             $this,
@@ -872,12 +872,12 @@  discard block
 block discarded – undo
872 872
      * @return void
873 873
      * @throws \EE_Error
874 874
      */
875
-	protected function _increase_reserved_for_datetimes( $qty = 1 ) {
875
+	protected function _increase_reserved_for_datetimes($qty = 1) {
876 876
 		$datetimes = $this->datetimes();
877
-		if ( is_array( $datetimes ) ) {
878
-			foreach ( $datetimes as $datetime ) {
879
-				if ( $datetime instanceof EE_Datetime ) {
880
-					$datetime->increase_reserved( $qty );
877
+		if (is_array($datetimes)) {
878
+			foreach ($datetimes as $datetime) {
879
+				if ($datetime instanceof EE_Datetime) {
880
+					$datetime->increase_reserved($qty);
881 881
 					$datetime->save();
882 882
 				}
883 883
 			}
@@ -894,12 +894,12 @@  discard block
 block discarded – undo
894 894
      * @return void
895 895
      * @throws \EE_Error
896 896
      */
897
-	public function decrease_reserved( $qty = 1, $adjust_datetimes = true ) {
898
-		$reserved = $this->reserved() - absint( $qty );
899
-		if ( $adjust_datetimes ) {
900
-			$this->_decrease_reserved_for_datetimes( $qty );
897
+	public function decrease_reserved($qty = 1, $adjust_datetimes = true) {
898
+		$reserved = $this->reserved() - absint($qty);
899
+		if ($adjust_datetimes) {
900
+			$this->_decrease_reserved_for_datetimes($qty);
901 901
 		}
902
-		$this->set_reserved( $reserved );
902
+		$this->set_reserved($reserved);
903 903
         do_action(
904 904
             'AHEE__EE_Ticket__decrease_reserved',
905 905
             $this,
@@ -917,12 +917,12 @@  discard block
 block discarded – undo
917 917
      * @return void
918 918
      * @throws \EE_Error
919 919
      */
920
-	protected function _decrease_reserved_for_datetimes( $qty = 1 ) {
920
+	protected function _decrease_reserved_for_datetimes($qty = 1) {
921 921
 		$datetimes = $this->datetimes();
922
-		if ( is_array( $datetimes ) ) {
923
-			foreach ( $datetimes as $datetime ) {
924
-				if ( $datetime instanceof EE_Datetime ) {
925
-					$datetime->decrease_reserved( $qty );
922
+		if (is_array($datetimes)) {
923
+			foreach ($datetimes as $datetime) {
924
+				if ($datetime instanceof EE_Datetime) {
925
+					$datetime->decrease_reserved($qty);
926 926
 					$datetime->save();
927 927
 				}
928 928
 			}
@@ -943,14 +943,14 @@  discard block
 block discarded – undo
943 943
      * @return int
944 944
      * @throws \EE_Error
945 945
      */
946
-	public function qty( $context = '' ) {
947
-		switch ( $context ) {
946
+	public function qty($context = '') {
947
+		switch ($context) {
948 948
 			case 'reg_limit' :
949 949
 				return $this->real_quantity_on_ticket();
950 950
 			case 'saleable' :
951
-				return $this->real_quantity_on_ticket( 'saleable' );
951
+				return $this->real_quantity_on_ticket('saleable');
952 952
 			default:
953
-				return $this->get_raw( 'TKT_qty' );
953
+				return $this->get_raw('TKT_qty');
954 954
 		}
955 955
 	}
956 956
 
@@ -969,15 +969,15 @@  discard block
 block discarded – undo
969 969
      * @return int
970 970
      * @throws \EE_Error
971 971
      */
972
-	public function real_quantity_on_ticket( $context = 'reg_limit', $DTT_ID = 0 ) {
973
-		$raw = $this->get_raw( 'TKT_qty' );
972
+	public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0) {
973
+		$raw = $this->get_raw('TKT_qty');
974 974
 		// return immediately if it's zero
975
-		if ( $raw === 0 ) {
975
+		if ($raw === 0) {
976 976
 			return $raw;
977 977
 		}
978 978
 		//echo "\n\n<br />Ticket: " . $this->name() . '<br />';
979 979
 		// ensure qty doesn't exceed raw value for THIS ticket
980
-		$qty = min( EE_INF, $raw );
980
+		$qty = min(EE_INF, $raw);
981 981
 		//echo "\n . qty: " . $qty . '<br />';
982 982
 		// calculate this ticket's total sales and reservations
983 983
 		$sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved();
@@ -986,23 +986,23 @@  discard block
 block discarded – undo
986 986
 		//echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />';
987 987
 		// first we need to calculate the maximum number of tickets available for the datetime
988 988
 		// do we want data for one datetime or all of them ?
989
-		$query_params = $DTT_ID ? array( array( 'DTT_ID' => $DTT_ID ) ) : array();
990
-		$datetimes = $this->datetimes( $query_params );
991
-		if ( is_array( $datetimes ) && ! empty( $datetimes ) ) {
992
-			foreach ( $datetimes as $datetime ) {
993
-				if ( $datetime instanceof EE_Datetime ) {
989
+		$query_params = $DTT_ID ? array(array('DTT_ID' => $DTT_ID)) : array();
990
+		$datetimes = $this->datetimes($query_params);
991
+		if (is_array($datetimes) && ! empty($datetimes)) {
992
+			foreach ($datetimes as $datetime) {
993
+				if ($datetime instanceof EE_Datetime) {
994 994
 					$datetime->refresh_from_db();
995 995
 					//echo "\n . . datetime name: " . $datetime->name() . '<br />';
996 996
 					//echo "\n . . datetime ID: " . $datetime->ID() . '<br />';
997 997
 					// initialize with no restrictions for each datetime
998 998
 					// but adjust datetime qty based on datetime reg limit
999
-					$datetime_qty = min( EE_INF, $datetime->reg_limit() );
999
+					$datetime_qty = min(EE_INF, $datetime->reg_limit());
1000 1000
 					//echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />';
1001 1001
 					//echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1002 1002
 					// if we want the actual saleable amount, then we need to consider OTHER ticket sales
1003 1003
 					// and reservations for this datetime, that do NOT include sales and reservations
1004 1004
 					// for this ticket (so we add $this->sold() and $this->reserved() back in)
1005
-					if ( $context === 'saleable' ) {
1005
+					if ($context === 'saleable') {
1006 1006
 						$datetime_qty = max(
1007 1007
 							$datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket,
1008 1008
 							0
@@ -1014,16 +1014,16 @@  discard block
 block discarded – undo
1014 1014
 						$datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0;
1015 1015
 						//echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1016 1016
 					}
1017
-					$qty = min( $datetime_qty, $qty );
1017
+					$qty = min($datetime_qty, $qty);
1018 1018
 					//echo "\n . . qty: " . $qty . '<br />';
1019 1019
 				}
1020 1020
 			}
1021 1021
 		}
1022 1022
 		// NOW that we know the  maximum number of tickets available for the datetime
1023 1023
 		// we can finally factor in the details for this specific ticket
1024
-		if ( $qty > 0 && $context === 'saleable' ) {
1024
+		if ($qty > 0 && $context === 'saleable') {
1025 1025
 			// and subtract the sales for THIS ticket
1026
-			$qty = max( $qty - $sold_and_reserved_for_this_ticket, 0 );
1026
+			$qty = max($qty - $sold_and_reserved_for_this_ticket, 0);
1027 1027
 			//echo "\n . qty: " . $qty . '<br />';
1028 1028
 		}
1029 1029
 		//echo "\nFINAL QTY: " . $qty . "<br /><br />";
@@ -1039,14 +1039,14 @@  discard block
 block discarded – undo
1039 1039
 	 * @return void
1040 1040
 	 * @throws \EE_Error
1041 1041
 	 */
1042
-	public function set_qty( $qty ) {
1042
+	public function set_qty($qty) {
1043 1043
 		$datetimes = $this->datetimes();
1044
-		foreach ( $datetimes as $datetime ) {
1045
-			if ( $datetime instanceof EE_Datetime ) {
1046
-				$qty = min( $qty, $datetime->reg_limit() );
1044
+		foreach ($datetimes as $datetime) {
1045
+			if ($datetime instanceof EE_Datetime) {
1046
+				$qty = min($qty, $datetime->reg_limit());
1047 1047
 			}
1048 1048
 		}
1049
-		$this->set( 'TKT_qty', $qty );
1049
+		$this->set('TKT_qty', $qty);
1050 1050
 	}
1051 1051
 
1052 1052
 
@@ -1058,7 +1058,7 @@  discard block
 block discarded – undo
1058 1058
      * @throws \EE_Error
1059 1059
      */
1060 1060
 	public function uses() {
1061
-		return $this->get( 'TKT_uses' );
1061
+		return $this->get('TKT_uses');
1062 1062
 	}
1063 1063
 
1064 1064
 
@@ -1070,8 +1070,8 @@  discard block
 block discarded – undo
1070 1070
      * @return void
1071 1071
      * @throws \EE_Error
1072 1072
      */
1073
-	public function set_uses( $uses ) {
1074
-		$this->set( 'TKT_uses', $uses );
1073
+	public function set_uses($uses) {
1074
+		$this->set('TKT_uses', $uses);
1075 1075
 	}
1076 1076
 
1077 1077
 
@@ -1083,7 +1083,7 @@  discard block
 block discarded – undo
1083 1083
      * @throws \EE_Error
1084 1084
      */
1085 1085
 	public function required() {
1086
-		return $this->get( 'TKT_required' );
1086
+		return $this->get('TKT_required');
1087 1087
 	}
1088 1088
 
1089 1089
 
@@ -1095,8 +1095,8 @@  discard block
 block discarded – undo
1095 1095
      * @return void
1096 1096
      * @throws \EE_Error
1097 1097
      */
1098
-	public function set_required( $required ) {
1099
-		$this->set( 'TKT_required', $required );
1098
+	public function set_required($required) {
1099
+		$this->set('TKT_required', $required);
1100 1100
 	}
1101 1101
 
1102 1102
 
@@ -1108,7 +1108,7 @@  discard block
 block discarded – undo
1108 1108
      * @throws \EE_Error
1109 1109
      */
1110 1110
 	public function taxable() {
1111
-		return $this->get( 'TKT_taxable' );
1111
+		return $this->get('TKT_taxable');
1112 1112
 	}
1113 1113
 
1114 1114
 
@@ -1120,8 +1120,8 @@  discard block
 block discarded – undo
1120 1120
      * @return void
1121 1121
      * @throws \EE_Error
1122 1122
      */
1123
-	public function set_taxable( $taxable ) {
1124
-		$this->set( 'TKT_taxable', $taxable );
1123
+	public function set_taxable($taxable) {
1124
+		$this->set('TKT_taxable', $taxable);
1125 1125
 	}
1126 1126
 
1127 1127
 
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
      * @throws \EE_Error
1134 1134
      */
1135 1135
 	public function is_default() {
1136
-		return $this->get( 'TKT_is_default' );
1136
+		return $this->get('TKT_is_default');
1137 1137
 	}
1138 1138
 
1139 1139
 
@@ -1145,8 +1145,8 @@  discard block
 block discarded – undo
1145 1145
      * @return void
1146 1146
      * @throws \EE_Error
1147 1147
      */
1148
-	public function set_is_default( $is_default ) {
1149
-		$this->set( 'TKT_is_default', $is_default );
1148
+	public function set_is_default($is_default) {
1149
+		$this->set('TKT_is_default', $is_default);
1150 1150
 	}
1151 1151
 
1152 1152
 
@@ -1158,7 +1158,7 @@  discard block
 block discarded – undo
1158 1158
      * @throws \EE_Error
1159 1159
      */
1160 1160
 	public function order() {
1161
-		return $this->get( 'TKT_order' );
1161
+		return $this->get('TKT_order');
1162 1162
 	}
1163 1163
 
1164 1164
 
@@ -1170,8 +1170,8 @@  discard block
 block discarded – undo
1170 1170
      * @return void
1171 1171
      * @throws \EE_Error
1172 1172
      */
1173
-	public function set_order( $order ) {
1174
-		$this->set( 'TKT_order', $order );
1173
+	public function set_order($order) {
1174
+		$this->set('TKT_order', $order);
1175 1175
 	}
1176 1176
 
1177 1177
 
@@ -1183,7 +1183,7 @@  discard block
 block discarded – undo
1183 1183
      * @throws \EE_Error
1184 1184
      */
1185 1185
 	public function row() {
1186
-		return $this->get( 'TKT_row' );
1186
+		return $this->get('TKT_row');
1187 1187
 	}
1188 1188
 
1189 1189
 
@@ -1195,8 +1195,8 @@  discard block
 block discarded – undo
1195 1195
      * @return void
1196 1196
      * @throws \EE_Error
1197 1197
      */
1198
-	public function set_row( $row ) {
1199
-		$this->set( 'TKT_row', $row );
1198
+	public function set_row($row) {
1199
+		$this->set('TKT_row', $row);
1200 1200
 	}
1201 1201
 
1202 1202
 
@@ -1208,7 +1208,7 @@  discard block
 block discarded – undo
1208 1208
      * @throws \EE_Error
1209 1209
      */
1210 1210
 	public function deleted() {
1211
-		return $this->get( 'TKT_deleted' );
1211
+		return $this->get('TKT_deleted');
1212 1212
 	}
1213 1213
 
1214 1214
 
@@ -1220,8 +1220,8 @@  discard block
 block discarded – undo
1220 1220
      * @return void
1221 1221
      * @throws \EE_Error
1222 1222
      */
1223
-	public function set_deleted( $deleted ) {
1224
-		$this->set( 'TKT_deleted', $deleted );
1223
+	public function set_deleted($deleted) {
1224
+		$this->set('TKT_deleted', $deleted);
1225 1225
 	}
1226 1226
 
1227 1227
 
@@ -1233,7 +1233,7 @@  discard block
 block discarded – undo
1233 1233
      * @throws \EE_Error
1234 1234
      */
1235 1235
 	public function parent_ID() {
1236
-		return $this->get( 'TKT_parent' );
1236
+		return $this->get('TKT_parent');
1237 1237
 	}
1238 1238
 
1239 1239
 
@@ -1245,8 +1245,8 @@  discard block
 block discarded – undo
1245 1245
      * @return void
1246 1246
      * @throws \EE_Error
1247 1247
      */
1248
-	public function set_parent_ID( $parent ) {
1249
-		$this->set( 'TKT_parent', $parent );
1248
+	public function set_parent_ID($parent) {
1249
+		$this->set('TKT_parent', $parent);
1250 1250
 	}
1251 1251
 
1252 1252
 
@@ -1259,10 +1259,10 @@  discard block
 block discarded – undo
1259 1259
      */
1260 1260
 	public function name_and_info() {
1261 1261
 		$times = array();
1262
-		foreach ( $this->datetimes() as $datetime ) {
1262
+		foreach ($this->datetimes() as $datetime) {
1263 1263
 			$times[] = $datetime->start_date_and_time();
1264 1264
 		}
1265
-		return $this->name() . ' @ ' . implode( ', ', $times ) . ' for ' . $this->pretty_price();
1265
+		return $this->name().' @ '.implode(', ', $times).' for '.$this->pretty_price();
1266 1266
 	}
1267 1267
 
1268 1268
 
@@ -1274,7 +1274,7 @@  discard block
 block discarded – undo
1274 1274
      * @throws \EE_Error
1275 1275
      */
1276 1276
 	public function name() {
1277
-		return $this->get( 'TKT_name' );
1277
+		return $this->get('TKT_name');
1278 1278
 	}
1279 1279
 
1280 1280
 
@@ -1286,7 +1286,7 @@  discard block
 block discarded – undo
1286 1286
      * @throws \EE_Error
1287 1287
      */
1288 1288
 	public function price() {
1289
-		return $this->get( 'TKT_price' );
1289
+		return $this->get('TKT_price');
1290 1290
 	}
1291 1291
 
1292 1292
 
@@ -1298,8 +1298,8 @@  discard block
 block discarded – undo
1298 1298
      * @return EE_Registration[]|EE_Base_Class[]
1299 1299
      * @throws \EE_Error
1300 1300
      */
1301
-	public function registrations( $query_params = array() ) {
1302
-		return $this->get_many_related( 'Registration', $query_params );
1301
+	public function registrations($query_params = array()) {
1302
+		return $this->get_many_related('Registration', $query_params);
1303 1303
 	}
1304 1304
 
1305 1305
 
@@ -1338,7 +1338,7 @@  discard block
 block discarded – undo
1338 1338
 	 * @param array $query_params like EEM_Base::get_all's
1339 1339
 	 * @return int
1340 1340
 	 */
1341
-	public function count_registrations( $query_params = array() ) {
1341
+	public function count_registrations($query_params = array()) {
1342 1342
 		return $this->count_related('Registration', $query_params);
1343 1343
 	}
1344 1344
 
@@ -1366,23 +1366,23 @@  discard block
 block discarded – undo
1366 1366
 	public function get_related_event() {
1367 1367
 		//get one datetime to use for getting the event
1368 1368
 		$datetime = $this->first_datetime();
1369
-		if ( ! $datetime instanceof \EE_Datetime ) {
1369
+		if ( ! $datetime instanceof \EE_Datetime) {
1370 1370
 			throw new UnexpectedEntityException(
1371 1371
 				$datetime,
1372 1372
                 'EE_Datetime',
1373 1373
 				sprintf(
1374
-					__( 'The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1374
+					__('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1375 1375
 					$this->name()
1376 1376
 				)
1377 1377
 			);
1378 1378
 		}
1379 1379
 		$event = $datetime->event();
1380
-		if ( ! $event instanceof \EE_Event ) {
1380
+		if ( ! $event instanceof \EE_Event) {
1381 1381
 			throw new UnexpectedEntityException(
1382 1382
 				$event,
1383 1383
                 'EE_Event',
1384 1384
 				sprintf(
1385
-					__( 'The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1385
+					__('The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1386 1386
 					$this->name()
1387 1387
 				)
1388 1388
 			);
Please login to merge, or discard this patch.
core/db_classes/EE_Datetime.class.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -435,7 +435,7 @@  discard block
 block discarded – undo
435 435
 	 * @param string $dt_frmt     - string representation of date format defaults to WP settings
436 436
 	 * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with
437 437
 	 *                            the end date ie: Jan 01 "to" Dec 31
438
-	 * @return mixed        string on success, FALSE on fail
438
+	 * @return string        string on success, FALSE on fail
439 439
 	 * @throws \EE_Error
440 440
 	 */
441 441
 	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
 	 * @param string $tm_format   string representation of time format defaults to 'g:i a'
508 508
 	 * @param string $conjunction conjunction junction what's your function ?
509 509
 	 *                            this string joins the start date with the end date ie: Jan 01 "to" Dec 31
510
-	 * @return mixed              string on success, FALSE on fail
510
+	 * @return string              string on success, FALSE on fail
511 511
 	 * @throws \EE_Error
512 512
 	 */
513 513
 	public function time_range( $tm_format = '', $conjunction = ' - ' ) {
Please login to merge, or discard this patch.
Indentation   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -210,13 +210,13 @@  discard block
 block discarded – undo
210 210
 		// remove ticket reservation
211 211
 		$this->decrease_reserved( $qty );
212 212
 		$this->set_sold( $sold );
213
-        do_action(
214
-            'AHEE__EE_Datetime__increase_sold',
215
-            $this,
216
-            $qty,
217
-            $sold
218
-        );
219
-    }
213
+		do_action(
214
+			'AHEE__EE_Datetime__increase_sold',
215
+			$this,
216
+			$qty,
217
+			$sold
218
+		);
219
+	}
220 220
 
221 221
 
222 222
 
@@ -227,13 +227,13 @@  discard block
 block discarded – undo
227 227
 	public function decrease_sold( $qty = 1 ) {
228 228
 		$sold = $this->sold() - $qty;
229 229
 		$this->set_sold( $sold );
230
-        do_action(
231
-            'AHEE__EE_Datetime__decrease_sold',
232
-            $this,
233
-            $qty,
234
-            $sold
235
-        );
236
-    }
230
+		do_action(
231
+			'AHEE__EE_Datetime__decrease_sold',
232
+			$this,
233
+			$qty,
234
+			$sold
235
+		);
236
+	}
237 237
 
238 238
 
239 239
 
@@ -269,13 +269,13 @@  discard block
 block discarded – undo
269 269
 	 */
270 270
 	public function increase_reserved( $qty = 1 ) {
271 271
 		$reserved = $this->reserved() + absint( $qty );
272
-        do_action(
273
-            'AHEE__EE_Datetime__increase_reserved',
274
-            $this,
275
-            $qty,
276
-            $reserved
277
-        );
278
-        $this->set_reserved( $reserved );
272
+		do_action(
273
+			'AHEE__EE_Datetime__increase_reserved',
274
+			$this,
275
+			$qty,
276
+			$reserved
277
+		);
278
+		$this->set_reserved( $reserved );
279 279
 	}
280 280
 
281 281
 
@@ -288,13 +288,13 @@  discard block
 block discarded – undo
288 288
 	 */
289 289
 	public function decrease_reserved( $qty = 1 ) {
290 290
 		$reserved = $this->reserved() - absint( $qty );
291
-        do_action(
292
-            'AHEE__EE_Datetime__decrease_reserved',
293
-            $this,
294
-            $qty,
295
-            $reserved
296
-        );
297
-        $this->set_reserved( $reserved );
291
+		do_action(
292
+			'AHEE__EE_Datetime__decrease_reserved',
293
+			$this,
294
+			$qty,
295
+			$reserved
296
+		);
297
+		$this->set_reserved( $reserved );
298 298
 	}
299 299
 
300 300
 
@@ -382,13 +382,13 @@  discard block
 block discarded – undo
382 382
 
383 383
 
384 384
 
385
-    /**
386
-     * get event start date.  Provide either the date format, or NULL to re-use the
387
-     * last-used format, or '' to use the default date format
388
-     *
389
-     * @param string $dt_frmt - string representation of date format defaults to 'F j, Y'
390
-     * @return        mixed        string on success, FALSE on fail
391
-     */
385
+	/**
386
+	 * get event start date.  Provide either the date format, or NULL to re-use the
387
+	 * last-used format, or '' to use the default date format
388
+	 *
389
+	 * @param string $dt_frmt - string representation of date format defaults to 'F j, Y'
390
+	 * @return        mixed        string on success, FALSE on fail
391
+	 */
392 392
 	public function start_date( $dt_frmt = '' ) {
393 393
 		return $this->_show_datetime( 'D', 'start', $dt_frmt );
394 394
 	}
@@ -405,13 +405,13 @@  discard block
 block discarded – undo
405 405
 
406 406
 
407 407
 
408
-    /**
409
-     * get end date. Provide either the date format, or NULL to re-use the
410
-     * last-used format, or '' to use the default date format
411
-     *
412
-     * @param string $dt_frmt - string representation of date format defaults to 'F j, Y'
413
-     * @return        mixed        string on success, FALSE on fail
414
-     */
408
+	/**
409
+	 * get end date. Provide either the date format, or NULL to re-use the
410
+	 * last-used format, or '' to use the default date format
411
+	 *
412
+	 * @param string $dt_frmt - string representation of date format defaults to 'F j, Y'
413
+	 * @return        mixed        string on success, FALSE on fail
414
+	 */
415 415
 	public function end_date( $dt_frmt = '' ) {
416 416
 		return $this->_show_datetime( 'D', 'end', $dt_frmt );
417 417
 	}
@@ -533,23 +533,23 @@  discard block
 block discarded – undo
533 533
 	/**
534 534
 	 * This returns a range representation of the date and times.
535 535
 	 * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end.
536
-     * Also, the return value is localized.
537
-     *
538
-     * @param string $dt_format
536
+	 * Also, the return value is localized.
537
+	 *
538
+	 * @param string $dt_format
539 539
 	 * @param string $tm_format
540 540
 	 * @param string $conjunction used between two different dates or times.
541
-     *                            ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm
542
-     * @param string $separator   used between the date and time formats.
543
-     *                            ex: Dec 1, 2016{$separator}2pm
541
+	 *                            ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm
542
+	 * @param string $separator   used between the date and time formats.
543
+	 *                            ex: Dec 1, 2016{$separator}2pm
544 544
 	 * @return string
545 545
 	 * @throws \EE_Error
546 546
 	 */
547 547
 	public function date_and_time_range(
548
-	    $dt_format = '',
549
-        $tm_format = '',
550
-        $conjunction = ' - ' ,
551
-        $separator = ' '
552
-    ) {
548
+		$dt_format = '',
549
+		$tm_format = '',
550
+		$conjunction = ' - ' ,
551
+		$separator = ' '
552
+	) {
553 553
 		$dt_format = ! empty( $dt_format ) ? $dt_format : $this->_dt_frmt;
554 554
 		$tm_format = ! empty( $tm_format ) ? $tm_format : $this->_tm_frmt;
555 555
 		$full_format = $dt_format . $separator . $tm_format;
@@ -563,14 +563,14 @@  discard block
 block discarded – undo
563 563
 			//start and end date are the same but times are different
564 564
 			case ( $this->start_date() === $this->end_date() ) :
565 565
 				$output = $this->get_i18n_datetime( 'DTT_EVT_start', $full_format )
566
-				          . $conjunction
567
-				          . $this->get_i18n_datetime( 'DTT_EVT_end', $tm_format );
566
+						  . $conjunction
567
+						  . $this->get_i18n_datetime( 'DTT_EVT_end', $tm_format );
568 568
 				break;
569 569
 			//all other conditions
570 570
 			default :
571 571
 				$output = $this->get_i18n_datetime( 'DTT_EVT_start', $full_format )
572
-				          . $conjunction
573
-				          . $this->get_i18n_datetime( 'DTT_EVT_end', $full_format );
572
+						  . $conjunction
573
+						  . $this->get_i18n_datetime( 'DTT_EVT_end', $full_format );
574 574
 				break;
575 575
 		}
576 576
 		return $output;
@@ -654,13 +654,13 @@  discard block
 block discarded – undo
654 654
 
655 655
 
656 656
 	/**
657
-     *        get end date and time
658
-     *
659
-     * @param string $dt_frmt   - string representation of date format defaults to 'F j, Y'
660
-     * @param string $tm_format - string representation of time format defaults to 'g:i a'
661
-     * @return    mixed                string on success, FALSE on fail
662
-     */
663
-    public function end_date_and_time($dt_frmt = '', $tm_format = '') {
657
+	 *        get end date and time
658
+	 *
659
+	 * @param string $dt_frmt   - string representation of date format defaults to 'F j, Y'
660
+	 * @param string $tm_format - string representation of time format defaults to 'g:i a'
661
+	 * @return    mixed                string on success, FALSE on fail
662
+	 */
663
+	public function end_date_and_time($dt_frmt = '', $tm_format = '') {
664 664
 		return $this->_show_datetime( '', 'end', $dt_frmt, $tm_format );
665 665
 	}
666 666
 
@@ -929,13 +929,13 @@  discard block
 block discarded – undo
929 929
 
930 930
 
931 931
 
932
-    /**
933
-     * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime (via the tickets).
934
-     * into account
935
-     *
936
-     * @return int
937
-     * @throws \EE_Error
938
-     */
932
+	/**
933
+	 * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime (via the tickets).
934
+	 * into account
935
+	 *
936
+	 * @return int
937
+	 * @throws \EE_Error
938
+	 */
939 939
 	public function update_sold() {
940 940
 		$count_regs_for_this_datetime = EEM_Registration::instance()->count(
941 941
 			array( array(
@@ -944,14 +944,14 @@  discard block
 block discarded – undo
944 944
 				'Ticket.Datetime.DTT_ID' 	=> $this->ID(),
945 945
 			) )
946 946
 		);
947
-        $sold = $this->sold();
948
-        if ($count_regs_for_this_datetime > $sold) {
949
-            $this->increase_sold($count_regs_for_this_datetime - $sold);
950
-            $this->save();
951
-        } else if ($count_regs_for_this_datetime < $sold) {
952
-            $this->decrease_sold($count_regs_for_this_datetime - $sold);
953
-            $this->save();
954
-        }
947
+		$sold = $this->sold();
948
+		if ($count_regs_for_this_datetime > $sold) {
949
+			$this->increase_sold($count_regs_for_this_datetime - $sold);
950
+			$this->save();
951
+		} else if ($count_regs_for_this_datetime < $sold) {
952
+			$this->decrease_sold($count_regs_for_this_datetime - $sold);
953
+			$this->save();
954
+		}
955 955
 		return $count_regs_for_this_datetime;
956 956
 	}
957 957
 }
Please login to merge, or discard this patch.
Spacing   +149 added lines, -149 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1
-<?php if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
-	exit( 'No direct script access allowed' );
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 /**
5 5
  * Event Espresso
@@ -74,9 +74,9 @@  discard block
 block discarded – undo
74 74
 	 *                             		    date_format and the second value is the time format
75 75
 	 * @return EE_Datetime
76 76
 	 */
77
-	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
78
-		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
79
-		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
77
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) {
78
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
79
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
80 80
 	}
81 81
 
82 82
 
@@ -87,8 +87,8 @@  discard block
 block discarded – undo
87 87
 	 *                          		the website will be used.
88 88
 	 * @return EE_Datetime
89 89
 	 */
90
-	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
91
-		return new self( $props_n_values, TRUE, $timezone );
90
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null) {
91
+		return new self($props_n_values, TRUE, $timezone);
92 92
 	}
93 93
 
94 94
 
@@ -96,8 +96,8 @@  discard block
 block discarded – undo
96 96
 	/**
97 97
 	 * @param $name
98 98
 	 */
99
-	public function set_name( $name ) {
100
-		$this->set( 'DTT_name', $name );
99
+	public function set_name($name) {
100
+		$this->set('DTT_name', $name);
101 101
 	}
102 102
 
103 103
 
@@ -105,8 +105,8 @@  discard block
 block discarded – undo
105 105
 	/**
106 106
 	 * @param $description
107 107
 	 */
108
-	public function set_description( $description ) {
109
-		$this->set( 'DTT_description', $description );
108
+	public function set_description($description) {
109
+		$this->set('DTT_description', $description);
110 110
 	}
111 111
 
112 112
 
@@ -118,8 +118,8 @@  discard block
 block discarded – undo
118 118
 	 *
119 119
 	 * @param        string $date a string representation of the event's date ex:  Dec. 25, 2025 or 12-25-2025
120 120
 	 */
121
-	public function set_start_date( $date ) {
122
-		$this->_set_date_for( $date, 'DTT_EVT_start' );
121
+	public function set_start_date($date) {
122
+		$this->_set_date_for($date, 'DTT_EVT_start');
123 123
 	}
124 124
 
125 125
 
@@ -131,8 +131,8 @@  discard block
 block discarded – undo
131 131
 	 *
132 132
 	 * @param        string $time a string representation of the event time ex:  9am  or  7:30 PM
133 133
 	 */
134
-	public function set_start_time( $time ) {
135
-		$this->_set_time_for( $time, 'DTT_EVT_start' );
134
+	public function set_start_time($time) {
135
+		$this->_set_time_for($time, 'DTT_EVT_start');
136 136
 	}
137 137
 
138 138
 
@@ -144,8 +144,8 @@  discard block
 block discarded – undo
144 144
 	 *
145 145
 	 * @param        string $date a string representation of the event's date ex:  Dec. 25, 2025 or 12-25-2025
146 146
 	 */
147
-	public function set_end_date( $date ) {
148
-		$this->_set_date_for( $date, 'DTT_EVT_end' );
147
+	public function set_end_date($date) {
148
+		$this->_set_date_for($date, 'DTT_EVT_end');
149 149
 	}
150 150
 
151 151
 
@@ -157,8 +157,8 @@  discard block
 block discarded – undo
157 157
 	 *
158 158
 	 * @param        string $time a string representation of the event time ex:  9am  or  7:30 PM
159 159
 	 */
160
-	public function set_end_time( $time ) {
161
-		$this->_set_time_for( $time, 'DTT_EVT_end' );
160
+	public function set_end_time($time) {
161
+		$this->_set_time_for($time, 'DTT_EVT_end');
162 162
 	}
163 163
 
164 164
 
@@ -170,8 +170,8 @@  discard block
 block discarded – undo
170 170
 	 *
171 171
 	 * @param        int $reg_limit
172 172
 	 */
173
-	public function set_reg_limit( $reg_limit ) {
174
-		$this->set( 'DTT_reg_limit', $reg_limit );
173
+	public function set_reg_limit($reg_limit) {
174
+		$this->set('DTT_reg_limit', $reg_limit);
175 175
 	}
176 176
 
177 177
 
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
 	 * @return        mixed        int on success, FALSE on fail
184 184
 	 */
185 185
 	public function sold() {
186
-		return $this->get_raw( 'DTT_sold' );
186
+		return $this->get_raw('DTT_sold');
187 187
 	}
188 188
 
189 189
 
@@ -193,10 +193,10 @@  discard block
 block discarded – undo
193 193
 	 *
194 194
 	 * @param        int $sold
195 195
 	 */
196
-	public function set_sold( $sold ) {
196
+	public function set_sold($sold) {
197 197
 		// sold can not go below zero
198
-		$sold = max( 0, $sold );
199
-		$this->set( 'DTT_sold', $sold );
198
+		$sold = max(0, $sold);
199
+		$this->set('DTT_sold', $sold);
200 200
 	}
201 201
 
202 202
 
@@ -205,11 +205,11 @@  discard block
 block discarded – undo
205 205
 	 * increments sold by amount passed by $qty
206 206
 	 * @param int $qty
207 207
 	 */
208
-	public function increase_sold( $qty = 1 ) {
208
+	public function increase_sold($qty = 1) {
209 209
 		$sold = $this->sold() + $qty;
210 210
 		// remove ticket reservation
211
-		$this->decrease_reserved( $qty );
212
-		$this->set_sold( $sold );
211
+		$this->decrease_reserved($qty);
212
+		$this->set_sold($sold);
213 213
         do_action(
214 214
             'AHEE__EE_Datetime__increase_sold',
215 215
             $this,
@@ -224,9 +224,9 @@  discard block
 block discarded – undo
224 224
 	 * decrements (subtracts) sold amount passed by $qty
225 225
 	 * @param int $qty
226 226
 	 */
227
-	public function decrease_sold( $qty = 1 ) {
227
+	public function decrease_sold($qty = 1) {
228 228
 		$sold = $this->sold() - $qty;
229
-		$this->set_sold( $sold );
229
+		$this->set_sold($sold);
230 230
         do_action(
231 231
             'AHEE__EE_Datetime__decrease_sold',
232 232
             $this,
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
 	 * @return int
244 244
 	 */
245 245
 	public function reserved() {
246
-		return $this->get_raw( 'DTT_reserved' );
246
+		return $this->get_raw('DTT_reserved');
247 247
 	}
248 248
 
249 249
 
@@ -253,10 +253,10 @@  discard block
 block discarded – undo
253 253
 	 *
254 254
 	 * @param int $reserved
255 255
 	 */
256
-	public function set_reserved( $reserved ) {
256
+	public function set_reserved($reserved) {
257 257
 		// reserved can not go below zero
258
-		$reserved = max( 0, (int) $reserved );
259
-		$this->set( 'DTT_reserved', $reserved );
258
+		$reserved = max(0, (int) $reserved);
259
+		$this->set('DTT_reserved', $reserved);
260 260
 	}
261 261
 
262 262
 
@@ -267,15 +267,15 @@  discard block
 block discarded – undo
267 267
 	 * @param int $qty
268 268
 	 * @return void
269 269
 	 */
270
-	public function increase_reserved( $qty = 1 ) {
271
-		$reserved = $this->reserved() + absint( $qty );
270
+	public function increase_reserved($qty = 1) {
271
+		$reserved = $this->reserved() + absint($qty);
272 272
         do_action(
273 273
             'AHEE__EE_Datetime__increase_reserved',
274 274
             $this,
275 275
             $qty,
276 276
             $reserved
277 277
         );
278
-        $this->set_reserved( $reserved );
278
+        $this->set_reserved($reserved);
279 279
 	}
280 280
 
281 281
 
@@ -286,15 +286,15 @@  discard block
 block discarded – undo
286 286
 	 * @param int $qty
287 287
 	 * @return void
288 288
 	 */
289
-	public function decrease_reserved( $qty = 1 ) {
290
-		$reserved = $this->reserved() - absint( $qty );
289
+	public function decrease_reserved($qty = 1) {
290
+		$reserved = $this->reserved() - absint($qty);
291 291
         do_action(
292 292
             'AHEE__EE_Datetime__decrease_reserved',
293 293
             $this,
294 294
             $qty,
295 295
             $reserved
296 296
         );
297
-        $this->set_reserved( $reserved );
297
+        $this->set_reserved($reserved);
298 298
 	}
299 299
 
300 300
 
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
 	 * @return string
316 316
 	 */
317 317
 	public function name() {
318
-		return $this->get( 'DTT_name' );
318
+		return $this->get('DTT_name');
319 319
 	}
320 320
 
321 321
 
@@ -325,7 +325,7 @@  discard block
 block discarded – undo
325 325
 	 * @return string
326 326
 	 */
327 327
 	public function description() {
328
-		return $this->get( 'DTT_description' );
328
+		return $this->get('DTT_description');
329 329
 	}
330 330
 
331 331
 
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
 	 * @return boolean          TRUE if is primary, FALSE if not.
336 336
 	 */
337 337
 	public function is_primary() {
338
-		return $this->get( 'DTT_is_primary' );
338
+		return $this->get('DTT_is_primary');
339 339
 	}
340 340
 
341 341
 
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
 	 * @return int         The order of the datetime for this event.
346 346
 	 */
347 347
 	public function order() {
348
-		return $this->get( 'DTT_order' );
348
+		return $this->get('DTT_order');
349 349
 	}
350 350
 
351 351
 
@@ -355,7 +355,7 @@  discard block
 block discarded – undo
355 355
 	 * @return int
356 356
 	 */
357 357
 	public function parent() {
358
-		return $this->get( 'DTT_parent' );
358
+		return $this->get('DTT_parent');
359 359
 	}
360 360
 
361 361
 
@@ -371,10 +371,10 @@  discard block
 block discarded – undo
371 371
 	 * @param    bool   $echo         - whether we echo or return (note echoing uses "pretty" formats, otherwise we use the standard formats)
372 372
 	 * @return    string|bool  string on success, FALSE on fail
373 373
 	 */
374
-	private function _show_datetime( $date_or_time = NULL, $start_or_end = 'start', $dt_frmt = '', $tm_frmt = '', $echo = FALSE ) {
374
+	private function _show_datetime($date_or_time = NULL, $start_or_end = 'start', $dt_frmt = '', $tm_frmt = '', $echo = FALSE) {
375 375
 		$field_name = "DTT_EVT_{$start_or_end}";
376
-		$dtt = $this->_get_datetime( $field_name, $dt_frmt, $tm_frmt, $date_or_time, $echo );
377
-		if ( ! $echo ) {
376
+		$dtt = $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, $date_or_time, $echo);
377
+		if ( ! $echo) {
378 378
 			return $dtt;
379 379
 		}
380 380
 		return '';
@@ -389,8 +389,8 @@  discard block
 block discarded – undo
389 389
      * @param string $dt_frmt - string representation of date format defaults to 'F j, Y'
390 390
      * @return        mixed        string on success, FALSE on fail
391 391
      */
392
-	public function start_date( $dt_frmt = '' ) {
393
-		return $this->_show_datetime( 'D', 'start', $dt_frmt );
392
+	public function start_date($dt_frmt = '') {
393
+		return $this->_show_datetime('D', 'start', $dt_frmt);
394 394
 	}
395 395
 
396 396
 
@@ -399,8 +399,8 @@  discard block
 block discarded – undo
399 399
 	 * Echoes start_date()
400 400
 	 * @param string $dt_frmt
401 401
 	 */
402
-	public function e_start_date( $dt_frmt = '' ) {
403
-		$this->_show_datetime( 'D', 'start', $dt_frmt, NULL, TRUE );
402
+	public function e_start_date($dt_frmt = '') {
403
+		$this->_show_datetime('D', 'start', $dt_frmt, NULL, TRUE);
404 404
 	}
405 405
 
406 406
 
@@ -412,8 +412,8 @@  discard block
 block discarded – undo
412 412
      * @param string $dt_frmt - string representation of date format defaults to 'F j, Y'
413 413
      * @return        mixed        string on success, FALSE on fail
414 414
      */
415
-	public function end_date( $dt_frmt = '' ) {
416
-		return $this->_show_datetime( 'D', 'end', $dt_frmt );
415
+	public function end_date($dt_frmt = '') {
416
+		return $this->_show_datetime('D', 'end', $dt_frmt);
417 417
 	}
418 418
 
419 419
 
@@ -422,8 +422,8 @@  discard block
 block discarded – undo
422 422
 	 * Echoes the end date. See end_date()
423 423
 	 * @param string $dt_frmt
424 424
 	 */
425
-	public function e_end_date( $dt_frmt = '' ) {
426
-		$this->_show_datetime( 'D', 'end', $dt_frmt, NULL, TRUE );
425
+	public function e_end_date($dt_frmt = '') {
426
+		$this->_show_datetime('D', 'end', $dt_frmt, NULL, TRUE);
427 427
 	}
428 428
 
429 429
 
@@ -438,11 +438,11 @@  discard block
 block discarded – undo
438 438
 	 * @return mixed        string on success, FALSE on fail
439 439
 	 * @throws \EE_Error
440 440
 	 */
441
-	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
442
-		$dt_frmt = ! empty( $dt_frmt ) ? $dt_frmt : $this->_dt_frmt;
443
-		$start = str_replace( ' ', '&nbsp;', $this->get_i18n_datetime( 'DTT_EVT_start', $dt_frmt ) );
444
-		$end = str_replace( ' ', '&nbsp;', $this->get_i18n_datetime( 'DTT_EVT_end', $dt_frmt ) );
445
-		return $start !== $end ? $start . $conjunction . $end : $start;
441
+	public function date_range($dt_frmt = '', $conjunction = ' - ') {
442
+		$dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt;
443
+		$start = str_replace(' ', '&nbsp;', $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt));
444
+		$end = str_replace(' ', '&nbsp;', $this->get_i18n_datetime('DTT_EVT_end', $dt_frmt));
445
+		return $start !== $end ? $start.$conjunction.$end : $start;
446 446
 	}
447 447
 
448 448
 
@@ -452,8 +452,8 @@  discard block
 block discarded – undo
452 452
 	 * @param string $conjunction
453 453
 	 * @throws \EE_Error
454 454
 	 */
455
-	public function e_date_range( $dt_frmt = '', $conjunction = ' - ' ) {
456
-		echo $this->date_range( $dt_frmt, $conjunction );
455
+	public function e_date_range($dt_frmt = '', $conjunction = ' - ') {
456
+		echo $this->date_range($dt_frmt, $conjunction);
457 457
 	}
458 458
 
459 459
 
@@ -464,8 +464,8 @@  discard block
 block discarded – undo
464 464
 	 * @param string $tm_format - string representation of time format defaults to 'g:i a'
465 465
 	 * @return mixed        string on success, FALSE on fail
466 466
 	 */
467
-	public function start_time( $tm_format = '' ) {
468
-		return $this->_show_datetime( 'T', 'start', NULL, $tm_format );
467
+	public function start_time($tm_format = '') {
468
+		return $this->_show_datetime('T', 'start', NULL, $tm_format);
469 469
 	}
470 470
 
471 471
 
@@ -473,8 +473,8 @@  discard block
 block discarded – undo
473 473
 	/**
474 474
 	 * @param string $tm_format
475 475
 	 */
476
-	public function e_start_time( $tm_format = '' ) {
477
-		$this->_show_datetime( 'T', 'start', NULL, $tm_format, TRUE );
476
+	public function e_start_time($tm_format = '') {
477
+		$this->_show_datetime('T', 'start', NULL, $tm_format, TRUE);
478 478
 	}
479 479
 
480 480
 
@@ -485,8 +485,8 @@  discard block
 block discarded – undo
485 485
 	 * @param string $tm_format - string representation of time format defaults to 'g:i a'
486 486
 	 * @return mixed        string on success, FALSE on fail
487 487
 	 */
488
-	public function end_time( $tm_format = '' ) {
489
-		return $this->_show_datetime( 'T', 'end', NULL, $tm_format );
488
+	public function end_time($tm_format = '') {
489
+		return $this->_show_datetime('T', 'end', NULL, $tm_format);
490 490
 	}
491 491
 
492 492
 
@@ -494,8 +494,8 @@  discard block
 block discarded – undo
494 494
 	/**
495 495
 	 * @param string $tm_format
496 496
 	 */
497
-	public function e_end_time( $tm_format = '' ) {
498
-		$this->_show_datetime( 'T', 'end', NULL, $tm_format, TRUE );
497
+	public function e_end_time($tm_format = '') {
498
+		$this->_show_datetime('T', 'end', NULL, $tm_format, TRUE);
499 499
 	}
500 500
 
501 501
 
@@ -510,11 +510,11 @@  discard block
 block discarded – undo
510 510
 	 * @return mixed              string on success, FALSE on fail
511 511
 	 * @throws \EE_Error
512 512
 	 */
513
-	public function time_range( $tm_format = '', $conjunction = ' - ' ) {
514
-		$tm_format = ! empty( $tm_format ) ? $tm_format : $this->_tm_frmt;
515
-		$start = str_replace( ' ', '&nbsp;', $this->get_i18n_datetime( 'DTT_EVT_start', $tm_format ) );
516
-		$end = str_replace( ' ', '&nbsp;', $this->get_i18n_datetime( 'DTT_EVT_end',  $tm_format ) );
517
-		return $start !== $end ? $start . $conjunction . $end : $start;
513
+	public function time_range($tm_format = '', $conjunction = ' - ') {
514
+		$tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt;
515
+		$start = str_replace(' ', '&nbsp;', $this->get_i18n_datetime('DTT_EVT_start', $tm_format));
516
+		$end = str_replace(' ', '&nbsp;', $this->get_i18n_datetime('DTT_EVT_end', $tm_format));
517
+		return $start !== $end ? $start.$conjunction.$end : $start;
518 518
 	}
519 519
 
520 520
 
@@ -524,8 +524,8 @@  discard block
 block discarded – undo
524 524
 	 * @param string $conjunction
525 525
 	 * @throws \EE_Error
526 526
 	 */
527
-	public function e_time_range( $tm_format = '', $conjunction = ' - ' ) {
528
-		echo $this->time_range( $tm_format, $conjunction );
527
+	public function e_time_range($tm_format = '', $conjunction = ' - ') {
528
+		echo $this->time_range($tm_format, $conjunction);
529 529
 	}
530 530
 
531 531
 
@@ -547,30 +547,30 @@  discard block
 block discarded – undo
547 547
 	public function date_and_time_range(
548 548
 	    $dt_format = '',
549 549
         $tm_format = '',
550
-        $conjunction = ' - ' ,
550
+        $conjunction = ' - ',
551 551
         $separator = ' '
552 552
     ) {
553
-		$dt_format = ! empty( $dt_format ) ? $dt_format : $this->_dt_frmt;
554
-		$tm_format = ! empty( $tm_format ) ? $tm_format : $this->_tm_frmt;
555
-		$full_format = $dt_format . $separator . $tm_format;
553
+		$dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt;
554
+		$tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt;
555
+		$full_format = $dt_format.$separator.$tm_format;
556 556
 
557 557
 		//the range output depends on various conditions
558
-		switch ( true ) {
558
+		switch (true) {
559 559
 			//start date timestamp and end date timestamp are the same.
560
-			case ( $this->get_raw( 'DTT_EVT_start' ) === $this->get_raw( 'DTT_EVT_end' ) ) :
561
-				$output = $this->get_i18n_datetime( 'DTT_EVT_start', $full_format );
560
+			case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')) :
561
+				$output = $this->get_i18n_datetime('DTT_EVT_start', $full_format);
562 562
 				break;
563 563
 			//start and end date are the same but times are different
564
-			case ( $this->start_date() === $this->end_date() ) :
565
-				$output = $this->get_i18n_datetime( 'DTT_EVT_start', $full_format )
564
+			case ($this->start_date() === $this->end_date()) :
565
+				$output = $this->get_i18n_datetime('DTT_EVT_start', $full_format)
566 566
 				          . $conjunction
567
-				          . $this->get_i18n_datetime( 'DTT_EVT_end', $tm_format );
567
+				          . $this->get_i18n_datetime('DTT_EVT_end', $tm_format);
568 568
 				break;
569 569
 			//all other conditions
570 570
 			default :
571
-				$output = $this->get_i18n_datetime( 'DTT_EVT_start', $full_format )
571
+				$output = $this->get_i18n_datetime('DTT_EVT_start', $full_format)
572 572
 				          . $conjunction
573
-				          . $this->get_i18n_datetime( 'DTT_EVT_end', $full_format );
573
+				          . $this->get_i18n_datetime('DTT_EVT_end', $full_format);
574 574
 				break;
575 575
 		}
576 576
 		return $output;
@@ -588,8 +588,8 @@  discard block
 block discarded – undo
588 588
 	 * @return void
589 589
 	 * @throws \EE_Error
590 590
 	 */
591
-	public function e_date_and_time_range( $dt_format = '', $tm_format = '', $conjunction = ' - ' ) {
592
-		echo $this->date_and_time_range( $dt_format, $tm_format, $conjunction );
591
+	public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ') {
592
+		echo $this->date_and_time_range($dt_format, $tm_format, $conjunction);
593 593
 	}
594 594
 
595 595
 
@@ -601,8 +601,8 @@  discard block
 block discarded – undo
601 601
 	 * @param 	string 	$tm_format - string representation of time format defaults to 'g:i a'
602 602
 	 * @return 	mixed 	string on success, FALSE on fail
603 603
 	 */
604
-	public function start_date_and_time( $dt_format = '', $tm_format = '' ) {
605
-		return $this->_show_datetime( '', 'start', $dt_format, $tm_format );
604
+	public function start_date_and_time($dt_format = '', $tm_format = '') {
605
+		return $this->_show_datetime('', 'start', $dt_format, $tm_format);
606 606
 	}
607 607
 
608 608
 
@@ -611,8 +611,8 @@  discard block
 block discarded – undo
611 611
 	 * @param string $dt_frmt
612 612
 	 * @param string $tm_format
613 613
 	 */
614
-	public function e_start_date_and_time( $dt_frmt = '', $tm_format = '' ) {
615
-		$this->_show_datetime( '', 'start', $dt_frmt, $tm_format, TRUE );
614
+	public function e_start_date_and_time($dt_frmt = '', $tm_format = '') {
615
+		$this->_show_datetime('', 'start', $dt_frmt, $tm_format, TRUE);
616 616
 	}
617 617
 
618 618
 
@@ -626,11 +626,11 @@  discard block
 block discarded – undo
626 626
 	 * @param bool   $round_up
627 627
 	 * @return float|int|mixed
628 628
 	 */
629
-	public function length( $units = 'seconds', $round_up = FALSE ) {
630
-		$start = $this->get_raw( 'DTT_EVT_start' );
631
-		$end = $this->get_raw( 'DTT_EVT_end' );
629
+	public function length($units = 'seconds', $round_up = FALSE) {
630
+		$start = $this->get_raw('DTT_EVT_start');
631
+		$end = $this->get_raw('DTT_EVT_end');
632 632
 		$length_in_units = $end - $start;
633
-		switch ( $units ) {
633
+		switch ($units) {
634 634
 			//NOTE: We purposefully don't use "break;" in order to chain the divisions
635 635
 			/** @noinspection PhpMissingBreakStatementInspection */
636 636
 			case 'days':
@@ -643,10 +643,10 @@  discard block
 block discarded – undo
643 643
 				$length_in_units /= 60;
644 644
 			case 'seconds':
645 645
 			default:
646
-				$length_in_units = ceil( $length_in_units );
646
+				$length_in_units = ceil($length_in_units);
647 647
 		}
648
-		if ( $round_up ) {
649
-			$length_in_units = max( $length_in_units, 1 );
648
+		if ($round_up) {
649
+			$length_in_units = max($length_in_units, 1);
650 650
 		}
651 651
 		return $length_in_units;
652 652
 	}
@@ -661,7 +661,7 @@  discard block
 block discarded – undo
661 661
      * @return    mixed                string on success, FALSE on fail
662 662
      */
663 663
     public function end_date_and_time($dt_frmt = '', $tm_format = '') {
664
-		return $this->_show_datetime( '', 'end', $dt_frmt, $tm_format );
664
+		return $this->_show_datetime('', 'end', $dt_frmt, $tm_format);
665 665
 	}
666 666
 
667 667
 
@@ -670,8 +670,8 @@  discard block
 block discarded – undo
670 670
 	 * @param string $dt_frmt
671 671
 	 * @param string $tm_format
672 672
 	 */
673
-	public function e_end_date_and_time( $dt_frmt = '', $tm_format = '' ) {
674
-		$this->_show_datetime( '', 'end', $dt_frmt, $tm_format, TRUE );
673
+	public function e_end_date_and_time($dt_frmt = '', $tm_format = '') {
674
+		$this->_show_datetime('', 'end', $dt_frmt, $tm_format, TRUE);
675 675
 	}
676 676
 
677 677
 
@@ -682,7 +682,7 @@  discard block
 block discarded – undo
682 682
 	 * @return        int
683 683
 	 */
684 684
 	public function start() {
685
-		return $this->get_raw( 'DTT_EVT_start' );
685
+		return $this->get_raw('DTT_EVT_start');
686 686
 	}
687 687
 
688 688
 
@@ -693,7 +693,7 @@  discard block
 block discarded – undo
693 693
 	 * @return        int
694 694
 	 */
695 695
 	public function end() {
696
-		return $this->get_raw( 'DTT_EVT_end' );
696
+		return $this->get_raw('DTT_EVT_end');
697 697
 	}
698 698
 
699 699
 
@@ -704,7 +704,7 @@  discard block
 block discarded – undo
704 704
 	 * @return        mixed        int on success, FALSE on fail
705 705
 	 */
706 706
 	public function reg_limit() {
707
-		return $this->get_raw( 'DTT_reg_limit' );
707
+		return $this->get_raw('DTT_reg_limit');
708 708
 	}
709 709
 
710 710
 
@@ -732,15 +732,15 @@  discard block
 block discarded – undo
732 732
 	 * 																	the spaces remaining for this particular datetime, hence the flag.
733 733
 	 * @return 	int
734 734
 	 */
735
-	public function spaces_remaining( $consider_tickets = FALSE ) {
735
+	public function spaces_remaining($consider_tickets = FALSE) {
736 736
 		// tickets remaining available for purchase
737 737
 		//no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF
738 738
 		$dtt_remaining = $this->reg_limit() - $this->sold_and_reserved();
739
-		if ( ! $consider_tickets ) {
739
+		if ( ! $consider_tickets) {
740 740
 			return $dtt_remaining;
741 741
 		}
742 742
 		$tickets_remaining = $this->tickets_remaining();
743
-		return min( $dtt_remaining, $tickets_remaining );
743
+		return min($dtt_remaining, $tickets_remaining);
744 744
 	}
745 745
 
746 746
 
@@ -751,19 +751,19 @@  discard block
 block discarded – undo
751 751
 	 * @param array $query_params like EEM_Base::get_all's
752 752
 	 * @return int
753 753
 	 */
754
-	public function tickets_remaining( $query_params = array() ) {
754
+	public function tickets_remaining($query_params = array()) {
755 755
 		$sum = 0;
756
-		$tickets = $this->tickets( $query_params );
757
-		if ( ! empty( $tickets ) ) {
758
-			foreach ( $tickets as $ticket ) {
759
-				if ( $ticket instanceof EE_Ticket ) {
756
+		$tickets = $this->tickets($query_params);
757
+		if ( ! empty($tickets)) {
758
+			foreach ($tickets as $ticket) {
759
+				if ($ticket instanceof EE_Ticket) {
760 760
 					// get the actual amount of tickets that can be sold
761
-					$qty = $ticket->qty( 'saleable' );
762
-					if ( $qty === EE_INF ) {
761
+					$qty = $ticket->qty('saleable');
762
+					if ($qty === EE_INF) {
763 763
 						return EE_INF;
764 764
 					}
765 765
 					// no negative ticket quantities plz
766
-					if ( $qty > 0 ) {
766
+					if ($qty > 0) {
767 767
 						$sum += $qty;
768 768
 					}
769 769
 				}
@@ -780,8 +780,8 @@  discard block
 block discarded – undo
780 780
 	 * @param array $query_params like EEM_Base::get_all's
781 781
 	 * @return int
782 782
 	 */
783
-	public function sum_tickets_initially_available( $query_params = array() ) {
784
-		return $this->sum_related( 'Ticket', $query_params, 'TKT_qty' );
783
+	public function sum_tickets_initially_available($query_params = array()) {
784
+		return $this->sum_related('Ticket', $query_params, 'TKT_qty');
785 785
 	}
786 786
 
787 787
 
@@ -793,7 +793,7 @@  discard block
 block discarded – undo
793 793
 	 * @return int
794 794
 	 */
795 795
 	public function total_tickets_available_at_this_datetime() {
796
-		return $this->spaces_remaining( true );
796
+		return $this->spaces_remaining(true);
797 797
 	}
798 798
 
799 799
 
@@ -804,7 +804,7 @@  discard block
 block discarded – undo
804 804
 	 * @return boolean
805 805
 	 */
806 806
 	public function is_upcoming() {
807
-		return ( $this->get_raw( 'DTT_EVT_start' ) > time() );
807
+		return ($this->get_raw('DTT_EVT_start') > time());
808 808
 	}
809 809
 
810 810
 
@@ -814,7 +814,7 @@  discard block
 block discarded – undo
814 814
 	 * @return boolean
815 815
 	 */
816 816
 	public function is_active() {
817
-		return ( $this->get_raw( 'DTT_EVT_start' ) < time() && $this->get_raw( 'DTT_EVT_end' ) > time() );
817
+		return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time());
818 818
 	}
819 819
 
820 820
 
@@ -824,7 +824,7 @@  discard block
 block discarded – undo
824 824
 	 * @return boolean
825 825
 	 */
826 826
 	public function is_expired() {
827
-		return ( $this->get_raw( 'DTT_EVT_end' ) < time() );
827
+		return ($this->get_raw('DTT_EVT_end') < time());
828 828
 	}
829 829
 
830 830
 
@@ -835,16 +835,16 @@  discard block
 block discarded – undo
835 835
 	 */
836 836
 	public function get_active_status() {
837 837
 		$total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime();
838
-		if ( $total_tickets_for_this_dtt !== FALSE && $total_tickets_for_this_dtt < 1 ) {
838
+		if ($total_tickets_for_this_dtt !== FALSE && $total_tickets_for_this_dtt < 1) {
839 839
 			return EE_Datetime::sold_out;
840 840
 		}
841
-		if ( $this->is_expired() ) {
841
+		if ($this->is_expired()) {
842 842
 			return EE_Datetime::expired;
843 843
 		}
844
-		if ( $this->is_upcoming() ) {
844
+		if ($this->is_upcoming()) {
845 845
 			return EE_Datetime::upcoming;
846 846
 		}
847
-		if ( $this->is_active() ) {
847
+		if ($this->is_active()) {
848 848
 			return EE_Datetime::active;
849 849
 		}
850 850
 		return NULL;
@@ -858,24 +858,24 @@  discard block
 block discarded – undo
858 858
 	 * @param  boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty.
859 859
 	 * @return string
860 860
 	 */
861
-	public function get_dtt_display_name( $use_dtt_name = FALSE ) {
862
-		if ( $use_dtt_name ) {
861
+	public function get_dtt_display_name($use_dtt_name = FALSE) {
862
+		if ($use_dtt_name) {
863 863
 			$dtt_name = $this->name();
864
-			if ( !empty( $dtt_name ) ) {
864
+			if ( ! empty($dtt_name)) {
865 865
 				return $dtt_name;
866 866
 			}
867 867
 		}
868 868
 		//first condition is to see if the months are different
869
-		if ( date( 'm', $this->get_raw( 'DTT_EVT_start' ) ) != date( 'm', $this->get_raw( 'DTT_EVT_end' ) ) ) {
870
-			$display_date = $this->start_date( 'M j\, Y g:i a' ) . ' - ' . $this->end_date( 'M j\, Y g:i a' );
869
+		if (date('m', $this->get_raw('DTT_EVT_start')) != date('m', $this->get_raw('DTT_EVT_end'))) {
870
+			$display_date = $this->start_date('M j\, Y g:i a').' - '.$this->end_date('M j\, Y g:i a');
871 871
 			//next condition is if its the same month but different day
872 872
 		}
873 873
 		else {
874
-			if ( date( 'm', $this->get_raw( 'DTT_EVT_start' ) ) == date( 'm', $this->get_raw( 'DTT_EVT_end' ) ) && date( 'd', $this->get_raw( 'DTT_EVT_start' ) ) != date( 'd', $this->get_raw( 'DTT_EVT_end' ) ) ) {
875
-				$display_date = $this->start_date( 'M j\, g:i a' ) . ' - ' . $this->end_date( 'M j\, g:i a Y' );
874
+			if (date('m', $this->get_raw('DTT_EVT_start')) == date('m', $this->get_raw('DTT_EVT_end')) && date('d', $this->get_raw('DTT_EVT_start')) != date('d', $this->get_raw('DTT_EVT_end'))) {
875
+				$display_date = $this->start_date('M j\, g:i a').' - '.$this->end_date('M j\, g:i a Y');
876 876
 			}
877 877
 			else {
878
-				$display_date = $this->start_date( 'F j\, Y' ) . ' @ ' . $this->start_date( 'g:i a' ) . ' - ' . $this->end_date( 'g:i a' );
878
+				$display_date = $this->start_date('F j\, Y').' @ '.$this->start_date('g:i a').' - '.$this->end_date('g:i a');
879 879
 			}
880 880
 		}
881 881
 		return $display_date;
@@ -889,8 +889,8 @@  discard block
 block discarded – undo
889 889
 *@param array $query_params see EEM_Base::get_all()
890 890
 	 * @return EE_Ticket[]
891 891
 	 */
892
-	public function tickets( $query_params = array() ) {
893
-		return $this->get_many_related( 'Ticket', $query_params );
892
+	public function tickets($query_params = array()) {
893
+		return $this->get_many_related('Ticket', $query_params);
894 894
 	}
895 895
 
896 896
 
@@ -900,21 +900,21 @@  discard block
 block discarded – undo
900 900
 	 * @param array $query_params like EEM_Base::get_all's
901 901
 	 * @return EE_Ticket[]
902 902
 	 */
903
-	public function ticket_types_available_for_purchase( $query_params = array() ) {
903
+	public function ticket_types_available_for_purchase($query_params = array()) {
904 904
 		// first check if datetime is valid
905
-		if ( ! ( $this->is_upcoming() || $this->is_active() ) || $this->sold_out() ) {
905
+		if ( ! ($this->is_upcoming() || $this->is_active()) || $this->sold_out()) {
906 906
 			return array();
907 907
 		}
908
-		if ( empty( $query_params ) ) {
908
+		if (empty($query_params)) {
909 909
 			$query_params = array(
910 910
 				array(
911
-					'TKT_start_date' => array( '<=', EEM_Ticket::instance()->current_time_for_query( 'TKT_start_date' ) ),
912
-					'TKT_end_date'   => array( '>=', EEM_Ticket::instance()->current_time_for_query( 'TKT_end_date' ) ),
911
+					'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')),
912
+					'TKT_end_date'   => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
913 913
 					'TKT_deleted'    => false
914 914
 				)
915 915
 			);
916 916
 		}
917
-		return $this->tickets( $query_params );
917
+		return $this->tickets($query_params);
918 918
 	}
919 919
 
920 920
 
@@ -924,7 +924,7 @@  discard block
 block discarded – undo
924 924
 	 * @return EE_Event
925 925
 	 */
926 926
 	public function event() {
927
-		return $this->get_first_related( 'Event' );
927
+		return $this->get_first_related('Event');
928 928
 	}
929 929
 
930 930
 
@@ -938,11 +938,11 @@  discard block
 block discarded – undo
938 938
      */
939 939
 	public function update_sold() {
940 940
 		$count_regs_for_this_datetime = EEM_Registration::instance()->count(
941
-			array( array(
941
+			array(array(
942 942
 				'STS_ID' 					=> EEM_Registration::status_id_approved,
943 943
 				'REG_deleted' 				=> 0,
944 944
 				'Ticket.Datetime.DTT_ID' 	=> $this->ID(),
945
-			) )
945
+			))
946 946
 		);
947 947
         $sold = $this->sold();
948 948
         if ($count_regs_for_this_datetime > $sold) {
Please login to merge, or discard this patch.
reg_steps/payment_options/EE_SPCO_Reg_Step_Payment_Options.class.php 2 patches
Indentation   +2870 added lines, -2870 removed lines patch added patch discarded remove patch
@@ -15,2874 +15,2874 @@
 block discarded – undo
15 15
 class EE_SPCO_Reg_Step_Payment_Options extends EE_SPCO_Reg_Step
16 16
 {
17 17
 
18
-    /**
19
-     * @access protected
20
-     * @var EE_Line_Item_Display $Line_Item_Display
21
-     */
22
-    protected $line_item_display;
23
-
24
-    /**
25
-     * @access protected
26
-     * @var boolean $handle_IPN_in_this_request
27
-     */
28
-    protected $handle_IPN_in_this_request = false;
29
-
30
-
31
-    /**
32
-     *    set_hooks - for hooking into EE Core, other modules, etc
33
-     *
34
-     * @access    public
35
-     * @return    void
36
-     */
37
-    public static function set_hooks()
38
-    {
39
-        add_filter(
40
-            'FHEE__SPCO__EE_Line_Item_Filter_Collection',
41
-            array('EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters')
42
-        );
43
-        add_action(
44
-            'wp_ajax_switch_spco_billing_form',
45
-            array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
46
-        );
47
-        add_action(
48
-            'wp_ajax_nopriv_switch_spco_billing_form',
49
-            array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
50
-        );
51
-        add_action('wp_ajax_save_payer_details', array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details'));
52
-        add_action(
53
-            'wp_ajax_nopriv_save_payer_details',
54
-            array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details')
55
-        );
56
-        add_action(
57
-            'wp_ajax_get_transaction_details_for_gateways',
58
-            array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
59
-        );
60
-        add_action(
61
-            'wp_ajax_nopriv_get_transaction_details_for_gateways',
62
-            array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
63
-        );
64
-        add_filter(
65
-            'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
66
-            array('EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'),
67
-            10,
68
-            1
69
-        );
70
-    }
71
-
72
-
73
-    /**
74
-     *    ajax switch_spco_billing_form
75
-     *
76
-     * @throws \EE_Error
77
-     */
78
-    public static function switch_spco_billing_form()
79
-    {
80
-        EED_Single_Page_Checkout::process_ajax_request('switch_payment_method');
81
-    }
82
-
83
-
84
-    /**
85
-     *    ajax save_payer_details
86
-     *
87
-     * @throws \EE_Error
88
-     */
89
-    public static function save_payer_details()
90
-    {
91
-        EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax');
92
-    }
93
-
94
-
95
-    /**
96
-     *    ajax get_transaction_details
97
-     *
98
-     * @throws \EE_Error
99
-     */
100
-    public static function get_transaction_details()
101
-    {
102
-        EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
103
-    }
104
-
105
-
106
-    /**
107
-     * bypass_recaptcha_for_load_payment_method
108
-     *
109
-     * @access public
110
-     * @return array
111
-     * @throws InvalidArgumentException
112
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
113
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
114
-     */
115
-    public static function bypass_recaptcha_for_load_payment_method()
116
-    {
117
-        return array(
118
-            'EESID'  => EE_Registry::instance()->SSN->id(),
119
-            'step'   => 'payment_options',
120
-            'action' => 'spco_billing_form',
121
-        );
122
-    }
123
-
124
-
125
-    /**
126
-     *    class constructor
127
-     *
128
-     * @access    public
129
-     * @param    EE_Checkout $checkout
130
-     */
131
-    public function __construct(EE_Checkout $checkout)
132
-    {
133
-        $this->_slug     = 'payment_options';
134
-        $this->_name     = esc_html__('Payment Options', 'event_espresso');
135
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'payment_options_main.template.php';
136
-        $this->checkout  = $checkout;
137
-        $this->_reset_success_message();
138
-        $this->set_instructions(
139
-            esc_html__(
140
-                'Please select a method of payment and provide any necessary billing information before proceeding.',
141
-                'event_espresso'
142
-            )
143
-        );
144
-    }
145
-
146
-
147
-    /**
148
-     * @return null
149
-     */
150
-    public function line_item_display()
151
-    {
152
-        return $this->line_item_display;
153
-    }
154
-
155
-
156
-    /**
157
-     * @param null $line_item_display
158
-     */
159
-    public function set_line_item_display($line_item_display)
160
-    {
161
-        $this->line_item_display = $line_item_display;
162
-    }
163
-
164
-
165
-    /**
166
-     * @return boolean
167
-     */
168
-    public function handle_IPN_in_this_request()
169
-    {
170
-        return $this->handle_IPN_in_this_request;
171
-    }
172
-
173
-
174
-    /**
175
-     * @param boolean $handle_IPN_in_this_request
176
-     */
177
-    public function set_handle_IPN_in_this_request($handle_IPN_in_this_request)
178
-    {
179
-        $this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN);
180
-    }
181
-
182
-
183
-    /**
184
-     * translate_js_strings
185
-     *
186
-     * @return void
187
-     */
188
-    public function translate_js_strings()
189
-    {
190
-        EE_Registry::$i18n_js_strings['no_payment_method']      = esc_html__(
191
-            'Please select a method of payment in order to continue.',
192
-            'event_espresso'
193
-        );
194
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__(
195
-            'A valid method of payment could not be determined. Please refresh the page and try again.',
196
-            'event_espresso'
197
-        );
198
-        EE_Registry::$i18n_js_strings['forwarding_to_offsite']  = esc_html__(
199
-            'Forwarding to Secure Payment Provider.',
200
-            'event_espresso'
201
-        );
202
-    }
203
-
204
-
205
-    /**
206
-     * enqueue_styles_and_scripts
207
-     *
208
-     * @return void
209
-     * @throws EE_Error
210
-     * @throws InvalidArgumentException
211
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
212
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
213
-     */
214
-    public function enqueue_styles_and_scripts()
215
-    {
216
-        $transaction = $this->checkout->transaction;
217
-        //if the transaction isn't set or nothing is owed on it, don't enqueue any JS
218
-        if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
219
-            return;
220
-        }
221
-        foreach (EEM_Payment_Method::instance()->get_all_for_transaction($transaction, EEM_Payment_Method::scope_cart) as $payment_method) {
222
-            $type_obj = $payment_method->type_obj();
223
-            if ($type_obj instanceof EE_PMT_Base) {
224
-                $billing_form = $type_obj->generate_new_billing_form($transaction);
225
-                if ($billing_form instanceof EE_Form_Section_Proper) {
226
-                    $billing_form->enqueue_js();
227
-                }
228
-            }
229
-        }
230
-    }
231
-
232
-
233
-    /**
234
-     * initialize_reg_step
235
-     *
236
-     * @return bool
237
-     * @throws EE_Error
238
-     * @throws InvalidArgumentException
239
-     * @throws ReflectionException
240
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
241
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
242
-     */
243
-    public function initialize_reg_step()
244
-    {
245
-        // TODO: if /when we implement donations, then this will need overriding
246
-        if (// don't need payment options for:
247
-            // 	registrations made via the admin
248
-            // 	completed transactions
249
-            // 	overpaid transactions
250
-            // 	$ 0.00 transactions (no payment required)
251
-            ! $this->checkout->payment_required()
252
-            // but do NOT remove if current action being called belongs to this reg step
253
-            && ! is_callable(array($this, $this->checkout->action))
254
-            && ! $this->completed()
255
-        ) {
256
-            // and if so, then we no longer need the Payment Options step
257
-            if ($this->is_current_step()) {
258
-                $this->checkout->generate_reg_form = false;
259
-            }
260
-            $this->checkout->remove_reg_step($this->_slug);
261
-            // DEBUG LOG
262
-            //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
263
-            return false;
264
-        }
265
-        // load EEM_Payment_Method
266
-        EE_Registry::instance()->load_model('Payment_Method');
267
-        // get all active payment methods
268
-        $this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
269
-            $this->checkout->transaction,
270
-            EEM_Payment_Method::scope_cart
271
-        );
272
-        return true;
273
-    }
274
-
275
-
276
-    /**
277
-     * @return EE_Form_Section_Proper
278
-     * @throws EE_Error
279
-     * @throws InvalidArgumentException
280
-     * @throws ReflectionException
281
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
282
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
283
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
284
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
285
-     */
286
-    public function generate_reg_form()
287
-    {
288
-        // reset in case someone changes their mind
289
-        $this->_reset_selected_method_of_payment();
290
-        // set some defaults
291
-        $this->checkout->selected_method_of_payment = 'payments_closed';
292
-        $registrations_requiring_payment            = array();
293
-        $registrations_for_free_events              = array();
294
-        $registrations_requiring_pre_approval       = array();
295
-        $sold_out_events                            = array();
296
-        $insufficient_spaces_available              = array();
297
-        $no_payment_required                        = true;
298
-        // loop thru registrations to gather info
299
-        $registrations         = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
300
-        $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
301
-            $registrations,
302
-            $this->checkout->revisit
303
-        );
304
-        foreach ($registrations as $REG_ID => $registration) {
305
-            /** @var $registration EE_Registration */
306
-            // has this registration lost it's space ?
307
-            if (isset($ejected_registrations[ $REG_ID ])) {
308
-                if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
309
-                    $sold_out_events[ $registration->event()->ID() ] = $registration->event();
310
-                } else {
311
-                    $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
312
-                }
313
-                continue;
314
-            }
315
-            // event requires admin approval
316
-            if ($registration->status_ID() === EEM_Registration::status_id_not_approved) {
317
-                // add event to list of events with pre-approval reg status
318
-                $registrations_requiring_pre_approval[$REG_ID] = $registration;
319
-                do_action(
320
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
321
-                    $registration->event(),
322
-                    $this
323
-                );
324
-                continue;
325
-            }
326
-            if ($this->checkout->revisit
327
-                && $registration->status_ID() !== EEM_Registration::status_id_approved
328
-                && (
329
-                    $registration->event()->is_sold_out()
330
-                    || $registration->event()->is_sold_out(true)
331
-                )
332
-            ) {
333
-                // add event to list of events that are sold out
334
-                $sold_out_events[$registration->event()->ID()] = $registration->event();
335
-                do_action(
336
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
337
-                    $registration->event(),
338
-                    $this
339
-                );
340
-                continue;
341
-            }
342
-            // are they allowed to pay now and is there monies owing?
343
-            if ($registration->owes_monies_and_can_pay()) {
344
-                $registrations_requiring_payment[$REG_ID] = $registration;
345
-                do_action(
346
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
347
-                    $registration->event(),
348
-                    $this
349
-                );
350
-            } elseif (! $this->checkout->revisit
351
-                && $registration->status_ID() !== EEM_Registration::status_id_not_approved
352
-                && $registration->ticket()->is_free()
353
-            ) {
354
-                $registrations_for_free_events[$registration->event()->ID()] = $registration;
355
-            }
356
-        }
357
-        $subsections = array();
358
-        // now decide which template to load
359
-        if (! empty($sold_out_events)) {
360
-            $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
361
-        }
362
-        if (! empty($insufficient_spaces_available)) {
363
-            $subsections['insufficient_space'] = $this->_insufficient_spaces_available(
364
-                $insufficient_spaces_available
365
-            );
366
-        }
367
-        if (! empty($registrations_requiring_pre_approval)) {
368
-            $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
369
-                $registrations_requiring_pre_approval
370
-            );
371
-        }
372
-        if (! empty($registrations_for_free_events)) {
373
-            $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
374
-        }
375
-        if (! empty($registrations_requiring_payment)) {
376
-            if ($this->checkout->amount_owing > 0) {
377
-                // autoload Line_Item_Display classes
378
-                EEH_Autoloader::register_line_item_filter_autoloaders();
379
-                $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
380
-                    apply_filters(
381
-                        'FHEE__SPCO__EE_Line_Item_Filter_Collection',
382
-                        new EE_Line_Item_Filter_Collection()
383
-                    ),
384
-                    $this->checkout->cart->get_grand_total()
385
-                );
386
-                /** @var EE_Line_Item $filtered_line_item_tree */
387
-                $filtered_line_item_tree = $line_item_filter_processor->process();
388
-                EEH_Autoloader::register_line_item_display_autoloaders();
389
-                $this->set_line_item_display(new EE_Line_Item_Display('spco'));
390
-                $subsections['payment_options'] = $this->_display_payment_options(
391
-                    $this->line_item_display->display_line_item(
392
-                        $filtered_line_item_tree,
393
-                        array('registrations' => $registrations)
394
-                    )
395
-                );
396
-                $this->checkout->amount_owing   = $filtered_line_item_tree->total();
397
-                $this->_apply_registration_payments_to_amount_owing($registrations);
398
-            }
399
-            $no_payment_required = false;
400
-        } else {
401
-            $this->_hide_reg_step_submit_button_if_revisit();
402
-        }
403
-        $this->_save_selected_method_of_payment();
404
-
405
-        $subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs();
406
-        $subsections['extra_hidden_inputs']   = $this->_extra_hidden_inputs($no_payment_required);
407
-
408
-        return new EE_Form_Section_Proper(
409
-            array(
410
-                'name'            => $this->reg_form_name(),
411
-                'html_id'         => $this->reg_form_name(),
412
-                'subsections'     => $subsections,
413
-                'layout_strategy' => new EE_No_Layout(),
414
-            )
415
-        );
416
-    }
417
-
418
-
419
-    /**
420
-     * add line item filters required for this reg step
421
-     * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
422
-     *        add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options',
423
-     *        'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the
424
-     *        payment options reg step, can apply these filters via the following: apply_filters(
425
-     *        'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing
426
-     *        filter collection by passing that instead of instantiating a new collection
427
-     *
428
-     * @param \EE_Line_Item_Filter_Collection $line_item_filter_collection
429
-     * @return EE_Line_Item_Filter_Collection
430
-     * @throws EE_Error
431
-     * @throws InvalidArgumentException
432
-     * @throws ReflectionException
433
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
434
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
435
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
436
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
437
-     */
438
-    public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
439
-    {
440
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
441
-            return $line_item_filter_collection;
442
-        }
443
-        if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
444
-            return $line_item_filter_collection;
445
-        }
446
-        if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
447
-            return $line_item_filter_collection;
448
-        }
449
-        $line_item_filter_collection->add(
450
-            new EE_Billable_Line_Item_Filter(
451
-                EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations(
452
-                    EE_Registry::instance()->SSN->checkout()->transaction->registrations(
453
-                        EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
454
-                    )
455
-                )
456
-            )
457
-        );
458
-        $line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
459
-        return $line_item_filter_collection;
460
-    }
461
-
462
-
463
-    /**
464
-     * remove_ejected_registrations
465
-     * if a registrant has lost their potential space at an event due to lack of payment,
466
-     * then this method removes them from the list of registrations being paid for during this request
467
-     *
468
-     * @param \EE_Registration[] $registrations
469
-     * @return EE_Registration[]
470
-     * @throws EE_Error
471
-     * @throws InvalidArgumentException
472
-     * @throws ReflectionException
473
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
474
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
475
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
476
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
477
-     */
478
-    public static function remove_ejected_registrations(array $registrations)
479
-    {
480
-        $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
481
-            $registrations,
482
-            EE_Registry::instance()->SSN->checkout()->revisit
483
-        );
484
-        foreach ($registrations as $REG_ID => $registration) {
485
-            // has this registration lost it's space ?
486
-            if (isset($ejected_registrations[$REG_ID])) {
487
-                unset($registrations[$REG_ID]);
488
-                continue;
489
-            }
490
-        }
491
-        return $registrations;
492
-    }
493
-
494
-
495
-    /**
496
-     * find_registrations_that_lost_their_space
497
-     * If a registrant chooses an offline payment method like Invoice,
498
-     * then no space is reserved for them at the event until they fully pay fo that site
499
-     * (unless the event's default reg status is set to APPROVED)
500
-     * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales,
501
-     * then this method will determine which registrations have lost the ability to complete the reg process.
502
-     *
503
-     * @param \EE_Registration[] $registrations
504
-     * @param bool               $revisit
505
-     * @return array
506
-     * @throws EE_Error
507
-     * @throws InvalidArgumentException
508
-     * @throws ReflectionException
509
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
510
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
511
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
512
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
513
-     */
514
-    public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false)
515
-    {
516
-        // registrations per event
517
-        $event_reg_count = array();
518
-        // spaces left per event
519
-        $event_spaces_remaining = array();
520
-        // tickets left sorted by ID
521
-        $tickets_remaining = array();
522
-        // registrations that have lost their space
523
-        $ejected_registrations = array();
524
-        foreach ($registrations as $REG_ID => $registration) {
525
-            if ($registration->status_ID() === EEM_Registration::status_id_approved
526
-                || apply_filters(
527
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment',
528
-                    false,
529
-                    $registration,
530
-                    $revisit
531
-                )
532
-            ) {
533
-                continue;
534
-            }
535
-            $EVT_ID = $registration->event_ID();
536
-            $ticket = $registration->ticket();
537
-            if (! isset($tickets_remaining[$ticket->ID()])) {
538
-                $tickets_remaining[$ticket->ID()] = $ticket->remaining();
539
-            }
540
-            if ($tickets_remaining[$ticket->ID()] > 0) {
541
-                if (! isset($event_reg_count[$EVT_ID])) {
542
-                    $event_reg_count[$EVT_ID] = 0;
543
-                }
544
-                $event_reg_count[$EVT_ID]++;
545
-                if (! isset($event_spaces_remaining[$EVT_ID])) {
546
-                    $event_spaces_remaining[$EVT_ID] = $registration->event()->spaces_remaining_for_sale();
547
-                }
548
-            }
549
-            if ($revisit
550
-                && ($tickets_remaining[$ticket->ID()] === 0
551
-                    || $event_reg_count[$EVT_ID] > $event_spaces_remaining[$EVT_ID]
552
-                )
553
-            ) {
554
-                $ejected_registrations[$REG_ID] = $registration->event();
555
-                if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) {
556
-                    /** @type EE_Registration_Processor $registration_processor */
557
-                    $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
558
-                    // at this point, we should have enough details about the registrant to consider the registration
559
-                    // NOT incomplete
560
-                    $registration_processor->manually_update_registration_status(
561
-                        $registration,
562
-                        EEM_Registration::status_id_wait_list
563
-                    );
564
-                }
565
-            }
566
-        }
567
-        return $ejected_registrations;
568
-    }
569
-
570
-
571
-    /**
572
-     * _hide_reg_step_submit_button
573
-     * removes the html for the reg step submit button
574
-     * by replacing it with an empty string via filter callback
575
-     *
576
-     * @return void
577
-     */
578
-    protected function _adjust_registration_status_if_event_old_sold()
579
-    {
580
-    }
581
-
582
-
583
-    /**
584
-     * _hide_reg_step_submit_button
585
-     * removes the html for the reg step submit button
586
-     * by replacing it with an empty string via filter callback
587
-     *
588
-     * @return void
589
-     */
590
-    protected function _hide_reg_step_submit_button_if_revisit()
591
-    {
592
-        if ($this->checkout->revisit) {
593
-            add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string');
594
-        }
595
-    }
596
-
597
-
598
-    /**
599
-     * sold_out_events
600
-     * displays notices regarding events that have sold out since hte registrant first signed up
601
-     *
602
-     * @param \EE_Event[] $sold_out_events_array
603
-     * @return \EE_Form_Section_Proper
604
-     * @throws \EE_Error
605
-     */
606
-    private function _sold_out_events($sold_out_events_array = array())
607
-    {
608
-        // set some defaults
609
-        $this->checkout->selected_method_of_payment = 'events_sold_out';
610
-        $sold_out_events                            = '';
611
-        foreach ($sold_out_events_array as $sold_out_event) {
612
-            $sold_out_events .= EEH_HTML::li(
613
-                EEH_HTML::span(
614
-                    '  ' . $sold_out_event->name(),
615
-                    '',
616
-                    'dashicons dashicons-marker ee-icon-size-16 pink-text'
617
-                )
618
-            );
619
-        }
620
-        return new EE_Form_Section_Proper(
621
-            array(
622
-                'layout_strategy' => new EE_Template_Layout(
623
-                    array(
624
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
625
-                                                  . $this->_slug
626
-                                                  . DS
627
-                                                  . 'sold_out_events.template.php',
628
-                        'template_args'        => apply_filters(
629
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
630
-                            array(
631
-                                'sold_out_events'     => $sold_out_events,
632
-                                'sold_out_events_msg' => apply_filters(
633
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg',
634
-                                    sprintf(
635
-                                        esc_html__(
636
-                                            'It appears that the event you were about to make a payment for has sold out since you first registered. If you have already made a partial payment towards this event, please contact the event administrator for a refund.%3$s%3$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%2$s',
637
-                                            'event_espresso'
638
-                                        ),
639
-                                        '<strong>',
640
-                                        '</strong>',
641
-                                        '<br />'
642
-                                    )
643
-                                ),
644
-                            )
645
-                        ),
646
-                    )
647
-                ),
648
-            )
649
-        );
650
-    }
651
-
652
-
653
-    /**
654
-     * _insufficient_spaces_available
655
-     * displays notices regarding events that do not have enough remaining spaces
656
-     * to satisfy the current number of registrations looking to pay
657
-     *
658
-     * @param \EE_Event[] $insufficient_spaces_events_array
659
-     * @return \EE_Form_Section_Proper
660
-     * @throws \EE_Error
661
-     */
662
-    private function _insufficient_spaces_available($insufficient_spaces_events_array = array())
663
-    {
664
-        // set some defaults
665
-        $this->checkout->selected_method_of_payment = 'invoice';
666
-        $insufficient_space_events                  = '';
667
-        foreach ($insufficient_spaces_events_array as $event) {
668
-            if ($event instanceof EE_Event) {
669
-                $insufficient_space_events .= EEH_HTML::li(
670
-                    EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
671
-                );
672
-            }
673
-        }
674
-        return new EE_Form_Section_Proper(
675
-            array(
676
-                'subsections'     => array(
677
-                    'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
678
-                    'extra_hidden_inputs'   => $this->_extra_hidden_inputs(),
679
-                ),
680
-                'layout_strategy' => new EE_Template_Layout(
681
-                    array(
682
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
683
-                                                  . $this->_slug
684
-                                                  . DS
685
-                                                  . 'sold_out_events.template.php',
686
-                        'template_args'        => apply_filters(
687
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args',
688
-                            array(
689
-                                'sold_out_events'     => $insufficient_space_events,
690
-                                'sold_out_events_msg' => apply_filters(
691
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg',
692
-                                    esc_html__(
693
-                                        'It appears that the event you were about to make a payment for has sold additional tickets since you first registered, and there are no longer enough spaces left to accommodate your selections. You may continue to pay and secure the available space(s) remaining, or simply cancel if you no longer wish to purchase. If you have already made a partial payment towards this event, please contact the event administrator for a refund.',
694
-                                        'event_espresso'
695
-                                    )
696
-                                ),
697
-                            )
698
-                        ),
699
-                    )
700
-                ),
701
-            )
702
-        );
703
-    }
704
-
705
-
706
-    /**
707
-     * registrations_requiring_pre_approval
708
-     *
709
-     * @param array $registrations_requiring_pre_approval
710
-     * @return EE_Form_Section_Proper
711
-     * @throws EE_Error
712
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
713
-     */
714
-    private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = array())
715
-    {
716
-        $events_requiring_pre_approval = '';
717
-        foreach ($registrations_requiring_pre_approval as $registration) {
718
-            if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
719
-                $events_requiring_pre_approval[$registration->event()->ID()] = EEH_HTML::li(
720
-                    EEH_HTML::span(
721
-                        '',
722
-                        '',
723
-                        'dashicons dashicons-marker ee-icon-size-16 orange-text'
724
-                    )
725
-                    . EEH_HTML::span($registration->event()->name(), '', 'orange-text')
726
-                );
727
-            }
728
-        }
729
-        return new EE_Form_Section_Proper(
730
-            array(
731
-                'layout_strategy' => new EE_Template_Layout(
732
-                    array(
733
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
734
-                                                  . $this->_slug
735
-                                                  . DS
736
-                                                  . 'events_requiring_pre_approval.template.php', // layout_template
737
-                        'template_args'        => apply_filters(
738
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
739
-                            array(
740
-                                'events_requiring_pre_approval'     => implode('', $events_requiring_pre_approval),
741
-                                'events_requiring_pre_approval_msg' => apply_filters(
742
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg',
743
-                                    esc_html__(
744
-                                        'The following events do not require payment at this time and will not be billed during this transaction. Billing will only occur after the attendee has been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.',
745
-                                        'event_espresso'
746
-                                    )
747
-                                ),
748
-                            )
749
-                        ),
750
-                    )
751
-                ),
752
-            )
753
-        );
754
-    }
755
-
756
-
757
-    /**
758
-     * _no_payment_required
759
-     *
760
-     * @param \EE_Event[] $registrations_for_free_events
761
-     * @return \EE_Form_Section_Proper
762
-     * @throws \EE_Error
763
-     */
764
-    private function _no_payment_required($registrations_for_free_events = array())
765
-    {
766
-        // set some defaults
767
-        $this->checkout->selected_method_of_payment = 'no_payment_required';
768
-        // generate no_payment_required form
769
-        return new EE_Form_Section_Proper(
770
-            array(
771
-                'layout_strategy' => new EE_Template_Layout(
772
-                    array(
773
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
774
-                                                  . $this->_slug
775
-                                                  . DS
776
-                                                  . 'no_payment_required.template.php', // layout_template
777
-                        'template_args'        => apply_filters(
778
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args',
779
-                            array(
780
-                                'revisit'                       => $this->checkout->revisit,
781
-                                'registrations'                 => array(),
782
-                                'ticket_count'                  => array(),
783
-                                'registrations_for_free_events' => $registrations_for_free_events,
784
-                                'no_payment_required_msg'       => EEH_HTML::p(
785
-                                    esc_html__('This is a free event, so no billing will occur.', 'event_espresso')
786
-                                ),
787
-                            )
788
-                        ),
789
-                    )
790
-                ),
791
-            )
792
-        );
793
-    }
794
-
795
-
796
-    /**
797
-     * _display_payment_options
798
-     *
799
-     * @param string $transaction_details
800
-     * @return EE_Form_Section_Proper
801
-     * @throws EE_Error
802
-     * @throws InvalidArgumentException
803
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
804
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
805
-     */
806
-    private function _display_payment_options($transaction_details = '')
807
-    {
808
-        // has method_of_payment been set by no-js user?
809
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment();
810
-        // build payment options form
811
-        return apply_filters(
812
-            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form',
813
-            new EE_Form_Section_Proper(
814
-                array(
815
-                    'subsections'     => array(
816
-                        'before_payment_options' => apply_filters(
817
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options',
818
-                            new EE_Form_Section_Proper(
819
-                                array('layout_strategy' => new EE_Div_Per_Section_Layout())
820
-                            )
821
-                        ),
822
-                        'payment_options'        => $this->_setup_payment_options(),
823
-                        'after_payment_options'  => apply_filters(
824
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options',
825
-                            new EE_Form_Section_Proper(
826
-                                array('layout_strategy' => new EE_Div_Per_Section_Layout())
827
-                            )
828
-                        ),
829
-                    ),
830
-                    'layout_strategy' => new EE_Template_Layout(
831
-                        array(
832
-                            'layout_template_file' => $this->_template,
833
-                            'template_args'        => apply_filters(
834
-                                'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args',
835
-                                array(
836
-                                    'reg_count'                 => $this->line_item_display->total_items(),
837
-                                    'transaction_details'       => $transaction_details,
838
-                                    'available_payment_methods' => array(),
839
-                                )
840
-                            ),
841
-                        )
842
-                    ),
843
-                )
844
-            )
845
-        );
846
-    }
847
-
848
-
849
-    /**
850
-     * _extra_hidden_inputs
851
-     *
852
-     * @param bool $no_payment_required
853
-     * @return \EE_Form_Section_Proper
854
-     * @throws \EE_Error
855
-     */
856
-    private function _extra_hidden_inputs($no_payment_required = true)
857
-    {
858
-        return new EE_Form_Section_Proper(
859
-            array(
860
-                'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
861
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
862
-                'subsections'     => array(
863
-                    'spco_no_payment_required' => new EE_Hidden_Input(
864
-                        array(
865
-                            'normalization_strategy' => new EE_Boolean_Normalization(),
866
-                            'html_name'              => 'spco_no_payment_required',
867
-                            'html_id'                => 'spco-no-payment-required-payment_options',
868
-                            'default'                => $no_payment_required,
869
-                        )
870
-                    ),
871
-                    'spco_transaction_id'      => new EE_Fixed_Hidden_Input(
872
-                        array(
873
-                            'normalization_strategy' => new EE_Int_Normalization(),
874
-                            'html_name'              => 'spco_transaction_id',
875
-                            'html_id'                => 'spco-transaction-id',
876
-                            'default'                => $this->checkout->transaction->ID(),
877
-                        )
878
-                    ),
879
-                ),
880
-            )
881
-        );
882
-    }
883
-
884
-
885
-    /**
886
-     *    _apply_registration_payments_to_amount_owing
887
-     *
888
-     * @access protected
889
-     * @param array $registrations
890
-     * @throws EE_Error
891
-     */
892
-    protected function _apply_registration_payments_to_amount_owing(array $registrations)
893
-    {
894
-        $payments = array();
895
-        foreach ($registrations as $registration) {
896
-            if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
897
-                $payments += $registration->registration_payments();
898
-            }
899
-        }
900
-        if (! empty($payments)) {
901
-            foreach ($payments as $payment) {
902
-                if ($payment instanceof EE_Registration_Payment) {
903
-                    $this->checkout->amount_owing -= $payment->amount();
904
-                }
905
-            }
906
-        }
907
-    }
908
-
909
-
910
-    /**
911
-     *    _reset_selected_method_of_payment
912
-     *
913
-     * @access    private
914
-     * @param    bool $force_reset
915
-     * @return void
916
-     * @throws InvalidArgumentException
917
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
918
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
919
-     */
920
-    private function _reset_selected_method_of_payment($force_reset = false)
921
-    {
922
-        $reset_payment_method = $force_reset
923
-            ? true
924
-            : sanitize_text_field(EE_Registry::instance()->REQ->get('reset_payment_method', false));
925
-        if ($reset_payment_method) {
926
-            $this->checkout->selected_method_of_payment = null;
927
-            $this->checkout->payment_method             = null;
928
-            $this->checkout->billing_form               = null;
929
-            $this->_save_selected_method_of_payment();
930
-        }
931
-    }
932
-
933
-
934
-    /**
935
-     * _save_selected_method_of_payment
936
-     * stores the selected_method_of_payment in the session
937
-     * so that it's available for all subsequent requests including AJAX
938
-     *
939
-     * @access        private
940
-     * @param string $selected_method_of_payment
941
-     * @return void
942
-     * @throws InvalidArgumentException
943
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
944
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
945
-     */
946
-    private function _save_selected_method_of_payment($selected_method_of_payment = '')
947
-    {
948
-        $selected_method_of_payment = ! empty($selected_method_of_payment)
949
-            ? $selected_method_of_payment
950
-            : $this->checkout->selected_method_of_payment;
951
-        EE_Registry::instance()->SSN->set_session_data(
952
-            array('selected_method_of_payment' => $selected_method_of_payment)
953
-        );
954
-    }
955
-
956
-
957
-    /**
958
-     * _setup_payment_options
959
-     *
960
-     * @return EE_Form_Section_Proper
961
-     * @throws EE_Error
962
-     * @throws InvalidArgumentException
963
-     * @throws ReflectionException
964
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
965
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
966
-     */
967
-    public function _setup_payment_options()
968
-    {
969
-        // load payment method classes
970
-        $this->checkout->available_payment_methods = $this->_get_available_payment_methods();
971
-        if (empty($this->checkout->available_payment_methods)) {
972
-            EE_Error::add_error(
973
-                apply_filters(
974
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods',
975
-                    sprintf(
976
-                        esc_html__(
977
-                            'Sorry, you cannot complete your purchase because a payment method is not active.%1$s Please contact %2$s for assistance and provide a description of the problem.',
978
-                            'event_espresso'
979
-                        ),
980
-                        '<br>',
981
-                        EE_Registry::instance()->CFG->organization->get_pretty('email')
982
-                    )
983
-                ),
984
-                __FILE__,
985
-                __FUNCTION__,
986
-                __LINE__
987
-            );
988
-        }
989
-        // switch up header depending on number of available payment methods
990
-        $payment_method_header     = count($this->checkout->available_payment_methods) > 1
991
-            ? apply_filters(
992
-                'FHEE__registration_page_payment_options__method_of_payment_hdr',
993
-                esc_html__('Please Select Your Method of Payment', 'event_espresso')
994
-            )
995
-            : apply_filters(
996
-                'FHEE__registration_page_payment_options__method_of_payment_hdr',
997
-                esc_html__('Method of Payment', 'event_espresso')
998
-            );
999
-        $available_payment_methods = array(
1000
-            // display the "Payment Method" header
1001
-            'payment_method_header' => new EE_Form_Section_HTML(
1002
-                EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr')
1003
-            ),
1004
-        );
1005
-        // the list of actual payment methods ( invoice, paypal, etc ) in a  ( slug => HTML )  format
1006
-        $available_payment_method_options = array();
1007
-        $default_payment_method_option    = array();
1008
-        // additional instructions to be displayed and hidden below payment methods (adding a clearing div to start)
1009
-        $payment_methods_billing_info = array(
1010
-            new EE_Form_Section_HTML(
1011
-                EEH_HTML::div('<br />', '', '', 'clear:both;')
1012
-            ),
1013
-        );
1014
-        // loop through payment methods
1015
-        foreach ($this->checkout->available_payment_methods as $payment_method) {
1016
-            if ($payment_method instanceof EE_Payment_Method) {
1017
-                $payment_method_button = EEH_HTML::img(
1018
-                    $payment_method->button_url(),
1019
-                    $payment_method->name(),
1020
-                    'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1021
-                    'spco-payment-method-btn-img'
1022
-                );
1023
-                // check if any payment methods are set as default
1024
-                // if payment method is already selected OR nothing is selected and this payment method should be
1025
-                // open_by_default
1026
-                if (($this->checkout->selected_method_of_payment === $payment_method->slug())
1027
-                    || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1028
-                ) {
1029
-                    $this->checkout->selected_method_of_payment = $payment_method->slug();
1030
-                    $this->_save_selected_method_of_payment();
1031
-                    $default_payment_method_option[$payment_method->slug()] = $payment_method_button;
1032
-                } else {
1033
-                    $available_payment_method_options[$payment_method->slug()] = $payment_method_button;
1034
-                }
1035
-                $payment_methods_billing_info[$payment_method->slug() . '-info'] = $this->_payment_method_billing_info(
1036
-                    $payment_method
1037
-                );
1038
-            }
1039
-        }
1040
-        // prepend available_payment_method_options with default_payment_method_option so that it appears first in list
1041
-        // of PMs
1042
-        $available_payment_method_options = $default_payment_method_option + $available_payment_method_options;
1043
-        // now generate the actual form  inputs
1044
-        $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1045
-            $available_payment_method_options
1046
-        );
1047
-        $available_payment_methods                              += $payment_methods_billing_info;
1048
-        // build the available payment methods form
1049
-        return new EE_Form_Section_Proper(
1050
-            array(
1051
-                'html_id'         => 'spco-available-methods-of-payment-dv',
1052
-                'subsections'     => $available_payment_methods,
1053
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1054
-            )
1055
-        );
1056
-    }
1057
-
1058
-
1059
-    /**
1060
-     * _get_available_payment_methods
1061
-     *
1062
-     * @return EE_Payment_Method[]
1063
-     * @throws EE_Error
1064
-     * @throws InvalidArgumentException
1065
-     * @throws ReflectionException
1066
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1067
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1068
-     */
1069
-    protected function _get_available_payment_methods()
1070
-    {
1071
-        if (! empty($this->checkout->available_payment_methods)) {
1072
-            return $this->checkout->available_payment_methods;
1073
-        }
1074
-        $available_payment_methods = array();
1075
-        // load EEM_Payment_Method
1076
-        EE_Registry::instance()->load_model('Payment_Method');
1077
-        /** @type EEM_Payment_Method $EEM_Payment_Method */
1078
-        $EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
1079
-        // get all active payment methods
1080
-        $payment_methods = $EEM_Payment_Method->get_all_for_transaction(
1081
-            $this->checkout->transaction,
1082
-            EEM_Payment_Method::scope_cart
1083
-        );
1084
-        foreach ($payment_methods as $payment_method) {
1085
-            if ($payment_method instanceof EE_Payment_Method) {
1086
-                $available_payment_methods[$payment_method->slug()] = $payment_method;
1087
-            }
1088
-        }
1089
-        return $available_payment_methods;
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     *    _available_payment_method_inputs
1095
-     *
1096
-     * @access    private
1097
-     * @param    array $available_payment_method_options
1098
-     * @return    \EE_Form_Section_Proper
1099
-     */
1100
-    private function _available_payment_method_inputs($available_payment_method_options = array())
1101
-    {
1102
-        // generate inputs
1103
-        return new EE_Form_Section_Proper(
1104
-            array(
1105
-                'html_id'         => 'ee-available-payment-method-inputs',
1106
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1107
-                'subsections'     => array(
1108
-                    '' => new EE_Radio_Button_Input(
1109
-                        $available_payment_method_options,
1110
-                        array(
1111
-                            'html_name'          => 'selected_method_of_payment',
1112
-                            'html_class'         => 'spco-payment-method',
1113
-                            'default'            => $this->checkout->selected_method_of_payment,
1114
-                            'label_size'         => 11,
1115
-                            'enforce_label_size' => true,
1116
-                        )
1117
-                    ),
1118
-                ),
1119
-            )
1120
-        );
1121
-    }
1122
-
1123
-
1124
-    /**
1125
-     *    _payment_method_billing_info
1126
-     *
1127
-     * @access    private
1128
-     * @param    EE_Payment_Method $payment_method
1129
-     * @return EE_Form_Section_Proper
1130
-     * @throws EE_Error
1131
-     * @throws InvalidArgumentException
1132
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1133
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1134
-     */
1135
-    private function _payment_method_billing_info(EE_Payment_Method $payment_method)
1136
-    {
1137
-        $currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug()
1138
-            ? true
1139
-            : false;
1140
-        // generate the billing form for payment method
1141
-        $billing_form                 = $currently_selected
1142
-            ? $this->_get_billing_form_for_payment_method($payment_method)
1143
-            : new EE_Form_Section_HTML();
1144
-        $this->checkout->billing_form = $currently_selected
1145
-            ? $billing_form
1146
-            : $this->checkout->billing_form;
1147
-        // it's all in the details
1148
-        $info_html = EEH_HTML::h3(
1149
-            esc_html__('Important information regarding your payment', 'event_espresso'),
1150
-            '',
1151
-            'spco-payment-method-hdr'
1152
-        );
1153
-        // add some info regarding the step, either from what's saved in the admin,
1154
-        // or a default string depending on whether the PM has a billing form or not
1155
-        if ($payment_method->description()) {
1156
-            $payment_method_info = $payment_method->description();
1157
-        } elseif ($billing_form instanceof EE_Billing_Info_Form) {
1158
-            $payment_method_info = sprintf(
1159
-                esc_html__(
1160
-                    'Please provide the following billing information, then click the "%1$s" button below in order to proceed.',
1161
-                    'event_espresso'
1162
-                ),
1163
-                $this->submit_button_text()
1164
-            );
1165
-        } else {
1166
-            $payment_method_info = sprintf(
1167
-                esc_html__('Please click the "%1$s" button below in order to proceed.', 'event_espresso'),
1168
-                $this->submit_button_text()
1169
-            );
1170
-        }
1171
-        $info_html .= EEH_HTML::p(
1172
-            apply_filters(
1173
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options___payment_method_billing_info__payment_method_info',
1174
-                $payment_method_info
1175
-            ),
1176
-            '',
1177
-            'spco-payment-method-desc ee-attention'
1178
-        );
1179
-        return new EE_Form_Section_Proper(
1180
-            array(
1181
-                'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1182
-                'html_class'      => 'spco-payment-method-info-dv',
1183
-                // only display the selected or default PM
1184
-                'html_style'      => $currently_selected ? '' : 'display:none;',
1185
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1186
-                'subsections'     => array(
1187
-                    'info'         => new EE_Form_Section_HTML($info_html),
1188
-                    'billing_form' => $currently_selected ? $billing_form : new EE_Form_Section_HTML(),
1189
-                ),
1190
-            )
1191
-        );
1192
-    }
1193
-
1194
-
1195
-    /**
1196
-     * get_billing_form_html_for_payment_method
1197
-     *
1198
-     * @access public
1199
-     * @return string
1200
-     * @throws EE_Error
1201
-     * @throws InvalidArgumentException
1202
-     * @throws ReflectionException
1203
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1204
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1205
-     */
1206
-    public function get_billing_form_html_for_payment_method()
1207
-    {
1208
-        // how have they chosen to pay?
1209
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1210
-        $this->checkout->payment_method             = $this->_get_payment_method_for_selected_method_of_payment();
1211
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1212
-            return false;
1213
-        }
1214
-        if (apply_filters(
1215
-            'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1216
-            false
1217
-        )) {
1218
-            EE_Error::add_success(
1219
-                apply_filters(
1220
-                    'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1221
-                    sprintf(
1222
-                        esc_html__(
1223
-                            'You have selected "%s" as your method of payment. Please note the important payment information below.',
1224
-                            'event_espresso'
1225
-                        ),
1226
-                        $this->checkout->payment_method->name()
1227
-                    )
1228
-                )
1229
-            );
1230
-        }
1231
-        // now generate billing form for selected method of payment
1232
-        $payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method);
1233
-        // fill form with attendee info if applicable
1234
-        if ($payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form
1235
-            && $this->checkout->transaction_has_primary_registrant()
1236
-        ) {
1237
-            $payment_method_billing_form->populate_from_attendee(
1238
-                $this->checkout->transaction->primary_registration()->attendee()
1239
-            );
1240
-        }
1241
-        // and debug content
1242
-        if ($payment_method_billing_form instanceof EE_Billing_Info_Form
1243
-            && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1244
-        ) {
1245
-            $payment_method_billing_form =
1246
-                $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1247
-                    $payment_method_billing_form
1248
-                );
1249
-        }
1250
-        $billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper
1251
-            ? $payment_method_billing_form->get_html()
1252
-            : '';
1253
-        $this->checkout->json_response->set_return_data(array('payment_method_info' => $billing_info));
1254
-        // localize validation rules for main form
1255
-        $this->checkout->current_step->reg_form->localize_validation_rules();
1256
-        $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1257
-        return true;
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * _get_billing_form_for_payment_method
1263
-     *
1264
-     * @access private
1265
-     * @param EE_Payment_Method $payment_method
1266
-     * @return EE_Billing_Info_Form|EE_Form_Section_HTML
1267
-     * @throws EE_Error
1268
-     * @throws InvalidArgumentException
1269
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1270
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1271
-     */
1272
-    private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method)
1273
-    {
1274
-        $billing_form = $payment_method->type_obj()->billing_form(
1275
-            $this->checkout->transaction,
1276
-            array('amount_owing' => $this->checkout->amount_owing)
1277
-        );
1278
-        if ($billing_form instanceof EE_Billing_Info_Form) {
1279
-            if (apply_filters(
1280
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1281
-                false
1282
-            )
1283
-                && EE_Registry::instance()->REQ->is_set('payment_method')
1284
-            ) {
1285
-                EE_Error::add_success(
1286
-                    apply_filters(
1287
-                        'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1288
-                        sprintf(
1289
-                            esc_html__(
1290
-                                'You have selected "%s" as your method of payment. Please note the important payment information below.',
1291
-                                'event_espresso'
1292
-                            ),
1293
-                            $payment_method->name()
1294
-                        )
1295
-                    )
1296
-                );
1297
-            }
1298
-            return apply_filters(
1299
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
1300
-                $billing_form,
1301
-                $payment_method
1302
-            );
1303
-        }
1304
-        // no actual billing form, so return empty HTML form section
1305
-        return new EE_Form_Section_HTML();
1306
-    }
1307
-
1308
-
1309
-    /**
1310
-     * _get_selected_method_of_payment
1311
-     *
1312
-     * @access private
1313
-     * @param boolean $required whether to throw an error if the "selected_method_of_payment"
1314
-     *                          is not found in the incoming request
1315
-     * @param string  $request_param
1316
-     * @return NULL|string
1317
-     * @throws EE_Error
1318
-     * @throws InvalidArgumentException
1319
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1320
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1321
-     */
1322
-    private function _get_selected_method_of_payment(
1323
-        $required = false,
1324
-        $request_param = 'selected_method_of_payment'
1325
-    ) {
1326
-        // is selected_method_of_payment set in the request ?
1327
-        $selected_method_of_payment = EE_Registry::instance()->REQ->get($request_param, false);
1328
-        if ($selected_method_of_payment) {
1329
-            // sanitize it
1330
-            $selected_method_of_payment = is_array($selected_method_of_payment)
1331
-                ? array_shift($selected_method_of_payment)
1332
-                : $selected_method_of_payment;
1333
-            $selected_method_of_payment = sanitize_text_field($selected_method_of_payment);
1334
-            // store it in the session so that it's available for all subsequent requests including AJAX
1335
-            $this->_save_selected_method_of_payment($selected_method_of_payment);
1336
-        } else {
1337
-            // or is is set in the session ?
1338
-            $selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data(
1339
-                'selected_method_of_payment'
1340
-            );
1341
-        }
1342
-        // do ya really really gotta have it?
1343
-        if (empty($selected_method_of_payment) && $required) {
1344
-            EE_Error::add_error(
1345
-                sprintf(
1346
-                    esc_html__(
1347
-                        'The selected method of payment could not be determined.%sPlease ensure that you have selected one before proceeding.%sIf you continue to experience difficulties, then refresh your browser and try again, or contact %s for assistance.',
1348
-                        'event_espresso'
1349
-                    ),
1350
-                    '<br/>',
1351
-                    '<br/>',
1352
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
1353
-                ),
1354
-                __FILE__,
1355
-                __FUNCTION__,
1356
-                __LINE__
1357
-            );
1358
-            return null;
1359
-        }
1360
-        return $selected_method_of_payment;
1361
-    }
1362
-
1363
-
1364
-
1365
-
1366
-
1367
-
1368
-    /********************************************************************************************************/
1369
-    /***********************************  SWITCH PAYMENT METHOD  ************************************/
1370
-    /********************************************************************************************************/
1371
-    /**
1372
-     * switch_payment_method
1373
-     *
1374
-     * @access public
1375
-     * @return string
1376
-     * @throws EE_Error
1377
-     * @throws InvalidArgumentException
1378
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1379
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1380
-     */
1381
-    public function switch_payment_method()
1382
-    {
1383
-        if (! $this->_verify_payment_method_is_set()) {
1384
-            return false;
1385
-        }
1386
-        if (apply_filters(
1387
-            'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1388
-            false
1389
-        )) {
1390
-            EE_Error::add_success(
1391
-                apply_filters(
1392
-                    'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1393
-                    sprintf(
1394
-                        esc_html__(
1395
-                            'You have selected "%s" as your method of payment. Please note the important payment information below.',
1396
-                            'event_espresso'
1397
-                        ),
1398
-                        $this->checkout->payment_method->name()
1399
-                    )
1400
-                )
1401
-            );
1402
-        }
1403
-        // generate billing form for selected method of payment if it hasn't been done already
1404
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1405
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1406
-                $this->checkout->payment_method
1407
-            );
1408
-        }
1409
-        // fill form with attendee info if applicable
1410
-        if (apply_filters(
1411
-            'FHEE__populate_billing_form_fields_from_attendee',
1412
-            (
1413
-                $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
1414
-                && $this->checkout->transaction_has_primary_registrant()
1415
-            ),
1416
-            $this->checkout->billing_form,
1417
-            $this->checkout->transaction
1418
-        )
1419
-        ) {
1420
-            $this->checkout->billing_form->populate_from_attendee(
1421
-                $this->checkout->transaction->primary_registration()->attendee()
1422
-            );
1423
-        }
1424
-        // and debug content
1425
-        if ($this->checkout->billing_form instanceof EE_Billing_Info_Form
1426
-            && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1427
-        ) {
1428
-            $this->checkout->billing_form =
1429
-                $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1430
-                    $this->checkout->billing_form
1431
-                );
1432
-        }
1433
-        // get html and validation rules for form
1434
-        if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) {
1435
-            $this->checkout->json_response->set_return_data(
1436
-                array('payment_method_info' => $this->checkout->billing_form->get_html())
1437
-            );
1438
-            // localize validation rules for main form
1439
-            $this->checkout->billing_form->localize_validation_rules(true);
1440
-            $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1441
-        } else {
1442
-            $this->checkout->json_response->set_return_data(array('payment_method_info' => ''));
1443
-        }
1444
-        //prevents advancement to next step
1445
-        $this->checkout->continue_reg = false;
1446
-        return true;
1447
-    }
1448
-
1449
-
1450
-    /**
1451
-     * _verify_payment_method_is_set
1452
-     *
1453
-     * @return bool
1454
-     * @throws EE_Error
1455
-     * @throws InvalidArgumentException
1456
-     * @throws ReflectionException
1457
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1458
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1459
-     */
1460
-    protected function _verify_payment_method_is_set()
1461
-    {
1462
-        // generate billing form for selected method of payment if it hasn't been done already
1463
-        if (empty($this->checkout->selected_method_of_payment)) {
1464
-            // how have they chosen to pay?
1465
-            $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1466
-        } else {
1467
-            // choose your own adventure based on method_of_payment
1468
-            switch ($this->checkout->selected_method_of_payment) {
1469
-                case 'events_sold_out' :
1470
-                    EE_Error::add_attention(
1471
-                        apply_filters(
1472
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg',
1473
-                            esc_html__(
1474
-                                'It appears that the event you were about to make a payment for has sold out since this form first loaded. Please contact the event administrator if you believe this is an error.',
1475
-                                'event_espresso'
1476
-                            )
1477
-                        ),
1478
-                        __FILE__, __FUNCTION__, __LINE__
1479
-                    );
1480
-                    return false;
1481
-                    break;
1482
-                case 'payments_closed' :
1483
-                    EE_Error::add_attention(
1484
-                        apply_filters(
1485
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg',
1486
-                            esc_html__(
1487
-                                'It appears that the event you were about to make a payment for is not accepting payments at this time. Please contact the event administrator if you believe this is an error.',
1488
-                                'event_espresso'
1489
-                            )
1490
-                        ),
1491
-                        __FILE__, __FUNCTION__, __LINE__
1492
-                    );
1493
-                    return false;
1494
-                    break;
1495
-                case 'no_payment_required' :
1496
-                    EE_Error::add_attention(
1497
-                        apply_filters(
1498
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg',
1499
-                            esc_html__(
1500
-                                'It appears that the event you were about to make a payment for does not require payment. Please contact the event administrator if you believe this is an error.',
1501
-                                'event_espresso'
1502
-                            )
1503
-                        ),
1504
-                        __FILE__, __FUNCTION__, __LINE__
1505
-                    );
1506
-                    return false;
1507
-                    break;
1508
-                default:
1509
-            }
1510
-        }
1511
-        // verify payment method
1512
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1513
-            // get payment method for selected method of payment
1514
-            $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1515
-        }
1516
-        return $this->checkout->payment_method instanceof EE_Payment_Method ? true : false;
1517
-    }
1518
-
1519
-
1520
-
1521
-    /********************************************************************************************************/
1522
-    /***************************************  SAVE PAYER DETAILS  ****************************************/
1523
-    /********************************************************************************************************/
1524
-    /**
1525
-     * save_payer_details_via_ajax
1526
-     *
1527
-     * @return void
1528
-     * @throws EE_Error
1529
-     * @throws InvalidArgumentException
1530
-     * @throws ReflectionException
1531
-     * @throws RuntimeException
1532
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1533
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1534
-     */
1535
-    public function save_payer_details_via_ajax()
1536
-    {
1537
-        if (! $this->_verify_payment_method_is_set()) {
1538
-            return;
1539
-        }
1540
-        // generate billing form for selected method of payment if it hasn't been done already
1541
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1542
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1543
-                $this->checkout->payment_method
1544
-            );
1545
-        }
1546
-        // generate primary attendee from payer info if applicable
1547
-        if (! $this->checkout->transaction_has_primary_registrant()) {
1548
-            $attendee = $this->_create_attendee_from_request_data();
1549
-            if ($attendee instanceof EE_Attendee) {
1550
-                foreach ($this->checkout->transaction->registrations() as $registration) {
1551
-                    if ($registration->is_primary_registrant()) {
1552
-                        $this->checkout->primary_attendee_obj = $attendee;
1553
-                        $registration->_add_relation_to($attendee, 'Attendee');
1554
-                        $registration->set_attendee_id($attendee->ID());
1555
-                        $registration->update_cache_after_object_save('Attendee', $attendee);
1556
-                    }
1557
-                }
1558
-            }
1559
-        }
1560
-    }
1561
-
1562
-
1563
-    /**
1564
-     * create_attendee_from_request_data
1565
-     * uses info from alternate GET or POST data (such as AJAX) to create a new attendee
1566
-     *
1567
-     * @return EE_Attendee
1568
-     * @throws EE_Error
1569
-     * @throws InvalidArgumentException
1570
-     * @throws ReflectionException
1571
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1572
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1573
-     */
1574
-    protected function _create_attendee_from_request_data()
1575
-    {
1576
-        // get State ID
1577
-        $STA_ID = ! empty($_REQUEST['state']) ? sanitize_text_field($_REQUEST['state']) : '';
1578
-        if (! empty($STA_ID)) {
1579
-            // can we get state object from name ?
1580
-            EE_Registry::instance()->load_model('State');
1581
-            $state  = EEM_State::instance()->get_col(array(array('STA_name' => $STA_ID), 'limit' => 1), 'STA_ID');
1582
-            $STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID;
1583
-        }
1584
-        // get Country ISO
1585
-        $CNT_ISO = ! empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';
1586
-        if (! empty($CNT_ISO)) {
1587
-            // can we get country object from name ?
1588
-            EE_Registry::instance()->load_model('Country');
1589
-            $country = EEM_Country::instance()->get_col(
1590
-                array(array('CNT_name' => $CNT_ISO), 'limit' => 1),
1591
-                'CNT_ISO'
1592
-            );
1593
-            $CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO;
1594
-        }
1595
-        // grab attendee data
1596
-        $attendee_data = array(
1597
-            'ATT_fname'    => ! empty($_REQUEST['first_name']) ? sanitize_text_field($_REQUEST['first_name']) : '',
1598
-            'ATT_lname'    => ! empty($_REQUEST['last_name']) ? sanitize_text_field($_REQUEST['last_name']) : '',
1599
-            'ATT_email'    => ! empty($_REQUEST['email']) ? sanitize_email($_REQUEST['email']) : '',
1600
-            'ATT_address'  => ! empty($_REQUEST['address']) ? sanitize_text_field($_REQUEST['address']) : '',
1601
-            'ATT_address2' => ! empty($_REQUEST['address2']) ? sanitize_text_field($_REQUEST['address2']) : '',
1602
-            'ATT_city'     => ! empty($_REQUEST['city']) ? sanitize_text_field($_REQUEST['city']) : '',
1603
-            'STA_ID'       => $STA_ID,
1604
-            'CNT_ISO'      => $CNT_ISO,
1605
-            'ATT_zip'      => ! empty($_REQUEST['zip']) ? sanitize_text_field($_REQUEST['zip']) : '',
1606
-            'ATT_phone'    => ! empty($_REQUEST['phone']) ? sanitize_text_field($_REQUEST['phone']) : '',
1607
-        );
1608
-        // validate the email address since it is the most important piece of info
1609
-        if (empty($attendee_data['ATT_email']) || $attendee_data['ATT_email'] !== $_REQUEST['email']) {
1610
-            EE_Error::add_error(
1611
-                esc_html__('An invalid email address was submitted.', 'event_espresso'),
1612
-                __FILE__,
1613
-                __FUNCTION__,
1614
-                __LINE__
1615
-            );
1616
-        }
1617
-        // does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1618
-        // AND email address
1619
-        if (! empty($attendee_data['ATT_fname'])
1620
-            && ! empty($attendee_data['ATT_lname'])
1621
-            && ! empty($attendee_data['ATT_email'])
1622
-        ) {
1623
-            $existing_attendee = EE_Registry::instance()->LIB->EEM_Attendee->find_existing_attendee(
1624
-                array(
1625
-                    'ATT_fname' => $attendee_data['ATT_fname'],
1626
-                    'ATT_lname' => $attendee_data['ATT_lname'],
1627
-                    'ATT_email' => $attendee_data['ATT_email'],
1628
-                )
1629
-            );
1630
-            if ($existing_attendee instanceof EE_Attendee) {
1631
-                return $existing_attendee;
1632
-            }
1633
-        }
1634
-        // no existing attendee? kk let's create a new one
1635
-        // kinda lame, but we need a first and last name to create an attendee, so use the email address if those
1636
-        // don't exist
1637
-        $attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname'])
1638
-            ? $attendee_data['ATT_fname']
1639
-            : $attendee_data['ATT_email'];
1640
-        $attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname'])
1641
-            ? $attendee_data['ATT_lname']
1642
-            : $attendee_data['ATT_email'];
1643
-        return EE_Attendee::new_instance($attendee_data);
1644
-    }
1645
-
1646
-
1647
-
1648
-    /********************************************************************************************************/
1649
-    /****************************************  PROCESS REG STEP  *****************************************/
1650
-    /********************************************************************************************************/
1651
-    /**
1652
-     * process_reg_step
1653
-     *
1654
-     * @return bool
1655
-     * @throws EE_Error
1656
-     * @throws InvalidArgumentException
1657
-     * @throws ReflectionException
1658
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1659
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1660
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1661
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
1662
-     */
1663
-    public function process_reg_step()
1664
-    {
1665
-        // how have they chosen to pay?
1666
-        $this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free()
1667
-            ? 'no_payment_required'
1668
-            : $this->_get_selected_method_of_payment(true);
1669
-        // choose your own adventure based on method_of_payment
1670
-        switch ($this->checkout->selected_method_of_payment) {
1671
-
1672
-            case 'events_sold_out' :
1673
-                $this->checkout->redirect     = true;
1674
-                $this->checkout->redirect_url = $this->checkout->cancel_page_url;
1675
-                $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1676
-                // mark this reg step as completed
1677
-                $this->set_completed();
1678
-                return false;
1679
-                break;
1680
-
1681
-            case 'payments_closed' :
1682
-                if (apply_filters(
1683
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__payments_closed__display_success',
1684
-                    false
1685
-                )) {
1686
-                    EE_Error::add_success(
1687
-                        esc_html__('no payment required at this time.', 'event_espresso'),
1688
-                        __FILE__,
1689
-                        __FUNCTION__,
1690
-                        __LINE__
1691
-                    );
1692
-                }
1693
-                // mark this reg step as completed
1694
-                $this->set_completed();
1695
-                return true;
1696
-                break;
1697
-
1698
-            case 'no_payment_required' :
1699
-                if (apply_filters(
1700
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success',
1701
-                    false
1702
-                )) {
1703
-                    EE_Error::add_success(
1704
-                        esc_html__('no payment required.', 'event_espresso'),
1705
-                        __FILE__,
1706
-                        __FUNCTION__,
1707
-                        __LINE__
1708
-                    );
1709
-                }
1710
-                // mark this reg step as completed
1711
-                $this->set_completed();
1712
-                return true;
1713
-                break;
1714
-
1715
-            default:
1716
-                $registrations         = EE_Registry::instance()->SSN->checkout()->transaction->registrations(
1717
-                    EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
1718
-                );
1719
-                $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
1720
-                    $registrations,
1721
-                    EE_Registry::instance()->SSN->checkout()->revisit
1722
-                );
1723
-                // calculate difference between the two arrays
1724
-                $registrations = array_diff($registrations, $ejected_registrations);
1725
-                if (empty($registrations)) {
1726
-                    $this->_redirect_because_event_sold_out();
1727
-                    return false;
1728
-                }
1729
-                $payment_successful = $this->_process_payment();
1730
-                if ($payment_successful) {
1731
-                    $this->checkout->continue_reg = true;
1732
-                    $this->_maybe_set_completed($this->checkout->payment_method);
1733
-                } else {
1734
-                    $this->checkout->continue_reg = false;
1735
-                }
1736
-                return $payment_successful;
1737
-        }
1738
-    }
1739
-
1740
-
1741
-    /**
1742
-     * _redirect_because_event_sold_out
1743
-     *
1744
-     * @access protected
1745
-     * @return void
1746
-     */
1747
-    protected function _redirect_because_event_sold_out()
1748
-    {
1749
-        $this->checkout->continue_reg = false;
1750
-        // set redirect URL
1751
-        $this->checkout->redirect_url = add_query_arg(
1752
-            array('e_reg_url_link' => $this->checkout->reg_url_link),
1753
-            $this->checkout->current_step->reg_step_url()
1754
-        );
1755
-        $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1756
-    }
1757
-
1758
-
1759
-    /**
1760
-     * _maybe_set_completed
1761
-     *
1762
-     * @access protected
1763
-     * @param \EE_Payment_Method $payment_method
1764
-     * @return void
1765
-     * @throws \EE_Error
1766
-     */
1767
-    protected function _maybe_set_completed(EE_Payment_Method $payment_method)
1768
-    {
1769
-        switch ($payment_method->type_obj()->payment_occurs()) {
1770
-            case EE_PMT_Base::offsite :
1771
-                break;
1772
-            case EE_PMT_Base::onsite :
1773
-            case EE_PMT_Base::offline :
1774
-                // mark this reg step as completed
1775
-                $this->set_completed();
1776
-                break;
1777
-        }
1778
-    }
1779
-
1780
-
1781
-    /**
1782
-     *    update_reg_step
1783
-     *    this is the final step after a user  revisits the site to retry a payment
1784
-     *
1785
-     * @return bool
1786
-     * @throws EE_Error
1787
-     * @throws InvalidArgumentException
1788
-     * @throws ReflectionException
1789
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1790
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1791
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1792
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
1793
-     */
1794
-    public function update_reg_step()
1795
-    {
1796
-        $success = true;
1797
-        // if payment required
1798
-        if ($this->checkout->transaction->total() > 0) {
1799
-            do_action(
1800
-                'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway',
1801
-                $this->checkout->transaction
1802
-            );
1803
-            // attempt payment via payment method
1804
-            $success = $this->process_reg_step();
1805
-        }
1806
-        if ($success && ! $this->checkout->redirect) {
1807
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn(
1808
-                $this->checkout->transaction->ID()
1809
-            );
1810
-            // set return URL
1811
-            $this->checkout->redirect_url = add_query_arg(
1812
-                array('e_reg_url_link' => $this->checkout->reg_url_link),
1813
-                $this->checkout->thank_you_page_url
1814
-            );
1815
-        }
1816
-        return $success;
1817
-    }
1818
-
1819
-
1820
-    /**
1821
-     *    _process_payment
1822
-     *
1823
-     * @access private
1824
-     * @return bool
1825
-     * @throws EE_Error
1826
-     * @throws InvalidArgumentException
1827
-     * @throws ReflectionException
1828
-     * @throws RuntimeException
1829
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1830
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1831
-     */
1832
-    private function _process_payment()
1833
-    {
1834
-        // basically confirm that the event hasn't sold out since they hit the page
1835
-        if (! $this->_last_second_ticket_verifications()) {
1836
-            return false;
1837
-        }
1838
-        // ya gotta make a choice man
1839
-        if (empty($this->checkout->selected_method_of_payment)) {
1840
-            $this->checkout->json_response->set_plz_select_method_of_payment(
1841
-                esc_html__('Please select a method of payment before proceeding.', 'event_espresso')
1842
-            );
1843
-            return false;
1844
-        }
1845
-        // get EE_Payment_Method object
1846
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1847
-            return false;
1848
-        }
1849
-        // setup billing form
1850
-        if ($this->checkout->payment_method->is_on_site()) {
1851
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1852
-                $this->checkout->payment_method
1853
-            );
1854
-            // bad billing form ?
1855
-            if (! $this->_billing_form_is_valid()) {
1856
-                return false;
1857
-            }
1858
-        }
1859
-        // ensure primary registrant has been fully processed
1860
-        if (! $this->_setup_primary_registrant_prior_to_payment()) {
1861
-            return false;
1862
-        }
1863
-        // if session is close to expiring (under 10 minutes by default)
1864
-        if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) {
1865
-            // add some time to session expiration so that payment can be completed
1866
-            EE_Registry::instance()->SSN->extend_expiration();
1867
-        }
1868
-        /** @type EE_Transaction_Processor $transaction_processor */
1869
-        //$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1870
-        // in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations
1871
-        // for events with a default reg status of Approved
1872
-        // $transaction_processor->toggle_registration_statuses_for_default_approved_events(
1873
-        //      $this->checkout->transaction, $this->checkout->reg_cache_where_params
1874
-        // );
1875
-        // attempt payment
1876
-        $payment = $this->_attempt_payment($this->checkout->payment_method);
1877
-        // process results
1878
-        $payment = $this->_validate_payment($payment);
1879
-        $payment = $this->_post_payment_processing($payment);
1880
-        // verify payment
1881
-        if ($payment instanceof EE_Payment) {
1882
-            // store that for later
1883
-            $this->checkout->payment = $payment;
1884
-            // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned
1885
-            $this->checkout->transaction->toggle_failed_transaction_status();
1886
-            $payment_status = $payment->status();
1887
-            if (
1888
-                $payment_status === EEM_Payment::status_id_approved
1889
-                || $payment_status === EEM_Payment::status_id_pending
1890
-            ) {
1891
-                return true;
1892
-            } else {
1893
-                return false;
1894
-            }
1895
-        } else if ($payment === true) {
1896
-            // please note that offline payment methods will NOT make a payment,
1897
-            // but instead just mark themselves as the PMD_ID on the transaction, and return true
1898
-            $this->checkout->payment = $payment;
1899
-            return true;
1900
-        }
1901
-        // where's my money?
1902
-        return false;
1903
-    }
1904
-
1905
-
1906
-    /**
1907
-     * _last_second_ticket_verifications
1908
-     *
1909
-     * @access public
1910
-     * @return bool
1911
-     * @throws EE_Error
1912
-     */
1913
-    protected function _last_second_ticket_verifications()
1914
-    {
1915
-        // don't bother re-validating if not a return visit
1916
-        if (! $this->checkout->revisit) {
1917
-            return true;
1918
-        }
1919
-        $registrations = $this->checkout->transaction->registrations();
1920
-        if (empty($registrations)) {
1921
-            return false;
1922
-        }
1923
-        foreach ($registrations as $registration) {
1924
-            if ($registration instanceof EE_Registration) {
1925
-                $event = $registration->event_obj();
1926
-                if ($event instanceof EE_Event && $event->is_sold_out(true)) {
1927
-                    EE_Error::add_error(
1928
-                        apply_filters(
1929
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg',
1930
-                            sprintf(
1931
-                                esc_html__(
1932
-                                    'It appears that the %1$s event that you were about to make a payment for has sold out since you first registered and/or arrived at this page. Please refresh the page and try again. If you have already made a partial payment towards this event, please contact the event administrator for a refund.',
1933
-                                    'event_espresso'
1934
-                                ),
1935
-                                $event->name()
1936
-                            )
1937
-                        ),
1938
-                        __FILE__,
1939
-                        __FUNCTION__,
1940
-                        __LINE__
1941
-                    );
1942
-                    return false;
1943
-                }
1944
-            }
1945
-        }
1946
-        return true;
1947
-    }
1948
-
1949
-
1950
-    /**
1951
-     * redirect_form
1952
-     *
1953
-     * @access public
1954
-     * @return bool
1955
-     * @throws EE_Error
1956
-     * @throws InvalidArgumentException
1957
-     * @throws ReflectionException
1958
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1959
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1960
-     */
1961
-    public function redirect_form()
1962
-    {
1963
-        $payment_method_billing_info = $this->_payment_method_billing_info(
1964
-            $this->_get_payment_method_for_selected_method_of_payment()
1965
-        );
1966
-        $html                        = $payment_method_billing_info->get_html();
1967
-        $html                        .= $this->checkout->redirect_form;
1968
-        EE_Registry::instance()->REQ->add_output($html);
1969
-        return true;
1970
-    }
1971
-
1972
-
1973
-    /**
1974
-     * _billing_form_is_valid
1975
-     *
1976
-     * @access private
1977
-     * @return bool
1978
-     * @throws \EE_Error
1979
-     */
1980
-    private function _billing_form_is_valid()
1981
-    {
1982
-        if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1983
-            return true;
1984
-        }
1985
-        if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
1986
-            if ($this->checkout->billing_form->was_submitted()) {
1987
-                $this->checkout->billing_form->receive_form_submission();
1988
-                if ($this->checkout->billing_form->is_valid()) {
1989
-                    return true;
1990
-                }
1991
-                $validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated();
1992
-                $error_strings     = array();
1993
-                foreach ($validation_errors as $validation_error) {
1994
-                    if ($validation_error instanceof EE_Validation_Error) {
1995
-                        $form_section = $validation_error->get_form_section();
1996
-                        if ($form_section instanceof EE_Form_Input_Base) {
1997
-                            $label = $form_section->html_label_text();
1998
-                        } elseif ($form_section instanceof EE_Form_Section_Base) {
1999
-                            $label = $form_section->name();
2000
-                        } else {
2001
-                            $label = esc_html__('Validation Error', 'event_espresso');
2002
-                        }
2003
-                        $error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage());
2004
-                    }
2005
-                }
2006
-                EE_Error::add_error(
2007
-                    sprintf(
2008
-                        esc_html__(
2009
-                            'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s',
2010
-                            'event_espresso'
2011
-                        ),
2012
-                        '<br/>',
2013
-                        implode('<br/>', $error_strings)
2014
-                    ),
2015
-                    __FILE__,
2016
-                    __FUNCTION__,
2017
-                    __LINE__
2018
-                );
2019
-            } else {
2020
-                EE_Error::add_error(
2021
-                    esc_html__(
2022
-                        'The billing form was not submitted or something prevented it\'s submission.',
2023
-                        'event_espresso'
2024
-                    ),
2025
-                    __FILE__,
2026
-                    __FUNCTION__,
2027
-                    __LINE__
2028
-                );
2029
-            }
2030
-        } else {
2031
-            EE_Error::add_error(
2032
-                esc_html__('The submitted billing form is invalid possibly due to a technical reason.', 'event_espresso'),
2033
-                __FILE__,
2034
-                __FUNCTION__,
2035
-                __LINE__
2036
-            );
2037
-        }
2038
-        return false;
2039
-    }
2040
-
2041
-
2042
-    /**
2043
-     * _setup_primary_registrant_prior_to_payment
2044
-     * ensures that the primary registrant has a valid attendee object created with the critical details populated
2045
-     * (first & last name & email) and that both the transaction object and primary registration object have been saved
2046
-     * plz note that any other registrations will NOT be saved at this point (because they may not have any details
2047
-     * yet)
2048
-     *
2049
-     * @access private
2050
-     * @return bool
2051
-     * @throws EE_Error
2052
-     * @throws InvalidArgumentException
2053
-     * @throws ReflectionException
2054
-     * @throws RuntimeException
2055
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2056
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2057
-     */
2058
-    private function _setup_primary_registrant_prior_to_payment()
2059
-    {
2060
-        // check if transaction has a primary registrant and that it has a related Attendee object
2061
-        // if not, then we need to at least gather some primary registrant data before attempting payment
2062
-        if (
2063
-            $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
2064
-            && ! $this->checkout->transaction_has_primary_registrant()
2065
-            && ! $this->_capture_primary_registration_data_from_billing_form()
2066
-        ) {
2067
-            return false;
2068
-        }
2069
-        // because saving an object clears it's cache, we need to do the chevy shuffle
2070
-        // grab the primary_registration object
2071
-        $primary_registration = $this->checkout->transaction->primary_registration();
2072
-        // at this point we'll consider a TXN to not have been failed
2073
-        $this->checkout->transaction->toggle_failed_transaction_status();
2074
-        // save the TXN ( which clears cached copy of primary_registration)
2075
-        $this->checkout->transaction->save();
2076
-        // grab TXN ID and save it to the primary_registration
2077
-        $primary_registration->set_transaction_id($this->checkout->transaction->ID());
2078
-        // save what we have so far
2079
-        $primary_registration->save();
2080
-        return true;
2081
-    }
2082
-
2083
-
2084
-    /**
2085
-     * _capture_primary_registration_data_from_billing_form
2086
-     *
2087
-     * @access private
2088
-     * @return bool
2089
-     * @throws EE_Error
2090
-     * @throws InvalidArgumentException
2091
-     * @throws ReflectionException
2092
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2093
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2094
-     */
2095
-    private function _capture_primary_registration_data_from_billing_form()
2096
-    {
2097
-        // convert billing form data into an attendee
2098
-        $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data();
2099
-        if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2100
-            EE_Error::add_error(
2101
-                sprintf(
2102
-                    esc_html__(
2103
-                        'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.',
2104
-                        'event_espresso'
2105
-                    ),
2106
-                    '<br/>',
2107
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2108
-                ),
2109
-                __FILE__,
2110
-                __FUNCTION__,
2111
-                __LINE__
2112
-            );
2113
-            return false;
2114
-        }
2115
-        $primary_registration = $this->checkout->transaction->primary_registration();
2116
-        if (! $primary_registration instanceof EE_Registration) {
2117
-            EE_Error::add_error(
2118
-                sprintf(
2119
-                    esc_html__(
2120
-                        'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2121
-                        'event_espresso'
2122
-                    ),
2123
-                    '<br/>',
2124
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2125
-                ),
2126
-                __FILE__,
2127
-                __FUNCTION__,
2128
-                __LINE__
2129
-            );
2130
-            return false;
2131
-        }
2132
-        if (! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee')
2133
-              instanceof
2134
-              EE_Attendee
2135
-        ) {
2136
-            EE_Error::add_error(
2137
-                sprintf(
2138
-                    esc_html__(
2139
-                        'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.',
2140
-                        'event_espresso'
2141
-                    ),
2142
-                    '<br/>',
2143
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2144
-                ),
2145
-                __FILE__,
2146
-                __FUNCTION__,
2147
-                __LINE__
2148
-            );
2149
-            return false;
2150
-        }
2151
-        /** @type EE_Registration_Processor $registration_processor */
2152
-        $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
2153
-        // at this point, we should have enough details about the registrant to consider the registration NOT incomplete
2154
-        $registration_processor->toggle_incomplete_registration_status_to_default($primary_registration);
2155
-        return true;
2156
-    }
2157
-
2158
-
2159
-    /**
2160
-     * _get_payment_method_for_selected_method_of_payment
2161
-     * retrieves a valid payment method
2162
-     *
2163
-     * @access public
2164
-     * @return EE_Payment_Method
2165
-     * @throws EE_Error
2166
-     * @throws InvalidArgumentException
2167
-     * @throws ReflectionException
2168
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2169
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2170
-     */
2171
-    private function _get_payment_method_for_selected_method_of_payment()
2172
-    {
2173
-        if ($this->checkout->selected_method_of_payment === 'events_sold_out') {
2174
-            $this->_redirect_because_event_sold_out();
2175
-            return null;
2176
-        }
2177
-        // get EE_Payment_Method object
2178
-        if (isset($this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment])) {
2179
-            $payment_method = $this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment];
2180
-        } else {
2181
-            // load EEM_Payment_Method
2182
-            EE_Registry::instance()->load_model('Payment_Method');
2183
-            /** @type EEM_Payment_Method $EEM_Payment_Method */
2184
-            $EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
2185
-            $payment_method     = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2186
-        }
2187
-        // verify $payment_method
2188
-        if (! $payment_method instanceof EE_Payment_Method) {
2189
-            // not a payment
2190
-            EE_Error::add_error(
2191
-                sprintf(
2192
-                    esc_html__(
2193
-                        'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2194
-                        'event_espresso'
2195
-                    ),
2196
-                    '<br/>',
2197
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2198
-                ),
2199
-                __FILE__,
2200
-                __FUNCTION__,
2201
-                __LINE__
2202
-            );
2203
-            return null;
2204
-        }
2205
-        // and verify it has a valid Payment_Method Type object
2206
-        if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2207
-            // not a payment
2208
-            EE_Error::add_error(
2209
-                sprintf(
2210
-                    esc_html__(
2211
-                        'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2212
-                        'event_espresso'
2213
-                    ),
2214
-                    '<br/>',
2215
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2216
-                ),
2217
-                __FILE__,
2218
-                __FUNCTION__,
2219
-                __LINE__
2220
-            );
2221
-            return null;
2222
-        }
2223
-        return $payment_method;
2224
-    }
2225
-
2226
-
2227
-    /**
2228
-     *    _attempt_payment
2229
-     *
2230
-     * @access    private
2231
-     * @type    EE_Payment_Method $payment_method
2232
-     * @return mixed EE_Payment | boolean
2233
-     * @throws EE_Error
2234
-     * @throws InvalidArgumentException
2235
-     * @throws ReflectionException
2236
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2237
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2238
-     */
2239
-    private function _attempt_payment(EE_Payment_Method $payment_method)
2240
-    {
2241
-        $payment = null;
2242
-        $this->checkout->transaction->save();
2243
-        $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2244
-        if (! $payment_processor instanceof EE_Payment_Processor) {
2245
-            return false;
2246
-        }
2247
-        try {
2248
-            $payment_processor->set_revisit($this->checkout->revisit);
2249
-            // generate payment object
2250
-            $payment = $payment_processor->process_payment(
2251
-                $payment_method,
2252
-                $this->checkout->transaction,
2253
-                $this->checkout->amount_owing,
2254
-                $this->checkout->billing_form,
2255
-                $this->_get_return_url($payment_method),
2256
-                'CART',
2257
-                $this->checkout->admin_request,
2258
-                true,
2259
-                $this->reg_step_url()
2260
-            );
2261
-        } catch (Exception $e) {
2262
-            $this->_handle_payment_processor_exception($e);
2263
-        }
2264
-        return $payment;
2265
-    }
2266
-
2267
-
2268
-    /**
2269
-     * _handle_payment_processor_exception
2270
-     *
2271
-     * @access protected
2272
-     * @param \Exception $e
2273
-     * @return void
2274
-     * @throws EE_Error
2275
-     * @throws InvalidArgumentException
2276
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2277
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2278
-     */
2279
-    protected function _handle_payment_processor_exception(Exception $e)
2280
-    {
2281
-        EE_Error::add_error(
2282
-            sprintf(
2283
-                esc_html__(
2284
-                    'The payment could not br processed due to a technical issue.%1$sPlease try again or contact %2$s for assistance.||The following Exception was thrown in %4$s on line %5$s:%1$s%3$s',
2285
-                    'event_espresso'
2286
-                ),
2287
-                '<br/>',
2288
-                EE_Registry::instance()->CFG->organization->get_pretty('email'),
2289
-                $e->getMessage(),
2290
-                $e->getFile(),
2291
-                $e->getLine()
2292
-            ),
2293
-            __FILE__,
2294
-            __FUNCTION__,
2295
-            __LINE__
2296
-        );
2297
-    }
2298
-
2299
-
2300
-    /**
2301
-     * _get_return_url
2302
-     *
2303
-     * @access protected
2304
-     * @param \EE_Payment_Method $payment_method
2305
-     * @return string
2306
-     * @throws \EE_Error
2307
-     */
2308
-    protected function _get_return_url(EE_Payment_Method $payment_method)
2309
-    {
2310
-        $return_url = '';
2311
-        switch ($payment_method->type_obj()->payment_occurs()) {
2312
-            case EE_PMT_Base::offsite :
2313
-                $return_url = add_query_arg(
2314
-                    array(
2315
-                        'action'                     => 'process_gateway_response',
2316
-                        'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2317
-                        'spco_txn'                   => $this->checkout->transaction->ID(),
2318
-                    ),
2319
-                    $this->reg_step_url()
2320
-                );
2321
-                break;
2322
-            case EE_PMT_Base::onsite :
2323
-            case EE_PMT_Base::offline :
2324
-                $return_url = $this->checkout->next_step->reg_step_url();
2325
-                break;
2326
-        }
2327
-        return $return_url;
2328
-    }
2329
-
2330
-
2331
-    /**
2332
-     * _validate_payment
2333
-     *
2334
-     * @access private
2335
-     * @param EE_Payment $payment
2336
-     * @return EE_Payment|FALSE
2337
-     * @throws EE_Error
2338
-     * @throws InvalidArgumentException
2339
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2340
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2341
-     */
2342
-    private function _validate_payment($payment = null)
2343
-    {
2344
-        if ($this->checkout->payment_method->is_off_line()) {
2345
-            return true;
2346
-        }
2347
-        // verify payment object
2348
-        if (! $payment instanceof EE_Payment) {
2349
-            // not a payment
2350
-            EE_Error::add_error(
2351
-                sprintf(
2352
-                    esc_html__(
2353
-                        'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.',
2354
-                        'event_espresso'
2355
-                    ),
2356
-                    '<br/>',
2357
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2358
-                ),
2359
-                __FILE__,
2360
-                __FUNCTION__,
2361
-                __LINE__
2362
-            );
2363
-            return false;
2364
-        }
2365
-        return $payment;
2366
-    }
2367
-
2368
-
2369
-    /**
2370
-     * _post_payment_processing
2371
-     *
2372
-     * @access private
2373
-     * @param EE_Payment|bool $payment
2374
-     * @return bool
2375
-     * @throws EE_Error
2376
-     * @throws InvalidArgumentException
2377
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2378
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2379
-     */
2380
-    private function _post_payment_processing($payment = null)
2381
-    {
2382
-        // Off-Line payment?
2383
-        if ($payment === true) {
2384
-            //$this->_setup_redirect_for_next_step();
2385
-            return true;
2386
-            // On-Site payment?
2387
-        } else if ($this->checkout->payment_method->is_on_site()) {
2388
-            if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2389
-                //$this->_setup_redirect_for_next_step();
2390
-                $this->checkout->continue_reg = false;
2391
-            }
2392
-            // Off-Site payment?
2393
-        } else if ($this->checkout->payment_method->is_off_site()) {
2394
-            // if a payment object was made and it specifies a redirect url, then we'll setup that redirect info
2395
-            if ($payment instanceof EE_Payment && $payment->redirect_url()) {
2396
-                do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()');
2397
-                $this->checkout->redirect      = true;
2398
-                $this->checkout->redirect_form = $payment->redirect_form();
2399
-                $this->checkout->redirect_url  = $this->reg_step_url('redirect_form');
2400
-                // set JSON response
2401
-                $this->checkout->json_response->set_redirect_form($this->checkout->redirect_form);
2402
-                // and lastly, let's bump the payment status to pending
2403
-                $payment->set_status(EEM_Payment::status_id_pending);
2404
-                $payment->save();
2405
-            } else {
2406
-                // not a payment
2407
-                $this->checkout->continue_reg = false;
2408
-                EE_Error::add_error(
2409
-                    sprintf(
2410
-                        esc_html__(
2411
-                            'It appears the Off Site Payment Method was not configured properly.%sPlease try again or contact %s for assistance.',
2412
-                            'event_espresso'
2413
-                        ),
2414
-                        '<br/>',
2415
-                        EE_Registry::instance()->CFG->organization->get_pretty('email')
2416
-                    ),
2417
-                    __FILE__,
2418
-                    __FUNCTION__,
2419
-                    __LINE__
2420
-                );
2421
-            }
2422
-        } else {
2423
-            // ummm ya... not Off-Line, not On-Site, not off-Site ????
2424
-            $this->checkout->continue_reg = false;
2425
-            return false;
2426
-        }
2427
-        return $payment;
2428
-    }
2429
-
2430
-
2431
-    /**
2432
-     *    _process_payment_status
2433
-     *
2434
-     * @access private
2435
-     * @type    EE_Payment $payment
2436
-     * @param string       $payment_occurs
2437
-     * @return bool
2438
-     * @throws EE_Error
2439
-     * @throws InvalidArgumentException
2440
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2441
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2442
-     */
2443
-    private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline)
2444
-    {
2445
-        // off-line payment? carry on
2446
-        if ($payment_occurs === EE_PMT_Base::offline) {
2447
-            return true;
2448
-        }
2449
-        // verify payment validity
2450
-        if ($payment instanceof EE_Payment) {
2451
-            do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()');
2452
-            $msg = $payment->gateway_response();
2453
-            // check results
2454
-            switch ($payment->status()) {
2455
-                // good payment
2456
-                case EEM_Payment::status_id_approved :
2457
-                    EE_Error::add_success(
2458
-                        esc_html__('Your payment was processed successfully.', 'event_espresso'),
2459
-                        __FILE__,
2460
-                        __FUNCTION__,
2461
-                        __LINE__
2462
-                    );
2463
-                    return true;
2464
-                    break;
2465
-                // slow payment
2466
-                case EEM_Payment::status_id_pending :
2467
-                    if (empty($msg)) {
2468
-                        $msg = esc_html__(
2469
-                            'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.',
2470
-                            'event_espresso'
2471
-                        );
2472
-                    }
2473
-                    EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
2474
-                    return true;
2475
-                    break;
2476
-                // don't wanna payment
2477
-                case EEM_Payment::status_id_cancelled :
2478
-                    if (empty($msg)) {
2479
-                        $msg = _n(
2480
-                            'Payment cancelled. Please try again.',
2481
-                            'Payment cancelled. Please try again or select another method of payment.',
2482
-                            count($this->checkout->available_payment_methods),
2483
-                            'event_espresso'
2484
-                        );
2485
-                    }
2486
-                    EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2487
-                    return false;
2488
-                    break;
2489
-                // not enough payment
2490
-                case EEM_Payment::status_id_declined :
2491
-                    if (empty($msg)) {
2492
-                        $msg = _n(
2493
-                            'We\'re sorry but your payment was declined. Please try again.',
2494
-                            'We\'re sorry but your payment was declined. Please try again or select another method of payment.',
2495
-                            count($this->checkout->available_payment_methods),
2496
-                            'event_espresso'
2497
-                        );
2498
-                    }
2499
-                    EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2500
-                    return false;
2501
-                    break;
2502
-                // bad payment
2503
-                case EEM_Payment::status_id_failed :
2504
-                    if (! empty($msg)) {
2505
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2506
-                        return false;
2507
-                    }
2508
-                    // default to error below
2509
-                    break;
2510
-            }
2511
-        }
2512
-        // off-site payment gateway responses are too unreliable, so let's just assume that
2513
-        // the payment processing is just running slower than the registrant's request
2514
-        if ($payment_occurs === EE_PMT_Base::offsite) {
2515
-            return true;
2516
-        }
2517
-        EE_Error::add_error(
2518
-            sprintf(
2519
-                esc_html__(
2520
-                    'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.',
2521
-                    'event_espresso'
2522
-                ),
2523
-                '<br/>',
2524
-                EE_Registry::instance()->CFG->organization->get_pretty('email')
2525
-            ),
2526
-            __FILE__,
2527
-            __FUNCTION__,
2528
-            __LINE__
2529
-        );
2530
-        return false;
2531
-    }
2532
-
2533
-
2534
-
2535
-
2536
-
2537
-
2538
-    /********************************************************************************************************/
2539
-    /**********************************  PROCESS GATEWAY RESPONSE  **********************************/
2540
-    /********************************************************************************************************/
2541
-    /**
2542
-     * process_gateway_response
2543
-     * this is the return point for Off-Site Payment Methods
2544
-     * It will attempt to "handle the IPN" if it appears that this has not already occurred,
2545
-     * otherwise, it will load up the last payment made for the TXN.
2546
-     * If the payment retrieved looks good, it will then either:
2547
-     *    complete the current step and allow advancement to the next reg step
2548
-     *        or present the payment options again
2549
-     *
2550
-     * @access private
2551
-     * @return EE_Payment|FALSE
2552
-     * @throws EE_Error
2553
-     * @throws InvalidArgumentException
2554
-     * @throws ReflectionException
2555
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2556
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2557
-     * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2558
-     */
2559
-    public function process_gateway_response()
2560
-    {
2561
-        $payment = null;
2562
-        // how have they chosen to pay?
2563
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2564
-        // get EE_Payment_Method object
2565
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2566
-            $this->checkout->continue_reg = false;
2567
-            return false;
2568
-        }
2569
-        if (! $this->checkout->payment_method->is_off_site()) {
2570
-            return false;
2571
-        }
2572
-        $this->_validate_offsite_return();
2573
-        // DEBUG LOG
2574
-        //$this->checkout->log(
2575
-        //	__CLASS__, __FUNCTION__, __LINE__,
2576
-        //	array(
2577
-        //		'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2578
-        //		'payment_method' => $this->checkout->payment_method,
2579
-        //	),
2580
-        //	true
2581
-        //);
2582
-        // verify TXN
2583
-        if ($this->checkout->transaction instanceof EE_Transaction) {
2584
-            $gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2585
-            if (! $gateway instanceof EE_Offsite_Gateway) {
2586
-                $this->checkout->continue_reg = false;
2587
-                return false;
2588
-            }
2589
-            $payment = $this->_process_off_site_payment($gateway);
2590
-            $payment = $this->_process_cancelled_payments($payment);
2591
-            $payment = $this->_validate_payment($payment);
2592
-            // if payment was not declined by the payment gateway or cancelled by the registrant
2593
-            if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) {
2594
-                //$this->_setup_redirect_for_next_step();
2595
-                // store that for later
2596
-                $this->checkout->payment = $payment;
2597
-                // mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2598
-                // because we will complete this step during the IPN processing then
2599
-                if ($gateway instanceof EE_Offsite_Gateway && ! $this->handle_IPN_in_this_request()) {
2600
-                    $this->set_completed();
2601
-                }
2602
-                return true;
2603
-            }
2604
-        }
2605
-        // DEBUG LOG
2606
-        //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__,
2607
-        //	array( 'payment' => $payment )
2608
-        //);
2609
-        $this->checkout->continue_reg = false;
2610
-        return false;
2611
-    }
2612
-
2613
-
2614
-    /**
2615
-     * _validate_return
2616
-     *
2617
-     * @access private
2618
-     * @return void
2619
-     * @throws EE_Error
2620
-     * @throws InvalidArgumentException
2621
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2622
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2623
-     * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2624
-     */
2625
-    private function _validate_offsite_return()
2626
-    {
2627
-        $TXN_ID = (int)EE_Registry::instance()->REQ->get('spco_txn', 0);
2628
-        if ($TXN_ID !== $this->checkout->transaction->ID()) {
2629
-            // Houston... we might have a problem
2630
-            $invalid_TXN = false;
2631
-            // first gather some info
2632
-            $valid_TXN          = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2633
-            $primary_registrant = $valid_TXN instanceof EE_Transaction
2634
-                ? $valid_TXN->primary_registration()
2635
-                : null;
2636
-            // let's start by retrieving the cart for this TXN
2637
-            $cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction);
2638
-            if ($cart instanceof EE_Cart) {
2639
-                // verify that the current cart has tickets
2640
-                $tickets = $cart->get_tickets();
2641
-                if (empty($tickets)) {
2642
-                    $invalid_TXN = true;
2643
-                }
2644
-            } else {
2645
-                $invalid_TXN = true;
2646
-            }
2647
-            $valid_TXN_SID = $primary_registrant instanceof EE_Registration
2648
-                ? $primary_registrant->session_ID()
2649
-                : null;
2650
-            // validate current Session ID and compare against valid TXN session ID
2651
-            if (
2652
-                $invalid_TXN // if this is already true, then skip other checks
2653
-                || EE_Session::instance()->id() === null
2654
-                || (
2655
-                    // WARNING !!!
2656
-                    // this could be PayPal sending back duplicate requests (ya they do that)
2657
-                    // or it **could** mean someone is simply registering AGAIN after having just done so
2658
-                    // so now we need to determine if this current TXN looks valid or not
2659
-                    // and whether this reg step has even been started ?
2660
-                    EE_Session::instance()->id() === $valid_TXN_SID
2661
-                    // really? you're half way through this reg step, but you never started it ?
2662
-                    && $this->checkout->transaction->reg_step_completed($this->slug()) === false
2663
-                )
2664
-            ) {
2665
-                $invalid_TXN = true;
2666
-            }
2667
-            if ($invalid_TXN) {
2668
-                // is the valid TXN completed ?
2669
-                if ($valid_TXN instanceof EE_Transaction) {
2670
-                    // has this step even been started ?
2671
-                    $reg_step_completed = $valid_TXN->reg_step_completed($this->slug());
2672
-                    if ($reg_step_completed !== false && $reg_step_completed !== true) {
2673
-                        // so it **looks** like this is a double request from PayPal
2674
-                        // so let's try to pick up where we left off
2675
-                        $this->checkout->transaction = $valid_TXN;
2676
-                        $this->checkout->refresh_all_entities(true);
2677
-                        return;
2678
-                    }
2679
-                }
2680
-                // you appear to be lost?
2681
-                $this->_redirect_wayward_request($primary_registrant);
2682
-            }
2683
-        }
2684
-    }
2685
-
2686
-
2687
-    /**
2688
-     * _redirect_wayward_request
2689
-     *
2690
-     * @access private
2691
-     * @param \EE_Registration|null $primary_registrant
2692
-     * @return bool
2693
-     * @throws EE_Error
2694
-     * @throws InvalidArgumentException
2695
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2696
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2697
-     */
2698
-    private function _redirect_wayward_request(EE_Registration $primary_registrant)
2699
-    {
2700
-        if (! $primary_registrant instanceof EE_Registration) {
2701
-            // try redirecting based on the current TXN
2702
-            $primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2703
-                ? $this->checkout->transaction->primary_registration()
2704
-                : null;
2705
-        }
2706
-        if (! $primary_registrant instanceof EE_Registration) {
2707
-            EE_Error::add_error(
2708
-                sprintf(
2709
-                    esc_html__(
2710
-                        'Invalid information was received from the Off-Site Payment Processor and your Transaction details could not be retrieved from the database.%1$sPlease try again or contact %2$s for assistance.',
2711
-                        'event_espresso'
2712
-                    ),
2713
-                    '<br/>',
2714
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2715
-                ),
2716
-                __FILE__,
2717
-                __FUNCTION__,
2718
-                __LINE__
2719
-            );
2720
-            return false;
2721
-        }
2722
-        // make sure transaction is not locked
2723
-        $this->checkout->transaction->unlock();
2724
-        wp_safe_redirect(
2725
-            add_query_arg(
2726
-                array(
2727
-                    'e_reg_url_link' => $primary_registrant->reg_url_link(),
2728
-                ),
2729
-                $this->checkout->thank_you_page_url
2730
-            )
2731
-        );
2732
-        exit();
2733
-    }
2734
-
2735
-
2736
-    /**
2737
-     * _process_off_site_payment
2738
-     *
2739
-     * @access private
2740
-     * @param \EE_Offsite_Gateway $gateway
2741
-     * @return EE_Payment
2742
-     * @throws EE_Error
2743
-     * @throws InvalidArgumentException
2744
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2745
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2746
-     */
2747
-    private function _process_off_site_payment(EE_Offsite_Gateway $gateway)
2748
-    {
2749
-        try {
2750
-            $request_data = \EE_Registry::instance()->REQ->params();
2751
-            // if gateway uses_separate_IPN_request, then we don't have to process the IPN manually
2752
-            $this->set_handle_IPN_in_this_request(
2753
-                $gateway->handle_IPN_in_this_request($request_data, false)
2754
-            );
2755
-            if ($this->handle_IPN_in_this_request()) {
2756
-                // get payment details and process results
2757
-                /** @type EE_Payment_Processor $payment_processor */
2758
-                $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2759
-                $payment           = $payment_processor->process_ipn(
2760
-                    $request_data,
2761
-                    $this->checkout->transaction,
2762
-                    $this->checkout->payment_method,
2763
-                    true,
2764
-                    false
2765
-                );
2766
-                //$payment_source = 'process_ipn';
2767
-            } else {
2768
-                $payment = $this->checkout->transaction->last_payment();
2769
-                //$payment_source = 'last_payment';
2770
-            }
2771
-        } catch (Exception $e) {
2772
-            // let's just eat the exception and try to move on using any previously set payment info
2773
-            $payment = $this->checkout->transaction->last_payment();
2774
-            //$payment_source = 'last_payment after Exception';
2775
-            // but if we STILL don't have a payment object
2776
-            if (! $payment instanceof EE_Payment) {
2777
-                // then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2778
-                $this->_handle_payment_processor_exception($e);
2779
-            }
2780
-        }
2781
-        // DEBUG LOG
2782
-        //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__,
2783
-        //	array(
2784
-        //		'process_ipn_payment' => $payment,
2785
-        //		'payment_source'      => $payment_source,
2786
-        //	)
2787
-        //);
2788
-        return $payment;
2789
-    }
2790
-
2791
-
2792
-    /**
2793
-     * _process_cancelled_payments
2794
-     * just makes sure that the payment status gets updated correctly
2795
-     * so tha tan error isn't generated during payment validation
2796
-     *
2797
-     * @access private
2798
-     * @param EE_Payment $payment
2799
-     * @return EE_Payment | FALSE
2800
-     * @throws \EE_Error
2801
-     */
2802
-    private function _process_cancelled_payments($payment = null)
2803
-    {
2804
-        if (
2805
-            $payment instanceof EE_Payment
2806
-            && isset($_REQUEST['ee_cancel_payment'])
2807
-            && $payment->status() === EEM_Payment::status_id_failed
2808
-        ) {
2809
-            $payment->set_status(EEM_Payment::status_id_cancelled);
2810
-        }
2811
-        return $payment;
2812
-    }
2813
-
2814
-
2815
-    /**
2816
-     *    get_transaction_details_for_gateways
2817
-     *
2818
-     * @access    public
2819
-     * @return int
2820
-     * @throws EE_Error
2821
-     * @throws InvalidArgumentException
2822
-     * @throws ReflectionException
2823
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2824
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2825
-     */
2826
-    public function get_transaction_details_for_gateways()
2827
-    {
2828
-        $txn_details = array();
2829
-        // ya gotta make a choice man
2830
-        if (empty($this->checkout->selected_method_of_payment)) {
2831
-            $txn_details = array(
2832
-                'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'),
2833
-            );
2834
-        }
2835
-        // get EE_Payment_Method object
2836
-        if (
2837
-            empty($txn_details)
2838
-            &&
2839
-            ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()
2840
-        ) {
2841
-            $txn_details = array(
2842
-                'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2843
-                'error'                      => esc_html__(
2844
-                    'A valid Payment Method could not be determined.',
2845
-                    'event_espresso'
2846
-                ),
2847
-            );
2848
-        }
2849
-        if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) {
2850
-            $return_url  = $this->_get_return_url($this->checkout->payment_method);
2851
-            $txn_details = array(
2852
-                'TXN_ID'         => $this->checkout->transaction->ID(),
2853
-                'TXN_timestamp'  => $this->checkout->transaction->datetime(),
2854
-                'TXN_total'      => $this->checkout->transaction->total(),
2855
-                'TXN_paid'       => $this->checkout->transaction->paid(),
2856
-                'TXN_reg_steps'  => $this->checkout->transaction->reg_steps(),
2857
-                'STS_ID'         => $this->checkout->transaction->status_ID(),
2858
-                'PMD_ID'         => $this->checkout->transaction->payment_method_ID(),
2859
-                'payment_amount' => $this->checkout->amount_owing,
2860
-                'return_url'     => $return_url,
2861
-                'cancel_url'     => add_query_arg(array('ee_cancel_payment' => true), $return_url),
2862
-                'notify_url'     => EE_Config::instance()->core->txn_page_url(
2863
-                    array(
2864
-                        'e_reg_url_link'    => $this->checkout->transaction->primary_registration()->reg_url_link(),
2865
-                        'ee_payment_method' => $this->checkout->payment_method->slug(),
2866
-                    )
2867
-                ),
2868
-            );
2869
-        }
2870
-        echo wp_json_encode($txn_details);
2871
-        exit();
2872
-    }
2873
-
2874
-
2875
-    /**
2876
-     *    __sleep
2877
-     * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
2878
-     * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
2879
-     * reg form, because if needed, it will be regenerated anyways
2880
-     *
2881
-     * @return array
2882
-     */
2883
-    public function __sleep()
2884
-    {
2885
-        // remove the reg form and the checkout
2886
-        return array_diff(array_keys(get_object_vars($this)), array('reg_form', 'checkout', 'line_item_display'));
2887
-    }
18
+	/**
19
+	 * @access protected
20
+	 * @var EE_Line_Item_Display $Line_Item_Display
21
+	 */
22
+	protected $line_item_display;
23
+
24
+	/**
25
+	 * @access protected
26
+	 * @var boolean $handle_IPN_in_this_request
27
+	 */
28
+	protected $handle_IPN_in_this_request = false;
29
+
30
+
31
+	/**
32
+	 *    set_hooks - for hooking into EE Core, other modules, etc
33
+	 *
34
+	 * @access    public
35
+	 * @return    void
36
+	 */
37
+	public static function set_hooks()
38
+	{
39
+		add_filter(
40
+			'FHEE__SPCO__EE_Line_Item_Filter_Collection',
41
+			array('EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters')
42
+		);
43
+		add_action(
44
+			'wp_ajax_switch_spco_billing_form',
45
+			array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
46
+		);
47
+		add_action(
48
+			'wp_ajax_nopriv_switch_spco_billing_form',
49
+			array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
50
+		);
51
+		add_action('wp_ajax_save_payer_details', array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details'));
52
+		add_action(
53
+			'wp_ajax_nopriv_save_payer_details',
54
+			array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details')
55
+		);
56
+		add_action(
57
+			'wp_ajax_get_transaction_details_for_gateways',
58
+			array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
59
+		);
60
+		add_action(
61
+			'wp_ajax_nopriv_get_transaction_details_for_gateways',
62
+			array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
63
+		);
64
+		add_filter(
65
+			'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
66
+			array('EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'),
67
+			10,
68
+			1
69
+		);
70
+	}
71
+
72
+
73
+	/**
74
+	 *    ajax switch_spco_billing_form
75
+	 *
76
+	 * @throws \EE_Error
77
+	 */
78
+	public static function switch_spco_billing_form()
79
+	{
80
+		EED_Single_Page_Checkout::process_ajax_request('switch_payment_method');
81
+	}
82
+
83
+
84
+	/**
85
+	 *    ajax save_payer_details
86
+	 *
87
+	 * @throws \EE_Error
88
+	 */
89
+	public static function save_payer_details()
90
+	{
91
+		EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax');
92
+	}
93
+
94
+
95
+	/**
96
+	 *    ajax get_transaction_details
97
+	 *
98
+	 * @throws \EE_Error
99
+	 */
100
+	public static function get_transaction_details()
101
+	{
102
+		EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
103
+	}
104
+
105
+
106
+	/**
107
+	 * bypass_recaptcha_for_load_payment_method
108
+	 *
109
+	 * @access public
110
+	 * @return array
111
+	 * @throws InvalidArgumentException
112
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
113
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
114
+	 */
115
+	public static function bypass_recaptcha_for_load_payment_method()
116
+	{
117
+		return array(
118
+			'EESID'  => EE_Registry::instance()->SSN->id(),
119
+			'step'   => 'payment_options',
120
+			'action' => 'spco_billing_form',
121
+		);
122
+	}
123
+
124
+
125
+	/**
126
+	 *    class constructor
127
+	 *
128
+	 * @access    public
129
+	 * @param    EE_Checkout $checkout
130
+	 */
131
+	public function __construct(EE_Checkout $checkout)
132
+	{
133
+		$this->_slug     = 'payment_options';
134
+		$this->_name     = esc_html__('Payment Options', 'event_espresso');
135
+		$this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'payment_options_main.template.php';
136
+		$this->checkout  = $checkout;
137
+		$this->_reset_success_message();
138
+		$this->set_instructions(
139
+			esc_html__(
140
+				'Please select a method of payment and provide any necessary billing information before proceeding.',
141
+				'event_espresso'
142
+			)
143
+		);
144
+	}
145
+
146
+
147
+	/**
148
+	 * @return null
149
+	 */
150
+	public function line_item_display()
151
+	{
152
+		return $this->line_item_display;
153
+	}
154
+
155
+
156
+	/**
157
+	 * @param null $line_item_display
158
+	 */
159
+	public function set_line_item_display($line_item_display)
160
+	{
161
+		$this->line_item_display = $line_item_display;
162
+	}
163
+
164
+
165
+	/**
166
+	 * @return boolean
167
+	 */
168
+	public function handle_IPN_in_this_request()
169
+	{
170
+		return $this->handle_IPN_in_this_request;
171
+	}
172
+
173
+
174
+	/**
175
+	 * @param boolean $handle_IPN_in_this_request
176
+	 */
177
+	public function set_handle_IPN_in_this_request($handle_IPN_in_this_request)
178
+	{
179
+		$this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN);
180
+	}
181
+
182
+
183
+	/**
184
+	 * translate_js_strings
185
+	 *
186
+	 * @return void
187
+	 */
188
+	public function translate_js_strings()
189
+	{
190
+		EE_Registry::$i18n_js_strings['no_payment_method']      = esc_html__(
191
+			'Please select a method of payment in order to continue.',
192
+			'event_espresso'
193
+		);
194
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__(
195
+			'A valid method of payment could not be determined. Please refresh the page and try again.',
196
+			'event_espresso'
197
+		);
198
+		EE_Registry::$i18n_js_strings['forwarding_to_offsite']  = esc_html__(
199
+			'Forwarding to Secure Payment Provider.',
200
+			'event_espresso'
201
+		);
202
+	}
203
+
204
+
205
+	/**
206
+	 * enqueue_styles_and_scripts
207
+	 *
208
+	 * @return void
209
+	 * @throws EE_Error
210
+	 * @throws InvalidArgumentException
211
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
212
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
213
+	 */
214
+	public function enqueue_styles_and_scripts()
215
+	{
216
+		$transaction = $this->checkout->transaction;
217
+		//if the transaction isn't set or nothing is owed on it, don't enqueue any JS
218
+		if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
219
+			return;
220
+		}
221
+		foreach (EEM_Payment_Method::instance()->get_all_for_transaction($transaction, EEM_Payment_Method::scope_cart) as $payment_method) {
222
+			$type_obj = $payment_method->type_obj();
223
+			if ($type_obj instanceof EE_PMT_Base) {
224
+				$billing_form = $type_obj->generate_new_billing_form($transaction);
225
+				if ($billing_form instanceof EE_Form_Section_Proper) {
226
+					$billing_form->enqueue_js();
227
+				}
228
+			}
229
+		}
230
+	}
231
+
232
+
233
+	/**
234
+	 * initialize_reg_step
235
+	 *
236
+	 * @return bool
237
+	 * @throws EE_Error
238
+	 * @throws InvalidArgumentException
239
+	 * @throws ReflectionException
240
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
241
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
242
+	 */
243
+	public function initialize_reg_step()
244
+	{
245
+		// TODO: if /when we implement donations, then this will need overriding
246
+		if (// don't need payment options for:
247
+			// 	registrations made via the admin
248
+			// 	completed transactions
249
+			// 	overpaid transactions
250
+			// 	$ 0.00 transactions (no payment required)
251
+			! $this->checkout->payment_required()
252
+			// but do NOT remove if current action being called belongs to this reg step
253
+			&& ! is_callable(array($this, $this->checkout->action))
254
+			&& ! $this->completed()
255
+		) {
256
+			// and if so, then we no longer need the Payment Options step
257
+			if ($this->is_current_step()) {
258
+				$this->checkout->generate_reg_form = false;
259
+			}
260
+			$this->checkout->remove_reg_step($this->_slug);
261
+			// DEBUG LOG
262
+			//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
263
+			return false;
264
+		}
265
+		// load EEM_Payment_Method
266
+		EE_Registry::instance()->load_model('Payment_Method');
267
+		// get all active payment methods
268
+		$this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
269
+			$this->checkout->transaction,
270
+			EEM_Payment_Method::scope_cart
271
+		);
272
+		return true;
273
+	}
274
+
275
+
276
+	/**
277
+	 * @return EE_Form_Section_Proper
278
+	 * @throws EE_Error
279
+	 * @throws InvalidArgumentException
280
+	 * @throws ReflectionException
281
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
282
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
283
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
284
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
285
+	 */
286
+	public function generate_reg_form()
287
+	{
288
+		// reset in case someone changes their mind
289
+		$this->_reset_selected_method_of_payment();
290
+		// set some defaults
291
+		$this->checkout->selected_method_of_payment = 'payments_closed';
292
+		$registrations_requiring_payment            = array();
293
+		$registrations_for_free_events              = array();
294
+		$registrations_requiring_pre_approval       = array();
295
+		$sold_out_events                            = array();
296
+		$insufficient_spaces_available              = array();
297
+		$no_payment_required                        = true;
298
+		// loop thru registrations to gather info
299
+		$registrations         = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
300
+		$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
301
+			$registrations,
302
+			$this->checkout->revisit
303
+		);
304
+		foreach ($registrations as $REG_ID => $registration) {
305
+			/** @var $registration EE_Registration */
306
+			// has this registration lost it's space ?
307
+			if (isset($ejected_registrations[ $REG_ID ])) {
308
+				if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
309
+					$sold_out_events[ $registration->event()->ID() ] = $registration->event();
310
+				} else {
311
+					$insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
312
+				}
313
+				continue;
314
+			}
315
+			// event requires admin approval
316
+			if ($registration->status_ID() === EEM_Registration::status_id_not_approved) {
317
+				// add event to list of events with pre-approval reg status
318
+				$registrations_requiring_pre_approval[$REG_ID] = $registration;
319
+				do_action(
320
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
321
+					$registration->event(),
322
+					$this
323
+				);
324
+				continue;
325
+			}
326
+			if ($this->checkout->revisit
327
+				&& $registration->status_ID() !== EEM_Registration::status_id_approved
328
+				&& (
329
+					$registration->event()->is_sold_out()
330
+					|| $registration->event()->is_sold_out(true)
331
+				)
332
+			) {
333
+				// add event to list of events that are sold out
334
+				$sold_out_events[$registration->event()->ID()] = $registration->event();
335
+				do_action(
336
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
337
+					$registration->event(),
338
+					$this
339
+				);
340
+				continue;
341
+			}
342
+			// are they allowed to pay now and is there monies owing?
343
+			if ($registration->owes_monies_and_can_pay()) {
344
+				$registrations_requiring_payment[$REG_ID] = $registration;
345
+				do_action(
346
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
347
+					$registration->event(),
348
+					$this
349
+				);
350
+			} elseif (! $this->checkout->revisit
351
+				&& $registration->status_ID() !== EEM_Registration::status_id_not_approved
352
+				&& $registration->ticket()->is_free()
353
+			) {
354
+				$registrations_for_free_events[$registration->event()->ID()] = $registration;
355
+			}
356
+		}
357
+		$subsections = array();
358
+		// now decide which template to load
359
+		if (! empty($sold_out_events)) {
360
+			$subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
361
+		}
362
+		if (! empty($insufficient_spaces_available)) {
363
+			$subsections['insufficient_space'] = $this->_insufficient_spaces_available(
364
+				$insufficient_spaces_available
365
+			);
366
+		}
367
+		if (! empty($registrations_requiring_pre_approval)) {
368
+			$subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
369
+				$registrations_requiring_pre_approval
370
+			);
371
+		}
372
+		if (! empty($registrations_for_free_events)) {
373
+			$subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
374
+		}
375
+		if (! empty($registrations_requiring_payment)) {
376
+			if ($this->checkout->amount_owing > 0) {
377
+				// autoload Line_Item_Display classes
378
+				EEH_Autoloader::register_line_item_filter_autoloaders();
379
+				$line_item_filter_processor = new EE_Line_Item_Filter_Processor(
380
+					apply_filters(
381
+						'FHEE__SPCO__EE_Line_Item_Filter_Collection',
382
+						new EE_Line_Item_Filter_Collection()
383
+					),
384
+					$this->checkout->cart->get_grand_total()
385
+				);
386
+				/** @var EE_Line_Item $filtered_line_item_tree */
387
+				$filtered_line_item_tree = $line_item_filter_processor->process();
388
+				EEH_Autoloader::register_line_item_display_autoloaders();
389
+				$this->set_line_item_display(new EE_Line_Item_Display('spco'));
390
+				$subsections['payment_options'] = $this->_display_payment_options(
391
+					$this->line_item_display->display_line_item(
392
+						$filtered_line_item_tree,
393
+						array('registrations' => $registrations)
394
+					)
395
+				);
396
+				$this->checkout->amount_owing   = $filtered_line_item_tree->total();
397
+				$this->_apply_registration_payments_to_amount_owing($registrations);
398
+			}
399
+			$no_payment_required = false;
400
+		} else {
401
+			$this->_hide_reg_step_submit_button_if_revisit();
402
+		}
403
+		$this->_save_selected_method_of_payment();
404
+
405
+		$subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs();
406
+		$subsections['extra_hidden_inputs']   = $this->_extra_hidden_inputs($no_payment_required);
407
+
408
+		return new EE_Form_Section_Proper(
409
+			array(
410
+				'name'            => $this->reg_form_name(),
411
+				'html_id'         => $this->reg_form_name(),
412
+				'subsections'     => $subsections,
413
+				'layout_strategy' => new EE_No_Layout(),
414
+			)
415
+		);
416
+	}
417
+
418
+
419
+	/**
420
+	 * add line item filters required for this reg step
421
+	 * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
422
+	 *        add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options',
423
+	 *        'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the
424
+	 *        payment options reg step, can apply these filters via the following: apply_filters(
425
+	 *        'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing
426
+	 *        filter collection by passing that instead of instantiating a new collection
427
+	 *
428
+	 * @param \EE_Line_Item_Filter_Collection $line_item_filter_collection
429
+	 * @return EE_Line_Item_Filter_Collection
430
+	 * @throws EE_Error
431
+	 * @throws InvalidArgumentException
432
+	 * @throws ReflectionException
433
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
434
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
435
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
436
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
437
+	 */
438
+	public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
439
+	{
440
+		if (! EE_Registry::instance()->SSN instanceof EE_Session) {
441
+			return $line_item_filter_collection;
442
+		}
443
+		if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
444
+			return $line_item_filter_collection;
445
+		}
446
+		if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
447
+			return $line_item_filter_collection;
448
+		}
449
+		$line_item_filter_collection->add(
450
+			new EE_Billable_Line_Item_Filter(
451
+				EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations(
452
+					EE_Registry::instance()->SSN->checkout()->transaction->registrations(
453
+						EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
454
+					)
455
+				)
456
+			)
457
+		);
458
+		$line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
459
+		return $line_item_filter_collection;
460
+	}
461
+
462
+
463
+	/**
464
+	 * remove_ejected_registrations
465
+	 * if a registrant has lost their potential space at an event due to lack of payment,
466
+	 * then this method removes them from the list of registrations being paid for during this request
467
+	 *
468
+	 * @param \EE_Registration[] $registrations
469
+	 * @return EE_Registration[]
470
+	 * @throws EE_Error
471
+	 * @throws InvalidArgumentException
472
+	 * @throws ReflectionException
473
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
474
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
475
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
476
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
477
+	 */
478
+	public static function remove_ejected_registrations(array $registrations)
479
+	{
480
+		$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
481
+			$registrations,
482
+			EE_Registry::instance()->SSN->checkout()->revisit
483
+		);
484
+		foreach ($registrations as $REG_ID => $registration) {
485
+			// has this registration lost it's space ?
486
+			if (isset($ejected_registrations[$REG_ID])) {
487
+				unset($registrations[$REG_ID]);
488
+				continue;
489
+			}
490
+		}
491
+		return $registrations;
492
+	}
493
+
494
+
495
+	/**
496
+	 * find_registrations_that_lost_their_space
497
+	 * If a registrant chooses an offline payment method like Invoice,
498
+	 * then no space is reserved for them at the event until they fully pay fo that site
499
+	 * (unless the event's default reg status is set to APPROVED)
500
+	 * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales,
501
+	 * then this method will determine which registrations have lost the ability to complete the reg process.
502
+	 *
503
+	 * @param \EE_Registration[] $registrations
504
+	 * @param bool               $revisit
505
+	 * @return array
506
+	 * @throws EE_Error
507
+	 * @throws InvalidArgumentException
508
+	 * @throws ReflectionException
509
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
510
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
511
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
512
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
513
+	 */
514
+	public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false)
515
+	{
516
+		// registrations per event
517
+		$event_reg_count = array();
518
+		// spaces left per event
519
+		$event_spaces_remaining = array();
520
+		// tickets left sorted by ID
521
+		$tickets_remaining = array();
522
+		// registrations that have lost their space
523
+		$ejected_registrations = array();
524
+		foreach ($registrations as $REG_ID => $registration) {
525
+			if ($registration->status_ID() === EEM_Registration::status_id_approved
526
+				|| apply_filters(
527
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment',
528
+					false,
529
+					$registration,
530
+					$revisit
531
+				)
532
+			) {
533
+				continue;
534
+			}
535
+			$EVT_ID = $registration->event_ID();
536
+			$ticket = $registration->ticket();
537
+			if (! isset($tickets_remaining[$ticket->ID()])) {
538
+				$tickets_remaining[$ticket->ID()] = $ticket->remaining();
539
+			}
540
+			if ($tickets_remaining[$ticket->ID()] > 0) {
541
+				if (! isset($event_reg_count[$EVT_ID])) {
542
+					$event_reg_count[$EVT_ID] = 0;
543
+				}
544
+				$event_reg_count[$EVT_ID]++;
545
+				if (! isset($event_spaces_remaining[$EVT_ID])) {
546
+					$event_spaces_remaining[$EVT_ID] = $registration->event()->spaces_remaining_for_sale();
547
+				}
548
+			}
549
+			if ($revisit
550
+				&& ($tickets_remaining[$ticket->ID()] === 0
551
+					|| $event_reg_count[$EVT_ID] > $event_spaces_remaining[$EVT_ID]
552
+				)
553
+			) {
554
+				$ejected_registrations[$REG_ID] = $registration->event();
555
+				if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) {
556
+					/** @type EE_Registration_Processor $registration_processor */
557
+					$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
558
+					// at this point, we should have enough details about the registrant to consider the registration
559
+					// NOT incomplete
560
+					$registration_processor->manually_update_registration_status(
561
+						$registration,
562
+						EEM_Registration::status_id_wait_list
563
+					);
564
+				}
565
+			}
566
+		}
567
+		return $ejected_registrations;
568
+	}
569
+
570
+
571
+	/**
572
+	 * _hide_reg_step_submit_button
573
+	 * removes the html for the reg step submit button
574
+	 * by replacing it with an empty string via filter callback
575
+	 *
576
+	 * @return void
577
+	 */
578
+	protected function _adjust_registration_status_if_event_old_sold()
579
+	{
580
+	}
581
+
582
+
583
+	/**
584
+	 * _hide_reg_step_submit_button
585
+	 * removes the html for the reg step submit button
586
+	 * by replacing it with an empty string via filter callback
587
+	 *
588
+	 * @return void
589
+	 */
590
+	protected function _hide_reg_step_submit_button_if_revisit()
591
+	{
592
+		if ($this->checkout->revisit) {
593
+			add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string');
594
+		}
595
+	}
596
+
597
+
598
+	/**
599
+	 * sold_out_events
600
+	 * displays notices regarding events that have sold out since hte registrant first signed up
601
+	 *
602
+	 * @param \EE_Event[] $sold_out_events_array
603
+	 * @return \EE_Form_Section_Proper
604
+	 * @throws \EE_Error
605
+	 */
606
+	private function _sold_out_events($sold_out_events_array = array())
607
+	{
608
+		// set some defaults
609
+		$this->checkout->selected_method_of_payment = 'events_sold_out';
610
+		$sold_out_events                            = '';
611
+		foreach ($sold_out_events_array as $sold_out_event) {
612
+			$sold_out_events .= EEH_HTML::li(
613
+				EEH_HTML::span(
614
+					'  ' . $sold_out_event->name(),
615
+					'',
616
+					'dashicons dashicons-marker ee-icon-size-16 pink-text'
617
+				)
618
+			);
619
+		}
620
+		return new EE_Form_Section_Proper(
621
+			array(
622
+				'layout_strategy' => new EE_Template_Layout(
623
+					array(
624
+						'layout_template_file' => SPCO_REG_STEPS_PATH
625
+												  . $this->_slug
626
+												  . DS
627
+												  . 'sold_out_events.template.php',
628
+						'template_args'        => apply_filters(
629
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
630
+							array(
631
+								'sold_out_events'     => $sold_out_events,
632
+								'sold_out_events_msg' => apply_filters(
633
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg',
634
+									sprintf(
635
+										esc_html__(
636
+											'It appears that the event you were about to make a payment for has sold out since you first registered. If you have already made a partial payment towards this event, please contact the event administrator for a refund.%3$s%3$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%2$s',
637
+											'event_espresso'
638
+										),
639
+										'<strong>',
640
+										'</strong>',
641
+										'<br />'
642
+									)
643
+								),
644
+							)
645
+						),
646
+					)
647
+				),
648
+			)
649
+		);
650
+	}
651
+
652
+
653
+	/**
654
+	 * _insufficient_spaces_available
655
+	 * displays notices regarding events that do not have enough remaining spaces
656
+	 * to satisfy the current number of registrations looking to pay
657
+	 *
658
+	 * @param \EE_Event[] $insufficient_spaces_events_array
659
+	 * @return \EE_Form_Section_Proper
660
+	 * @throws \EE_Error
661
+	 */
662
+	private function _insufficient_spaces_available($insufficient_spaces_events_array = array())
663
+	{
664
+		// set some defaults
665
+		$this->checkout->selected_method_of_payment = 'invoice';
666
+		$insufficient_space_events                  = '';
667
+		foreach ($insufficient_spaces_events_array as $event) {
668
+			if ($event instanceof EE_Event) {
669
+				$insufficient_space_events .= EEH_HTML::li(
670
+					EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
671
+				);
672
+			}
673
+		}
674
+		return new EE_Form_Section_Proper(
675
+			array(
676
+				'subsections'     => array(
677
+					'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
678
+					'extra_hidden_inputs'   => $this->_extra_hidden_inputs(),
679
+				),
680
+				'layout_strategy' => new EE_Template_Layout(
681
+					array(
682
+						'layout_template_file' => SPCO_REG_STEPS_PATH
683
+												  . $this->_slug
684
+												  . DS
685
+												  . 'sold_out_events.template.php',
686
+						'template_args'        => apply_filters(
687
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args',
688
+							array(
689
+								'sold_out_events'     => $insufficient_space_events,
690
+								'sold_out_events_msg' => apply_filters(
691
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg',
692
+									esc_html__(
693
+										'It appears that the event you were about to make a payment for has sold additional tickets since you first registered, and there are no longer enough spaces left to accommodate your selections. You may continue to pay and secure the available space(s) remaining, or simply cancel if you no longer wish to purchase. If you have already made a partial payment towards this event, please contact the event administrator for a refund.',
694
+										'event_espresso'
695
+									)
696
+								),
697
+							)
698
+						),
699
+					)
700
+				),
701
+			)
702
+		);
703
+	}
704
+
705
+
706
+	/**
707
+	 * registrations_requiring_pre_approval
708
+	 *
709
+	 * @param array $registrations_requiring_pre_approval
710
+	 * @return EE_Form_Section_Proper
711
+	 * @throws EE_Error
712
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
713
+	 */
714
+	private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = array())
715
+	{
716
+		$events_requiring_pre_approval = '';
717
+		foreach ($registrations_requiring_pre_approval as $registration) {
718
+			if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
719
+				$events_requiring_pre_approval[$registration->event()->ID()] = EEH_HTML::li(
720
+					EEH_HTML::span(
721
+						'',
722
+						'',
723
+						'dashicons dashicons-marker ee-icon-size-16 orange-text'
724
+					)
725
+					. EEH_HTML::span($registration->event()->name(), '', 'orange-text')
726
+				);
727
+			}
728
+		}
729
+		return new EE_Form_Section_Proper(
730
+			array(
731
+				'layout_strategy' => new EE_Template_Layout(
732
+					array(
733
+						'layout_template_file' => SPCO_REG_STEPS_PATH
734
+												  . $this->_slug
735
+												  . DS
736
+												  . 'events_requiring_pre_approval.template.php', // layout_template
737
+						'template_args'        => apply_filters(
738
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
739
+							array(
740
+								'events_requiring_pre_approval'     => implode('', $events_requiring_pre_approval),
741
+								'events_requiring_pre_approval_msg' => apply_filters(
742
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg',
743
+									esc_html__(
744
+										'The following events do not require payment at this time and will not be billed during this transaction. Billing will only occur after the attendee has been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.',
745
+										'event_espresso'
746
+									)
747
+								),
748
+							)
749
+						),
750
+					)
751
+				),
752
+			)
753
+		);
754
+	}
755
+
756
+
757
+	/**
758
+	 * _no_payment_required
759
+	 *
760
+	 * @param \EE_Event[] $registrations_for_free_events
761
+	 * @return \EE_Form_Section_Proper
762
+	 * @throws \EE_Error
763
+	 */
764
+	private function _no_payment_required($registrations_for_free_events = array())
765
+	{
766
+		// set some defaults
767
+		$this->checkout->selected_method_of_payment = 'no_payment_required';
768
+		// generate no_payment_required form
769
+		return new EE_Form_Section_Proper(
770
+			array(
771
+				'layout_strategy' => new EE_Template_Layout(
772
+					array(
773
+						'layout_template_file' => SPCO_REG_STEPS_PATH
774
+												  . $this->_slug
775
+												  . DS
776
+												  . 'no_payment_required.template.php', // layout_template
777
+						'template_args'        => apply_filters(
778
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args',
779
+							array(
780
+								'revisit'                       => $this->checkout->revisit,
781
+								'registrations'                 => array(),
782
+								'ticket_count'                  => array(),
783
+								'registrations_for_free_events' => $registrations_for_free_events,
784
+								'no_payment_required_msg'       => EEH_HTML::p(
785
+									esc_html__('This is a free event, so no billing will occur.', 'event_espresso')
786
+								),
787
+							)
788
+						),
789
+					)
790
+				),
791
+			)
792
+		);
793
+	}
794
+
795
+
796
+	/**
797
+	 * _display_payment_options
798
+	 *
799
+	 * @param string $transaction_details
800
+	 * @return EE_Form_Section_Proper
801
+	 * @throws EE_Error
802
+	 * @throws InvalidArgumentException
803
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
804
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
805
+	 */
806
+	private function _display_payment_options($transaction_details = '')
807
+	{
808
+		// has method_of_payment been set by no-js user?
809
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment();
810
+		// build payment options form
811
+		return apply_filters(
812
+			'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form',
813
+			new EE_Form_Section_Proper(
814
+				array(
815
+					'subsections'     => array(
816
+						'before_payment_options' => apply_filters(
817
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options',
818
+							new EE_Form_Section_Proper(
819
+								array('layout_strategy' => new EE_Div_Per_Section_Layout())
820
+							)
821
+						),
822
+						'payment_options'        => $this->_setup_payment_options(),
823
+						'after_payment_options'  => apply_filters(
824
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options',
825
+							new EE_Form_Section_Proper(
826
+								array('layout_strategy' => new EE_Div_Per_Section_Layout())
827
+							)
828
+						),
829
+					),
830
+					'layout_strategy' => new EE_Template_Layout(
831
+						array(
832
+							'layout_template_file' => $this->_template,
833
+							'template_args'        => apply_filters(
834
+								'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args',
835
+								array(
836
+									'reg_count'                 => $this->line_item_display->total_items(),
837
+									'transaction_details'       => $transaction_details,
838
+									'available_payment_methods' => array(),
839
+								)
840
+							),
841
+						)
842
+					),
843
+				)
844
+			)
845
+		);
846
+	}
847
+
848
+
849
+	/**
850
+	 * _extra_hidden_inputs
851
+	 *
852
+	 * @param bool $no_payment_required
853
+	 * @return \EE_Form_Section_Proper
854
+	 * @throws \EE_Error
855
+	 */
856
+	private function _extra_hidden_inputs($no_payment_required = true)
857
+	{
858
+		return new EE_Form_Section_Proper(
859
+			array(
860
+				'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
861
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
862
+				'subsections'     => array(
863
+					'spco_no_payment_required' => new EE_Hidden_Input(
864
+						array(
865
+							'normalization_strategy' => new EE_Boolean_Normalization(),
866
+							'html_name'              => 'spco_no_payment_required',
867
+							'html_id'                => 'spco-no-payment-required-payment_options',
868
+							'default'                => $no_payment_required,
869
+						)
870
+					),
871
+					'spco_transaction_id'      => new EE_Fixed_Hidden_Input(
872
+						array(
873
+							'normalization_strategy' => new EE_Int_Normalization(),
874
+							'html_name'              => 'spco_transaction_id',
875
+							'html_id'                => 'spco-transaction-id',
876
+							'default'                => $this->checkout->transaction->ID(),
877
+						)
878
+					),
879
+				),
880
+			)
881
+		);
882
+	}
883
+
884
+
885
+	/**
886
+	 *    _apply_registration_payments_to_amount_owing
887
+	 *
888
+	 * @access protected
889
+	 * @param array $registrations
890
+	 * @throws EE_Error
891
+	 */
892
+	protected function _apply_registration_payments_to_amount_owing(array $registrations)
893
+	{
894
+		$payments = array();
895
+		foreach ($registrations as $registration) {
896
+			if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
897
+				$payments += $registration->registration_payments();
898
+			}
899
+		}
900
+		if (! empty($payments)) {
901
+			foreach ($payments as $payment) {
902
+				if ($payment instanceof EE_Registration_Payment) {
903
+					$this->checkout->amount_owing -= $payment->amount();
904
+				}
905
+			}
906
+		}
907
+	}
908
+
909
+
910
+	/**
911
+	 *    _reset_selected_method_of_payment
912
+	 *
913
+	 * @access    private
914
+	 * @param    bool $force_reset
915
+	 * @return void
916
+	 * @throws InvalidArgumentException
917
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
918
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
919
+	 */
920
+	private function _reset_selected_method_of_payment($force_reset = false)
921
+	{
922
+		$reset_payment_method = $force_reset
923
+			? true
924
+			: sanitize_text_field(EE_Registry::instance()->REQ->get('reset_payment_method', false));
925
+		if ($reset_payment_method) {
926
+			$this->checkout->selected_method_of_payment = null;
927
+			$this->checkout->payment_method             = null;
928
+			$this->checkout->billing_form               = null;
929
+			$this->_save_selected_method_of_payment();
930
+		}
931
+	}
932
+
933
+
934
+	/**
935
+	 * _save_selected_method_of_payment
936
+	 * stores the selected_method_of_payment in the session
937
+	 * so that it's available for all subsequent requests including AJAX
938
+	 *
939
+	 * @access        private
940
+	 * @param string $selected_method_of_payment
941
+	 * @return void
942
+	 * @throws InvalidArgumentException
943
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
944
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
945
+	 */
946
+	private function _save_selected_method_of_payment($selected_method_of_payment = '')
947
+	{
948
+		$selected_method_of_payment = ! empty($selected_method_of_payment)
949
+			? $selected_method_of_payment
950
+			: $this->checkout->selected_method_of_payment;
951
+		EE_Registry::instance()->SSN->set_session_data(
952
+			array('selected_method_of_payment' => $selected_method_of_payment)
953
+		);
954
+	}
955
+
956
+
957
+	/**
958
+	 * _setup_payment_options
959
+	 *
960
+	 * @return EE_Form_Section_Proper
961
+	 * @throws EE_Error
962
+	 * @throws InvalidArgumentException
963
+	 * @throws ReflectionException
964
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
965
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
966
+	 */
967
+	public function _setup_payment_options()
968
+	{
969
+		// load payment method classes
970
+		$this->checkout->available_payment_methods = $this->_get_available_payment_methods();
971
+		if (empty($this->checkout->available_payment_methods)) {
972
+			EE_Error::add_error(
973
+				apply_filters(
974
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods',
975
+					sprintf(
976
+						esc_html__(
977
+							'Sorry, you cannot complete your purchase because a payment method is not active.%1$s Please contact %2$s for assistance and provide a description of the problem.',
978
+							'event_espresso'
979
+						),
980
+						'<br>',
981
+						EE_Registry::instance()->CFG->organization->get_pretty('email')
982
+					)
983
+				),
984
+				__FILE__,
985
+				__FUNCTION__,
986
+				__LINE__
987
+			);
988
+		}
989
+		// switch up header depending on number of available payment methods
990
+		$payment_method_header     = count($this->checkout->available_payment_methods) > 1
991
+			? apply_filters(
992
+				'FHEE__registration_page_payment_options__method_of_payment_hdr',
993
+				esc_html__('Please Select Your Method of Payment', 'event_espresso')
994
+			)
995
+			: apply_filters(
996
+				'FHEE__registration_page_payment_options__method_of_payment_hdr',
997
+				esc_html__('Method of Payment', 'event_espresso')
998
+			);
999
+		$available_payment_methods = array(
1000
+			// display the "Payment Method" header
1001
+			'payment_method_header' => new EE_Form_Section_HTML(
1002
+				EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr')
1003
+			),
1004
+		);
1005
+		// the list of actual payment methods ( invoice, paypal, etc ) in a  ( slug => HTML )  format
1006
+		$available_payment_method_options = array();
1007
+		$default_payment_method_option    = array();
1008
+		// additional instructions to be displayed and hidden below payment methods (adding a clearing div to start)
1009
+		$payment_methods_billing_info = array(
1010
+			new EE_Form_Section_HTML(
1011
+				EEH_HTML::div('<br />', '', '', 'clear:both;')
1012
+			),
1013
+		);
1014
+		// loop through payment methods
1015
+		foreach ($this->checkout->available_payment_methods as $payment_method) {
1016
+			if ($payment_method instanceof EE_Payment_Method) {
1017
+				$payment_method_button = EEH_HTML::img(
1018
+					$payment_method->button_url(),
1019
+					$payment_method->name(),
1020
+					'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1021
+					'spco-payment-method-btn-img'
1022
+				);
1023
+				// check if any payment methods are set as default
1024
+				// if payment method is already selected OR nothing is selected and this payment method should be
1025
+				// open_by_default
1026
+				if (($this->checkout->selected_method_of_payment === $payment_method->slug())
1027
+					|| (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1028
+				) {
1029
+					$this->checkout->selected_method_of_payment = $payment_method->slug();
1030
+					$this->_save_selected_method_of_payment();
1031
+					$default_payment_method_option[$payment_method->slug()] = $payment_method_button;
1032
+				} else {
1033
+					$available_payment_method_options[$payment_method->slug()] = $payment_method_button;
1034
+				}
1035
+				$payment_methods_billing_info[$payment_method->slug() . '-info'] = $this->_payment_method_billing_info(
1036
+					$payment_method
1037
+				);
1038
+			}
1039
+		}
1040
+		// prepend available_payment_method_options with default_payment_method_option so that it appears first in list
1041
+		// of PMs
1042
+		$available_payment_method_options = $default_payment_method_option + $available_payment_method_options;
1043
+		// now generate the actual form  inputs
1044
+		$available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1045
+			$available_payment_method_options
1046
+		);
1047
+		$available_payment_methods                              += $payment_methods_billing_info;
1048
+		// build the available payment methods form
1049
+		return new EE_Form_Section_Proper(
1050
+			array(
1051
+				'html_id'         => 'spco-available-methods-of-payment-dv',
1052
+				'subsections'     => $available_payment_methods,
1053
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1054
+			)
1055
+		);
1056
+	}
1057
+
1058
+
1059
+	/**
1060
+	 * _get_available_payment_methods
1061
+	 *
1062
+	 * @return EE_Payment_Method[]
1063
+	 * @throws EE_Error
1064
+	 * @throws InvalidArgumentException
1065
+	 * @throws ReflectionException
1066
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1067
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1068
+	 */
1069
+	protected function _get_available_payment_methods()
1070
+	{
1071
+		if (! empty($this->checkout->available_payment_methods)) {
1072
+			return $this->checkout->available_payment_methods;
1073
+		}
1074
+		$available_payment_methods = array();
1075
+		// load EEM_Payment_Method
1076
+		EE_Registry::instance()->load_model('Payment_Method');
1077
+		/** @type EEM_Payment_Method $EEM_Payment_Method */
1078
+		$EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
1079
+		// get all active payment methods
1080
+		$payment_methods = $EEM_Payment_Method->get_all_for_transaction(
1081
+			$this->checkout->transaction,
1082
+			EEM_Payment_Method::scope_cart
1083
+		);
1084
+		foreach ($payment_methods as $payment_method) {
1085
+			if ($payment_method instanceof EE_Payment_Method) {
1086
+				$available_payment_methods[$payment_method->slug()] = $payment_method;
1087
+			}
1088
+		}
1089
+		return $available_payment_methods;
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 *    _available_payment_method_inputs
1095
+	 *
1096
+	 * @access    private
1097
+	 * @param    array $available_payment_method_options
1098
+	 * @return    \EE_Form_Section_Proper
1099
+	 */
1100
+	private function _available_payment_method_inputs($available_payment_method_options = array())
1101
+	{
1102
+		// generate inputs
1103
+		return new EE_Form_Section_Proper(
1104
+			array(
1105
+				'html_id'         => 'ee-available-payment-method-inputs',
1106
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1107
+				'subsections'     => array(
1108
+					'' => new EE_Radio_Button_Input(
1109
+						$available_payment_method_options,
1110
+						array(
1111
+							'html_name'          => 'selected_method_of_payment',
1112
+							'html_class'         => 'spco-payment-method',
1113
+							'default'            => $this->checkout->selected_method_of_payment,
1114
+							'label_size'         => 11,
1115
+							'enforce_label_size' => true,
1116
+						)
1117
+					),
1118
+				),
1119
+			)
1120
+		);
1121
+	}
1122
+
1123
+
1124
+	/**
1125
+	 *    _payment_method_billing_info
1126
+	 *
1127
+	 * @access    private
1128
+	 * @param    EE_Payment_Method $payment_method
1129
+	 * @return EE_Form_Section_Proper
1130
+	 * @throws EE_Error
1131
+	 * @throws InvalidArgumentException
1132
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1133
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1134
+	 */
1135
+	private function _payment_method_billing_info(EE_Payment_Method $payment_method)
1136
+	{
1137
+		$currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug()
1138
+			? true
1139
+			: false;
1140
+		// generate the billing form for payment method
1141
+		$billing_form                 = $currently_selected
1142
+			? $this->_get_billing_form_for_payment_method($payment_method)
1143
+			: new EE_Form_Section_HTML();
1144
+		$this->checkout->billing_form = $currently_selected
1145
+			? $billing_form
1146
+			: $this->checkout->billing_form;
1147
+		// it's all in the details
1148
+		$info_html = EEH_HTML::h3(
1149
+			esc_html__('Important information regarding your payment', 'event_espresso'),
1150
+			'',
1151
+			'spco-payment-method-hdr'
1152
+		);
1153
+		// add some info regarding the step, either from what's saved in the admin,
1154
+		// or a default string depending on whether the PM has a billing form or not
1155
+		if ($payment_method->description()) {
1156
+			$payment_method_info = $payment_method->description();
1157
+		} elseif ($billing_form instanceof EE_Billing_Info_Form) {
1158
+			$payment_method_info = sprintf(
1159
+				esc_html__(
1160
+					'Please provide the following billing information, then click the "%1$s" button below in order to proceed.',
1161
+					'event_espresso'
1162
+				),
1163
+				$this->submit_button_text()
1164
+			);
1165
+		} else {
1166
+			$payment_method_info = sprintf(
1167
+				esc_html__('Please click the "%1$s" button below in order to proceed.', 'event_espresso'),
1168
+				$this->submit_button_text()
1169
+			);
1170
+		}
1171
+		$info_html .= EEH_HTML::p(
1172
+			apply_filters(
1173
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options___payment_method_billing_info__payment_method_info',
1174
+				$payment_method_info
1175
+			),
1176
+			'',
1177
+			'spco-payment-method-desc ee-attention'
1178
+		);
1179
+		return new EE_Form_Section_Proper(
1180
+			array(
1181
+				'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1182
+				'html_class'      => 'spco-payment-method-info-dv',
1183
+				// only display the selected or default PM
1184
+				'html_style'      => $currently_selected ? '' : 'display:none;',
1185
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1186
+				'subsections'     => array(
1187
+					'info'         => new EE_Form_Section_HTML($info_html),
1188
+					'billing_form' => $currently_selected ? $billing_form : new EE_Form_Section_HTML(),
1189
+				),
1190
+			)
1191
+		);
1192
+	}
1193
+
1194
+
1195
+	/**
1196
+	 * get_billing_form_html_for_payment_method
1197
+	 *
1198
+	 * @access public
1199
+	 * @return string
1200
+	 * @throws EE_Error
1201
+	 * @throws InvalidArgumentException
1202
+	 * @throws ReflectionException
1203
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1204
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1205
+	 */
1206
+	public function get_billing_form_html_for_payment_method()
1207
+	{
1208
+		// how have they chosen to pay?
1209
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1210
+		$this->checkout->payment_method             = $this->_get_payment_method_for_selected_method_of_payment();
1211
+		if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1212
+			return false;
1213
+		}
1214
+		if (apply_filters(
1215
+			'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1216
+			false
1217
+		)) {
1218
+			EE_Error::add_success(
1219
+				apply_filters(
1220
+					'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1221
+					sprintf(
1222
+						esc_html__(
1223
+							'You have selected "%s" as your method of payment. Please note the important payment information below.',
1224
+							'event_espresso'
1225
+						),
1226
+						$this->checkout->payment_method->name()
1227
+					)
1228
+				)
1229
+			);
1230
+		}
1231
+		// now generate billing form for selected method of payment
1232
+		$payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method);
1233
+		// fill form with attendee info if applicable
1234
+		if ($payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form
1235
+			&& $this->checkout->transaction_has_primary_registrant()
1236
+		) {
1237
+			$payment_method_billing_form->populate_from_attendee(
1238
+				$this->checkout->transaction->primary_registration()->attendee()
1239
+			);
1240
+		}
1241
+		// and debug content
1242
+		if ($payment_method_billing_form instanceof EE_Billing_Info_Form
1243
+			&& $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1244
+		) {
1245
+			$payment_method_billing_form =
1246
+				$this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1247
+					$payment_method_billing_form
1248
+				);
1249
+		}
1250
+		$billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper
1251
+			? $payment_method_billing_form->get_html()
1252
+			: '';
1253
+		$this->checkout->json_response->set_return_data(array('payment_method_info' => $billing_info));
1254
+		// localize validation rules for main form
1255
+		$this->checkout->current_step->reg_form->localize_validation_rules();
1256
+		$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1257
+		return true;
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * _get_billing_form_for_payment_method
1263
+	 *
1264
+	 * @access private
1265
+	 * @param EE_Payment_Method $payment_method
1266
+	 * @return EE_Billing_Info_Form|EE_Form_Section_HTML
1267
+	 * @throws EE_Error
1268
+	 * @throws InvalidArgumentException
1269
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1270
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1271
+	 */
1272
+	private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method)
1273
+	{
1274
+		$billing_form = $payment_method->type_obj()->billing_form(
1275
+			$this->checkout->transaction,
1276
+			array('amount_owing' => $this->checkout->amount_owing)
1277
+		);
1278
+		if ($billing_form instanceof EE_Billing_Info_Form) {
1279
+			if (apply_filters(
1280
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1281
+				false
1282
+			)
1283
+				&& EE_Registry::instance()->REQ->is_set('payment_method')
1284
+			) {
1285
+				EE_Error::add_success(
1286
+					apply_filters(
1287
+						'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1288
+						sprintf(
1289
+							esc_html__(
1290
+								'You have selected "%s" as your method of payment. Please note the important payment information below.',
1291
+								'event_espresso'
1292
+							),
1293
+							$payment_method->name()
1294
+						)
1295
+					)
1296
+				);
1297
+			}
1298
+			return apply_filters(
1299
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
1300
+				$billing_form,
1301
+				$payment_method
1302
+			);
1303
+		}
1304
+		// no actual billing form, so return empty HTML form section
1305
+		return new EE_Form_Section_HTML();
1306
+	}
1307
+
1308
+
1309
+	/**
1310
+	 * _get_selected_method_of_payment
1311
+	 *
1312
+	 * @access private
1313
+	 * @param boolean $required whether to throw an error if the "selected_method_of_payment"
1314
+	 *                          is not found in the incoming request
1315
+	 * @param string  $request_param
1316
+	 * @return NULL|string
1317
+	 * @throws EE_Error
1318
+	 * @throws InvalidArgumentException
1319
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1320
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1321
+	 */
1322
+	private function _get_selected_method_of_payment(
1323
+		$required = false,
1324
+		$request_param = 'selected_method_of_payment'
1325
+	) {
1326
+		// is selected_method_of_payment set in the request ?
1327
+		$selected_method_of_payment = EE_Registry::instance()->REQ->get($request_param, false);
1328
+		if ($selected_method_of_payment) {
1329
+			// sanitize it
1330
+			$selected_method_of_payment = is_array($selected_method_of_payment)
1331
+				? array_shift($selected_method_of_payment)
1332
+				: $selected_method_of_payment;
1333
+			$selected_method_of_payment = sanitize_text_field($selected_method_of_payment);
1334
+			// store it in the session so that it's available for all subsequent requests including AJAX
1335
+			$this->_save_selected_method_of_payment($selected_method_of_payment);
1336
+		} else {
1337
+			// or is is set in the session ?
1338
+			$selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data(
1339
+				'selected_method_of_payment'
1340
+			);
1341
+		}
1342
+		// do ya really really gotta have it?
1343
+		if (empty($selected_method_of_payment) && $required) {
1344
+			EE_Error::add_error(
1345
+				sprintf(
1346
+					esc_html__(
1347
+						'The selected method of payment could not be determined.%sPlease ensure that you have selected one before proceeding.%sIf you continue to experience difficulties, then refresh your browser and try again, or contact %s for assistance.',
1348
+						'event_espresso'
1349
+					),
1350
+					'<br/>',
1351
+					'<br/>',
1352
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
1353
+				),
1354
+				__FILE__,
1355
+				__FUNCTION__,
1356
+				__LINE__
1357
+			);
1358
+			return null;
1359
+		}
1360
+		return $selected_method_of_payment;
1361
+	}
1362
+
1363
+
1364
+
1365
+
1366
+
1367
+
1368
+	/********************************************************************************************************/
1369
+	/***********************************  SWITCH PAYMENT METHOD  ************************************/
1370
+	/********************************************************************************************************/
1371
+	/**
1372
+	 * switch_payment_method
1373
+	 *
1374
+	 * @access public
1375
+	 * @return string
1376
+	 * @throws EE_Error
1377
+	 * @throws InvalidArgumentException
1378
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1379
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1380
+	 */
1381
+	public function switch_payment_method()
1382
+	{
1383
+		if (! $this->_verify_payment_method_is_set()) {
1384
+			return false;
1385
+		}
1386
+		if (apply_filters(
1387
+			'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1388
+			false
1389
+		)) {
1390
+			EE_Error::add_success(
1391
+				apply_filters(
1392
+					'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1393
+					sprintf(
1394
+						esc_html__(
1395
+							'You have selected "%s" as your method of payment. Please note the important payment information below.',
1396
+							'event_espresso'
1397
+						),
1398
+						$this->checkout->payment_method->name()
1399
+					)
1400
+				)
1401
+			);
1402
+		}
1403
+		// generate billing form for selected method of payment if it hasn't been done already
1404
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1405
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1406
+				$this->checkout->payment_method
1407
+			);
1408
+		}
1409
+		// fill form with attendee info if applicable
1410
+		if (apply_filters(
1411
+			'FHEE__populate_billing_form_fields_from_attendee',
1412
+			(
1413
+				$this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
1414
+				&& $this->checkout->transaction_has_primary_registrant()
1415
+			),
1416
+			$this->checkout->billing_form,
1417
+			$this->checkout->transaction
1418
+		)
1419
+		) {
1420
+			$this->checkout->billing_form->populate_from_attendee(
1421
+				$this->checkout->transaction->primary_registration()->attendee()
1422
+			);
1423
+		}
1424
+		// and debug content
1425
+		if ($this->checkout->billing_form instanceof EE_Billing_Info_Form
1426
+			&& $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1427
+		) {
1428
+			$this->checkout->billing_form =
1429
+				$this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1430
+					$this->checkout->billing_form
1431
+				);
1432
+		}
1433
+		// get html and validation rules for form
1434
+		if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) {
1435
+			$this->checkout->json_response->set_return_data(
1436
+				array('payment_method_info' => $this->checkout->billing_form->get_html())
1437
+			);
1438
+			// localize validation rules for main form
1439
+			$this->checkout->billing_form->localize_validation_rules(true);
1440
+			$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1441
+		} else {
1442
+			$this->checkout->json_response->set_return_data(array('payment_method_info' => ''));
1443
+		}
1444
+		//prevents advancement to next step
1445
+		$this->checkout->continue_reg = false;
1446
+		return true;
1447
+	}
1448
+
1449
+
1450
+	/**
1451
+	 * _verify_payment_method_is_set
1452
+	 *
1453
+	 * @return bool
1454
+	 * @throws EE_Error
1455
+	 * @throws InvalidArgumentException
1456
+	 * @throws ReflectionException
1457
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1458
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1459
+	 */
1460
+	protected function _verify_payment_method_is_set()
1461
+	{
1462
+		// generate billing form for selected method of payment if it hasn't been done already
1463
+		if (empty($this->checkout->selected_method_of_payment)) {
1464
+			// how have they chosen to pay?
1465
+			$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1466
+		} else {
1467
+			// choose your own adventure based on method_of_payment
1468
+			switch ($this->checkout->selected_method_of_payment) {
1469
+				case 'events_sold_out' :
1470
+					EE_Error::add_attention(
1471
+						apply_filters(
1472
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg',
1473
+							esc_html__(
1474
+								'It appears that the event you were about to make a payment for has sold out since this form first loaded. Please contact the event administrator if you believe this is an error.',
1475
+								'event_espresso'
1476
+							)
1477
+						),
1478
+						__FILE__, __FUNCTION__, __LINE__
1479
+					);
1480
+					return false;
1481
+					break;
1482
+				case 'payments_closed' :
1483
+					EE_Error::add_attention(
1484
+						apply_filters(
1485
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg',
1486
+							esc_html__(
1487
+								'It appears that the event you were about to make a payment for is not accepting payments at this time. Please contact the event administrator if you believe this is an error.',
1488
+								'event_espresso'
1489
+							)
1490
+						),
1491
+						__FILE__, __FUNCTION__, __LINE__
1492
+					);
1493
+					return false;
1494
+					break;
1495
+				case 'no_payment_required' :
1496
+					EE_Error::add_attention(
1497
+						apply_filters(
1498
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg',
1499
+							esc_html__(
1500
+								'It appears that the event you were about to make a payment for does not require payment. Please contact the event administrator if you believe this is an error.',
1501
+								'event_espresso'
1502
+							)
1503
+						),
1504
+						__FILE__, __FUNCTION__, __LINE__
1505
+					);
1506
+					return false;
1507
+					break;
1508
+				default:
1509
+			}
1510
+		}
1511
+		// verify payment method
1512
+		if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1513
+			// get payment method for selected method of payment
1514
+			$this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1515
+		}
1516
+		return $this->checkout->payment_method instanceof EE_Payment_Method ? true : false;
1517
+	}
1518
+
1519
+
1520
+
1521
+	/********************************************************************************************************/
1522
+	/***************************************  SAVE PAYER DETAILS  ****************************************/
1523
+	/********************************************************************************************************/
1524
+	/**
1525
+	 * save_payer_details_via_ajax
1526
+	 *
1527
+	 * @return void
1528
+	 * @throws EE_Error
1529
+	 * @throws InvalidArgumentException
1530
+	 * @throws ReflectionException
1531
+	 * @throws RuntimeException
1532
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1533
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1534
+	 */
1535
+	public function save_payer_details_via_ajax()
1536
+	{
1537
+		if (! $this->_verify_payment_method_is_set()) {
1538
+			return;
1539
+		}
1540
+		// generate billing form for selected method of payment if it hasn't been done already
1541
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1542
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1543
+				$this->checkout->payment_method
1544
+			);
1545
+		}
1546
+		// generate primary attendee from payer info if applicable
1547
+		if (! $this->checkout->transaction_has_primary_registrant()) {
1548
+			$attendee = $this->_create_attendee_from_request_data();
1549
+			if ($attendee instanceof EE_Attendee) {
1550
+				foreach ($this->checkout->transaction->registrations() as $registration) {
1551
+					if ($registration->is_primary_registrant()) {
1552
+						$this->checkout->primary_attendee_obj = $attendee;
1553
+						$registration->_add_relation_to($attendee, 'Attendee');
1554
+						$registration->set_attendee_id($attendee->ID());
1555
+						$registration->update_cache_after_object_save('Attendee', $attendee);
1556
+					}
1557
+				}
1558
+			}
1559
+		}
1560
+	}
1561
+
1562
+
1563
+	/**
1564
+	 * create_attendee_from_request_data
1565
+	 * uses info from alternate GET or POST data (such as AJAX) to create a new attendee
1566
+	 *
1567
+	 * @return EE_Attendee
1568
+	 * @throws EE_Error
1569
+	 * @throws InvalidArgumentException
1570
+	 * @throws ReflectionException
1571
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1572
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1573
+	 */
1574
+	protected function _create_attendee_from_request_data()
1575
+	{
1576
+		// get State ID
1577
+		$STA_ID = ! empty($_REQUEST['state']) ? sanitize_text_field($_REQUEST['state']) : '';
1578
+		if (! empty($STA_ID)) {
1579
+			// can we get state object from name ?
1580
+			EE_Registry::instance()->load_model('State');
1581
+			$state  = EEM_State::instance()->get_col(array(array('STA_name' => $STA_ID), 'limit' => 1), 'STA_ID');
1582
+			$STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID;
1583
+		}
1584
+		// get Country ISO
1585
+		$CNT_ISO = ! empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';
1586
+		if (! empty($CNT_ISO)) {
1587
+			// can we get country object from name ?
1588
+			EE_Registry::instance()->load_model('Country');
1589
+			$country = EEM_Country::instance()->get_col(
1590
+				array(array('CNT_name' => $CNT_ISO), 'limit' => 1),
1591
+				'CNT_ISO'
1592
+			);
1593
+			$CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO;
1594
+		}
1595
+		// grab attendee data
1596
+		$attendee_data = array(
1597
+			'ATT_fname'    => ! empty($_REQUEST['first_name']) ? sanitize_text_field($_REQUEST['first_name']) : '',
1598
+			'ATT_lname'    => ! empty($_REQUEST['last_name']) ? sanitize_text_field($_REQUEST['last_name']) : '',
1599
+			'ATT_email'    => ! empty($_REQUEST['email']) ? sanitize_email($_REQUEST['email']) : '',
1600
+			'ATT_address'  => ! empty($_REQUEST['address']) ? sanitize_text_field($_REQUEST['address']) : '',
1601
+			'ATT_address2' => ! empty($_REQUEST['address2']) ? sanitize_text_field($_REQUEST['address2']) : '',
1602
+			'ATT_city'     => ! empty($_REQUEST['city']) ? sanitize_text_field($_REQUEST['city']) : '',
1603
+			'STA_ID'       => $STA_ID,
1604
+			'CNT_ISO'      => $CNT_ISO,
1605
+			'ATT_zip'      => ! empty($_REQUEST['zip']) ? sanitize_text_field($_REQUEST['zip']) : '',
1606
+			'ATT_phone'    => ! empty($_REQUEST['phone']) ? sanitize_text_field($_REQUEST['phone']) : '',
1607
+		);
1608
+		// validate the email address since it is the most important piece of info
1609
+		if (empty($attendee_data['ATT_email']) || $attendee_data['ATT_email'] !== $_REQUEST['email']) {
1610
+			EE_Error::add_error(
1611
+				esc_html__('An invalid email address was submitted.', 'event_espresso'),
1612
+				__FILE__,
1613
+				__FUNCTION__,
1614
+				__LINE__
1615
+			);
1616
+		}
1617
+		// does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1618
+		// AND email address
1619
+		if (! empty($attendee_data['ATT_fname'])
1620
+			&& ! empty($attendee_data['ATT_lname'])
1621
+			&& ! empty($attendee_data['ATT_email'])
1622
+		) {
1623
+			$existing_attendee = EE_Registry::instance()->LIB->EEM_Attendee->find_existing_attendee(
1624
+				array(
1625
+					'ATT_fname' => $attendee_data['ATT_fname'],
1626
+					'ATT_lname' => $attendee_data['ATT_lname'],
1627
+					'ATT_email' => $attendee_data['ATT_email'],
1628
+				)
1629
+			);
1630
+			if ($existing_attendee instanceof EE_Attendee) {
1631
+				return $existing_attendee;
1632
+			}
1633
+		}
1634
+		// no existing attendee? kk let's create a new one
1635
+		// kinda lame, but we need a first and last name to create an attendee, so use the email address if those
1636
+		// don't exist
1637
+		$attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname'])
1638
+			? $attendee_data['ATT_fname']
1639
+			: $attendee_data['ATT_email'];
1640
+		$attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname'])
1641
+			? $attendee_data['ATT_lname']
1642
+			: $attendee_data['ATT_email'];
1643
+		return EE_Attendee::new_instance($attendee_data);
1644
+	}
1645
+
1646
+
1647
+
1648
+	/********************************************************************************************************/
1649
+	/****************************************  PROCESS REG STEP  *****************************************/
1650
+	/********************************************************************************************************/
1651
+	/**
1652
+	 * process_reg_step
1653
+	 *
1654
+	 * @return bool
1655
+	 * @throws EE_Error
1656
+	 * @throws InvalidArgumentException
1657
+	 * @throws ReflectionException
1658
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1659
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1660
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1661
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
1662
+	 */
1663
+	public function process_reg_step()
1664
+	{
1665
+		// how have they chosen to pay?
1666
+		$this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free()
1667
+			? 'no_payment_required'
1668
+			: $this->_get_selected_method_of_payment(true);
1669
+		// choose your own adventure based on method_of_payment
1670
+		switch ($this->checkout->selected_method_of_payment) {
1671
+
1672
+			case 'events_sold_out' :
1673
+				$this->checkout->redirect     = true;
1674
+				$this->checkout->redirect_url = $this->checkout->cancel_page_url;
1675
+				$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1676
+				// mark this reg step as completed
1677
+				$this->set_completed();
1678
+				return false;
1679
+				break;
1680
+
1681
+			case 'payments_closed' :
1682
+				if (apply_filters(
1683
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__payments_closed__display_success',
1684
+					false
1685
+				)) {
1686
+					EE_Error::add_success(
1687
+						esc_html__('no payment required at this time.', 'event_espresso'),
1688
+						__FILE__,
1689
+						__FUNCTION__,
1690
+						__LINE__
1691
+					);
1692
+				}
1693
+				// mark this reg step as completed
1694
+				$this->set_completed();
1695
+				return true;
1696
+				break;
1697
+
1698
+			case 'no_payment_required' :
1699
+				if (apply_filters(
1700
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success',
1701
+					false
1702
+				)) {
1703
+					EE_Error::add_success(
1704
+						esc_html__('no payment required.', 'event_espresso'),
1705
+						__FILE__,
1706
+						__FUNCTION__,
1707
+						__LINE__
1708
+					);
1709
+				}
1710
+				// mark this reg step as completed
1711
+				$this->set_completed();
1712
+				return true;
1713
+				break;
1714
+
1715
+			default:
1716
+				$registrations         = EE_Registry::instance()->SSN->checkout()->transaction->registrations(
1717
+					EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
1718
+				);
1719
+				$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
1720
+					$registrations,
1721
+					EE_Registry::instance()->SSN->checkout()->revisit
1722
+				);
1723
+				// calculate difference between the two arrays
1724
+				$registrations = array_diff($registrations, $ejected_registrations);
1725
+				if (empty($registrations)) {
1726
+					$this->_redirect_because_event_sold_out();
1727
+					return false;
1728
+				}
1729
+				$payment_successful = $this->_process_payment();
1730
+				if ($payment_successful) {
1731
+					$this->checkout->continue_reg = true;
1732
+					$this->_maybe_set_completed($this->checkout->payment_method);
1733
+				} else {
1734
+					$this->checkout->continue_reg = false;
1735
+				}
1736
+				return $payment_successful;
1737
+		}
1738
+	}
1739
+
1740
+
1741
+	/**
1742
+	 * _redirect_because_event_sold_out
1743
+	 *
1744
+	 * @access protected
1745
+	 * @return void
1746
+	 */
1747
+	protected function _redirect_because_event_sold_out()
1748
+	{
1749
+		$this->checkout->continue_reg = false;
1750
+		// set redirect URL
1751
+		$this->checkout->redirect_url = add_query_arg(
1752
+			array('e_reg_url_link' => $this->checkout->reg_url_link),
1753
+			$this->checkout->current_step->reg_step_url()
1754
+		);
1755
+		$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1756
+	}
1757
+
1758
+
1759
+	/**
1760
+	 * _maybe_set_completed
1761
+	 *
1762
+	 * @access protected
1763
+	 * @param \EE_Payment_Method $payment_method
1764
+	 * @return void
1765
+	 * @throws \EE_Error
1766
+	 */
1767
+	protected function _maybe_set_completed(EE_Payment_Method $payment_method)
1768
+	{
1769
+		switch ($payment_method->type_obj()->payment_occurs()) {
1770
+			case EE_PMT_Base::offsite :
1771
+				break;
1772
+			case EE_PMT_Base::onsite :
1773
+			case EE_PMT_Base::offline :
1774
+				// mark this reg step as completed
1775
+				$this->set_completed();
1776
+				break;
1777
+		}
1778
+	}
1779
+
1780
+
1781
+	/**
1782
+	 *    update_reg_step
1783
+	 *    this is the final step after a user  revisits the site to retry a payment
1784
+	 *
1785
+	 * @return bool
1786
+	 * @throws EE_Error
1787
+	 * @throws InvalidArgumentException
1788
+	 * @throws ReflectionException
1789
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1790
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1791
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1792
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
1793
+	 */
1794
+	public function update_reg_step()
1795
+	{
1796
+		$success = true;
1797
+		// if payment required
1798
+		if ($this->checkout->transaction->total() > 0) {
1799
+			do_action(
1800
+				'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway',
1801
+				$this->checkout->transaction
1802
+			);
1803
+			// attempt payment via payment method
1804
+			$success = $this->process_reg_step();
1805
+		}
1806
+		if ($success && ! $this->checkout->redirect) {
1807
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn(
1808
+				$this->checkout->transaction->ID()
1809
+			);
1810
+			// set return URL
1811
+			$this->checkout->redirect_url = add_query_arg(
1812
+				array('e_reg_url_link' => $this->checkout->reg_url_link),
1813
+				$this->checkout->thank_you_page_url
1814
+			);
1815
+		}
1816
+		return $success;
1817
+	}
1818
+
1819
+
1820
+	/**
1821
+	 *    _process_payment
1822
+	 *
1823
+	 * @access private
1824
+	 * @return bool
1825
+	 * @throws EE_Error
1826
+	 * @throws InvalidArgumentException
1827
+	 * @throws ReflectionException
1828
+	 * @throws RuntimeException
1829
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1830
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1831
+	 */
1832
+	private function _process_payment()
1833
+	{
1834
+		// basically confirm that the event hasn't sold out since they hit the page
1835
+		if (! $this->_last_second_ticket_verifications()) {
1836
+			return false;
1837
+		}
1838
+		// ya gotta make a choice man
1839
+		if (empty($this->checkout->selected_method_of_payment)) {
1840
+			$this->checkout->json_response->set_plz_select_method_of_payment(
1841
+				esc_html__('Please select a method of payment before proceeding.', 'event_espresso')
1842
+			);
1843
+			return false;
1844
+		}
1845
+		// get EE_Payment_Method object
1846
+		if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1847
+			return false;
1848
+		}
1849
+		// setup billing form
1850
+		if ($this->checkout->payment_method->is_on_site()) {
1851
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1852
+				$this->checkout->payment_method
1853
+			);
1854
+			// bad billing form ?
1855
+			if (! $this->_billing_form_is_valid()) {
1856
+				return false;
1857
+			}
1858
+		}
1859
+		// ensure primary registrant has been fully processed
1860
+		if (! $this->_setup_primary_registrant_prior_to_payment()) {
1861
+			return false;
1862
+		}
1863
+		// if session is close to expiring (under 10 minutes by default)
1864
+		if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) {
1865
+			// add some time to session expiration so that payment can be completed
1866
+			EE_Registry::instance()->SSN->extend_expiration();
1867
+		}
1868
+		/** @type EE_Transaction_Processor $transaction_processor */
1869
+		//$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1870
+		// in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations
1871
+		// for events with a default reg status of Approved
1872
+		// $transaction_processor->toggle_registration_statuses_for_default_approved_events(
1873
+		//      $this->checkout->transaction, $this->checkout->reg_cache_where_params
1874
+		// );
1875
+		// attempt payment
1876
+		$payment = $this->_attempt_payment($this->checkout->payment_method);
1877
+		// process results
1878
+		$payment = $this->_validate_payment($payment);
1879
+		$payment = $this->_post_payment_processing($payment);
1880
+		// verify payment
1881
+		if ($payment instanceof EE_Payment) {
1882
+			// store that for later
1883
+			$this->checkout->payment = $payment;
1884
+			// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned
1885
+			$this->checkout->transaction->toggle_failed_transaction_status();
1886
+			$payment_status = $payment->status();
1887
+			if (
1888
+				$payment_status === EEM_Payment::status_id_approved
1889
+				|| $payment_status === EEM_Payment::status_id_pending
1890
+			) {
1891
+				return true;
1892
+			} else {
1893
+				return false;
1894
+			}
1895
+		} else if ($payment === true) {
1896
+			// please note that offline payment methods will NOT make a payment,
1897
+			// but instead just mark themselves as the PMD_ID on the transaction, and return true
1898
+			$this->checkout->payment = $payment;
1899
+			return true;
1900
+		}
1901
+		// where's my money?
1902
+		return false;
1903
+	}
1904
+
1905
+
1906
+	/**
1907
+	 * _last_second_ticket_verifications
1908
+	 *
1909
+	 * @access public
1910
+	 * @return bool
1911
+	 * @throws EE_Error
1912
+	 */
1913
+	protected function _last_second_ticket_verifications()
1914
+	{
1915
+		// don't bother re-validating if not a return visit
1916
+		if (! $this->checkout->revisit) {
1917
+			return true;
1918
+		}
1919
+		$registrations = $this->checkout->transaction->registrations();
1920
+		if (empty($registrations)) {
1921
+			return false;
1922
+		}
1923
+		foreach ($registrations as $registration) {
1924
+			if ($registration instanceof EE_Registration) {
1925
+				$event = $registration->event_obj();
1926
+				if ($event instanceof EE_Event && $event->is_sold_out(true)) {
1927
+					EE_Error::add_error(
1928
+						apply_filters(
1929
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg',
1930
+							sprintf(
1931
+								esc_html__(
1932
+									'It appears that the %1$s event that you were about to make a payment for has sold out since you first registered and/or arrived at this page. Please refresh the page and try again. If you have already made a partial payment towards this event, please contact the event administrator for a refund.',
1933
+									'event_espresso'
1934
+								),
1935
+								$event->name()
1936
+							)
1937
+						),
1938
+						__FILE__,
1939
+						__FUNCTION__,
1940
+						__LINE__
1941
+					);
1942
+					return false;
1943
+				}
1944
+			}
1945
+		}
1946
+		return true;
1947
+	}
1948
+
1949
+
1950
+	/**
1951
+	 * redirect_form
1952
+	 *
1953
+	 * @access public
1954
+	 * @return bool
1955
+	 * @throws EE_Error
1956
+	 * @throws InvalidArgumentException
1957
+	 * @throws ReflectionException
1958
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1959
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1960
+	 */
1961
+	public function redirect_form()
1962
+	{
1963
+		$payment_method_billing_info = $this->_payment_method_billing_info(
1964
+			$this->_get_payment_method_for_selected_method_of_payment()
1965
+		);
1966
+		$html                        = $payment_method_billing_info->get_html();
1967
+		$html                        .= $this->checkout->redirect_form;
1968
+		EE_Registry::instance()->REQ->add_output($html);
1969
+		return true;
1970
+	}
1971
+
1972
+
1973
+	/**
1974
+	 * _billing_form_is_valid
1975
+	 *
1976
+	 * @access private
1977
+	 * @return bool
1978
+	 * @throws \EE_Error
1979
+	 */
1980
+	private function _billing_form_is_valid()
1981
+	{
1982
+		if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1983
+			return true;
1984
+		}
1985
+		if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
1986
+			if ($this->checkout->billing_form->was_submitted()) {
1987
+				$this->checkout->billing_form->receive_form_submission();
1988
+				if ($this->checkout->billing_form->is_valid()) {
1989
+					return true;
1990
+				}
1991
+				$validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated();
1992
+				$error_strings     = array();
1993
+				foreach ($validation_errors as $validation_error) {
1994
+					if ($validation_error instanceof EE_Validation_Error) {
1995
+						$form_section = $validation_error->get_form_section();
1996
+						if ($form_section instanceof EE_Form_Input_Base) {
1997
+							$label = $form_section->html_label_text();
1998
+						} elseif ($form_section instanceof EE_Form_Section_Base) {
1999
+							$label = $form_section->name();
2000
+						} else {
2001
+							$label = esc_html__('Validation Error', 'event_espresso');
2002
+						}
2003
+						$error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage());
2004
+					}
2005
+				}
2006
+				EE_Error::add_error(
2007
+					sprintf(
2008
+						esc_html__(
2009
+							'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s',
2010
+							'event_espresso'
2011
+						),
2012
+						'<br/>',
2013
+						implode('<br/>', $error_strings)
2014
+					),
2015
+					__FILE__,
2016
+					__FUNCTION__,
2017
+					__LINE__
2018
+				);
2019
+			} else {
2020
+				EE_Error::add_error(
2021
+					esc_html__(
2022
+						'The billing form was not submitted or something prevented it\'s submission.',
2023
+						'event_espresso'
2024
+					),
2025
+					__FILE__,
2026
+					__FUNCTION__,
2027
+					__LINE__
2028
+				);
2029
+			}
2030
+		} else {
2031
+			EE_Error::add_error(
2032
+				esc_html__('The submitted billing form is invalid possibly due to a technical reason.', 'event_espresso'),
2033
+				__FILE__,
2034
+				__FUNCTION__,
2035
+				__LINE__
2036
+			);
2037
+		}
2038
+		return false;
2039
+	}
2040
+
2041
+
2042
+	/**
2043
+	 * _setup_primary_registrant_prior_to_payment
2044
+	 * ensures that the primary registrant has a valid attendee object created with the critical details populated
2045
+	 * (first & last name & email) and that both the transaction object and primary registration object have been saved
2046
+	 * plz note that any other registrations will NOT be saved at this point (because they may not have any details
2047
+	 * yet)
2048
+	 *
2049
+	 * @access private
2050
+	 * @return bool
2051
+	 * @throws EE_Error
2052
+	 * @throws InvalidArgumentException
2053
+	 * @throws ReflectionException
2054
+	 * @throws RuntimeException
2055
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2056
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2057
+	 */
2058
+	private function _setup_primary_registrant_prior_to_payment()
2059
+	{
2060
+		// check if transaction has a primary registrant and that it has a related Attendee object
2061
+		// if not, then we need to at least gather some primary registrant data before attempting payment
2062
+		if (
2063
+			$this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
2064
+			&& ! $this->checkout->transaction_has_primary_registrant()
2065
+			&& ! $this->_capture_primary_registration_data_from_billing_form()
2066
+		) {
2067
+			return false;
2068
+		}
2069
+		// because saving an object clears it's cache, we need to do the chevy shuffle
2070
+		// grab the primary_registration object
2071
+		$primary_registration = $this->checkout->transaction->primary_registration();
2072
+		// at this point we'll consider a TXN to not have been failed
2073
+		$this->checkout->transaction->toggle_failed_transaction_status();
2074
+		// save the TXN ( which clears cached copy of primary_registration)
2075
+		$this->checkout->transaction->save();
2076
+		// grab TXN ID and save it to the primary_registration
2077
+		$primary_registration->set_transaction_id($this->checkout->transaction->ID());
2078
+		// save what we have so far
2079
+		$primary_registration->save();
2080
+		return true;
2081
+	}
2082
+
2083
+
2084
+	/**
2085
+	 * _capture_primary_registration_data_from_billing_form
2086
+	 *
2087
+	 * @access private
2088
+	 * @return bool
2089
+	 * @throws EE_Error
2090
+	 * @throws InvalidArgumentException
2091
+	 * @throws ReflectionException
2092
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2093
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2094
+	 */
2095
+	private function _capture_primary_registration_data_from_billing_form()
2096
+	{
2097
+		// convert billing form data into an attendee
2098
+		$this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data();
2099
+		if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2100
+			EE_Error::add_error(
2101
+				sprintf(
2102
+					esc_html__(
2103
+						'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.',
2104
+						'event_espresso'
2105
+					),
2106
+					'<br/>',
2107
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2108
+				),
2109
+				__FILE__,
2110
+				__FUNCTION__,
2111
+				__LINE__
2112
+			);
2113
+			return false;
2114
+		}
2115
+		$primary_registration = $this->checkout->transaction->primary_registration();
2116
+		if (! $primary_registration instanceof EE_Registration) {
2117
+			EE_Error::add_error(
2118
+				sprintf(
2119
+					esc_html__(
2120
+						'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2121
+						'event_espresso'
2122
+					),
2123
+					'<br/>',
2124
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2125
+				),
2126
+				__FILE__,
2127
+				__FUNCTION__,
2128
+				__LINE__
2129
+			);
2130
+			return false;
2131
+		}
2132
+		if (! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee')
2133
+			  instanceof
2134
+			  EE_Attendee
2135
+		) {
2136
+			EE_Error::add_error(
2137
+				sprintf(
2138
+					esc_html__(
2139
+						'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.',
2140
+						'event_espresso'
2141
+					),
2142
+					'<br/>',
2143
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2144
+				),
2145
+				__FILE__,
2146
+				__FUNCTION__,
2147
+				__LINE__
2148
+			);
2149
+			return false;
2150
+		}
2151
+		/** @type EE_Registration_Processor $registration_processor */
2152
+		$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
2153
+		// at this point, we should have enough details about the registrant to consider the registration NOT incomplete
2154
+		$registration_processor->toggle_incomplete_registration_status_to_default($primary_registration);
2155
+		return true;
2156
+	}
2157
+
2158
+
2159
+	/**
2160
+	 * _get_payment_method_for_selected_method_of_payment
2161
+	 * retrieves a valid payment method
2162
+	 *
2163
+	 * @access public
2164
+	 * @return EE_Payment_Method
2165
+	 * @throws EE_Error
2166
+	 * @throws InvalidArgumentException
2167
+	 * @throws ReflectionException
2168
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2169
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2170
+	 */
2171
+	private function _get_payment_method_for_selected_method_of_payment()
2172
+	{
2173
+		if ($this->checkout->selected_method_of_payment === 'events_sold_out') {
2174
+			$this->_redirect_because_event_sold_out();
2175
+			return null;
2176
+		}
2177
+		// get EE_Payment_Method object
2178
+		if (isset($this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment])) {
2179
+			$payment_method = $this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment];
2180
+		} else {
2181
+			// load EEM_Payment_Method
2182
+			EE_Registry::instance()->load_model('Payment_Method');
2183
+			/** @type EEM_Payment_Method $EEM_Payment_Method */
2184
+			$EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
2185
+			$payment_method     = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2186
+		}
2187
+		// verify $payment_method
2188
+		if (! $payment_method instanceof EE_Payment_Method) {
2189
+			// not a payment
2190
+			EE_Error::add_error(
2191
+				sprintf(
2192
+					esc_html__(
2193
+						'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2194
+						'event_espresso'
2195
+					),
2196
+					'<br/>',
2197
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2198
+				),
2199
+				__FILE__,
2200
+				__FUNCTION__,
2201
+				__LINE__
2202
+			);
2203
+			return null;
2204
+		}
2205
+		// and verify it has a valid Payment_Method Type object
2206
+		if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2207
+			// not a payment
2208
+			EE_Error::add_error(
2209
+				sprintf(
2210
+					esc_html__(
2211
+						'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2212
+						'event_espresso'
2213
+					),
2214
+					'<br/>',
2215
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2216
+				),
2217
+				__FILE__,
2218
+				__FUNCTION__,
2219
+				__LINE__
2220
+			);
2221
+			return null;
2222
+		}
2223
+		return $payment_method;
2224
+	}
2225
+
2226
+
2227
+	/**
2228
+	 *    _attempt_payment
2229
+	 *
2230
+	 * @access    private
2231
+	 * @type    EE_Payment_Method $payment_method
2232
+	 * @return mixed EE_Payment | boolean
2233
+	 * @throws EE_Error
2234
+	 * @throws InvalidArgumentException
2235
+	 * @throws ReflectionException
2236
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2237
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2238
+	 */
2239
+	private function _attempt_payment(EE_Payment_Method $payment_method)
2240
+	{
2241
+		$payment = null;
2242
+		$this->checkout->transaction->save();
2243
+		$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2244
+		if (! $payment_processor instanceof EE_Payment_Processor) {
2245
+			return false;
2246
+		}
2247
+		try {
2248
+			$payment_processor->set_revisit($this->checkout->revisit);
2249
+			// generate payment object
2250
+			$payment = $payment_processor->process_payment(
2251
+				$payment_method,
2252
+				$this->checkout->transaction,
2253
+				$this->checkout->amount_owing,
2254
+				$this->checkout->billing_form,
2255
+				$this->_get_return_url($payment_method),
2256
+				'CART',
2257
+				$this->checkout->admin_request,
2258
+				true,
2259
+				$this->reg_step_url()
2260
+			);
2261
+		} catch (Exception $e) {
2262
+			$this->_handle_payment_processor_exception($e);
2263
+		}
2264
+		return $payment;
2265
+	}
2266
+
2267
+
2268
+	/**
2269
+	 * _handle_payment_processor_exception
2270
+	 *
2271
+	 * @access protected
2272
+	 * @param \Exception $e
2273
+	 * @return void
2274
+	 * @throws EE_Error
2275
+	 * @throws InvalidArgumentException
2276
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2277
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2278
+	 */
2279
+	protected function _handle_payment_processor_exception(Exception $e)
2280
+	{
2281
+		EE_Error::add_error(
2282
+			sprintf(
2283
+				esc_html__(
2284
+					'The payment could not br processed due to a technical issue.%1$sPlease try again or contact %2$s for assistance.||The following Exception was thrown in %4$s on line %5$s:%1$s%3$s',
2285
+					'event_espresso'
2286
+				),
2287
+				'<br/>',
2288
+				EE_Registry::instance()->CFG->organization->get_pretty('email'),
2289
+				$e->getMessage(),
2290
+				$e->getFile(),
2291
+				$e->getLine()
2292
+			),
2293
+			__FILE__,
2294
+			__FUNCTION__,
2295
+			__LINE__
2296
+		);
2297
+	}
2298
+
2299
+
2300
+	/**
2301
+	 * _get_return_url
2302
+	 *
2303
+	 * @access protected
2304
+	 * @param \EE_Payment_Method $payment_method
2305
+	 * @return string
2306
+	 * @throws \EE_Error
2307
+	 */
2308
+	protected function _get_return_url(EE_Payment_Method $payment_method)
2309
+	{
2310
+		$return_url = '';
2311
+		switch ($payment_method->type_obj()->payment_occurs()) {
2312
+			case EE_PMT_Base::offsite :
2313
+				$return_url = add_query_arg(
2314
+					array(
2315
+						'action'                     => 'process_gateway_response',
2316
+						'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2317
+						'spco_txn'                   => $this->checkout->transaction->ID(),
2318
+					),
2319
+					$this->reg_step_url()
2320
+				);
2321
+				break;
2322
+			case EE_PMT_Base::onsite :
2323
+			case EE_PMT_Base::offline :
2324
+				$return_url = $this->checkout->next_step->reg_step_url();
2325
+				break;
2326
+		}
2327
+		return $return_url;
2328
+	}
2329
+
2330
+
2331
+	/**
2332
+	 * _validate_payment
2333
+	 *
2334
+	 * @access private
2335
+	 * @param EE_Payment $payment
2336
+	 * @return EE_Payment|FALSE
2337
+	 * @throws EE_Error
2338
+	 * @throws InvalidArgumentException
2339
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2340
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2341
+	 */
2342
+	private function _validate_payment($payment = null)
2343
+	{
2344
+		if ($this->checkout->payment_method->is_off_line()) {
2345
+			return true;
2346
+		}
2347
+		// verify payment object
2348
+		if (! $payment instanceof EE_Payment) {
2349
+			// not a payment
2350
+			EE_Error::add_error(
2351
+				sprintf(
2352
+					esc_html__(
2353
+						'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.',
2354
+						'event_espresso'
2355
+					),
2356
+					'<br/>',
2357
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2358
+				),
2359
+				__FILE__,
2360
+				__FUNCTION__,
2361
+				__LINE__
2362
+			);
2363
+			return false;
2364
+		}
2365
+		return $payment;
2366
+	}
2367
+
2368
+
2369
+	/**
2370
+	 * _post_payment_processing
2371
+	 *
2372
+	 * @access private
2373
+	 * @param EE_Payment|bool $payment
2374
+	 * @return bool
2375
+	 * @throws EE_Error
2376
+	 * @throws InvalidArgumentException
2377
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2378
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2379
+	 */
2380
+	private function _post_payment_processing($payment = null)
2381
+	{
2382
+		// Off-Line payment?
2383
+		if ($payment === true) {
2384
+			//$this->_setup_redirect_for_next_step();
2385
+			return true;
2386
+			// On-Site payment?
2387
+		} else if ($this->checkout->payment_method->is_on_site()) {
2388
+			if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2389
+				//$this->_setup_redirect_for_next_step();
2390
+				$this->checkout->continue_reg = false;
2391
+			}
2392
+			// Off-Site payment?
2393
+		} else if ($this->checkout->payment_method->is_off_site()) {
2394
+			// if a payment object was made and it specifies a redirect url, then we'll setup that redirect info
2395
+			if ($payment instanceof EE_Payment && $payment->redirect_url()) {
2396
+				do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()');
2397
+				$this->checkout->redirect      = true;
2398
+				$this->checkout->redirect_form = $payment->redirect_form();
2399
+				$this->checkout->redirect_url  = $this->reg_step_url('redirect_form');
2400
+				// set JSON response
2401
+				$this->checkout->json_response->set_redirect_form($this->checkout->redirect_form);
2402
+				// and lastly, let's bump the payment status to pending
2403
+				$payment->set_status(EEM_Payment::status_id_pending);
2404
+				$payment->save();
2405
+			} else {
2406
+				// not a payment
2407
+				$this->checkout->continue_reg = false;
2408
+				EE_Error::add_error(
2409
+					sprintf(
2410
+						esc_html__(
2411
+							'It appears the Off Site Payment Method was not configured properly.%sPlease try again or contact %s for assistance.',
2412
+							'event_espresso'
2413
+						),
2414
+						'<br/>',
2415
+						EE_Registry::instance()->CFG->organization->get_pretty('email')
2416
+					),
2417
+					__FILE__,
2418
+					__FUNCTION__,
2419
+					__LINE__
2420
+				);
2421
+			}
2422
+		} else {
2423
+			// ummm ya... not Off-Line, not On-Site, not off-Site ????
2424
+			$this->checkout->continue_reg = false;
2425
+			return false;
2426
+		}
2427
+		return $payment;
2428
+	}
2429
+
2430
+
2431
+	/**
2432
+	 *    _process_payment_status
2433
+	 *
2434
+	 * @access private
2435
+	 * @type    EE_Payment $payment
2436
+	 * @param string       $payment_occurs
2437
+	 * @return bool
2438
+	 * @throws EE_Error
2439
+	 * @throws InvalidArgumentException
2440
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2441
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2442
+	 */
2443
+	private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline)
2444
+	{
2445
+		// off-line payment? carry on
2446
+		if ($payment_occurs === EE_PMT_Base::offline) {
2447
+			return true;
2448
+		}
2449
+		// verify payment validity
2450
+		if ($payment instanceof EE_Payment) {
2451
+			do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()');
2452
+			$msg = $payment->gateway_response();
2453
+			// check results
2454
+			switch ($payment->status()) {
2455
+				// good payment
2456
+				case EEM_Payment::status_id_approved :
2457
+					EE_Error::add_success(
2458
+						esc_html__('Your payment was processed successfully.', 'event_espresso'),
2459
+						__FILE__,
2460
+						__FUNCTION__,
2461
+						__LINE__
2462
+					);
2463
+					return true;
2464
+					break;
2465
+				// slow payment
2466
+				case EEM_Payment::status_id_pending :
2467
+					if (empty($msg)) {
2468
+						$msg = esc_html__(
2469
+							'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.',
2470
+							'event_espresso'
2471
+						);
2472
+					}
2473
+					EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
2474
+					return true;
2475
+					break;
2476
+				// don't wanna payment
2477
+				case EEM_Payment::status_id_cancelled :
2478
+					if (empty($msg)) {
2479
+						$msg = _n(
2480
+							'Payment cancelled. Please try again.',
2481
+							'Payment cancelled. Please try again or select another method of payment.',
2482
+							count($this->checkout->available_payment_methods),
2483
+							'event_espresso'
2484
+						);
2485
+					}
2486
+					EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2487
+					return false;
2488
+					break;
2489
+				// not enough payment
2490
+				case EEM_Payment::status_id_declined :
2491
+					if (empty($msg)) {
2492
+						$msg = _n(
2493
+							'We\'re sorry but your payment was declined. Please try again.',
2494
+							'We\'re sorry but your payment was declined. Please try again or select another method of payment.',
2495
+							count($this->checkout->available_payment_methods),
2496
+							'event_espresso'
2497
+						);
2498
+					}
2499
+					EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2500
+					return false;
2501
+					break;
2502
+				// bad payment
2503
+				case EEM_Payment::status_id_failed :
2504
+					if (! empty($msg)) {
2505
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2506
+						return false;
2507
+					}
2508
+					// default to error below
2509
+					break;
2510
+			}
2511
+		}
2512
+		// off-site payment gateway responses are too unreliable, so let's just assume that
2513
+		// the payment processing is just running slower than the registrant's request
2514
+		if ($payment_occurs === EE_PMT_Base::offsite) {
2515
+			return true;
2516
+		}
2517
+		EE_Error::add_error(
2518
+			sprintf(
2519
+				esc_html__(
2520
+					'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.',
2521
+					'event_espresso'
2522
+				),
2523
+				'<br/>',
2524
+				EE_Registry::instance()->CFG->organization->get_pretty('email')
2525
+			),
2526
+			__FILE__,
2527
+			__FUNCTION__,
2528
+			__LINE__
2529
+		);
2530
+		return false;
2531
+	}
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+	/********************************************************************************************************/
2539
+	/**********************************  PROCESS GATEWAY RESPONSE  **********************************/
2540
+	/********************************************************************************************************/
2541
+	/**
2542
+	 * process_gateway_response
2543
+	 * this is the return point for Off-Site Payment Methods
2544
+	 * It will attempt to "handle the IPN" if it appears that this has not already occurred,
2545
+	 * otherwise, it will load up the last payment made for the TXN.
2546
+	 * If the payment retrieved looks good, it will then either:
2547
+	 *    complete the current step and allow advancement to the next reg step
2548
+	 *        or present the payment options again
2549
+	 *
2550
+	 * @access private
2551
+	 * @return EE_Payment|FALSE
2552
+	 * @throws EE_Error
2553
+	 * @throws InvalidArgumentException
2554
+	 * @throws ReflectionException
2555
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2556
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2557
+	 * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2558
+	 */
2559
+	public function process_gateway_response()
2560
+	{
2561
+		$payment = null;
2562
+		// how have they chosen to pay?
2563
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2564
+		// get EE_Payment_Method object
2565
+		if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2566
+			$this->checkout->continue_reg = false;
2567
+			return false;
2568
+		}
2569
+		if (! $this->checkout->payment_method->is_off_site()) {
2570
+			return false;
2571
+		}
2572
+		$this->_validate_offsite_return();
2573
+		// DEBUG LOG
2574
+		//$this->checkout->log(
2575
+		//	__CLASS__, __FUNCTION__, __LINE__,
2576
+		//	array(
2577
+		//		'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2578
+		//		'payment_method' => $this->checkout->payment_method,
2579
+		//	),
2580
+		//	true
2581
+		//);
2582
+		// verify TXN
2583
+		if ($this->checkout->transaction instanceof EE_Transaction) {
2584
+			$gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2585
+			if (! $gateway instanceof EE_Offsite_Gateway) {
2586
+				$this->checkout->continue_reg = false;
2587
+				return false;
2588
+			}
2589
+			$payment = $this->_process_off_site_payment($gateway);
2590
+			$payment = $this->_process_cancelled_payments($payment);
2591
+			$payment = $this->_validate_payment($payment);
2592
+			// if payment was not declined by the payment gateway or cancelled by the registrant
2593
+			if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) {
2594
+				//$this->_setup_redirect_for_next_step();
2595
+				// store that for later
2596
+				$this->checkout->payment = $payment;
2597
+				// mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2598
+				// because we will complete this step during the IPN processing then
2599
+				if ($gateway instanceof EE_Offsite_Gateway && ! $this->handle_IPN_in_this_request()) {
2600
+					$this->set_completed();
2601
+				}
2602
+				return true;
2603
+			}
2604
+		}
2605
+		// DEBUG LOG
2606
+		//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__,
2607
+		//	array( 'payment' => $payment )
2608
+		//);
2609
+		$this->checkout->continue_reg = false;
2610
+		return false;
2611
+	}
2612
+
2613
+
2614
+	/**
2615
+	 * _validate_return
2616
+	 *
2617
+	 * @access private
2618
+	 * @return void
2619
+	 * @throws EE_Error
2620
+	 * @throws InvalidArgumentException
2621
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2622
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2623
+	 * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2624
+	 */
2625
+	private function _validate_offsite_return()
2626
+	{
2627
+		$TXN_ID = (int)EE_Registry::instance()->REQ->get('spco_txn', 0);
2628
+		if ($TXN_ID !== $this->checkout->transaction->ID()) {
2629
+			// Houston... we might have a problem
2630
+			$invalid_TXN = false;
2631
+			// first gather some info
2632
+			$valid_TXN          = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2633
+			$primary_registrant = $valid_TXN instanceof EE_Transaction
2634
+				? $valid_TXN->primary_registration()
2635
+				: null;
2636
+			// let's start by retrieving the cart for this TXN
2637
+			$cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction);
2638
+			if ($cart instanceof EE_Cart) {
2639
+				// verify that the current cart has tickets
2640
+				$tickets = $cart->get_tickets();
2641
+				if (empty($tickets)) {
2642
+					$invalid_TXN = true;
2643
+				}
2644
+			} else {
2645
+				$invalid_TXN = true;
2646
+			}
2647
+			$valid_TXN_SID = $primary_registrant instanceof EE_Registration
2648
+				? $primary_registrant->session_ID()
2649
+				: null;
2650
+			// validate current Session ID and compare against valid TXN session ID
2651
+			if (
2652
+				$invalid_TXN // if this is already true, then skip other checks
2653
+				|| EE_Session::instance()->id() === null
2654
+				|| (
2655
+					// WARNING !!!
2656
+					// this could be PayPal sending back duplicate requests (ya they do that)
2657
+					// or it **could** mean someone is simply registering AGAIN after having just done so
2658
+					// so now we need to determine if this current TXN looks valid or not
2659
+					// and whether this reg step has even been started ?
2660
+					EE_Session::instance()->id() === $valid_TXN_SID
2661
+					// really? you're half way through this reg step, but you never started it ?
2662
+					&& $this->checkout->transaction->reg_step_completed($this->slug()) === false
2663
+				)
2664
+			) {
2665
+				$invalid_TXN = true;
2666
+			}
2667
+			if ($invalid_TXN) {
2668
+				// is the valid TXN completed ?
2669
+				if ($valid_TXN instanceof EE_Transaction) {
2670
+					// has this step even been started ?
2671
+					$reg_step_completed = $valid_TXN->reg_step_completed($this->slug());
2672
+					if ($reg_step_completed !== false && $reg_step_completed !== true) {
2673
+						// so it **looks** like this is a double request from PayPal
2674
+						// so let's try to pick up where we left off
2675
+						$this->checkout->transaction = $valid_TXN;
2676
+						$this->checkout->refresh_all_entities(true);
2677
+						return;
2678
+					}
2679
+				}
2680
+				// you appear to be lost?
2681
+				$this->_redirect_wayward_request($primary_registrant);
2682
+			}
2683
+		}
2684
+	}
2685
+
2686
+
2687
+	/**
2688
+	 * _redirect_wayward_request
2689
+	 *
2690
+	 * @access private
2691
+	 * @param \EE_Registration|null $primary_registrant
2692
+	 * @return bool
2693
+	 * @throws EE_Error
2694
+	 * @throws InvalidArgumentException
2695
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2696
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2697
+	 */
2698
+	private function _redirect_wayward_request(EE_Registration $primary_registrant)
2699
+	{
2700
+		if (! $primary_registrant instanceof EE_Registration) {
2701
+			// try redirecting based on the current TXN
2702
+			$primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2703
+				? $this->checkout->transaction->primary_registration()
2704
+				: null;
2705
+		}
2706
+		if (! $primary_registrant instanceof EE_Registration) {
2707
+			EE_Error::add_error(
2708
+				sprintf(
2709
+					esc_html__(
2710
+						'Invalid information was received from the Off-Site Payment Processor and your Transaction details could not be retrieved from the database.%1$sPlease try again or contact %2$s for assistance.',
2711
+						'event_espresso'
2712
+					),
2713
+					'<br/>',
2714
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2715
+				),
2716
+				__FILE__,
2717
+				__FUNCTION__,
2718
+				__LINE__
2719
+			);
2720
+			return false;
2721
+		}
2722
+		// make sure transaction is not locked
2723
+		$this->checkout->transaction->unlock();
2724
+		wp_safe_redirect(
2725
+			add_query_arg(
2726
+				array(
2727
+					'e_reg_url_link' => $primary_registrant->reg_url_link(),
2728
+				),
2729
+				$this->checkout->thank_you_page_url
2730
+			)
2731
+		);
2732
+		exit();
2733
+	}
2734
+
2735
+
2736
+	/**
2737
+	 * _process_off_site_payment
2738
+	 *
2739
+	 * @access private
2740
+	 * @param \EE_Offsite_Gateway $gateway
2741
+	 * @return EE_Payment
2742
+	 * @throws EE_Error
2743
+	 * @throws InvalidArgumentException
2744
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2745
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2746
+	 */
2747
+	private function _process_off_site_payment(EE_Offsite_Gateway $gateway)
2748
+	{
2749
+		try {
2750
+			$request_data = \EE_Registry::instance()->REQ->params();
2751
+			// if gateway uses_separate_IPN_request, then we don't have to process the IPN manually
2752
+			$this->set_handle_IPN_in_this_request(
2753
+				$gateway->handle_IPN_in_this_request($request_data, false)
2754
+			);
2755
+			if ($this->handle_IPN_in_this_request()) {
2756
+				// get payment details and process results
2757
+				/** @type EE_Payment_Processor $payment_processor */
2758
+				$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2759
+				$payment           = $payment_processor->process_ipn(
2760
+					$request_data,
2761
+					$this->checkout->transaction,
2762
+					$this->checkout->payment_method,
2763
+					true,
2764
+					false
2765
+				);
2766
+				//$payment_source = 'process_ipn';
2767
+			} else {
2768
+				$payment = $this->checkout->transaction->last_payment();
2769
+				//$payment_source = 'last_payment';
2770
+			}
2771
+		} catch (Exception $e) {
2772
+			// let's just eat the exception and try to move on using any previously set payment info
2773
+			$payment = $this->checkout->transaction->last_payment();
2774
+			//$payment_source = 'last_payment after Exception';
2775
+			// but if we STILL don't have a payment object
2776
+			if (! $payment instanceof EE_Payment) {
2777
+				// then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2778
+				$this->_handle_payment_processor_exception($e);
2779
+			}
2780
+		}
2781
+		// DEBUG LOG
2782
+		//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__,
2783
+		//	array(
2784
+		//		'process_ipn_payment' => $payment,
2785
+		//		'payment_source'      => $payment_source,
2786
+		//	)
2787
+		//);
2788
+		return $payment;
2789
+	}
2790
+
2791
+
2792
+	/**
2793
+	 * _process_cancelled_payments
2794
+	 * just makes sure that the payment status gets updated correctly
2795
+	 * so tha tan error isn't generated during payment validation
2796
+	 *
2797
+	 * @access private
2798
+	 * @param EE_Payment $payment
2799
+	 * @return EE_Payment | FALSE
2800
+	 * @throws \EE_Error
2801
+	 */
2802
+	private function _process_cancelled_payments($payment = null)
2803
+	{
2804
+		if (
2805
+			$payment instanceof EE_Payment
2806
+			&& isset($_REQUEST['ee_cancel_payment'])
2807
+			&& $payment->status() === EEM_Payment::status_id_failed
2808
+		) {
2809
+			$payment->set_status(EEM_Payment::status_id_cancelled);
2810
+		}
2811
+		return $payment;
2812
+	}
2813
+
2814
+
2815
+	/**
2816
+	 *    get_transaction_details_for_gateways
2817
+	 *
2818
+	 * @access    public
2819
+	 * @return int
2820
+	 * @throws EE_Error
2821
+	 * @throws InvalidArgumentException
2822
+	 * @throws ReflectionException
2823
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2824
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2825
+	 */
2826
+	public function get_transaction_details_for_gateways()
2827
+	{
2828
+		$txn_details = array();
2829
+		// ya gotta make a choice man
2830
+		if (empty($this->checkout->selected_method_of_payment)) {
2831
+			$txn_details = array(
2832
+				'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'),
2833
+			);
2834
+		}
2835
+		// get EE_Payment_Method object
2836
+		if (
2837
+			empty($txn_details)
2838
+			&&
2839
+			! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()
2840
+		) {
2841
+			$txn_details = array(
2842
+				'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2843
+				'error'                      => esc_html__(
2844
+					'A valid Payment Method could not be determined.',
2845
+					'event_espresso'
2846
+				),
2847
+			);
2848
+		}
2849
+		if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) {
2850
+			$return_url  = $this->_get_return_url($this->checkout->payment_method);
2851
+			$txn_details = array(
2852
+				'TXN_ID'         => $this->checkout->transaction->ID(),
2853
+				'TXN_timestamp'  => $this->checkout->transaction->datetime(),
2854
+				'TXN_total'      => $this->checkout->transaction->total(),
2855
+				'TXN_paid'       => $this->checkout->transaction->paid(),
2856
+				'TXN_reg_steps'  => $this->checkout->transaction->reg_steps(),
2857
+				'STS_ID'         => $this->checkout->transaction->status_ID(),
2858
+				'PMD_ID'         => $this->checkout->transaction->payment_method_ID(),
2859
+				'payment_amount' => $this->checkout->amount_owing,
2860
+				'return_url'     => $return_url,
2861
+				'cancel_url'     => add_query_arg(array('ee_cancel_payment' => true), $return_url),
2862
+				'notify_url'     => EE_Config::instance()->core->txn_page_url(
2863
+					array(
2864
+						'e_reg_url_link'    => $this->checkout->transaction->primary_registration()->reg_url_link(),
2865
+						'ee_payment_method' => $this->checkout->payment_method->slug(),
2866
+					)
2867
+				),
2868
+			);
2869
+		}
2870
+		echo wp_json_encode($txn_details);
2871
+		exit();
2872
+	}
2873
+
2874
+
2875
+	/**
2876
+	 *    __sleep
2877
+	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
2878
+	 * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
2879
+	 * reg form, because if needed, it will be regenerated anyways
2880
+	 *
2881
+	 * @return array
2882
+	 */
2883
+	public function __sleep()
2884
+	{
2885
+		// remove the reg form and the checkout
2886
+		return array_diff(array_keys(get_object_vars($this)), array('reg_form', 'checkout', 'line_item_display'));
2887
+	}
2888 2888
 }
Please login to merge, or discard this patch.
Spacing   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
     {
133 133
         $this->_slug     = 'payment_options';
134 134
         $this->_name     = esc_html__('Payment Options', 'event_espresso');
135
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'payment_options_main.template.php';
135
+        $this->_template = SPCO_REG_STEPS_PATH.$this->_slug.DS.'payment_options_main.template.php';
136 136
         $this->checkout  = $checkout;
137 137
         $this->_reset_success_message();
138 138
         $this->set_instructions(
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
      */
188 188
     public function translate_js_strings()
189 189
     {
190
-        EE_Registry::$i18n_js_strings['no_payment_method']      = esc_html__(
190
+        EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__(
191 191
             'Please select a method of payment in order to continue.',
192 192
             'event_espresso'
193 193
         );
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
             'A valid method of payment could not be determined. Please refresh the page and try again.',
196 196
             'event_espresso'
197 197
         );
198
-        EE_Registry::$i18n_js_strings['forwarding_to_offsite']  = esc_html__(
198
+        EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__(
199 199
             'Forwarding to Secure Payment Provider.',
200 200
             'event_espresso'
201 201
         );
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
     {
216 216
         $transaction = $this->checkout->transaction;
217 217
         //if the transaction isn't set or nothing is owed on it, don't enqueue any JS
218
-        if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
218
+        if ( ! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
219 219
             return;
220 220
         }
221 221
         foreach (EEM_Payment_Method::instance()->get_all_for_transaction($transaction, EEM_Payment_Method::scope_cart) as $payment_method) {
@@ -304,11 +304,11 @@  discard block
 block discarded – undo
304 304
         foreach ($registrations as $REG_ID => $registration) {
305 305
             /** @var $registration EE_Registration */
306 306
             // has this registration lost it's space ?
307
-            if (isset($ejected_registrations[ $REG_ID ])) {
307
+            if (isset($ejected_registrations[$REG_ID])) {
308 308
                 if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
309
-                    $sold_out_events[ $registration->event()->ID() ] = $registration->event();
309
+                    $sold_out_events[$registration->event()->ID()] = $registration->event();
310 310
                 } else {
311
-                    $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
311
+                    $insufficient_spaces_available[$registration->event()->ID()] = $registration->event();
312 312
                 }
313 313
                 continue;
314 314
             }
@@ -347,7 +347,7 @@  discard block
 block discarded – undo
347 347
                     $registration->event(),
348 348
                     $this
349 349
                 );
350
-            } elseif (! $this->checkout->revisit
350
+            } elseif ( ! $this->checkout->revisit
351 351
                 && $registration->status_ID() !== EEM_Registration::status_id_not_approved
352 352
                 && $registration->ticket()->is_free()
353 353
             ) {
@@ -356,23 +356,23 @@  discard block
 block discarded – undo
356 356
         }
357 357
         $subsections = array();
358 358
         // now decide which template to load
359
-        if (! empty($sold_out_events)) {
359
+        if ( ! empty($sold_out_events)) {
360 360
             $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
361 361
         }
362
-        if (! empty($insufficient_spaces_available)) {
362
+        if ( ! empty($insufficient_spaces_available)) {
363 363
             $subsections['insufficient_space'] = $this->_insufficient_spaces_available(
364 364
                 $insufficient_spaces_available
365 365
             );
366 366
         }
367
-        if (! empty($registrations_requiring_pre_approval)) {
367
+        if ( ! empty($registrations_requiring_pre_approval)) {
368 368
             $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
369 369
                 $registrations_requiring_pre_approval
370 370
             );
371 371
         }
372
-        if (! empty($registrations_for_free_events)) {
372
+        if ( ! empty($registrations_for_free_events)) {
373 373
             $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
374 374
         }
375
-        if (! empty($registrations_requiring_payment)) {
375
+        if ( ! empty($registrations_requiring_payment)) {
376 376
             if ($this->checkout->amount_owing > 0) {
377 377
                 // autoload Line_Item_Display classes
378 378
                 EEH_Autoloader::register_line_item_filter_autoloaders();
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
                         array('registrations' => $registrations)
394 394
                     )
395 395
                 );
396
-                $this->checkout->amount_owing   = $filtered_line_item_tree->total();
396
+                $this->checkout->amount_owing = $filtered_line_item_tree->total();
397 397
                 $this->_apply_registration_payments_to_amount_owing($registrations);
398 398
             }
399 399
             $no_payment_required = false;
@@ -437,13 +437,13 @@  discard block
 block discarded – undo
437 437
      */
438 438
     public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
439 439
     {
440
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
440
+        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
441 441
             return $line_item_filter_collection;
442 442
         }
443
-        if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
443
+        if ( ! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
444 444
             return $line_item_filter_collection;
445 445
         }
446
-        if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
446
+        if ( ! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
447 447
             return $line_item_filter_collection;
448 448
         }
449 449
         $line_item_filter_collection->add(
@@ -534,15 +534,15 @@  discard block
 block discarded – undo
534 534
             }
535 535
             $EVT_ID = $registration->event_ID();
536 536
             $ticket = $registration->ticket();
537
-            if (! isset($tickets_remaining[$ticket->ID()])) {
537
+            if ( ! isset($tickets_remaining[$ticket->ID()])) {
538 538
                 $tickets_remaining[$ticket->ID()] = $ticket->remaining();
539 539
             }
540 540
             if ($tickets_remaining[$ticket->ID()] > 0) {
541
-                if (! isset($event_reg_count[$EVT_ID])) {
541
+                if ( ! isset($event_reg_count[$EVT_ID])) {
542 542
                     $event_reg_count[$EVT_ID] = 0;
543 543
                 }
544 544
                 $event_reg_count[$EVT_ID]++;
545
-                if (! isset($event_spaces_remaining[$EVT_ID])) {
545
+                if ( ! isset($event_spaces_remaining[$EVT_ID])) {
546 546
                     $event_spaces_remaining[$EVT_ID] = $registration->event()->spaces_remaining_for_sale();
547 547
                 }
548 548
             }
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
         foreach ($sold_out_events_array as $sold_out_event) {
612 612
             $sold_out_events .= EEH_HTML::li(
613 613
                 EEH_HTML::span(
614
-                    '  ' . $sold_out_event->name(),
614
+                    '  '.$sold_out_event->name(),
615 615
                     '',
616 616
                     'dashicons dashicons-marker ee-icon-size-16 pink-text'
617 617
                 )
@@ -667,7 +667,7 @@  discard block
 block discarded – undo
667 667
         foreach ($insufficient_spaces_events_array as $event) {
668 668
             if ($event instanceof EE_Event) {
669 669
                 $insufficient_space_events .= EEH_HTML::li(
670
-                    EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
670
+                    EEH_HTML::span(' '.$event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
671 671
                 );
672 672
             }
673 673
         }
@@ -857,7 +857,7 @@  discard block
 block discarded – undo
857 857
     {
858 858
         return new EE_Form_Section_Proper(
859 859
             array(
860
-                'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
860
+                'html_id'         => 'ee-'.$this->slug().'-extra-hidden-inputs',
861 861
                 'layout_strategy' => new EE_Div_Per_Section_Layout(),
862 862
                 'subsections'     => array(
863 863
                     'spco_no_payment_required' => new EE_Hidden_Input(
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
                 $payments += $registration->registration_payments();
898 898
             }
899 899
         }
900
-        if (! empty($payments)) {
900
+        if ( ! empty($payments)) {
901 901
             foreach ($payments as $payment) {
902 902
                 if ($payment instanceof EE_Registration_Payment) {
903 903
                     $this->checkout->amount_owing -= $payment->amount();
@@ -987,7 +987,7 @@  discard block
 block discarded – undo
987 987
             );
988 988
         }
989 989
         // switch up header depending on number of available payment methods
990
-        $payment_method_header     = count($this->checkout->available_payment_methods) > 1
990
+        $payment_method_header = count($this->checkout->available_payment_methods) > 1
991 991
             ? apply_filters(
992 992
                 'FHEE__registration_page_payment_options__method_of_payment_hdr',
993 993
                 esc_html__('Please Select Your Method of Payment', 'event_espresso')
@@ -1017,14 +1017,14 @@  discard block
 block discarded – undo
1017 1017
                 $payment_method_button = EEH_HTML::img(
1018 1018
                     $payment_method->button_url(),
1019 1019
                     $payment_method->name(),
1020
-                    'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1020
+                    'spco-payment-method-'.$payment_method->slug().'-btn-img',
1021 1021
                     'spco-payment-method-btn-img'
1022 1022
                 );
1023 1023
                 // check if any payment methods are set as default
1024 1024
                 // if payment method is already selected OR nothing is selected and this payment method should be
1025 1025
                 // open_by_default
1026 1026
                 if (($this->checkout->selected_method_of_payment === $payment_method->slug())
1027
-                    || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1027
+                    || ( ! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1028 1028
                 ) {
1029 1029
                     $this->checkout->selected_method_of_payment = $payment_method->slug();
1030 1030
                     $this->_save_selected_method_of_payment();
@@ -1032,7 +1032,7 @@  discard block
 block discarded – undo
1032 1032
                 } else {
1033 1033
                     $available_payment_method_options[$payment_method->slug()] = $payment_method_button;
1034 1034
                 }
1035
-                $payment_methods_billing_info[$payment_method->slug() . '-info'] = $this->_payment_method_billing_info(
1035
+                $payment_methods_billing_info[$payment_method->slug().'-info'] = $this->_payment_method_billing_info(
1036 1036
                     $payment_method
1037 1037
                 );
1038 1038
             }
@@ -1044,7 +1044,7 @@  discard block
 block discarded – undo
1044 1044
         $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1045 1045
             $available_payment_method_options
1046 1046
         );
1047
-        $available_payment_methods                              += $payment_methods_billing_info;
1047
+        $available_payment_methods += $payment_methods_billing_info;
1048 1048
         // build the available payment methods form
1049 1049
         return new EE_Form_Section_Proper(
1050 1050
             array(
@@ -1068,7 +1068,7 @@  discard block
 block discarded – undo
1068 1068
      */
1069 1069
     protected function _get_available_payment_methods()
1070 1070
     {
1071
-        if (! empty($this->checkout->available_payment_methods)) {
1071
+        if ( ! empty($this->checkout->available_payment_methods)) {
1072 1072
             return $this->checkout->available_payment_methods;
1073 1073
         }
1074 1074
         $available_payment_methods = array();
@@ -1178,7 +1178,7 @@  discard block
 block discarded – undo
1178 1178
         );
1179 1179
         return new EE_Form_Section_Proper(
1180 1180
             array(
1181
-                'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1181
+                'html_id'         => 'spco-payment-method-info-'.$payment_method->slug(),
1182 1182
                 'html_class'      => 'spco-payment-method-info-dv',
1183 1183
                 // only display the selected or default PM
1184 1184
                 'html_style'      => $currently_selected ? '' : 'display:none;',
@@ -1208,7 +1208,7 @@  discard block
 block discarded – undo
1208 1208
         // how have they chosen to pay?
1209 1209
         $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1210 1210
         $this->checkout->payment_method             = $this->_get_payment_method_for_selected_method_of_payment();
1211
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1211
+        if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) {
1212 1212
             return false;
1213 1213
         }
1214 1214
         if (apply_filters(
@@ -1380,7 +1380,7 @@  discard block
 block discarded – undo
1380 1380
      */
1381 1381
     public function switch_payment_method()
1382 1382
     {
1383
-        if (! $this->_verify_payment_method_is_set()) {
1383
+        if ( ! $this->_verify_payment_method_is_set()) {
1384 1384
             return false;
1385 1385
         }
1386 1386
         if (apply_filters(
@@ -1509,7 +1509,7 @@  discard block
 block discarded – undo
1509 1509
             }
1510 1510
         }
1511 1511
         // verify payment method
1512
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1512
+        if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) {
1513 1513
             // get payment method for selected method of payment
1514 1514
             $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1515 1515
         }
@@ -1534,7 +1534,7 @@  discard block
 block discarded – undo
1534 1534
      */
1535 1535
     public function save_payer_details_via_ajax()
1536 1536
     {
1537
-        if (! $this->_verify_payment_method_is_set()) {
1537
+        if ( ! $this->_verify_payment_method_is_set()) {
1538 1538
             return;
1539 1539
         }
1540 1540
         // generate billing form for selected method of payment if it hasn't been done already
@@ -1544,7 +1544,7 @@  discard block
 block discarded – undo
1544 1544
             );
1545 1545
         }
1546 1546
         // generate primary attendee from payer info if applicable
1547
-        if (! $this->checkout->transaction_has_primary_registrant()) {
1547
+        if ( ! $this->checkout->transaction_has_primary_registrant()) {
1548 1548
             $attendee = $this->_create_attendee_from_request_data();
1549 1549
             if ($attendee instanceof EE_Attendee) {
1550 1550
                 foreach ($this->checkout->transaction->registrations() as $registration) {
@@ -1575,7 +1575,7 @@  discard block
 block discarded – undo
1575 1575
     {
1576 1576
         // get State ID
1577 1577
         $STA_ID = ! empty($_REQUEST['state']) ? sanitize_text_field($_REQUEST['state']) : '';
1578
-        if (! empty($STA_ID)) {
1578
+        if ( ! empty($STA_ID)) {
1579 1579
             // can we get state object from name ?
1580 1580
             EE_Registry::instance()->load_model('State');
1581 1581
             $state  = EEM_State::instance()->get_col(array(array('STA_name' => $STA_ID), 'limit' => 1), 'STA_ID');
@@ -1583,7 +1583,7 @@  discard block
 block discarded – undo
1583 1583
         }
1584 1584
         // get Country ISO
1585 1585
         $CNT_ISO = ! empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';
1586
-        if (! empty($CNT_ISO)) {
1586
+        if ( ! empty($CNT_ISO)) {
1587 1587
             // can we get country object from name ?
1588 1588
             EE_Registry::instance()->load_model('Country');
1589 1589
             $country = EEM_Country::instance()->get_col(
@@ -1616,7 +1616,7 @@  discard block
 block discarded – undo
1616 1616
         }
1617 1617
         // does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1618 1618
         // AND email address
1619
-        if (! empty($attendee_data['ATT_fname'])
1619
+        if ( ! empty($attendee_data['ATT_fname'])
1620 1620
             && ! empty($attendee_data['ATT_lname'])
1621 1621
             && ! empty($attendee_data['ATT_email'])
1622 1622
         ) {
@@ -1832,7 +1832,7 @@  discard block
 block discarded – undo
1832 1832
     private function _process_payment()
1833 1833
     {
1834 1834
         // basically confirm that the event hasn't sold out since they hit the page
1835
-        if (! $this->_last_second_ticket_verifications()) {
1835
+        if ( ! $this->_last_second_ticket_verifications()) {
1836 1836
             return false;
1837 1837
         }
1838 1838
         // ya gotta make a choice man
@@ -1843,7 +1843,7 @@  discard block
 block discarded – undo
1843 1843
             return false;
1844 1844
         }
1845 1845
         // get EE_Payment_Method object
1846
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1846
+        if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1847 1847
             return false;
1848 1848
         }
1849 1849
         // setup billing form
@@ -1852,12 +1852,12 @@  discard block
 block discarded – undo
1852 1852
                 $this->checkout->payment_method
1853 1853
             );
1854 1854
             // bad billing form ?
1855
-            if (! $this->_billing_form_is_valid()) {
1855
+            if ( ! $this->_billing_form_is_valid()) {
1856 1856
                 return false;
1857 1857
             }
1858 1858
         }
1859 1859
         // ensure primary registrant has been fully processed
1860
-        if (! $this->_setup_primary_registrant_prior_to_payment()) {
1860
+        if ( ! $this->_setup_primary_registrant_prior_to_payment()) {
1861 1861
             return false;
1862 1862
         }
1863 1863
         // if session is close to expiring (under 10 minutes by default)
@@ -1913,7 +1913,7 @@  discard block
 block discarded – undo
1913 1913
     protected function _last_second_ticket_verifications()
1914 1914
     {
1915 1915
         // don't bother re-validating if not a return visit
1916
-        if (! $this->checkout->revisit) {
1916
+        if ( ! $this->checkout->revisit) {
1917 1917
             return true;
1918 1918
         }
1919 1919
         $registrations = $this->checkout->transaction->registrations();
@@ -1964,7 +1964,7 @@  discard block
 block discarded – undo
1964 1964
             $this->_get_payment_method_for_selected_method_of_payment()
1965 1965
         );
1966 1966
         $html                        = $payment_method_billing_info->get_html();
1967
-        $html                        .= $this->checkout->redirect_form;
1967
+        $html .= $this->checkout->redirect_form;
1968 1968
         EE_Registry::instance()->REQ->add_output($html);
1969 1969
         return true;
1970 1970
     }
@@ -1979,7 +1979,7 @@  discard block
 block discarded – undo
1979 1979
      */
1980 1980
     private function _billing_form_is_valid()
1981 1981
     {
1982
-        if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1982
+        if ( ! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1983 1983
             return true;
1984 1984
         }
1985 1985
         if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
@@ -2096,7 +2096,7 @@  discard block
 block discarded – undo
2096 2096
     {
2097 2097
         // convert billing form data into an attendee
2098 2098
         $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data();
2099
-        if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2099
+        if ( ! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2100 2100
             EE_Error::add_error(
2101 2101
                 sprintf(
2102 2102
                     esc_html__(
@@ -2113,7 +2113,7 @@  discard block
 block discarded – undo
2113 2113
             return false;
2114 2114
         }
2115 2115
         $primary_registration = $this->checkout->transaction->primary_registration();
2116
-        if (! $primary_registration instanceof EE_Registration) {
2116
+        if ( ! $primary_registration instanceof EE_Registration) {
2117 2117
             EE_Error::add_error(
2118 2118
                 sprintf(
2119 2119
                     esc_html__(
@@ -2129,7 +2129,7 @@  discard block
 block discarded – undo
2129 2129
             );
2130 2130
             return false;
2131 2131
         }
2132
-        if (! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee')
2132
+        if ( ! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee')
2133 2133
               instanceof
2134 2134
               EE_Attendee
2135 2135
         ) {
@@ -2185,7 +2185,7 @@  discard block
 block discarded – undo
2185 2185
             $payment_method     = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2186 2186
         }
2187 2187
         // verify $payment_method
2188
-        if (! $payment_method instanceof EE_Payment_Method) {
2188
+        if ( ! $payment_method instanceof EE_Payment_Method) {
2189 2189
             // not a payment
2190 2190
             EE_Error::add_error(
2191 2191
                 sprintf(
@@ -2203,7 +2203,7 @@  discard block
 block discarded – undo
2203 2203
             return null;
2204 2204
         }
2205 2205
         // and verify it has a valid Payment_Method Type object
2206
-        if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2206
+        if ( ! $payment_method->type_obj() instanceof EE_PMT_Base) {
2207 2207
             // not a payment
2208 2208
             EE_Error::add_error(
2209 2209
                 sprintf(
@@ -2241,7 +2241,7 @@  discard block
 block discarded – undo
2241 2241
         $payment = null;
2242 2242
         $this->checkout->transaction->save();
2243 2243
         $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2244
-        if (! $payment_processor instanceof EE_Payment_Processor) {
2244
+        if ( ! $payment_processor instanceof EE_Payment_Processor) {
2245 2245
             return false;
2246 2246
         }
2247 2247
         try {
@@ -2345,7 +2345,7 @@  discard block
 block discarded – undo
2345 2345
             return true;
2346 2346
         }
2347 2347
         // verify payment object
2348
-        if (! $payment instanceof EE_Payment) {
2348
+        if ( ! $payment instanceof EE_Payment) {
2349 2349
             // not a payment
2350 2350
             EE_Error::add_error(
2351 2351
                 sprintf(
@@ -2385,7 +2385,7 @@  discard block
 block discarded – undo
2385 2385
             return true;
2386 2386
             // On-Site payment?
2387 2387
         } else if ($this->checkout->payment_method->is_on_site()) {
2388
-            if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2388
+            if ( ! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2389 2389
                 //$this->_setup_redirect_for_next_step();
2390 2390
                 $this->checkout->continue_reg = false;
2391 2391
             }
@@ -2501,7 +2501,7 @@  discard block
 block discarded – undo
2501 2501
                     break;
2502 2502
                 // bad payment
2503 2503
                 case EEM_Payment::status_id_failed :
2504
-                    if (! empty($msg)) {
2504
+                    if ( ! empty($msg)) {
2505 2505
                         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2506 2506
                         return false;
2507 2507
                     }
@@ -2562,11 +2562,11 @@  discard block
 block discarded – undo
2562 2562
         // how have they chosen to pay?
2563 2563
         $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2564 2564
         // get EE_Payment_Method object
2565
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2565
+        if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2566 2566
             $this->checkout->continue_reg = false;
2567 2567
             return false;
2568 2568
         }
2569
-        if (! $this->checkout->payment_method->is_off_site()) {
2569
+        if ( ! $this->checkout->payment_method->is_off_site()) {
2570 2570
             return false;
2571 2571
         }
2572 2572
         $this->_validate_offsite_return();
@@ -2582,7 +2582,7 @@  discard block
 block discarded – undo
2582 2582
         // verify TXN
2583 2583
         if ($this->checkout->transaction instanceof EE_Transaction) {
2584 2584
             $gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2585
-            if (! $gateway instanceof EE_Offsite_Gateway) {
2585
+            if ( ! $gateway instanceof EE_Offsite_Gateway) {
2586 2586
                 $this->checkout->continue_reg = false;
2587 2587
                 return false;
2588 2588
             }
@@ -2624,7 +2624,7 @@  discard block
 block discarded – undo
2624 2624
      */
2625 2625
     private function _validate_offsite_return()
2626 2626
     {
2627
-        $TXN_ID = (int)EE_Registry::instance()->REQ->get('spco_txn', 0);
2627
+        $TXN_ID = (int) EE_Registry::instance()->REQ->get('spco_txn', 0);
2628 2628
         if ($TXN_ID !== $this->checkout->transaction->ID()) {
2629 2629
             // Houston... we might have a problem
2630 2630
             $invalid_TXN = false;
@@ -2697,13 +2697,13 @@  discard block
 block discarded – undo
2697 2697
      */
2698 2698
     private function _redirect_wayward_request(EE_Registration $primary_registrant)
2699 2699
     {
2700
-        if (! $primary_registrant instanceof EE_Registration) {
2700
+        if ( ! $primary_registrant instanceof EE_Registration) {
2701 2701
             // try redirecting based on the current TXN
2702 2702
             $primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2703 2703
                 ? $this->checkout->transaction->primary_registration()
2704 2704
                 : null;
2705 2705
         }
2706
-        if (! $primary_registrant instanceof EE_Registration) {
2706
+        if ( ! $primary_registrant instanceof EE_Registration) {
2707 2707
             EE_Error::add_error(
2708 2708
                 sprintf(
2709 2709
                     esc_html__(
@@ -2773,7 +2773,7 @@  discard block
 block discarded – undo
2773 2773
             $payment = $this->checkout->transaction->last_payment();
2774 2774
             //$payment_source = 'last_payment after Exception';
2775 2775
             // but if we STILL don't have a payment object
2776
-            if (! $payment instanceof EE_Payment) {
2776
+            if ( ! $payment instanceof EE_Payment) {
2777 2777
                 // then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2778 2778
                 $this->_handle_payment_processor_exception($e);
2779 2779
             }
Please login to merge, or discard this patch.
admin_pages/maintenance/Maintenance_Admin_Page.core.php 2 patches
Indentation   +813 added lines, -813 removed lines patch added patch discarded remove patch
@@ -29,829 +29,829 @@
 block discarded – undo
29 29
 {
30 30
 
31 31
 
32
-    /**
33
-     * @var EE_Datetime_Offset_Fix_Form
34
-     */
35
-    protected $datetime_fix_offset_form;
36
-
37
-
38
-
39
-    protected function _init_page_props()
40
-    {
41
-        $this->page_slug = EE_MAINTENANCE_PG_SLUG;
42
-        $this->page_label = EE_MAINTENANCE_LABEL;
43
-        $this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL;
44
-        $this->_admin_base_path = EE_MAINTENANCE_ADMIN;
45
-    }
46
-
47
-
48
-
49
-    protected function _ajax_hooks()
50
-    {
51
-        add_action('wp_ajax_migration_step', array($this, 'migration_step'));
52
-        add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran'));
53
-    }
54
-
55
-
56
-
57
-    protected function _define_page_props()
58
-    {
59
-        $this->_admin_page_title = EE_MAINTENANCE_LABEL;
60
-        $this->_labels = array(
61
-            'buttons' => array(
62
-                'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
63
-                'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
64
-            ),
65
-        );
66
-    }
67
-
68
-
69
-
70
-    protected function _set_page_routes()
71
-    {
72
-        $this->_page_routes = array(
73
-            'default'                             => array(
74
-                'func'       => '_maintenance',
75
-                'capability' => 'manage_options',
76
-            ),
77
-            'change_maintenance_level'            => array(
78
-                'func'       => '_change_maintenance_level',
79
-                'capability' => 'manage_options',
80
-                'noheader'   => true,
81
-            ),
82
-            'system_status'                       => array(
83
-                'func'       => '_system_status',
84
-                'capability' => 'manage_options',
85
-            ),
86
-            'download_system_status' => array(
87
-                'func'       => '_download_system_status',
88
-                'capability' => 'manage_options',
89
-                'noheader'   => true,
90
-            ),
91
-            'send_migration_crash_report'         => array(
92
-                'func'       => '_send_migration_crash_report',
93
-                'capability' => 'manage_options',
94
-                'noheader'   => true,
95
-            ),
96
-            'confirm_migration_crash_report_sent' => array(
97
-                'func'       => '_confirm_migration_crash_report_sent',
98
-                'capability' => 'manage_options',
99
-            ),
100
-            'data_reset'                          => array(
101
-                'func'       => '_data_reset_and_delete',
102
-                'capability' => 'manage_options',
103
-            ),
104
-            'reset_db'                            => array(
105
-                'func'       => '_reset_db',
106
-                'capability' => 'manage_options',
107
-                'noheader'   => true,
108
-                'args'       => array('nuke_old_ee4_data' => true),
109
-            ),
110
-            'start_with_fresh_ee4_db'             => array(
111
-                'func'       => '_reset_db',
112
-                'capability' => 'manage_options',
113
-                'noheader'   => true,
114
-                'args'       => array('nuke_old_ee4_data' => false),
115
-            ),
116
-            'delete_db'                           => array(
117
-                'func'       => '_delete_db',
118
-                'capability' => 'manage_options',
119
-                'noheader'   => true,
120
-            ),
121
-            'rerun_migration_from_ee3'            => array(
122
-                'func'       => '_rerun_migration_from_ee3',
123
-                'capability' => 'manage_options',
124
-                'noheader'   => true,
125
-            ),
126
-            'reset_reservations'                  => array(
127
-                'func'       => '_reset_reservations',
128
-                'capability' => 'manage_options',
129
-                'noheader'   => true,
130
-            ),
131
-            'reset_capabilities'                  => array(
132
-                'func'       => '_reset_capabilities',
133
-                'capability' => 'manage_options',
134
-                'noheader'   => true,
135
-            ),
136
-            'reattempt_migration'                 => array(
137
-                'func'       => '_reattempt_migration',
138
-                'capability' => 'manage_options',
139
-                'noheader'   => true,
140
-            ),
141
-            'datetime_tools' => array(
142
-                'func' => '_datetime_tools',
143
-                'capability' => 'manage_options'
144
-            ),
145
-            'run_datetime_offset_fix' => array(
146
-                'func' => '_apply_datetime_offset',
147
-                'noheader' => true,
148
-                'headers_sent_route' => 'datetime_tools',
149
-                'capability' => 'manage_options'
150
-            )
151
-        );
152
-    }
153
-
154
-
155
-
156
-    protected function _set_page_config()
157
-    {
158
-        $this->_page_config = array(
159
-            'default'       => array(
160
-                'nav'           => array(
161
-                    'label' => esc_html__('Maintenance', 'event_espresso'),
162
-                    'order' => 10,
163
-                ),
164
-                'require_nonce' => false,
165
-            ),
166
-            'data_reset'    => array(
167
-                'nav'           => array(
168
-                    'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
169
-                    'order' => 20,
170
-                ),
171
-                'require_nonce' => false,
172
-            ),
173
-            'datetime_tools' => array(
174
-                'nav' => array(
175
-                    'label' => esc_html__('Datetime Utilities', 'event_espresso'),
176
-                    'order' => 25
177
-                ),
178
-                'require_nonce' => false,
179
-            ),
180
-            'system_status' => array(
181
-                'nav'           => array(
182
-                    'label' => esc_html__("System Information", "event_espresso"),
183
-                    'order' => 30,
184
-                ),
185
-                'require_nonce' => false,
186
-            ),
187
-        );
188
-    }
189
-
190
-
191
-
192
-    /**
193
-     * default maintenance page. If we're in maintenance mode level 2, then we need to show
194
-     * the migration scripts and all that UI.
195
-     */
196
-    public function _maintenance()
197
-    {
198
-        //it all depends if we're in maintenance model level 1 (frontend-only) or
199
-        //level 2 (everything except maintenance page)
200
-        try {
201
-            //get the current maintenance level and check if
202
-            //we are removed
203
-            $mm = EE_Maintenance_Mode::instance()->level();
204
-            $placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
205
-            if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
206
-                //we just took the site out of maintenance mode, so notify the user.
207
-                //unfortunately this message appears to be echoed on the NEXT page load...
208
-                //oh well, we should really be checking for this on addon deactivation anyways
209
-                EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required',
210
-                    'event_espresso'));
211
-                $this->_process_notices(array('page' => 'espresso_maintenance_settings'), false);
212
-            }
213
-            //in case an exception is thrown while trying to handle migrations
214
-            switch (EE_Maintenance_Mode::instance()->level()) {
215
-                case EE_Maintenance_Mode::level_0_not_in_maintenance:
216
-                case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
217
-                    $show_maintenance_switch = true;
218
-                    $show_backup_db_text = false;
219
-                    $show_migration_progress = false;
220
-                    $script_names = array();
221
-                    $addons_should_be_upgraded_first = false;
222
-                    break;
223
-                case EE_Maintenance_Mode::level_2_complete_maintenance:
224
-                    $show_maintenance_switch = false;
225
-                    $show_migration_progress = true;
226
-                    if (isset($this->_req_data['continue_migration'])) {
227
-                        $show_backup_db_text = false;
228
-                    } else {
229
-                        $show_backup_db_text = true;
230
-                    }
231
-                    $scripts_needing_to_run = EE_Data_Migration_Manager::instance()
232
-                                                                       ->check_for_applicable_data_migration_scripts();
233
-                    $addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating();
234
-                    $script_names = array();
235
-                    $current_script = null;
236
-                    foreach ($scripts_needing_to_run as $script) {
237
-                        if ($script instanceof EE_Data_Migration_Script_Base) {
238
-                            if ( ! $current_script) {
239
-                                $current_script = $script;
240
-                                $current_script->migration_page_hooks();
241
-                            }
242
-                            $script_names[] = $script->pretty_name();
243
-                        }
244
-                    }
245
-                    break;
246
-            }
247
-            $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
248
-            $exception_thrown = false;
249
-        } catch (EE_Error $e) {
250
-            EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
251
-            //now, just so we can display the page correctly, make a error migration script stage object
252
-            //and also put the error on it. It only persists for the duration of this request
253
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
254
-            $most_recent_migration->add_error($e->getMessage());
255
-            $exception_thrown = true;
256
-        }
257
-        $current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set();
258
-        $current_db_state = str_replace('.decaf', '', $current_db_state);
259
-        if ($exception_thrown
260
-            || ($most_recent_migration
261
-                && $most_recent_migration instanceof EE_Data_Migration_Script_Base
262
-                && $most_recent_migration->is_broken()
263
-            )
264
-        ) {
265
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
266
-            $this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267
-            $this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268
-                                                                                        'success' => '0',
269
-            ), EE_MAINTENANCE_ADMIN_URL);
270
-        } elseif ($addons_should_be_upgraded_first) {
271
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
272
-        } else {
273
-            if ($most_recent_migration
274
-                && $most_recent_migration instanceof EE_Data_Migration_Script_Base
275
-                && $most_recent_migration->can_continue()
276
-            ) {
277
-                $show_backup_db_text = false;
278
-                $show_continue_current_migration_script = true;
279
-                $show_most_recent_migration = true;
280
-            } elseif (isset($this->_req_data['continue_migration'])) {
281
-                $show_most_recent_migration = true;
282
-                $show_continue_current_migration_script = false;
283
-            } else {
284
-                $show_most_recent_migration = false;
285
-                $show_continue_current_migration_script = false;
286
-            }
287
-            if (isset($current_script)) {
288
-                $migrates_to = $current_script->migrates_to_version();
289
-                $plugin_slug = $migrates_to['slug'];
290
-                $new_version = $migrates_to['version'];
291
-                $this->_template_args = array_merge($this->_template_args, array(
292
-                    'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"),
293
-                        isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug),
294
-                    'next_db_state'    => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'),
295
-                        $new_version, $plugin_slug) : null,
296
-                ));
297
-            } else {
298
-                $this->_template_args['current_db_state'] = null;
299
-                $this->_template_args['next_db_state'] = null;
300
-            }
301
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
302
-            $this->_template_args = array_merge(
303
-                $this->_template_args,
304
-                array(
305
-                    'show_most_recent_migration'             => $show_most_recent_migration,
306
-                    //flag for showing the most recent migration's status and/or errors
307
-                    'show_migration_progress'                => $show_migration_progress,
308
-                    //flag for showing the option to run migrations and see their progress
309
-                    'show_backup_db_text'                    => $show_backup_db_text,
310
-                    //flag for showing text telling the user to backup their DB
311
-                    'show_maintenance_switch'                => $show_maintenance_switch,
312
-                    //flag for showing the option to change maintenance mode between levels 0 and 1
313
-                    'script_names'                           => $script_names,
314
-                    //array of names of scripts that have run
315
-                    'show_continue_current_migration_script' => $show_continue_current_migration_script,
316
-                    //flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
317
-                    'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
318
-                        EE_MAINTENANCE_ADMIN_URL),
319
-                    'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
320
-                        EE_MAINTENANCE_ADMIN_URL),
321
-                    'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'),
322
-                        EE_MAINTENANCE_ADMIN_URL),
323
-                    'ultimate_db_state'                      => sprintf(__("EE%s", 'event_espresso'),
324
-                        espresso_version()),
325
-                )
326
-            );
327
-            //make sure we have the form fields helper available. It usually is, but sometimes it isn't
328
-        }
329
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
330
-        //now render the migration options part, and put it in a variable
331
-        $migration_options_template_file = apply_filters(
332
-            'FHEE__ee_migration_page__migration_options_template',
333
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
334
-        );
335
-        $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
336
-        $this->_template_args['migration_options_html'] = $migration_options_html;
337
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338
-            $this->_template_args, true);
339
-        $this->display_admin_page_with_sidebar();
340
-    }
341
-
342
-
343
-
344
-    /**
345
-     * returns JSON and executes another step of the currently-executing data migration (called via ajax)
346
-     */
347
-    public function migration_step()
348
-    {
349
-        $this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request();
350
-        $this->_return_json();
351
-    }
352
-
353
-
354
-
355
-    /**
356
-     * Can be used by js when it notices a response with HTML in it in order
357
-     * to log the malformed response
358
-     */
359
-    public function add_error_to_migrations_ran()
360
-    {
361
-        EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']);
362
-        $this->_template_args['data'] = array('ok' => true);
363
-        $this->_return_json();
364
-    }
365
-
366
-
367
-
368
-    /**
369
-     * changes the maintenance level, provided there are still no migration scripts that should run
370
-     */
371
-    public function _change_maintenance_level()
372
-    {
373
-        $new_level = absint($this->_req_data['maintenance_mode_level']);
374
-        if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) {
375
-            EE_Maintenance_Mode::instance()->set_maintenance_level($new_level);
376
-            $success = true;
377
-        } else {
378
-            EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
379
-            $success = false;
380
-        }
381
-        $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
382
-    }
383
-
384
-
385
-
386
-    /**
387
-     * a tab with options for resetting and/or deleting EE data
388
-     *
389
-     * @throws \EE_Error
390
-     * @throws \DomainException
391
-     */
392
-    public function _data_reset_and_delete()
393
-    {
394
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
395
-        $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396
-            'reset_reservations',
397
-            'reset_reservations',
398
-            array(),
399
-            'button button-primary ee-confirm',
400
-            '',
401
-            false
402
-        );
403
-        $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
404
-            'reset_capabilities',
405
-            'reset_capabilities',
406
-            array(),
407
-            'button button-primary ee-confirm',
408
-            '',
409
-            false
410
-        );
411
-        $this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
412
-            array('action' => 'delete_db'),
413
-            EE_MAINTENANCE_ADMIN_URL
414
-        );
415
-        $this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
416
-            array('action' => 'reset_db'),
417
-            EE_MAINTENANCE_ADMIN_URL
418
-        );
419
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
420
-            $this->_template_path,
421
-            $this->_template_args,
422
-            true
423
-        );
424
-        $this->display_admin_page_with_sidebar();
425
-    }
426
-
427
-
428
-
429
-    protected function _reset_reservations()
430
-    {
431
-        if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432
-            EE_Error::add_success(
433
-                __(
434
-                    'Ticket and datetime reserved counts have been successfully reset.',
435
-                    'event_espresso'
436
-                )
437
-            );
438
-        } else {
439
-            EE_Error::add_success(
440
-                __(
441
-                    'Ticket and datetime reserved counts were correct and did not need resetting.',
442
-                    'event_espresso'
443
-                )
444
-            );
445
-        }
446
-        $this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true);
447
-    }
448
-
449
-
450
-
451
-    protected function _reset_capabilities()
452
-    {
453
-        EE_Registry::instance()->CAP->init_caps(true);
454
-        EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.',
455
-            'event_espresso'));
456
-        $this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true);
457
-    }
458
-
459
-
460
-
461
-    /**
462
-     * resets the DMSs so we can attempt to continue migrating after a fatal error
463
-     * (only a good idea when someone has somehow tried ot fix whatever caused
464
-     * the fatal error in teh first place)
465
-     */
466
-    protected function _reattempt_migration()
467
-    {
468
-        EE_Data_Migration_Manager::instance()->reattempt();
469
-        $this->_redirect_after_action(false, '', '', array('action' => 'default'), true);
470
-    }
471
-
472
-
473
-
474
-    /**
475
-     * shows the big ol' System Information page
476
-     */
477
-    public function _system_status()
478
-    {
479
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
480
-        $this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481
-        $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482
-            array(
483
-                'action' => 'download_system_status',
484
-            ),
485
-            EE_MAINTENANCE_ADMIN_URL
486
-        );
487
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
488
-            $this->_template_args, true);
489
-        $this->display_admin_page_with_sidebar();
490
-    }
491
-
492
-    /**
493
-     * Downloads an HTML file of the system status that can be easily stored or emailed
494
-     */
495
-    public function _download_system_status()
496
-    {
497
-        $status_info = EEM_System_Status::instance()->get_system_stati();
498
-        header( 'Content-Disposition: attachment' );
499
-        header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
500
-        echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
-        echo "<h1>System Information for " . site_url() . "</h1>";
502
-        echo EEH_Template::layout_array_as_table( $status_info );
503
-        die;
504
-    }
505
-
506
-
507
-
508
-    public function _send_migration_crash_report()
509
-    {
510
-        $from = $this->_req_data['from'];
511
-        $from_name = $this->_req_data['from_name'];
512
-        $body = $this->_req_data['body'];
513
-        try {
514
-            $success = wp_mail(EE_SUPPORT_EMAIL,
515
-                'Migration Crash Report',
516
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
517
-                array(
518
-                    "from:$from_name<$from>",
519
-                    //					'content-type:text/html charset=UTF-8'
520
-                ));
521
-        } catch (Exception $e) {
522
-            $success = false;
523
-        }
524
-        $this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"),
525
-            esc_html__("sent", "event_espresso"),
526
-            array('success' => $success, 'action' => 'confirm_migration_crash_report_sent'));
527
-    }
528
-
529
-
530
-
531
-    public function _confirm_migration_crash_report_sent()
532
-    {
533
-        try {
534
-            $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
535
-        } catch (EE_Error $e) {
536
-            EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
537
-            //now, just so we can display the page correctly, make a error migration script stage object
538
-            //and also put the error on it. It only persists for the duration of this request
539
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
540
-            $most_recent_migration->add_error($e->getMessage());
541
-        }
542
-        $success = $this->_req_data['success'] == '1' ? true : false;
543
-        $this->_template_args['success'] = $success;
544
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;
545
-        $this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
546
-            EE_MAINTENANCE_ADMIN_URL);
547
-        $this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
548
-            EE_MAINTENANCE_ADMIN_URL);
549
-        $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550
-            EE_MAINTENANCE_ADMIN_URL);
551
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
552
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553
-            $this->_template_args, true);
554
-        $this->display_admin_page_with_sidebar();
555
-    }
556
-
557
-
558
-
559
-    /**
560
-     * Resets the entire EE4 database.
561
-     * Currently basically only sets up ee4 database for a fresh install- doesn't
562
-     * actually clean out the old wp options, or cpts (although does erase old ee table data)
563
-     *
564
-     * @param boolean $nuke_old_ee4_data controls whether or not we
565
-     *                                   destroy the old ee4 data, or just try initializing ee4 default data
566
-     */
567
-    public function _reset_db($nuke_old_ee4_data = true)
568
-    {
569
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
570
-        if ($nuke_old_ee4_data) {
571
-            EEH_Activation::delete_all_espresso_cpt_data();
572
-            EEH_Activation::delete_all_espresso_tables_and_data(false);
573
-            EEH_Activation::remove_cron_tasks();
574
-        }
575
-        //make sure when we reset the registry's config that it
576
-        //switches to using the new singleton
577
-        EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
578
-        EE_System::instance()->initialize_db_if_no_migrations_required(true);
579
-        EE_System::instance()->redirect_to_about_ee();
580
-    }
581
-
582
-
583
-
584
-    /**
585
-     * Deletes ALL EE tables, Records, and Options from the database.
586
-     */
587
-    public function _delete_db()
588
-    {
589
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
590
-        EEH_Activation::delete_all_espresso_cpt_data();
591
-        EEH_Activation::delete_all_espresso_tables_and_data();
592
-        EEH_Activation::remove_cron_tasks();
593
-        EEH_Activation::deactivate_event_espresso();
594
-        wp_safe_redirect(admin_url('plugins.php'));
595
-        exit;
596
-    }
597
-
598
-
599
-
600
-    /**
601
-     * sets up EE4 to rerun the migrations from ee3 to ee4
602
-     */
603
-    public function _rerun_migration_from_ee3()
604
-    {
605
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
606
-        EEH_Activation::delete_all_espresso_cpt_data();
607
-        EEH_Activation::delete_all_espresso_tables_and_data(false);
608
-        //set the db state to something that will require migrations
609
-        update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
610
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
611
-        $this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso'));
612
-    }
613
-
614
-
615
-
616
-    //none of the below group are currently used for Gateway Settings
617
-    protected function _add_screen_options()
618
-    {
619
-    }
620
-
621
-
622
-
623
-    protected function _add_feature_pointers()
624
-    {
625
-    }
626
-
32
+	/**
33
+	 * @var EE_Datetime_Offset_Fix_Form
34
+	 */
35
+	protected $datetime_fix_offset_form;
36
+
37
+
38
+
39
+	protected function _init_page_props()
40
+	{
41
+		$this->page_slug = EE_MAINTENANCE_PG_SLUG;
42
+		$this->page_label = EE_MAINTENANCE_LABEL;
43
+		$this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL;
44
+		$this->_admin_base_path = EE_MAINTENANCE_ADMIN;
45
+	}
46
+
47
+
48
+
49
+	protected function _ajax_hooks()
50
+	{
51
+		add_action('wp_ajax_migration_step', array($this, 'migration_step'));
52
+		add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran'));
53
+	}
54
+
55
+
56
+
57
+	protected function _define_page_props()
58
+	{
59
+		$this->_admin_page_title = EE_MAINTENANCE_LABEL;
60
+		$this->_labels = array(
61
+			'buttons' => array(
62
+				'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
63
+				'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
64
+			),
65
+		);
66
+	}
67
+
68
+
69
+
70
+	protected function _set_page_routes()
71
+	{
72
+		$this->_page_routes = array(
73
+			'default'                             => array(
74
+				'func'       => '_maintenance',
75
+				'capability' => 'manage_options',
76
+			),
77
+			'change_maintenance_level'            => array(
78
+				'func'       => '_change_maintenance_level',
79
+				'capability' => 'manage_options',
80
+				'noheader'   => true,
81
+			),
82
+			'system_status'                       => array(
83
+				'func'       => '_system_status',
84
+				'capability' => 'manage_options',
85
+			),
86
+			'download_system_status' => array(
87
+				'func'       => '_download_system_status',
88
+				'capability' => 'manage_options',
89
+				'noheader'   => true,
90
+			),
91
+			'send_migration_crash_report'         => array(
92
+				'func'       => '_send_migration_crash_report',
93
+				'capability' => 'manage_options',
94
+				'noheader'   => true,
95
+			),
96
+			'confirm_migration_crash_report_sent' => array(
97
+				'func'       => '_confirm_migration_crash_report_sent',
98
+				'capability' => 'manage_options',
99
+			),
100
+			'data_reset'                          => array(
101
+				'func'       => '_data_reset_and_delete',
102
+				'capability' => 'manage_options',
103
+			),
104
+			'reset_db'                            => array(
105
+				'func'       => '_reset_db',
106
+				'capability' => 'manage_options',
107
+				'noheader'   => true,
108
+				'args'       => array('nuke_old_ee4_data' => true),
109
+			),
110
+			'start_with_fresh_ee4_db'             => array(
111
+				'func'       => '_reset_db',
112
+				'capability' => 'manage_options',
113
+				'noheader'   => true,
114
+				'args'       => array('nuke_old_ee4_data' => false),
115
+			),
116
+			'delete_db'                           => array(
117
+				'func'       => '_delete_db',
118
+				'capability' => 'manage_options',
119
+				'noheader'   => true,
120
+			),
121
+			'rerun_migration_from_ee3'            => array(
122
+				'func'       => '_rerun_migration_from_ee3',
123
+				'capability' => 'manage_options',
124
+				'noheader'   => true,
125
+			),
126
+			'reset_reservations'                  => array(
127
+				'func'       => '_reset_reservations',
128
+				'capability' => 'manage_options',
129
+				'noheader'   => true,
130
+			),
131
+			'reset_capabilities'                  => array(
132
+				'func'       => '_reset_capabilities',
133
+				'capability' => 'manage_options',
134
+				'noheader'   => true,
135
+			),
136
+			'reattempt_migration'                 => array(
137
+				'func'       => '_reattempt_migration',
138
+				'capability' => 'manage_options',
139
+				'noheader'   => true,
140
+			),
141
+			'datetime_tools' => array(
142
+				'func' => '_datetime_tools',
143
+				'capability' => 'manage_options'
144
+			),
145
+			'run_datetime_offset_fix' => array(
146
+				'func' => '_apply_datetime_offset',
147
+				'noheader' => true,
148
+				'headers_sent_route' => 'datetime_tools',
149
+				'capability' => 'manage_options'
150
+			)
151
+		);
152
+	}
153
+
154
+
155
+
156
+	protected function _set_page_config()
157
+	{
158
+		$this->_page_config = array(
159
+			'default'       => array(
160
+				'nav'           => array(
161
+					'label' => esc_html__('Maintenance', 'event_espresso'),
162
+					'order' => 10,
163
+				),
164
+				'require_nonce' => false,
165
+			),
166
+			'data_reset'    => array(
167
+				'nav'           => array(
168
+					'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
169
+					'order' => 20,
170
+				),
171
+				'require_nonce' => false,
172
+			),
173
+			'datetime_tools' => array(
174
+				'nav' => array(
175
+					'label' => esc_html__('Datetime Utilities', 'event_espresso'),
176
+					'order' => 25
177
+				),
178
+				'require_nonce' => false,
179
+			),
180
+			'system_status' => array(
181
+				'nav'           => array(
182
+					'label' => esc_html__("System Information", "event_espresso"),
183
+					'order' => 30,
184
+				),
185
+				'require_nonce' => false,
186
+			),
187
+		);
188
+	}
189
+
190
+
191
+
192
+	/**
193
+	 * default maintenance page. If we're in maintenance mode level 2, then we need to show
194
+	 * the migration scripts and all that UI.
195
+	 */
196
+	public function _maintenance()
197
+	{
198
+		//it all depends if we're in maintenance model level 1 (frontend-only) or
199
+		//level 2 (everything except maintenance page)
200
+		try {
201
+			//get the current maintenance level and check if
202
+			//we are removed
203
+			$mm = EE_Maintenance_Mode::instance()->level();
204
+			$placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
205
+			if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
206
+				//we just took the site out of maintenance mode, so notify the user.
207
+				//unfortunately this message appears to be echoed on the NEXT page load...
208
+				//oh well, we should really be checking for this on addon deactivation anyways
209
+				EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required',
210
+					'event_espresso'));
211
+				$this->_process_notices(array('page' => 'espresso_maintenance_settings'), false);
212
+			}
213
+			//in case an exception is thrown while trying to handle migrations
214
+			switch (EE_Maintenance_Mode::instance()->level()) {
215
+				case EE_Maintenance_Mode::level_0_not_in_maintenance:
216
+				case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
217
+					$show_maintenance_switch = true;
218
+					$show_backup_db_text = false;
219
+					$show_migration_progress = false;
220
+					$script_names = array();
221
+					$addons_should_be_upgraded_first = false;
222
+					break;
223
+				case EE_Maintenance_Mode::level_2_complete_maintenance:
224
+					$show_maintenance_switch = false;
225
+					$show_migration_progress = true;
226
+					if (isset($this->_req_data['continue_migration'])) {
227
+						$show_backup_db_text = false;
228
+					} else {
229
+						$show_backup_db_text = true;
230
+					}
231
+					$scripts_needing_to_run = EE_Data_Migration_Manager::instance()
232
+																	   ->check_for_applicable_data_migration_scripts();
233
+					$addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating();
234
+					$script_names = array();
235
+					$current_script = null;
236
+					foreach ($scripts_needing_to_run as $script) {
237
+						if ($script instanceof EE_Data_Migration_Script_Base) {
238
+							if ( ! $current_script) {
239
+								$current_script = $script;
240
+								$current_script->migration_page_hooks();
241
+							}
242
+							$script_names[] = $script->pretty_name();
243
+						}
244
+					}
245
+					break;
246
+			}
247
+			$most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
248
+			$exception_thrown = false;
249
+		} catch (EE_Error $e) {
250
+			EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
251
+			//now, just so we can display the page correctly, make a error migration script stage object
252
+			//and also put the error on it. It only persists for the duration of this request
253
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
254
+			$most_recent_migration->add_error($e->getMessage());
255
+			$exception_thrown = true;
256
+		}
257
+		$current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set();
258
+		$current_db_state = str_replace('.decaf', '', $current_db_state);
259
+		if ($exception_thrown
260
+			|| ($most_recent_migration
261
+				&& $most_recent_migration instanceof EE_Data_Migration_Script_Base
262
+				&& $most_recent_migration->is_broken()
263
+			)
264
+		) {
265
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
266
+			$this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267
+			$this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268
+																						'success' => '0',
269
+			), EE_MAINTENANCE_ADMIN_URL);
270
+		} elseif ($addons_should_be_upgraded_first) {
271
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
272
+		} else {
273
+			if ($most_recent_migration
274
+				&& $most_recent_migration instanceof EE_Data_Migration_Script_Base
275
+				&& $most_recent_migration->can_continue()
276
+			) {
277
+				$show_backup_db_text = false;
278
+				$show_continue_current_migration_script = true;
279
+				$show_most_recent_migration = true;
280
+			} elseif (isset($this->_req_data['continue_migration'])) {
281
+				$show_most_recent_migration = true;
282
+				$show_continue_current_migration_script = false;
283
+			} else {
284
+				$show_most_recent_migration = false;
285
+				$show_continue_current_migration_script = false;
286
+			}
287
+			if (isset($current_script)) {
288
+				$migrates_to = $current_script->migrates_to_version();
289
+				$plugin_slug = $migrates_to['slug'];
290
+				$new_version = $migrates_to['version'];
291
+				$this->_template_args = array_merge($this->_template_args, array(
292
+					'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"),
293
+						isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug),
294
+					'next_db_state'    => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'),
295
+						$new_version, $plugin_slug) : null,
296
+				));
297
+			} else {
298
+				$this->_template_args['current_db_state'] = null;
299
+				$this->_template_args['next_db_state'] = null;
300
+			}
301
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
302
+			$this->_template_args = array_merge(
303
+				$this->_template_args,
304
+				array(
305
+					'show_most_recent_migration'             => $show_most_recent_migration,
306
+					//flag for showing the most recent migration's status and/or errors
307
+					'show_migration_progress'                => $show_migration_progress,
308
+					//flag for showing the option to run migrations and see their progress
309
+					'show_backup_db_text'                    => $show_backup_db_text,
310
+					//flag for showing text telling the user to backup their DB
311
+					'show_maintenance_switch'                => $show_maintenance_switch,
312
+					//flag for showing the option to change maintenance mode between levels 0 and 1
313
+					'script_names'                           => $script_names,
314
+					//array of names of scripts that have run
315
+					'show_continue_current_migration_script' => $show_continue_current_migration_script,
316
+					//flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
317
+					'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
318
+						EE_MAINTENANCE_ADMIN_URL),
319
+					'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
320
+						EE_MAINTENANCE_ADMIN_URL),
321
+					'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'),
322
+						EE_MAINTENANCE_ADMIN_URL),
323
+					'ultimate_db_state'                      => sprintf(__("EE%s", 'event_espresso'),
324
+						espresso_version()),
325
+				)
326
+			);
327
+			//make sure we have the form fields helper available. It usually is, but sometimes it isn't
328
+		}
329
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
330
+		//now render the migration options part, and put it in a variable
331
+		$migration_options_template_file = apply_filters(
332
+			'FHEE__ee_migration_page__migration_options_template',
333
+			EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
334
+		);
335
+		$migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
336
+		$this->_template_args['migration_options_html'] = $migration_options_html;
337
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338
+			$this->_template_args, true);
339
+		$this->display_admin_page_with_sidebar();
340
+	}
341
+
342
+
343
+
344
+	/**
345
+	 * returns JSON and executes another step of the currently-executing data migration (called via ajax)
346
+	 */
347
+	public function migration_step()
348
+	{
349
+		$this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request();
350
+		$this->_return_json();
351
+	}
352
+
353
+
354
+
355
+	/**
356
+	 * Can be used by js when it notices a response with HTML in it in order
357
+	 * to log the malformed response
358
+	 */
359
+	public function add_error_to_migrations_ran()
360
+	{
361
+		EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']);
362
+		$this->_template_args['data'] = array('ok' => true);
363
+		$this->_return_json();
364
+	}
365
+
366
+
367
+
368
+	/**
369
+	 * changes the maintenance level, provided there are still no migration scripts that should run
370
+	 */
371
+	public function _change_maintenance_level()
372
+	{
373
+		$new_level = absint($this->_req_data['maintenance_mode_level']);
374
+		if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) {
375
+			EE_Maintenance_Mode::instance()->set_maintenance_level($new_level);
376
+			$success = true;
377
+		} else {
378
+			EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
379
+			$success = false;
380
+		}
381
+		$this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
382
+	}
383
+
384
+
385
+
386
+	/**
387
+	 * a tab with options for resetting and/or deleting EE data
388
+	 *
389
+	 * @throws \EE_Error
390
+	 * @throws \DomainException
391
+	 */
392
+	public function _data_reset_and_delete()
393
+	{
394
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
395
+		$this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396
+			'reset_reservations',
397
+			'reset_reservations',
398
+			array(),
399
+			'button button-primary ee-confirm',
400
+			'',
401
+			false
402
+		);
403
+		$this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
404
+			'reset_capabilities',
405
+			'reset_capabilities',
406
+			array(),
407
+			'button button-primary ee-confirm',
408
+			'',
409
+			false
410
+		);
411
+		$this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
412
+			array('action' => 'delete_db'),
413
+			EE_MAINTENANCE_ADMIN_URL
414
+		);
415
+		$this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
416
+			array('action' => 'reset_db'),
417
+			EE_MAINTENANCE_ADMIN_URL
418
+		);
419
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
420
+			$this->_template_path,
421
+			$this->_template_args,
422
+			true
423
+		);
424
+		$this->display_admin_page_with_sidebar();
425
+	}
426
+
427
+
428
+
429
+	protected function _reset_reservations()
430
+	{
431
+		if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432
+			EE_Error::add_success(
433
+				__(
434
+					'Ticket and datetime reserved counts have been successfully reset.',
435
+					'event_espresso'
436
+				)
437
+			);
438
+		} else {
439
+			EE_Error::add_success(
440
+				__(
441
+					'Ticket and datetime reserved counts were correct and did not need resetting.',
442
+					'event_espresso'
443
+				)
444
+			);
445
+		}
446
+		$this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true);
447
+	}
448
+
449
+
450
+
451
+	protected function _reset_capabilities()
452
+	{
453
+		EE_Registry::instance()->CAP->init_caps(true);
454
+		EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.',
455
+			'event_espresso'));
456
+		$this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true);
457
+	}
458
+
459
+
460
+
461
+	/**
462
+	 * resets the DMSs so we can attempt to continue migrating after a fatal error
463
+	 * (only a good idea when someone has somehow tried ot fix whatever caused
464
+	 * the fatal error in teh first place)
465
+	 */
466
+	protected function _reattempt_migration()
467
+	{
468
+		EE_Data_Migration_Manager::instance()->reattempt();
469
+		$this->_redirect_after_action(false, '', '', array('action' => 'default'), true);
470
+	}
471
+
472
+
473
+
474
+	/**
475
+	 * shows the big ol' System Information page
476
+	 */
477
+	public function _system_status()
478
+	{
479
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
480
+		$this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481
+		$this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482
+			array(
483
+				'action' => 'download_system_status',
484
+			),
485
+			EE_MAINTENANCE_ADMIN_URL
486
+		);
487
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
488
+			$this->_template_args, true);
489
+		$this->display_admin_page_with_sidebar();
490
+	}
491
+
492
+	/**
493
+	 * Downloads an HTML file of the system status that can be easily stored or emailed
494
+	 */
495
+	public function _download_system_status()
496
+	{
497
+		$status_info = EEM_System_Status::instance()->get_system_stati();
498
+		header( 'Content-Disposition: attachment' );
499
+		header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
500
+		echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
+		echo "<h1>System Information for " . site_url() . "</h1>";
502
+		echo EEH_Template::layout_array_as_table( $status_info );
503
+		die;
504
+	}
505
+
506
+
507
+
508
+	public function _send_migration_crash_report()
509
+	{
510
+		$from = $this->_req_data['from'];
511
+		$from_name = $this->_req_data['from_name'];
512
+		$body = $this->_req_data['body'];
513
+		try {
514
+			$success = wp_mail(EE_SUPPORT_EMAIL,
515
+				'Migration Crash Report',
516
+				$body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
517
+				array(
518
+					"from:$from_name<$from>",
519
+					//					'content-type:text/html charset=UTF-8'
520
+				));
521
+		} catch (Exception $e) {
522
+			$success = false;
523
+		}
524
+		$this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"),
525
+			esc_html__("sent", "event_espresso"),
526
+			array('success' => $success, 'action' => 'confirm_migration_crash_report_sent'));
527
+	}
528
+
529
+
530
+
531
+	public function _confirm_migration_crash_report_sent()
532
+	{
533
+		try {
534
+			$most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
535
+		} catch (EE_Error $e) {
536
+			EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
537
+			//now, just so we can display the page correctly, make a error migration script stage object
538
+			//and also put the error on it. It only persists for the duration of this request
539
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
540
+			$most_recent_migration->add_error($e->getMessage());
541
+		}
542
+		$success = $this->_req_data['success'] == '1' ? true : false;
543
+		$this->_template_args['success'] = $success;
544
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;
545
+		$this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
546
+			EE_MAINTENANCE_ADMIN_URL);
547
+		$this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
548
+			EE_MAINTENANCE_ADMIN_URL);
549
+		$this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550
+			EE_MAINTENANCE_ADMIN_URL);
551
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
552
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553
+			$this->_template_args, true);
554
+		$this->display_admin_page_with_sidebar();
555
+	}
556
+
557
+
558
+
559
+	/**
560
+	 * Resets the entire EE4 database.
561
+	 * Currently basically only sets up ee4 database for a fresh install- doesn't
562
+	 * actually clean out the old wp options, or cpts (although does erase old ee table data)
563
+	 *
564
+	 * @param boolean $nuke_old_ee4_data controls whether or not we
565
+	 *                                   destroy the old ee4 data, or just try initializing ee4 default data
566
+	 */
567
+	public function _reset_db($nuke_old_ee4_data = true)
568
+	{
569
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
570
+		if ($nuke_old_ee4_data) {
571
+			EEH_Activation::delete_all_espresso_cpt_data();
572
+			EEH_Activation::delete_all_espresso_tables_and_data(false);
573
+			EEH_Activation::remove_cron_tasks();
574
+		}
575
+		//make sure when we reset the registry's config that it
576
+		//switches to using the new singleton
577
+		EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
578
+		EE_System::instance()->initialize_db_if_no_migrations_required(true);
579
+		EE_System::instance()->redirect_to_about_ee();
580
+	}
581
+
582
+
583
+
584
+	/**
585
+	 * Deletes ALL EE tables, Records, and Options from the database.
586
+	 */
587
+	public function _delete_db()
588
+	{
589
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
590
+		EEH_Activation::delete_all_espresso_cpt_data();
591
+		EEH_Activation::delete_all_espresso_tables_and_data();
592
+		EEH_Activation::remove_cron_tasks();
593
+		EEH_Activation::deactivate_event_espresso();
594
+		wp_safe_redirect(admin_url('plugins.php'));
595
+		exit;
596
+	}
597
+
598
+
599
+
600
+	/**
601
+	 * sets up EE4 to rerun the migrations from ee3 to ee4
602
+	 */
603
+	public function _rerun_migration_from_ee3()
604
+	{
605
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
606
+		EEH_Activation::delete_all_espresso_cpt_data();
607
+		EEH_Activation::delete_all_espresso_tables_and_data(false);
608
+		//set the db state to something that will require migrations
609
+		update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
610
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
611
+		$this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso'));
612
+	}
613
+
614
+
615
+
616
+	//none of the below group are currently used for Gateway Settings
617
+	protected function _add_screen_options()
618
+	{
619
+	}
620
+
621
+
622
+
623
+	protected function _add_feature_pointers()
624
+	{
625
+	}
626
+
627 627
 
628 628
 
629
-    public function admin_init()
630
-    {
631
-    }
632
-
633
-
634
-
635
-    public function admin_notices()
636
-    {
637
-    }
638
-
629
+	public function admin_init()
630
+	{
631
+	}
632
+
633
+
634
+
635
+	public function admin_notices()
636
+	{
637
+	}
638
+
639 639
 
640 640
 
641
-    public function admin_footer_scripts()
642
-    {
643
-    }
641
+	public function admin_footer_scripts()
642
+	{
643
+	}
644 644
 
645 645
 
646 646
 
647
-    public function load_scripts_styles()
648
-    {
649
-        wp_enqueue_script('ee_admin_js');
647
+	public function load_scripts_styles()
648
+	{
649
+		wp_enqueue_script('ee_admin_js');
650 650
 //		wp_enqueue_media();
651 651
 //		wp_enqueue_script('media-upload');
652
-        wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
653
-            EVENT_ESPRESSO_VERSION, true);
654
-        wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
655
-            EVENT_ESPRESSO_VERSION);
656
-        wp_enqueue_style('espresso_maintenance');
657
-        //localize script stuff
658
-        wp_localize_script('ee-maintenance', 'ee_maintenance', array(
659
-            'migrating'                        => esc_html__("Updating Database...", "event_espresso"),
660
-            'next'                             => esc_html__("Next", "event_espresso"),
661
-            'fatal_error'                      => esc_html__("A Fatal Error Has Occurred", "event_espresso"),
662
-            'click_next_when_ready'            => esc_html__(
663
-                "The current Database Update has ended. Click 'next' when ready to proceed",
664
-                "event_espresso"
665
-            ),
666
-            'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
667
-            'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
668
-            'status_completed'                 => EE_Data_Migration_Manager::status_completed,
669
-            'confirm'                          => esc_html__(
670
-                'Are you sure you want to do this? It CANNOT be undone!',
671
-                'event_espresso'
672
-            ),
673
-            'confirm_skip_migration' => esc_html__(
674
-                'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
675
-                'event_espresso'
676
-            )
677
-        ));
678
-    }
679
-
680
-
681
-
682
-    public function load_scripts_styles_default()
683
-    {
684
-        //styles
652
+		wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
653
+			EVENT_ESPRESSO_VERSION, true);
654
+		wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
655
+			EVENT_ESPRESSO_VERSION);
656
+		wp_enqueue_style('espresso_maintenance');
657
+		//localize script stuff
658
+		wp_localize_script('ee-maintenance', 'ee_maintenance', array(
659
+			'migrating'                        => esc_html__("Updating Database...", "event_espresso"),
660
+			'next'                             => esc_html__("Next", "event_espresso"),
661
+			'fatal_error'                      => esc_html__("A Fatal Error Has Occurred", "event_espresso"),
662
+			'click_next_when_ready'            => esc_html__(
663
+				"The current Database Update has ended. Click 'next' when ready to proceed",
664
+				"event_espresso"
665
+			),
666
+			'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
667
+			'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
668
+			'status_completed'                 => EE_Data_Migration_Manager::status_completed,
669
+			'confirm'                          => esc_html__(
670
+				'Are you sure you want to do this? It CANNOT be undone!',
671
+				'event_espresso'
672
+			),
673
+			'confirm_skip_migration' => esc_html__(
674
+				'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
675
+				'event_espresso'
676
+			)
677
+		));
678
+	}
679
+
680
+
681
+
682
+	public function load_scripts_styles_default()
683
+	{
684
+		//styles
685 685
 //		wp_enqueue_style('ee-text-links');
686 686
 //		//scripts
687 687
 //		wp_enqueue_script('ee-text-links');
688
-    }
689
-
690
-
691
-    /**
692
-     * Enqueue scripts and styles for the datetime tools page.
693
-     */
694
-    public function load_scripts_styles_datetime_tools()
695
-    {
696
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
697
-    }
698
-
699
-
700
-    protected function _datetime_tools()
701
-    {
702
-        $form_action = EE_Admin_Page::add_query_args_and_nonce(
703
-            array(
704
-                'action' => 'run_datetime_offset_fix',
705
-                'return_action' => $this->_req_action
706
-            ),
707
-            EE_MAINTENANCE_ADMIN_URL
708
-        );
709
-        $form = $this->_get_datetime_offset_fix_form();
710
-        $this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso');
711
-        $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
712
-                                                      . $form->get_html_and_js()
713
-                                                      . $form->form_close();
714
-        $this->display_admin_page_with_no_sidebar();
715
-    }
716
-
717
-
718
-
719
-    protected function _get_datetime_offset_fix_form()
720
-    {
721
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
-            $this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
723
-                array(
724
-                    'name' => 'datetime_offset_fix_option',
725
-                    'layout_strategy' => new EE_Admin_Two_Column_Layout(),
726
-                    'subsections' => array(
727
-                        'title' => new EE_Form_Section_HTML(
728
-                            EEH_HTML::h2(
729
-                                esc_html__('Datetime Offset Tool', 'event_espresso')
730
-                            )
731
-                        ),
732
-                        'explanation' => new EE_Form_Section_HTML(
733
-                            EEH_HTML::p(
734
-                                esc_html__(
735
-                                    'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
736
-                                    'event_espresso'
737
-                                )
738
-                            )
739
-                            . EEH_HTML::p(
740
-                                esc_html__(
741
-                                    'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
742
-                                    'event_espresso'
743
-                                )
744
-                            )
745
-                        ),
746
-                        'offset_input' => new EE_Float_Input(
747
-                            array(
748
-                                'html_name' => 'offset_for_datetimes',
749
-                                'html_label_text' => esc_html__(
750
-                                    'Offset to apply (in hours):',
751
-                                    'event_espresso'
752
-                                ),
753
-                                'min_value' => '-12',
754
-                                'max_value' => '14',
755
-                                'step_value' => '.25',
756
-                                'default' => DatetimeOffsetFix::getOffset()
757
-                            )
758
-                        ),
759
-                        'date_range_explanation' => new EE_Form_Section_HTML(
760
-                            EEH_HTML::p(
761
-                                esc_html__(
762
-                                    'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
763
-                                    'event_espresso'
764
-                                )
765
-                            )
766
-                            . EEH_HTML::p(
767
-                                EEH_HTML::strong(
768
-                                    sprintf(
769
-                                        esc_html__(
770
-                                            'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
771
-                                            'event_espresso'
772
-                                        ),
773
-                                        '<a href="https://www.timeanddate.com/worldclock/converter.html">',
774
-                                        '</a>'
775
-                                    )
776
-                                )
777
-                            )
778
-                        ),
779
-                        'date_range_start_date' => new EE_Datepicker_Input(
780
-                            array(
781
-                                'html_name' => 'offset_date_start_range',
782
-                                'html_label_text' => esc_html__(
783
-                                    'Start Date for dates the offset applied to:',
784
-                                    'event_espresso'
785
-                                )
786
-                            )
787
-                        ),
788
-                        'date_range_end_date' => new EE_Datepicker_Input(
789
-                            array(
790
-                                'html_name' => 'offset_date_end_range',
791
-                                'html_label_text' => esc_html(
792
-                                    'End Date for dates the offset is applied to:',
793
-                                    'event_espresso'
794
-                                )
795
-                            )
796
-                        ),
797
-                        'submit' => new EE_Submit_Input(
798
-                            array(
799
-                                'html_label_text' => '',
800
-                                'default' => esc_html__('Apply Offset', 'event_espresso')
801
-                            )
802
-                        ),
803
-                    )
804
-                )
805
-            );
806
-        }
807
-        return $this->datetime_fix_offset_form;
808
-    }
809
-
810
-
811
-    /**
812
-     * Callback for the run_datetime_offset_fix route.
813
-     * @throws EE_Error
814
-     */
815
-    protected function _apply_datetime_offset()
816
-    {
817
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
818
-            $form = $this->_get_datetime_offset_fix_form();
819
-            $form->receive_form_submission($this->_req_data);
820
-            if ($form->is_valid()) {
821
-                //save offset data so batch processor can get it.
822
-                DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
823
-                $utc_timezone = new DateTimeZone('UTC');
824
-                $date_range_start_date = DateTime::createFromFormat(
825
-                    'm/d/Y H:i:s',
826
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
827
-                    $utc_timezone
828
-                );
829
-                $date_range_end_date = DateTime::createFromFormat(
830
-                        'm/d/Y H:i:s',
831
-                        $form->get_input_value('date_range_end_date') . ' 23:59:59',
832
-                        $utc_timezone
833
-                );
834
-                if ($date_range_start_date instanceof DateTime) {
835
-                    DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
836
-                }
837
-                if ($date_range_end_date instanceof DateTime) {
838
-                    DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
839
-                }
840
-                //redirect to batch tool
841
-                wp_redirect(
842
-                    EE_Admin_Page::add_query_args_and_nonce(
843
-                        array(
844
-                            'page' => 'espresso_batch',
845
-                            'batch' => 'job',
846
-                            'label' => esc_html__('Applying Offset', 'event_espresso'),
847
-                            'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
848
-                            'return_url' => urlencode(home_url(add_query_arg(null, null))),
849
-                        ),
850
-                        admin_url()
851
-                    )
852
-                );
853
-                exit;
854
-            }
855
-        }
856
-    }
688
+	}
689
+
690
+
691
+	/**
692
+	 * Enqueue scripts and styles for the datetime tools page.
693
+	 */
694
+	public function load_scripts_styles_datetime_tools()
695
+	{
696
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
697
+	}
698
+
699
+
700
+	protected function _datetime_tools()
701
+	{
702
+		$form_action = EE_Admin_Page::add_query_args_and_nonce(
703
+			array(
704
+				'action' => 'run_datetime_offset_fix',
705
+				'return_action' => $this->_req_action
706
+			),
707
+			EE_MAINTENANCE_ADMIN_URL
708
+		);
709
+		$form = $this->_get_datetime_offset_fix_form();
710
+		$this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso');
711
+		$this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
712
+													  . $form->get_html_and_js()
713
+													  . $form->form_close();
714
+		$this->display_admin_page_with_no_sidebar();
715
+	}
716
+
717
+
718
+
719
+	protected function _get_datetime_offset_fix_form()
720
+	{
721
+		if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
+			$this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
723
+				array(
724
+					'name' => 'datetime_offset_fix_option',
725
+					'layout_strategy' => new EE_Admin_Two_Column_Layout(),
726
+					'subsections' => array(
727
+						'title' => new EE_Form_Section_HTML(
728
+							EEH_HTML::h2(
729
+								esc_html__('Datetime Offset Tool', 'event_espresso')
730
+							)
731
+						),
732
+						'explanation' => new EE_Form_Section_HTML(
733
+							EEH_HTML::p(
734
+								esc_html__(
735
+									'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
736
+									'event_espresso'
737
+								)
738
+							)
739
+							. EEH_HTML::p(
740
+								esc_html__(
741
+									'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
742
+									'event_espresso'
743
+								)
744
+							)
745
+						),
746
+						'offset_input' => new EE_Float_Input(
747
+							array(
748
+								'html_name' => 'offset_for_datetimes',
749
+								'html_label_text' => esc_html__(
750
+									'Offset to apply (in hours):',
751
+									'event_espresso'
752
+								),
753
+								'min_value' => '-12',
754
+								'max_value' => '14',
755
+								'step_value' => '.25',
756
+								'default' => DatetimeOffsetFix::getOffset()
757
+							)
758
+						),
759
+						'date_range_explanation' => new EE_Form_Section_HTML(
760
+							EEH_HTML::p(
761
+								esc_html__(
762
+									'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
763
+									'event_espresso'
764
+								)
765
+							)
766
+							. EEH_HTML::p(
767
+								EEH_HTML::strong(
768
+									sprintf(
769
+										esc_html__(
770
+											'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
771
+											'event_espresso'
772
+										),
773
+										'<a href="https://www.timeanddate.com/worldclock/converter.html">',
774
+										'</a>'
775
+									)
776
+								)
777
+							)
778
+						),
779
+						'date_range_start_date' => new EE_Datepicker_Input(
780
+							array(
781
+								'html_name' => 'offset_date_start_range',
782
+								'html_label_text' => esc_html__(
783
+									'Start Date for dates the offset applied to:',
784
+									'event_espresso'
785
+								)
786
+							)
787
+						),
788
+						'date_range_end_date' => new EE_Datepicker_Input(
789
+							array(
790
+								'html_name' => 'offset_date_end_range',
791
+								'html_label_text' => esc_html(
792
+									'End Date for dates the offset is applied to:',
793
+									'event_espresso'
794
+								)
795
+							)
796
+						),
797
+						'submit' => new EE_Submit_Input(
798
+							array(
799
+								'html_label_text' => '',
800
+								'default' => esc_html__('Apply Offset', 'event_espresso')
801
+							)
802
+						),
803
+					)
804
+				)
805
+			);
806
+		}
807
+		return $this->datetime_fix_offset_form;
808
+	}
809
+
810
+
811
+	/**
812
+	 * Callback for the run_datetime_offset_fix route.
813
+	 * @throws EE_Error
814
+	 */
815
+	protected function _apply_datetime_offset()
816
+	{
817
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
818
+			$form = $this->_get_datetime_offset_fix_form();
819
+			$form->receive_form_submission($this->_req_data);
820
+			if ($form->is_valid()) {
821
+				//save offset data so batch processor can get it.
822
+				DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
823
+				$utc_timezone = new DateTimeZone('UTC');
824
+				$date_range_start_date = DateTime::createFromFormat(
825
+					'm/d/Y H:i:s',
826
+					$form->get_input_value('date_range_start_date') . ' 00:00:00',
827
+					$utc_timezone
828
+				);
829
+				$date_range_end_date = DateTime::createFromFormat(
830
+						'm/d/Y H:i:s',
831
+						$form->get_input_value('date_range_end_date') . ' 23:59:59',
832
+						$utc_timezone
833
+				);
834
+				if ($date_range_start_date instanceof DateTime) {
835
+					DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
836
+				}
837
+				if ($date_range_end_date instanceof DateTime) {
838
+					DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
839
+				}
840
+				//redirect to batch tool
841
+				wp_redirect(
842
+					EE_Admin_Page::add_query_args_and_nonce(
843
+						array(
844
+							'page' => 'espresso_batch',
845
+							'batch' => 'job',
846
+							'label' => esc_html__('Applying Offset', 'event_espresso'),
847
+							'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
848
+							'return_url' => urlencode(home_url(add_query_arg(null, null))),
849
+						),
850
+						admin_url()
851
+					)
852
+				);
853
+				exit;
854
+			}
855
+		}
856
+	}
857 857
 } //end Maintenance_Admin_Page class
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -262,13 +262,13 @@  discard block
 block discarded – undo
262 262
                 && $most_recent_migration->is_broken()
263 263
             )
264 264
         ) {
265
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
265
+            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_migration_was_borked_page.template.php';
266 266
             $this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267 267
             $this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268 268
                                                                                         'success' => '0',
269 269
             ), EE_MAINTENANCE_ADMIN_URL);
270 270
         } elseif ($addons_should_be_upgraded_first) {
271
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
271
+            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_upgrade_addons_before_migrating.template.php';
272 272
         } else {
273 273
             if ($most_recent_migration
274 274
                 && $most_recent_migration instanceof EE_Data_Migration_Script_Base
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
                 $this->_template_args['current_db_state'] = null;
299 299
                 $this->_template_args['next_db_state'] = null;
300 300
             }
301
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
301
+            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_migration_page.template.php';
302 302
             $this->_template_args = array_merge(
303 303
                 $this->_template_args,
304 304
                 array(
@@ -326,13 +326,13 @@  discard block
 block discarded – undo
326 326
             );
327 327
             //make sure we have the form fields helper available. It usually is, but sometimes it isn't
328 328
         }
329
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
329
+        $this->_template_args['most_recent_migration'] = $most_recent_migration; //the actual most recently ran migration
330 330
         //now render the migration options part, and put it in a variable
331 331
         $migration_options_template_file = apply_filters(
332 332
             'FHEE__ee_migration_page__migration_options_template',
333
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
333
+            EE_MAINTENANCE_TEMPLATE_PATH.'migration_options_from_ee4.template.php'
334 334
         );
335
-        $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
335
+        $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args, true);
336 336
         $this->_template_args['migration_options_html'] = $migration_options_html;
337 337
         $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338 338
             $this->_template_args, true);
@@ -391,7 +391,7 @@  discard block
 block discarded – undo
391 391
      */
392 392
     public function _data_reset_and_delete()
393 393
     {
394
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
394
+        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_data_reset_and_delete.template.php';
395 395
         $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396 396
             'reset_reservations',
397 397
             'reset_reservations',
@@ -428,7 +428,7 @@  discard block
 block discarded – undo
428 428
 
429 429
     protected function _reset_reservations()
430 430
     {
431
-        if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
431
+        if (\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432 432
             EE_Error::add_success(
433 433
                 __(
434 434
                     'Ticket and datetime reserved counts have been successfully reset.',
@@ -476,7 +476,7 @@  discard block
 block discarded – undo
476 476
      */
477 477
     public function _system_status()
478 478
     {
479
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
479
+        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_system_stati_page.template.php';
480 480
         $this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481 481
         $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482 482
             array(
@@ -495,11 +495,11 @@  discard block
 block discarded – undo
495 495
     public function _download_system_status()
496 496
     {
497 497
         $status_info = EEM_System_Status::instance()->get_system_stati();
498
-        header( 'Content-Disposition: attachment' );
499
-        header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
498
+        header('Content-Disposition: attachment');
499
+        header("Content-Disposition: attachment; filename=system_status_".sanitize_key(site_url()).".html");
500 500
         echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
-        echo "<h1>System Information for " . site_url() . "</h1>";
502
-        echo EEH_Template::layout_array_as_table( $status_info );
501
+        echo "<h1>System Information for ".site_url()."</h1>";
502
+        echo EEH_Template::layout_array_as_table($status_info);
503 503
         die;
504 504
     }
505 505
 
@@ -513,7 +513,7 @@  discard block
 block discarded – undo
513 513
         try {
514 514
             $success = wp_mail(EE_SUPPORT_EMAIL,
515 515
                 'Migration Crash Report',
516
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
516
+                $body."/r/n<br>".print_r(EEM_System_Status::instance()->get_system_stati(), true),
517 517
                 array(
518 518
                     "from:$from_name<$from>",
519 519
                     //					'content-type:text/html charset=UTF-8'
@@ -548,7 +548,7 @@  discard block
 block discarded – undo
548 548
             EE_MAINTENANCE_ADMIN_URL);
549 549
         $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550 550
             EE_MAINTENANCE_ADMIN_URL);
551
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
551
+        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_confirm_migration_crash_report_sent.template.php';
552 552
         $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553 553
             $this->_template_args, true);
554 554
         $this->display_admin_page_with_sidebar();
@@ -649,9 +649,9 @@  discard block
 block discarded – undo
649 649
         wp_enqueue_script('ee_admin_js');
650 650
 //		wp_enqueue_media();
651 651
 //		wp_enqueue_script('media-upload');
652
-        wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
652
+        wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL.'ee-maintenance.js', array('jquery'),
653 653
             EVENT_ESPRESSO_VERSION, true);
654
-        wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
654
+        wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL.'ee-maintenance.css', array(),
655 655
             EVENT_ESPRESSO_VERSION);
656 656
         wp_enqueue_style('espresso_maintenance');
657 657
         //localize script stuff
@@ -718,8 +718,8 @@  discard block
 block discarded – undo
718 718
 
719 719
     protected function _get_datetime_offset_fix_form()
720 720
     {
721
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
-            $this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
721
+        if ( ! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
+            $this->datetime_fix_offset_form = new EE_Form_Section_Proper(
723 723
                 array(
724 724
                     'name' => 'datetime_offset_fix_option',
725 725
                     'layout_strategy' => new EE_Admin_Two_Column_Layout(),
@@ -823,12 +823,12 @@  discard block
 block discarded – undo
823 823
                 $utc_timezone = new DateTimeZone('UTC');
824 824
                 $date_range_start_date = DateTime::createFromFormat(
825 825
                     'm/d/Y H:i:s',
826
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
826
+                    $form->get_input_value('date_range_start_date').' 00:00:00',
827 827
                     $utc_timezone
828 828
                 );
829 829
                 $date_range_end_date = DateTime::createFromFormat(
830 830
                         'm/d/Y H:i:s',
831
-                        $form->get_input_value('date_range_end_date') . ' 23:59:59',
831
+                        $form->get_input_value('date_range_end_date').' 23:59:59',
832 832
                         $utc_timezone
833 833
                 );
834 834
                 if ($date_range_start_date instanceof DateTime) {
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 1 patch
Indentation   +1260 added lines, -1260 removed lines patch added patch discarded remove patch
@@ -14,1264 +14,1264 @@
 block discarded – undo
14 14
 {
15 15
 
16 16
 
17
-    /**
18
-     * Extend_Events_Admin_Page constructor.
19
-     *
20
-     * @param bool $routing
21
-     */
22
-    public function __construct($routing = true)
23
-    {
24
-        parent::__construct($routing);
25
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
26
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
27
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
28
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
29
-        }
30
-    }
31
-
32
-
33
-    /**
34
-     * Sets routes.
35
-     */
36
-    protected function _extend_page_config()
37
-    {
38
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
39
-        //is there a evt_id in the request?
40
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
41
-            ? $this->_req_data['EVT_ID']
42
-            : 0;
43
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
44
-        //tkt_id?
45
-        $tkt_id             = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
46
-            ? $this->_req_data['TKT_ID']
47
-            : 0;
48
-        $new_page_routes    = array(
49
-            'duplicate_event'          => array(
50
-                'func'       => '_duplicate_event',
51
-                'capability' => 'ee_edit_event',
52
-                'obj_id'     => $evt_id,
53
-                'noheader'   => true,
54
-            ),
55
-            'ticket_list_table'        => array(
56
-                'func'       => '_tickets_overview_list_table',
57
-                'capability' => 'ee_read_default_tickets',
58
-            ),
59
-            'trash_ticket'             => array(
60
-                'func'       => '_trash_or_restore_ticket',
61
-                'capability' => 'ee_delete_default_ticket',
62
-                'obj_id'     => $tkt_id,
63
-                'noheader'   => true,
64
-                'args'       => array('trash' => true),
65
-            ),
66
-            'trash_tickets'            => array(
67
-                'func'       => '_trash_or_restore_ticket',
68
-                'capability' => 'ee_delete_default_tickets',
69
-                'noheader'   => true,
70
-                'args'       => array('trash' => true),
71
-            ),
72
-            'restore_ticket'           => array(
73
-                'func'       => '_trash_or_restore_ticket',
74
-                'capability' => 'ee_delete_default_ticket',
75
-                'obj_id'     => $tkt_id,
76
-                'noheader'   => true,
77
-            ),
78
-            'restore_tickets'          => array(
79
-                'func'       => '_trash_or_restore_ticket',
80
-                'capability' => 'ee_delete_default_tickets',
81
-                'noheader'   => true,
82
-            ),
83
-            'delete_ticket'            => array(
84
-                'func'       => '_delete_ticket',
85
-                'capability' => 'ee_delete_default_ticket',
86
-                'obj_id'     => $tkt_id,
87
-                'noheader'   => true,
88
-            ),
89
-            'delete_tickets'           => array(
90
-                'func'       => '_delete_ticket',
91
-                'capability' => 'ee_delete_default_tickets',
92
-                'noheader'   => true,
93
-            ),
94
-            'import_page'              => array(
95
-                'func'       => '_import_page',
96
-                'capability' => 'import',
97
-            ),
98
-            'import'                   => array(
99
-                'func'       => '_import_events',
100
-                'capability' => 'import',
101
-                'noheader'   => true,
102
-            ),
103
-            'import_events'            => array(
104
-                'func'       => '_import_events',
105
-                'capability' => 'import',
106
-                'noheader'   => true,
107
-            ),
108
-            'export_events'            => array(
109
-                'func'       => '_events_export',
110
-                'capability' => 'export',
111
-                'noheader'   => true,
112
-            ),
113
-            'export_categories'        => array(
114
-                'func'       => '_categories_export',
115
-                'capability' => 'export',
116
-                'noheader'   => true,
117
-            ),
118
-            'sample_export_file'       => array(
119
-                'func'       => '_sample_export_file',
120
-                'capability' => 'export',
121
-                'noheader'   => true,
122
-            ),
123
-            'update_template_settings' => array(
124
-                'func'       => '_update_template_settings',
125
-                'capability' => 'manage_options',
126
-                'noheader'   => true,
127
-            ),
128
-        );
129
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
130
-        //partial route/config override
131
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
132
-        $this->_page_config['create_new']['metaboxes'][]  = '_premium_event_editor_meta_boxes';
133
-        $this->_page_config['create_new']['qtips'][]      = 'EE_Event_Editor_Tips';
134
-        $this->_page_config['edit']['qtips'][]            = 'EE_Event_Editor_Tips';
135
-        $this->_page_config['edit']['metaboxes'][]        = '_premium_event_editor_meta_boxes';
136
-        $this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
137
-        //add tickets tab but only if there are more than one default ticket!
138
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
139
-            array(array('TKT_is_default' => 1)),
140
-            'TKT_ID',
141
-            true
142
-        );
143
-        if ($tkt_count > 1) {
144
-            $new_page_config = array(
145
-                'ticket_list_table' => array(
146
-                    'nav'           => array(
147
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
148
-                        'order' => 60,
149
-                    ),
150
-                    'list_table'    => 'Tickets_List_Table',
151
-                    'require_nonce' => false,
152
-                ),
153
-            );
154
-        }
155
-        //template settings
156
-        $new_page_config['template_settings'] = array(
157
-            'nav'           => array(
158
-                'label' => esc_html__('Templates', 'event_espresso'),
159
-                'order' => 30,
160
-            ),
161
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
162
-            'help_tabs'     => array(
163
-                'general_settings_templates_help_tab' => array(
164
-                    'title'    => esc_html__('Templates', 'event_espresso'),
165
-                    'filename' => 'general_settings_templates',
166
-                ),
167
-            ),
168
-            'help_tour'     => array('Templates_Help_Tour'),
169
-            'require_nonce' => false,
170
-        );
171
-        $this->_page_config                   = array_merge($this->_page_config, $new_page_config);
172
-        //add filters and actions
173
-        //modifying _views
174
-        add_filter(
175
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
176
-            array($this, 'add_additional_datetime_button'),
177
-            10,
178
-            2
179
-        );
180
-        add_filter(
181
-            'FHEE_event_datetime_metabox_clone_button_template',
182
-            array($this, 'add_datetime_clone_button'),
183
-            10,
184
-            2
185
-        );
186
-        add_filter(
187
-            'FHEE_event_datetime_metabox_timezones_template',
188
-            array($this, 'datetime_timezones_template'),
189
-            10,
190
-            2
191
-        );
192
-        //filters for event list table
193
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
194
-        add_filter(
195
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
196
-            array($this, 'extra_list_table_actions'),
197
-            10,
198
-            2
199
-        );
200
-        //legend item
201
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
202
-        add_action('admin_init', array($this, 'admin_init'));
203
-        //heartbeat stuff
204
-        add_filter('heartbeat_received', array($this, 'heartbeat_response'), 10, 2);
205
-    }
206
-
207
-
208
-    /**
209
-     * admin_init
210
-     */
211
-    public function admin_init()
212
-    {
213
-        EE_Registry::$i18n_js_strings = array_merge(
214
-            EE_Registry::$i18n_js_strings,
215
-            array(
216
-                'image_confirm'          => esc_html__(
217
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
218
-                    'event_espresso'
219
-                ),
220
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
221
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
222
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
223
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
224
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
225
-            )
226
-        );
227
-    }
228
-
229
-
230
-    /**
231
-     * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
232
-     * accordingly.
233
-     *
234
-     * @param array $response The existing heartbeat response array.
235
-     * @param array $data     The incoming data package.
236
-     * @return array  possibly appended response.
237
-     */
238
-    public function heartbeat_response($response, $data)
239
-    {
240
-        /**
241
-         * check whether count of tickets is approaching the potential
242
-         * limits for the server.
243
-         */
244
-        if (! empty($data['input_count'])) {
245
-            $response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check(
246
-                $data['input_count']
247
-            );
248
-        }
249
-        return $response;
250
-    }
251
-
252
-
253
-    /**
254
-     * Add per page screen options to the default ticket list table view.
255
-     */
256
-    protected function _add_screen_options_ticket_list_table()
257
-    {
258
-        $this->_per_page_screen_option();
259
-    }
260
-
261
-
262
-    /**
263
-     * @param string $return
264
-     * @param int    $id
265
-     * @param string $new_title
266
-     * @param string $new_slug
267
-     * @return string
268
-     */
269
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
270
-    {
271
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
272
-        //make sure this is only when editing
273
-        if (! empty($id)) {
274
-            $href   = EE_Admin_Page::add_query_args_and_nonce(
275
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
276
-                $this->_admin_base_url
277
-            );
278
-            $title  = esc_attr__('Duplicate Event', 'event_espresso');
279
-            $return .= '<a href="'
280
-                       . $href
281
-                       . '" title="'
282
-                       . $title
283
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
284
-                       . $title
285
-                       . '</a>';
286
-        }
287
-        return $return;
288
-    }
289
-
290
-
291
-    /**
292
-     * Set the list table views for the default ticket list table view.
293
-     */
294
-    public function _set_list_table_views_ticket_list_table()
295
-    {
296
-        $this->_views = array(
297
-            'all'     => array(
298
-                'slug'        => 'all',
299
-                'label'       => esc_html__('All', 'event_espresso'),
300
-                'count'       => 0,
301
-                'bulk_action' => array(
302
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
303
-                ),
304
-            ),
305
-            'trashed' => array(
306
-                'slug'        => 'trashed',
307
-                'label'       => esc_html__('Trash', 'event_espresso'),
308
-                'count'       => 0,
309
-                'bulk_action' => array(
310
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
311
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
312
-                ),
313
-            ),
314
-        );
315
-    }
316
-
317
-
318
-    /**
319
-     * Enqueue scripts and styles for the event editor.
320
-     */
321
-    public function load_scripts_styles_edit()
322
-    {
323
-        wp_register_script(
324
-            'ee-event-editor-heartbeat',
325
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
326
-            array('ee_admin_js', 'heartbeat'),
327
-            EVENT_ESPRESSO_VERSION,
328
-            true
329
-        );
330
-        wp_enqueue_script('ee-accounting');
331
-        //styles
332
-        wp_enqueue_style('espresso-ui-theme');
333
-        wp_enqueue_script('event_editor_js');
334
-        wp_enqueue_script('ee-event-editor-heartbeat');
335
-    }
336
-
337
-
338
-    /**
339
-     * Returns template for the additional datetime.
340
-     * @param $template
341
-     * @param $template_args
342
-     * @return mixed
343
-     * @throws DomainException
344
-     */
345
-    public function add_additional_datetime_button($template, $template_args)
346
-    {
347
-        return EEH_Template::display_template(
348
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
349
-            $template_args,
350
-            true
351
-        );
352
-    }
353
-
354
-
355
-    /**
356
-     * Returns the template for cloning a datetime.
357
-     * @param $template
358
-     * @param $template_args
359
-     * @return mixed
360
-     * @throws DomainException
361
-     */
362
-    public function add_datetime_clone_button($template, $template_args)
363
-    {
364
-        return EEH_Template::display_template(
365
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
366
-            $template_args,
367
-            true
368
-        );
369
-    }
370
-
371
-
372
-    /**
373
-     * Returns the template for datetime timezones.
374
-     * @param $template
375
-     * @param $template_args
376
-     * @return mixed
377
-     * @throws DomainException
378
-     */
379
-    public function datetime_timezones_template($template, $template_args)
380
-    {
381
-        return EEH_Template::display_template(
382
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
383
-            $template_args,
384
-            true
385
-        );
386
-    }
387
-
388
-
389
-    /**
390
-     * Sets the views for the default list table view.
391
-     */
392
-    protected function _set_list_table_views_default()
393
-    {
394
-        parent::_set_list_table_views_default();
395
-        $new_views    = array(
396
-            'today' => array(
397
-                'slug'        => 'today',
398
-                'label'       => esc_html__('Today', 'event_espresso'),
399
-                'count'       => $this->total_events_today(),
400
-                'bulk_action' => array(
401
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
402
-                ),
403
-            ),
404
-            'month' => array(
405
-                'slug'        => 'month',
406
-                'label'       => esc_html__('This Month', 'event_espresso'),
407
-                'count'       => $this->total_events_this_month(),
408
-                'bulk_action' => array(
409
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
410
-                ),
411
-            ),
412
-        );
413
-        $this->_views = array_merge($this->_views, $new_views);
414
-    }
415
-
416
-
417
-    /**
418
-     * Returns the extra action links for the default list table view.
419
-     * @param array     $action_links
420
-     * @param \EE_Event $event
421
-     * @return array
422
-     * @throws EE_Error
423
-     */
424
-    public function extra_list_table_actions(array $action_links, \EE_Event $event)
425
-    {
426
-        if (EE_Registry::instance()->CAP->current_user_can(
427
-            'ee_read_registrations',
428
-            'espresso_registrations_reports',
429
-            $event->ID()
430
-        )
431
-        ) {
432
-            $reports_query_args = array(
433
-                'action' => 'reports',
434
-                'EVT_ID' => $event->ID(),
435
-            );
436
-            $reports_link       = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
437
-            $action_links[]     = '<a href="'
438
-                                  . $reports_link
439
-                                  . '" title="'
440
-                                  . esc_attr__('View Report', 'event_espresso')
441
-                                  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
442
-                                  . "\n\t";
443
-        }
444
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
445
-            EE_Registry::instance()->load_helper('MSG_Template');
446
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
447
-                'see_notifications_for',
448
-                null,
449
-                array('EVT_ID' => $event->ID())
450
-            );
451
-        }
452
-        return $action_links;
453
-    }
454
-
455
-
456
-    /**
457
-     * @param $items
458
-     * @return mixed
459
-     */
460
-    public function additional_legend_items($items)
461
-    {
462
-        if (EE_Registry::instance()->CAP->current_user_can(
463
-            'ee_read_registrations',
464
-            'espresso_registrations_reports'
465
-        )
466
-        ) {
467
-            $items['reports'] = array(
468
-                'class' => 'dashicons dashicons-chart-bar',
469
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
470
-            );
471
-        }
472
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
473
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
474
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
475
-                $items['view_related_messages'] = array(
476
-                    'class' => $related_for_icon['css_class'],
477
-                    'desc'  => $related_for_icon['label'],
478
-                );
479
-            }
480
-        }
481
-        return $items;
482
-    }
483
-
484
-
485
-    /**
486
-     * This is the callback method for the duplicate event route
487
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
488
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
489
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
490
-     * After duplication the redirect is to the new event edit page.
491
-     *
492
-     * @return void
493
-     * @access protected
494
-     * @throws EE_Error If EE_Event is not available with given ID
495
-     */
496
-    protected function _duplicate_event()
497
-    {
498
-        // first make sure the ID for the event is in the request.
499
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
500
-        if (! isset($this->_req_data['EVT_ID'])) {
501
-            EE_Error::add_error(
502
-                esc_html__(
503
-                    'In order to duplicate an event an Event ID is required.  None was given.',
504
-                    'event_espresso'
505
-                ),
506
-                __FILE__,
507
-                __FUNCTION__,
508
-                __LINE__
509
-            );
510
-            $this->_redirect_after_action(false, '', '', array(), true);
511
-            return;
512
-        }
513
-        //k we've got EVT_ID so let's use that to get the event we'll duplicate
514
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
515
-        if (! $orig_event instanceof EE_Event) {
516
-            throw new EE_Error(
517
-                sprintf(
518
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
519
-                    $this->_req_data['EVT_ID']
520
-                )
521
-            );
522
-        }
523
-        //k now let's clone the $orig_event before getting relations
524
-        $new_event = clone $orig_event;
525
-        //original datetimes
526
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
527
-        //other original relations
528
-        $orig_ven = $orig_event->get_many_related('Venue');
529
-        //reset the ID and modify other details to make it clear this is a dupe
530
-        $new_event->set('EVT_ID', 0);
531
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
532
-        $new_event->set('EVT_name', $new_name);
533
-        $new_event->set(
534
-            'EVT_slug',
535
-            wp_unique_post_slug(
536
-                sanitize_title($orig_event->name()),
537
-                0,
538
-                'publish',
539
-                'espresso_events',
540
-                0
541
-            )
542
-        );
543
-        $new_event->set('status', 'draft');
544
-        //duplicate discussion settings
545
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
546
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
547
-        //save the new event
548
-        $new_event->save();
549
-        //venues
550
-        foreach ($orig_ven as $ven) {
551
-            $new_event->_add_relation_to($ven, 'Venue');
552
-        }
553
-        $new_event->save();
554
-        //now we need to get the question group relations and handle that
555
-        //first primary question groups
556
-        $orig_primary_qgs = $orig_event->get_many_related(
557
-            'Question_Group',
558
-            array(array('Event_Question_Group.EQG_primary' => 1))
559
-        );
560
-        if (! empty($orig_primary_qgs)) {
561
-            foreach ($orig_primary_qgs as $id => $obj) {
562
-                if ($obj instanceof EE_Question_Group) {
563
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
564
-                }
565
-            }
566
-        }
567
-        //next additional attendee question groups
568
-        $orig_additional_qgs = $orig_event->get_many_related(
569
-            'Question_Group',
570
-            array(array('Event_Question_Group.EQG_primary' => 0))
571
-        );
572
-        if (! empty($orig_additional_qgs)) {
573
-            foreach ($orig_additional_qgs as $id => $obj) {
574
-                if ($obj instanceof EE_Question_Group) {
575
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
576
-                }
577
-            }
578
-        }
579
-
580
-        $new_event->save();
581
-
582
-        //k now that we have the new event saved we can loop through the datetimes and start adding relations.
583
-        $cloned_tickets = array();
584
-        foreach ($orig_datetimes as $orig_dtt) {
585
-            if (! $orig_dtt instanceof EE_Datetime) {
586
-                continue;
587
-            }
588
-            $new_dtt   = clone $orig_dtt;
589
-            $orig_tkts = $orig_dtt->tickets();
590
-            //save new dtt then add to event
591
-            $new_dtt->set('DTT_ID', 0);
592
-            $new_dtt->set('DTT_sold', 0);
593
-            $new_dtt->set_reserved(0);
594
-            $new_dtt->save();
595
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
596
-            $new_event->save();
597
-            //now let's get the ticket relations setup.
598
-            foreach ((array)$orig_tkts as $orig_tkt) {
599
-                //it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
600
-                if (! $orig_tkt instanceof EE_Ticket) {
601
-                    continue;
602
-                }
603
-                //is this ticket archived?  If it is then let's skip
604
-                if ($orig_tkt->get('TKT_deleted')) {
605
-                    continue;
606
-                }
607
-                // does this original ticket already exist in the clone_tickets cache?
608
-                //  If so we'll just use the new ticket from it.
609
-                if (isset($cloned_tickets[$orig_tkt->ID()])) {
610
-                    $new_tkt = $cloned_tickets[$orig_tkt->ID()];
611
-                } else {
612
-                    $new_tkt = clone $orig_tkt;
613
-                    //get relations on the $orig_tkt that we need to setup.
614
-                    $orig_prices = $orig_tkt->prices();
615
-                    $new_tkt->set('TKT_ID', 0);
616
-                    $new_tkt->set('TKT_sold', 0);
617
-                    $new_tkt->set('TKT_reserved', 0);
618
-                    $new_tkt->save(); //make sure new ticket has ID.
619
-                    //price relations on new ticket need to be setup.
620
-                    foreach ($orig_prices as $orig_price) {
621
-                        $new_price = clone $orig_price;
622
-                        $new_price->set('PRC_ID', 0);
623
-                        $new_price->save();
624
-                        $new_tkt->_add_relation_to($new_price, 'Price');
625
-                        $new_tkt->save();
626
-                    }
627
-
628
-                    do_action(
629
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
630
-                        $orig_tkt,
631
-                        $new_tkt,
632
-                        $orig_prices,
633
-                        $orig_event,
634
-                        $orig_dtt,
635
-                        $new_dtt
636
-                    );
637
-                }
638
-                // k now we can add the new ticket as a relation to the new datetime
639
-                // and make sure its added to our cached $cloned_tickets array
640
-                // for use with later datetimes that have the same ticket.
641
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
642
-                $new_dtt->save();
643
-                $cloned_tickets[$orig_tkt->ID()] = $new_tkt;
644
-            }
645
-        }
646
-        //clone taxonomy information
647
-        $taxonomies_to_clone_with = apply_filters(
648
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
649
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
650
-        );
651
-        //get terms for original event (notice)
652
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
653
-        //loop through terms and add them to new event.
654
-        foreach ($orig_terms as $term) {
655
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
656
-        }
657
-
658
-        //duplicate other core WP_Post items for this event.
659
-        //post thumbnail (feature image).
660
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
661
-        if ($feature_image_id) {
662
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
663
-        }
664
-
665
-        //duplicate page_template setting
666
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
667
-        if ($page_template) {
668
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
669
-        }
670
-
671
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
672
-        //now let's redirect to the edit page for this duplicated event if we have a new event id.
673
-        if ($new_event->ID()) {
674
-            $redirect_args = array(
675
-                'post'   => $new_event->ID(),
676
-                'action' => 'edit',
677
-            );
678
-            EE_Error::add_success(
679
-                esc_html__(
680
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
681
-                    'event_espresso'
682
-                )
683
-            );
684
-        } else {
685
-            $redirect_args = array(
686
-                'action' => 'default',
687
-            );
688
-            EE_Error::add_error(
689
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
690
-                __FILE__,
691
-                __FUNCTION__,
692
-                __LINE__
693
-            );
694
-        }
695
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
696
-    }
697
-
698
-
699
-    /**
700
-     * Generates output for the import page.
701
-     * @throws DomainException
702
-     */
703
-    protected function _import_page()
704
-    {
705
-        $title                                      = esc_html__('Import', 'event_espresso');
706
-        $intro                                      = esc_html__(
707
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
708
-            'event_espresso'
709
-        );
710
-        $form_url                                   = EVENTS_ADMIN_URL;
711
-        $action                                     = 'import_events';
712
-        $type                                       = 'csv';
713
-        $this->_template_args['form']               = EE_Import::instance()->upload_form(
714
-            $title, $intro, $form_url, $action, $type
715
-        );
716
-        $this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
717
-            array('action' => 'sample_export_file'),
718
-            $this->_admin_base_url
719
-        );
720
-        $content                                    = EEH_Template::display_template(
721
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
722
-            $this->_template_args,
723
-            true
724
-        );
725
-        $this->_template_args['admin_page_content'] = $content;
726
-        $this->display_admin_page_with_sidebar();
727
-    }
728
-
729
-
730
-    /**
731
-     * _import_events
732
-     * This handles displaying the screen and running imports for importing events.
733
-     *
734
-     * @return void
735
-     */
736
-    protected function _import_events()
737
-    {
738
-        require_once(EE_CLASSES . 'EE_Import.class.php');
739
-        $success = EE_Import::instance()->import();
740
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
741
-    }
742
-
743
-
744
-    /**
745
-     * _events_export
746
-     * Will export all (or just the given event) to a Excel compatible file.
747
-     *
748
-     * @access protected
749
-     * @return void
750
-     */
751
-    protected function _events_export()
752
-    {
753
-        if (isset($this->_req_data['EVT_ID'])) {
754
-            $event_ids = $this->_req_data['EVT_ID'];
755
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
756
-            $event_ids = $this->_req_data['EVT_IDs'];
757
-        } else {
758
-            $event_ids = null;
759
-        }
760
-        //todo: I don't like doing this but it'll do until we modify EE_Export Class.
761
-        $new_request_args = array(
762
-            'export' => 'report',
763
-            'action' => 'all_event_data',
764
-            'EVT_ID' => $event_ids,
765
-        );
766
-        $this->_req_data  = array_merge($this->_req_data, $new_request_args);
767
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
768
-            require_once(EE_CLASSES . 'EE_Export.class.php');
769
-            $EE_Export = EE_Export::instance($this->_req_data);
770
-            $EE_Export->export();
771
-        }
772
-    }
773
-
774
-
775
-    /**
776
-     * handle category exports()
777
-     *
778
-     * @return void
779
-     */
780
-    protected function _categories_export()
781
-    {
782
-        //todo: I don't like doing this but it'll do until we modify EE_Export Class.
783
-        $new_request_args = array(
784
-            'export'       => 'report',
785
-            'action'       => 'categories',
786
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
787
-        );
788
-        $this->_req_data  = array_merge($this->_req_data, $new_request_args);
789
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
790
-            require_once(EE_CLASSES . 'EE_Export.class.php');
791
-            $EE_Export = EE_Export::instance($this->_req_data);
792
-            $EE_Export->export();
793
-        }
794
-    }
795
-
796
-
797
-    /**
798
-     * Creates a sample CSV file for importing
799
-     */
800
-    protected function _sample_export_file()
801
-    {
802
-        //		require_once(EE_CLASSES . 'EE_Export.class.php');
803
-        EE_Export::instance()->export_sample();
804
-    }
805
-
806
-
807
-    /*************        Template Settings        *************/
808
-    /**
809
-     * Generates template settings page output
810
-     * @throws DomainException
811
-     * @throws EE_Error
812
-     */
813
-    protected function _template_settings()
814
-    {
815
-        $this->_template_args['values'] = $this->_yes_no_values;
816
-        /**
817
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
818
-         * from General_Settings_Admin_Page to here.
819
-         */
820
-        $this->_template_args = apply_filters(
821
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
822
-            $this->_template_args
823
-        );
824
-        $this->_set_add_edit_form_tags('update_template_settings');
825
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
826
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
827
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
828
-            $this->_template_args,
829
-            true
830
-        );
831
-        $this->display_admin_page_with_sidebar();
832
-    }
833
-
834
-
835
-    /**
836
-     * Handler for updating template settings.
837
-     */
838
-    protected function _update_template_settings()
839
-    {
840
-        /**
841
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
842
-         * from General_Settings_Admin_Page to here.
843
-         */
844
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
845
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
846
-            EE_Registry::instance()->CFG->template_settings,
847
-            $this->_req_data
848
-        );
849
-        //update custom post type slugs and detect if we need to flush rewrite rules
850
-        $old_slug                                          = EE_Registry::instance()->CFG->core->event_cpt_slug;
851
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
852
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
853
-            : sanitize_title_with_dashes($this->_req_data['event_cpt_slug']);
854
-        $what                                              = 'Template Settings';
855
-        $success                                           = $this->_update_espresso_configuration(
856
-            $what,
857
-            EE_Registry::instance()->CFG->template_settings,
858
-            __FILE__,
859
-            __FUNCTION__,
860
-            __LINE__
861
-        );
862
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
863
-            update_option('ee_flush_rewrite_rules', true);
864
-        }
865
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
866
-    }
867
-
868
-
869
-    /**
870
-     * _premium_event_editor_meta_boxes
871
-     * add all metaboxes related to the event_editor
872
-     *
873
-     * @access protected
874
-     * @return void
875
-     * @throws EE_Error
876
-     */
877
-    protected function _premium_event_editor_meta_boxes()
878
-    {
879
-        $this->verify_cpt_object();
880
-        add_meta_box(
881
-            'espresso_event_editor_event_options',
882
-            esc_html__('Event Registration Options', 'event_espresso'),
883
-            array($this, 'registration_options_meta_box'),
884
-            $this->page_slug,
885
-            'side',
886
-            'core'
887
-        );
888
-    }
889
-
890
-
891
-    /**
892
-     * override caf metabox
893
-     *
894
-     * @return void
895
-     * @throws DomainException
896
-     */
897
-    public function registration_options_meta_box()
898
-    {
899
-        $yes_no_values                                    = array(
900
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
901
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
902
-        );
903
-        $default_reg_status_values                        = EEM_Registration::reg_status_array(
904
-            array(
905
-                EEM_Registration::status_id_cancelled,
906
-                EEM_Registration::status_id_declined,
907
-                EEM_Registration::status_id_incomplete,
908
-                EEM_Registration::status_id_wait_list,
909
-            ),
910
-            true
911
-        );
912
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
913
-        $template_args['_event']                          = $this->_cpt_model_obj;
914
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
915
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
916
-            'default_reg_status',
917
-            $default_reg_status_values,
918
-            $this->_cpt_model_obj->default_registration_status()
919
-        );
920
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
921
-            'display_desc',
922
-            $yes_no_values,
923
-            $this->_cpt_model_obj->display_description()
924
-        );
925
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
926
-            'display_ticket_selector',
927
-            $yes_no_values,
928
-            $this->_cpt_model_obj->display_ticket_selector(),
929
-            '',
930
-            '',
931
-            false
932
-        );
933
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
934
-            'EVT_default_registration_status',
935
-            $default_reg_status_values,
936
-            $this->_cpt_model_obj->default_registration_status()
937
-        );
938
-        $template_args['additional_registration_options'] = apply_filters(
939
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
940
-            '',
941
-            $template_args,
942
-            $yes_no_values,
943
-            $default_reg_status_values
944
-        );
945
-        EEH_Template::display_template(
946
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
947
-            $template_args
948
-        );
949
-    }
950
-
951
-
952
-
953
-    /**
954
-     * wp_list_table_mods for caf
955
-     * ============================
956
-     */
957
-    /**
958
-     * hook into list table filters and provide filters for caffeinated list table
959
-     *
960
-     * @param  array $old_filters    any existing filters present
961
-     * @param  array $list_table_obj the list table object
962
-     * @return array                  new filters
963
-     */
964
-    public function list_table_filters($old_filters, $list_table_obj)
965
-    {
966
-        $filters = array();
967
-        //first month/year filters
968
-        $filters[] = $this->espresso_event_months_dropdown();
969
-        $status    = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
970
-        //active status dropdown
971
-        if ($status !== 'draft') {
972
-            $filters[] = $this->active_status_dropdown(
973
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
974
-            );
975
-        }
976
-        //category filter
977
-        $filters[] = $this->category_dropdown();
978
-        return array_merge($old_filters, $filters);
979
-    }
980
-
981
-
982
-    /**
983
-     * espresso_event_months_dropdown
984
-     *
985
-     * @access public
986
-     * @return string                dropdown listing month/year selections for events.
987
-     */
988
-    public function espresso_event_months_dropdown()
989
-    {
990
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
991
-        // Note we need to include any other filters that are set!
992
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
993
-        //categories?
994
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
995
-            ? $this->_req_data['EVT_CAT']
996
-            : null;
997
-        //active status?
998
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
999
-        $cur_date      = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1000
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1001
-    }
1002
-
1003
-
1004
-    /**
1005
-     * returns a list of "active" statuses on the event
1006
-     *
1007
-     * @param  string $current_value whatever the current active status is
1008
-     * @return string
1009
-     */
1010
-    public function active_status_dropdown($current_value = '')
1011
-    {
1012
-        $select_name = 'active_status';
1013
-        $values      = array(
1014
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1015
-            'active'   => esc_html__('Active', 'event_espresso'),
1016
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1017
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1018
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1019
-        );
1020
-        $id          = 'id="espresso-active-status-dropdown-filter"';
1021
-        $class       = 'wide';
1022
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1023
-    }
1024
-
1025
-
1026
-    /**
1027
-     * output a dropdown of the categories for the category filter on the event admin list table
1028
-     *
1029
-     * @access  public
1030
-     * @return string html
1031
-     */
1032
-    public function category_dropdown()
1033
-    {
1034
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1035
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-     * get total number of events today
1041
-     *
1042
-     * @access public
1043
-     * @return int
1044
-     * @throws EE_Error
1045
-     */
1046
-    public function total_events_today()
1047
-    {
1048
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1049
-            'DTT_EVT_start',
1050
-            date('Y-m-d') . ' 00:00:00',
1051
-            'Y-m-d H:i:s',
1052
-            'UTC'
1053
-        );
1054
-        $end   = EEM_Datetime::instance()->convert_datetime_for_query(
1055
-            'DTT_EVT_start',
1056
-            date('Y-m-d') . ' 23:59:59',
1057
-            'Y-m-d H:i:s',
1058
-            'UTC'
1059
-        );
1060
-        $where = array(
1061
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1062
-        );
1063
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1064
-        return $count;
1065
-    }
1066
-
1067
-
1068
-    /**
1069
-     * get total number of events this month
1070
-     *
1071
-     * @access public
1072
-     * @return int
1073
-     * @throws EE_Error
1074
-     */
1075
-    public function total_events_this_month()
1076
-    {
1077
-        //Dates
1078
-        $this_year_r     = date('Y');
1079
-        $this_month_r    = date('m');
1080
-        $days_this_month = date('t');
1081
-        $start           = EEM_Datetime::instance()->convert_datetime_for_query(
1082
-            'DTT_EVT_start',
1083
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1084
-            'Y-m-d H:i:s',
1085
-            'UTC'
1086
-        );
1087
-        $end             = EEM_Datetime::instance()->convert_datetime_for_query(
1088
-            'DTT_EVT_start',
1089
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1090
-            'Y-m-d H:i:s',
1091
-            'UTC'
1092
-        );
1093
-        $where           = array(
1094
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1095
-        );
1096
-        $count           = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1097
-        return $count;
1098
-    }
1099
-
1100
-
1101
-    /** DEFAULT TICKETS STUFF **/
1102
-
1103
-    /**
1104
-     * Output default tickets list table view.
1105
-     */
1106
-    public function _tickets_overview_list_table()
1107
-    {
1108
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1109
-        $this->display_admin_list_table_page_with_no_sidebar();
1110
-    }
1111
-
1112
-
1113
-    /**
1114
-     * @param int  $per_page
1115
-     * @param bool $count
1116
-     * @param bool $trashed
1117
-     * @return \EE_Soft_Delete_Base_Class[]|int
1118
-     */
1119
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1120
-    {
1121
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1122
-        $order   = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1123
-        switch ($orderby) {
1124
-            case 'TKT_name':
1125
-                $orderby = array('TKT_name' => $order);
1126
-                break;
1127
-            case 'TKT_price':
1128
-                $orderby = array('TKT_price' => $order);
1129
-                break;
1130
-            case 'TKT_uses':
1131
-                $orderby = array('TKT_uses' => $order);
1132
-                break;
1133
-            case 'TKT_min':
1134
-                $orderby = array('TKT_min' => $order);
1135
-                break;
1136
-            case 'TKT_max':
1137
-                $orderby = array('TKT_max' => $order);
1138
-                break;
1139
-            case 'TKT_qty':
1140
-                $orderby = array('TKT_qty' => $order);
1141
-                break;
1142
-        }
1143
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1144
-            ? $this->_req_data['paged']
1145
-            : 1;
1146
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1147
-            ? $this->_req_data['perpage']
1148
-            : $per_page;
1149
-        $_where       = array(
1150
-            'TKT_is_default' => 1,
1151
-            'TKT_deleted'    => $trashed,
1152
-        );
1153
-        $offset       = ($current_page - 1) * $per_page;
1154
-        $limit        = array($offset, $per_page);
1155
-        if (isset($this->_req_data['s'])) {
1156
-            $sstr         = '%' . $this->_req_data['s'] . '%';
1157
-            $_where['OR'] = array(
1158
-                'TKT_name'        => array('LIKE', $sstr),
1159
-                'TKT_description' => array('LIKE', $sstr),
1160
-            );
1161
-        }
1162
-        $query_params = array(
1163
-            $_where,
1164
-            'order_by' => $orderby,
1165
-            'limit'    => $limit,
1166
-            'group_by' => 'TKT_ID',
1167
-        );
1168
-        if ($count) {
1169
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1170
-        } else {
1171
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1172
-        }
1173
-    }
1174
-
1175
-
1176
-    /**
1177
-     * @param bool $trash
1178
-     * @throws EE_Error
1179
-     */
1180
-    protected function _trash_or_restore_ticket($trash = false)
1181
-    {
1182
-        $success = 1;
1183
-        $TKT     = EEM_Ticket::instance();
1184
-        //checkboxes?
1185
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1186
-            //if array has more than one element then success message should be plural
1187
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1188
-            //cycle thru the boxes
1189
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1190
-                if ($trash) {
1191
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1192
-                        $success = 0;
1193
-                    }
1194
-                } else {
1195
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1196
-                        $success = 0;
1197
-                    }
1198
-                }
1199
-            }
1200
-        } else {
1201
-            //grab single id and trash
1202
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1203
-            if ($trash) {
1204
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1205
-                    $success = 0;
1206
-                }
1207
-            } else {
1208
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1209
-                    $success = 0;
1210
-                }
1211
-            }
1212
-        }
1213
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1214
-        $query_args  = array(
1215
-            'action' => 'ticket_list_table',
1216
-            'status' => $trash ? '' : 'trashed',
1217
-        );
1218
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1219
-    }
1220
-
1221
-
1222
-    /**
1223
-     * Handles trashing default ticket.
1224
-     */
1225
-    protected function _delete_ticket()
1226
-    {
1227
-        $success = 1;
1228
-        //checkboxes?
1229
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1230
-            //if array has more than one element then success message should be plural
1231
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1232
-            //cycle thru the boxes
1233
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1234
-                //delete
1235
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1236
-                    $success = 0;
1237
-                }
1238
-            }
1239
-        } else {
1240
-            //grab single id and trash
1241
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1242
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1243
-                $success = 0;
1244
-            }
1245
-        }
1246
-        $action_desc = 'deleted';
1247
-        $query_args  = array(
1248
-            'action' => 'ticket_list_table',
1249
-            'status' => 'trashed',
1250
-        );
1251
-        //fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1252
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1253
-            array(array('TKT_is_default' => 1)),
1254
-            'TKT_ID',
1255
-            true
1256
-        )
1257
-        ) {
1258
-            $query_args = array();
1259
-        }
1260
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1261
-    }
1262
-
1263
-
1264
-    /**
1265
-     * @param int $TKT_ID
1266
-     * @return bool|int
1267
-     * @throws EE_Error
1268
-     */
1269
-    protected function _delete_the_ticket($TKT_ID)
1270
-    {
1271
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1272
-        $tkt->_remove_relations('Datetime');
1273
-        //delete all related prices first
1274
-        $tkt->delete_related_permanently('Price');
1275
-        return $tkt->delete_permanently();
1276
-    }
17
+	/**
18
+	 * Extend_Events_Admin_Page constructor.
19
+	 *
20
+	 * @param bool $routing
21
+	 */
22
+	public function __construct($routing = true)
23
+	{
24
+		parent::__construct($routing);
25
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
26
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
27
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
28
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
29
+		}
30
+	}
31
+
32
+
33
+	/**
34
+	 * Sets routes.
35
+	 */
36
+	protected function _extend_page_config()
37
+	{
38
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
39
+		//is there a evt_id in the request?
40
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
41
+			? $this->_req_data['EVT_ID']
42
+			: 0;
43
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
44
+		//tkt_id?
45
+		$tkt_id             = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
46
+			? $this->_req_data['TKT_ID']
47
+			: 0;
48
+		$new_page_routes    = array(
49
+			'duplicate_event'          => array(
50
+				'func'       => '_duplicate_event',
51
+				'capability' => 'ee_edit_event',
52
+				'obj_id'     => $evt_id,
53
+				'noheader'   => true,
54
+			),
55
+			'ticket_list_table'        => array(
56
+				'func'       => '_tickets_overview_list_table',
57
+				'capability' => 'ee_read_default_tickets',
58
+			),
59
+			'trash_ticket'             => array(
60
+				'func'       => '_trash_or_restore_ticket',
61
+				'capability' => 'ee_delete_default_ticket',
62
+				'obj_id'     => $tkt_id,
63
+				'noheader'   => true,
64
+				'args'       => array('trash' => true),
65
+			),
66
+			'trash_tickets'            => array(
67
+				'func'       => '_trash_or_restore_ticket',
68
+				'capability' => 'ee_delete_default_tickets',
69
+				'noheader'   => true,
70
+				'args'       => array('trash' => true),
71
+			),
72
+			'restore_ticket'           => array(
73
+				'func'       => '_trash_or_restore_ticket',
74
+				'capability' => 'ee_delete_default_ticket',
75
+				'obj_id'     => $tkt_id,
76
+				'noheader'   => true,
77
+			),
78
+			'restore_tickets'          => array(
79
+				'func'       => '_trash_or_restore_ticket',
80
+				'capability' => 'ee_delete_default_tickets',
81
+				'noheader'   => true,
82
+			),
83
+			'delete_ticket'            => array(
84
+				'func'       => '_delete_ticket',
85
+				'capability' => 'ee_delete_default_ticket',
86
+				'obj_id'     => $tkt_id,
87
+				'noheader'   => true,
88
+			),
89
+			'delete_tickets'           => array(
90
+				'func'       => '_delete_ticket',
91
+				'capability' => 'ee_delete_default_tickets',
92
+				'noheader'   => true,
93
+			),
94
+			'import_page'              => array(
95
+				'func'       => '_import_page',
96
+				'capability' => 'import',
97
+			),
98
+			'import'                   => array(
99
+				'func'       => '_import_events',
100
+				'capability' => 'import',
101
+				'noheader'   => true,
102
+			),
103
+			'import_events'            => array(
104
+				'func'       => '_import_events',
105
+				'capability' => 'import',
106
+				'noheader'   => true,
107
+			),
108
+			'export_events'            => array(
109
+				'func'       => '_events_export',
110
+				'capability' => 'export',
111
+				'noheader'   => true,
112
+			),
113
+			'export_categories'        => array(
114
+				'func'       => '_categories_export',
115
+				'capability' => 'export',
116
+				'noheader'   => true,
117
+			),
118
+			'sample_export_file'       => array(
119
+				'func'       => '_sample_export_file',
120
+				'capability' => 'export',
121
+				'noheader'   => true,
122
+			),
123
+			'update_template_settings' => array(
124
+				'func'       => '_update_template_settings',
125
+				'capability' => 'manage_options',
126
+				'noheader'   => true,
127
+			),
128
+		);
129
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
130
+		//partial route/config override
131
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
132
+		$this->_page_config['create_new']['metaboxes'][]  = '_premium_event_editor_meta_boxes';
133
+		$this->_page_config['create_new']['qtips'][]      = 'EE_Event_Editor_Tips';
134
+		$this->_page_config['edit']['qtips'][]            = 'EE_Event_Editor_Tips';
135
+		$this->_page_config['edit']['metaboxes'][]        = '_premium_event_editor_meta_boxes';
136
+		$this->_page_config['default']['list_table']      = 'Extend_Events_Admin_List_Table';
137
+		//add tickets tab but only if there are more than one default ticket!
138
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
139
+			array(array('TKT_is_default' => 1)),
140
+			'TKT_ID',
141
+			true
142
+		);
143
+		if ($tkt_count > 1) {
144
+			$new_page_config = array(
145
+				'ticket_list_table' => array(
146
+					'nav'           => array(
147
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
148
+						'order' => 60,
149
+					),
150
+					'list_table'    => 'Tickets_List_Table',
151
+					'require_nonce' => false,
152
+				),
153
+			);
154
+		}
155
+		//template settings
156
+		$new_page_config['template_settings'] = array(
157
+			'nav'           => array(
158
+				'label' => esc_html__('Templates', 'event_espresso'),
159
+				'order' => 30,
160
+			),
161
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
162
+			'help_tabs'     => array(
163
+				'general_settings_templates_help_tab' => array(
164
+					'title'    => esc_html__('Templates', 'event_espresso'),
165
+					'filename' => 'general_settings_templates',
166
+				),
167
+			),
168
+			'help_tour'     => array('Templates_Help_Tour'),
169
+			'require_nonce' => false,
170
+		);
171
+		$this->_page_config                   = array_merge($this->_page_config, $new_page_config);
172
+		//add filters and actions
173
+		//modifying _views
174
+		add_filter(
175
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
176
+			array($this, 'add_additional_datetime_button'),
177
+			10,
178
+			2
179
+		);
180
+		add_filter(
181
+			'FHEE_event_datetime_metabox_clone_button_template',
182
+			array($this, 'add_datetime_clone_button'),
183
+			10,
184
+			2
185
+		);
186
+		add_filter(
187
+			'FHEE_event_datetime_metabox_timezones_template',
188
+			array($this, 'datetime_timezones_template'),
189
+			10,
190
+			2
191
+		);
192
+		//filters for event list table
193
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
194
+		add_filter(
195
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
196
+			array($this, 'extra_list_table_actions'),
197
+			10,
198
+			2
199
+		);
200
+		//legend item
201
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
202
+		add_action('admin_init', array($this, 'admin_init'));
203
+		//heartbeat stuff
204
+		add_filter('heartbeat_received', array($this, 'heartbeat_response'), 10, 2);
205
+	}
206
+
207
+
208
+	/**
209
+	 * admin_init
210
+	 */
211
+	public function admin_init()
212
+	{
213
+		EE_Registry::$i18n_js_strings = array_merge(
214
+			EE_Registry::$i18n_js_strings,
215
+			array(
216
+				'image_confirm'          => esc_html__(
217
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
218
+					'event_espresso'
219
+				),
220
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
221
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
222
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
223
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
224
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
225
+			)
226
+		);
227
+	}
228
+
229
+
230
+	/**
231
+	 * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
232
+	 * accordingly.
233
+	 *
234
+	 * @param array $response The existing heartbeat response array.
235
+	 * @param array $data     The incoming data package.
236
+	 * @return array  possibly appended response.
237
+	 */
238
+	public function heartbeat_response($response, $data)
239
+	{
240
+		/**
241
+		 * check whether count of tickets is approaching the potential
242
+		 * limits for the server.
243
+		 */
244
+		if (! empty($data['input_count'])) {
245
+			$response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check(
246
+				$data['input_count']
247
+			);
248
+		}
249
+		return $response;
250
+	}
251
+
252
+
253
+	/**
254
+	 * Add per page screen options to the default ticket list table view.
255
+	 */
256
+	protected function _add_screen_options_ticket_list_table()
257
+	{
258
+		$this->_per_page_screen_option();
259
+	}
260
+
261
+
262
+	/**
263
+	 * @param string $return
264
+	 * @param int    $id
265
+	 * @param string $new_title
266
+	 * @param string $new_slug
267
+	 * @return string
268
+	 */
269
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
270
+	{
271
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
272
+		//make sure this is only when editing
273
+		if (! empty($id)) {
274
+			$href   = EE_Admin_Page::add_query_args_and_nonce(
275
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
276
+				$this->_admin_base_url
277
+			);
278
+			$title  = esc_attr__('Duplicate Event', 'event_espresso');
279
+			$return .= '<a href="'
280
+					   . $href
281
+					   . '" title="'
282
+					   . $title
283
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
284
+					   . $title
285
+					   . '</a>';
286
+		}
287
+		return $return;
288
+	}
289
+
290
+
291
+	/**
292
+	 * Set the list table views for the default ticket list table view.
293
+	 */
294
+	public function _set_list_table_views_ticket_list_table()
295
+	{
296
+		$this->_views = array(
297
+			'all'     => array(
298
+				'slug'        => 'all',
299
+				'label'       => esc_html__('All', 'event_espresso'),
300
+				'count'       => 0,
301
+				'bulk_action' => array(
302
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
303
+				),
304
+			),
305
+			'trashed' => array(
306
+				'slug'        => 'trashed',
307
+				'label'       => esc_html__('Trash', 'event_espresso'),
308
+				'count'       => 0,
309
+				'bulk_action' => array(
310
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
311
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
312
+				),
313
+			),
314
+		);
315
+	}
316
+
317
+
318
+	/**
319
+	 * Enqueue scripts and styles for the event editor.
320
+	 */
321
+	public function load_scripts_styles_edit()
322
+	{
323
+		wp_register_script(
324
+			'ee-event-editor-heartbeat',
325
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
326
+			array('ee_admin_js', 'heartbeat'),
327
+			EVENT_ESPRESSO_VERSION,
328
+			true
329
+		);
330
+		wp_enqueue_script('ee-accounting');
331
+		//styles
332
+		wp_enqueue_style('espresso-ui-theme');
333
+		wp_enqueue_script('event_editor_js');
334
+		wp_enqueue_script('ee-event-editor-heartbeat');
335
+	}
336
+
337
+
338
+	/**
339
+	 * Returns template for the additional datetime.
340
+	 * @param $template
341
+	 * @param $template_args
342
+	 * @return mixed
343
+	 * @throws DomainException
344
+	 */
345
+	public function add_additional_datetime_button($template, $template_args)
346
+	{
347
+		return EEH_Template::display_template(
348
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
349
+			$template_args,
350
+			true
351
+		);
352
+	}
353
+
354
+
355
+	/**
356
+	 * Returns the template for cloning a datetime.
357
+	 * @param $template
358
+	 * @param $template_args
359
+	 * @return mixed
360
+	 * @throws DomainException
361
+	 */
362
+	public function add_datetime_clone_button($template, $template_args)
363
+	{
364
+		return EEH_Template::display_template(
365
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
366
+			$template_args,
367
+			true
368
+		);
369
+	}
370
+
371
+
372
+	/**
373
+	 * Returns the template for datetime timezones.
374
+	 * @param $template
375
+	 * @param $template_args
376
+	 * @return mixed
377
+	 * @throws DomainException
378
+	 */
379
+	public function datetime_timezones_template($template, $template_args)
380
+	{
381
+		return EEH_Template::display_template(
382
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
383
+			$template_args,
384
+			true
385
+		);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Sets the views for the default list table view.
391
+	 */
392
+	protected function _set_list_table_views_default()
393
+	{
394
+		parent::_set_list_table_views_default();
395
+		$new_views    = array(
396
+			'today' => array(
397
+				'slug'        => 'today',
398
+				'label'       => esc_html__('Today', 'event_espresso'),
399
+				'count'       => $this->total_events_today(),
400
+				'bulk_action' => array(
401
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
402
+				),
403
+			),
404
+			'month' => array(
405
+				'slug'        => 'month',
406
+				'label'       => esc_html__('This Month', 'event_espresso'),
407
+				'count'       => $this->total_events_this_month(),
408
+				'bulk_action' => array(
409
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
410
+				),
411
+			),
412
+		);
413
+		$this->_views = array_merge($this->_views, $new_views);
414
+	}
415
+
416
+
417
+	/**
418
+	 * Returns the extra action links for the default list table view.
419
+	 * @param array     $action_links
420
+	 * @param \EE_Event $event
421
+	 * @return array
422
+	 * @throws EE_Error
423
+	 */
424
+	public function extra_list_table_actions(array $action_links, \EE_Event $event)
425
+	{
426
+		if (EE_Registry::instance()->CAP->current_user_can(
427
+			'ee_read_registrations',
428
+			'espresso_registrations_reports',
429
+			$event->ID()
430
+		)
431
+		) {
432
+			$reports_query_args = array(
433
+				'action' => 'reports',
434
+				'EVT_ID' => $event->ID(),
435
+			);
436
+			$reports_link       = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
437
+			$action_links[]     = '<a href="'
438
+								  . $reports_link
439
+								  . '" title="'
440
+								  . esc_attr__('View Report', 'event_espresso')
441
+								  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
442
+								  . "\n\t";
443
+		}
444
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
445
+			EE_Registry::instance()->load_helper('MSG_Template');
446
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
447
+				'see_notifications_for',
448
+				null,
449
+				array('EVT_ID' => $event->ID())
450
+			);
451
+		}
452
+		return $action_links;
453
+	}
454
+
455
+
456
+	/**
457
+	 * @param $items
458
+	 * @return mixed
459
+	 */
460
+	public function additional_legend_items($items)
461
+	{
462
+		if (EE_Registry::instance()->CAP->current_user_can(
463
+			'ee_read_registrations',
464
+			'espresso_registrations_reports'
465
+		)
466
+		) {
467
+			$items['reports'] = array(
468
+				'class' => 'dashicons dashicons-chart-bar',
469
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
470
+			);
471
+		}
472
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
473
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
474
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
475
+				$items['view_related_messages'] = array(
476
+					'class' => $related_for_icon['css_class'],
477
+					'desc'  => $related_for_icon['label'],
478
+				);
479
+			}
480
+		}
481
+		return $items;
482
+	}
483
+
484
+
485
+	/**
486
+	 * This is the callback method for the duplicate event route
487
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
488
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
489
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
490
+	 * After duplication the redirect is to the new event edit page.
491
+	 *
492
+	 * @return void
493
+	 * @access protected
494
+	 * @throws EE_Error If EE_Event is not available with given ID
495
+	 */
496
+	protected function _duplicate_event()
497
+	{
498
+		// first make sure the ID for the event is in the request.
499
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
500
+		if (! isset($this->_req_data['EVT_ID'])) {
501
+			EE_Error::add_error(
502
+				esc_html__(
503
+					'In order to duplicate an event an Event ID is required.  None was given.',
504
+					'event_espresso'
505
+				),
506
+				__FILE__,
507
+				__FUNCTION__,
508
+				__LINE__
509
+			);
510
+			$this->_redirect_after_action(false, '', '', array(), true);
511
+			return;
512
+		}
513
+		//k we've got EVT_ID so let's use that to get the event we'll duplicate
514
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
515
+		if (! $orig_event instanceof EE_Event) {
516
+			throw new EE_Error(
517
+				sprintf(
518
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
519
+					$this->_req_data['EVT_ID']
520
+				)
521
+			);
522
+		}
523
+		//k now let's clone the $orig_event before getting relations
524
+		$new_event = clone $orig_event;
525
+		//original datetimes
526
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
527
+		//other original relations
528
+		$orig_ven = $orig_event->get_many_related('Venue');
529
+		//reset the ID and modify other details to make it clear this is a dupe
530
+		$new_event->set('EVT_ID', 0);
531
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
532
+		$new_event->set('EVT_name', $new_name);
533
+		$new_event->set(
534
+			'EVT_slug',
535
+			wp_unique_post_slug(
536
+				sanitize_title($orig_event->name()),
537
+				0,
538
+				'publish',
539
+				'espresso_events',
540
+				0
541
+			)
542
+		);
543
+		$new_event->set('status', 'draft');
544
+		//duplicate discussion settings
545
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
546
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
547
+		//save the new event
548
+		$new_event->save();
549
+		//venues
550
+		foreach ($orig_ven as $ven) {
551
+			$new_event->_add_relation_to($ven, 'Venue');
552
+		}
553
+		$new_event->save();
554
+		//now we need to get the question group relations and handle that
555
+		//first primary question groups
556
+		$orig_primary_qgs = $orig_event->get_many_related(
557
+			'Question_Group',
558
+			array(array('Event_Question_Group.EQG_primary' => 1))
559
+		);
560
+		if (! empty($orig_primary_qgs)) {
561
+			foreach ($orig_primary_qgs as $id => $obj) {
562
+				if ($obj instanceof EE_Question_Group) {
563
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
564
+				}
565
+			}
566
+		}
567
+		//next additional attendee question groups
568
+		$orig_additional_qgs = $orig_event->get_many_related(
569
+			'Question_Group',
570
+			array(array('Event_Question_Group.EQG_primary' => 0))
571
+		);
572
+		if (! empty($orig_additional_qgs)) {
573
+			foreach ($orig_additional_qgs as $id => $obj) {
574
+				if ($obj instanceof EE_Question_Group) {
575
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
576
+				}
577
+			}
578
+		}
579
+
580
+		$new_event->save();
581
+
582
+		//k now that we have the new event saved we can loop through the datetimes and start adding relations.
583
+		$cloned_tickets = array();
584
+		foreach ($orig_datetimes as $orig_dtt) {
585
+			if (! $orig_dtt instanceof EE_Datetime) {
586
+				continue;
587
+			}
588
+			$new_dtt   = clone $orig_dtt;
589
+			$orig_tkts = $orig_dtt->tickets();
590
+			//save new dtt then add to event
591
+			$new_dtt->set('DTT_ID', 0);
592
+			$new_dtt->set('DTT_sold', 0);
593
+			$new_dtt->set_reserved(0);
594
+			$new_dtt->save();
595
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
596
+			$new_event->save();
597
+			//now let's get the ticket relations setup.
598
+			foreach ((array)$orig_tkts as $orig_tkt) {
599
+				//it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
600
+				if (! $orig_tkt instanceof EE_Ticket) {
601
+					continue;
602
+				}
603
+				//is this ticket archived?  If it is then let's skip
604
+				if ($orig_tkt->get('TKT_deleted')) {
605
+					continue;
606
+				}
607
+				// does this original ticket already exist in the clone_tickets cache?
608
+				//  If so we'll just use the new ticket from it.
609
+				if (isset($cloned_tickets[$orig_tkt->ID()])) {
610
+					$new_tkt = $cloned_tickets[$orig_tkt->ID()];
611
+				} else {
612
+					$new_tkt = clone $orig_tkt;
613
+					//get relations on the $orig_tkt that we need to setup.
614
+					$orig_prices = $orig_tkt->prices();
615
+					$new_tkt->set('TKT_ID', 0);
616
+					$new_tkt->set('TKT_sold', 0);
617
+					$new_tkt->set('TKT_reserved', 0);
618
+					$new_tkt->save(); //make sure new ticket has ID.
619
+					//price relations on new ticket need to be setup.
620
+					foreach ($orig_prices as $orig_price) {
621
+						$new_price = clone $orig_price;
622
+						$new_price->set('PRC_ID', 0);
623
+						$new_price->save();
624
+						$new_tkt->_add_relation_to($new_price, 'Price');
625
+						$new_tkt->save();
626
+					}
627
+
628
+					do_action(
629
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
630
+						$orig_tkt,
631
+						$new_tkt,
632
+						$orig_prices,
633
+						$orig_event,
634
+						$orig_dtt,
635
+						$new_dtt
636
+					);
637
+				}
638
+				// k now we can add the new ticket as a relation to the new datetime
639
+				// and make sure its added to our cached $cloned_tickets array
640
+				// for use with later datetimes that have the same ticket.
641
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
642
+				$new_dtt->save();
643
+				$cloned_tickets[$orig_tkt->ID()] = $new_tkt;
644
+			}
645
+		}
646
+		//clone taxonomy information
647
+		$taxonomies_to_clone_with = apply_filters(
648
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
649
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
650
+		);
651
+		//get terms for original event (notice)
652
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
653
+		//loop through terms and add them to new event.
654
+		foreach ($orig_terms as $term) {
655
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
656
+		}
657
+
658
+		//duplicate other core WP_Post items for this event.
659
+		//post thumbnail (feature image).
660
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
661
+		if ($feature_image_id) {
662
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
663
+		}
664
+
665
+		//duplicate page_template setting
666
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
667
+		if ($page_template) {
668
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
669
+		}
670
+
671
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
672
+		//now let's redirect to the edit page for this duplicated event if we have a new event id.
673
+		if ($new_event->ID()) {
674
+			$redirect_args = array(
675
+				'post'   => $new_event->ID(),
676
+				'action' => 'edit',
677
+			);
678
+			EE_Error::add_success(
679
+				esc_html__(
680
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
681
+					'event_espresso'
682
+				)
683
+			);
684
+		} else {
685
+			$redirect_args = array(
686
+				'action' => 'default',
687
+			);
688
+			EE_Error::add_error(
689
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
690
+				__FILE__,
691
+				__FUNCTION__,
692
+				__LINE__
693
+			);
694
+		}
695
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
696
+	}
697
+
698
+
699
+	/**
700
+	 * Generates output for the import page.
701
+	 * @throws DomainException
702
+	 */
703
+	protected function _import_page()
704
+	{
705
+		$title                                      = esc_html__('Import', 'event_espresso');
706
+		$intro                                      = esc_html__(
707
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
708
+			'event_espresso'
709
+		);
710
+		$form_url                                   = EVENTS_ADMIN_URL;
711
+		$action                                     = 'import_events';
712
+		$type                                       = 'csv';
713
+		$this->_template_args['form']               = EE_Import::instance()->upload_form(
714
+			$title, $intro, $form_url, $action, $type
715
+		);
716
+		$this->_template_args['sample_file_link']   = EE_Admin_Page::add_query_args_and_nonce(
717
+			array('action' => 'sample_export_file'),
718
+			$this->_admin_base_url
719
+		);
720
+		$content                                    = EEH_Template::display_template(
721
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
722
+			$this->_template_args,
723
+			true
724
+		);
725
+		$this->_template_args['admin_page_content'] = $content;
726
+		$this->display_admin_page_with_sidebar();
727
+	}
728
+
729
+
730
+	/**
731
+	 * _import_events
732
+	 * This handles displaying the screen and running imports for importing events.
733
+	 *
734
+	 * @return void
735
+	 */
736
+	protected function _import_events()
737
+	{
738
+		require_once(EE_CLASSES . 'EE_Import.class.php');
739
+		$success = EE_Import::instance()->import();
740
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
741
+	}
742
+
743
+
744
+	/**
745
+	 * _events_export
746
+	 * Will export all (or just the given event) to a Excel compatible file.
747
+	 *
748
+	 * @access protected
749
+	 * @return void
750
+	 */
751
+	protected function _events_export()
752
+	{
753
+		if (isset($this->_req_data['EVT_ID'])) {
754
+			$event_ids = $this->_req_data['EVT_ID'];
755
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
756
+			$event_ids = $this->_req_data['EVT_IDs'];
757
+		} else {
758
+			$event_ids = null;
759
+		}
760
+		//todo: I don't like doing this but it'll do until we modify EE_Export Class.
761
+		$new_request_args = array(
762
+			'export' => 'report',
763
+			'action' => 'all_event_data',
764
+			'EVT_ID' => $event_ids,
765
+		);
766
+		$this->_req_data  = array_merge($this->_req_data, $new_request_args);
767
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
768
+			require_once(EE_CLASSES . 'EE_Export.class.php');
769
+			$EE_Export = EE_Export::instance($this->_req_data);
770
+			$EE_Export->export();
771
+		}
772
+	}
773
+
774
+
775
+	/**
776
+	 * handle category exports()
777
+	 *
778
+	 * @return void
779
+	 */
780
+	protected function _categories_export()
781
+	{
782
+		//todo: I don't like doing this but it'll do until we modify EE_Export Class.
783
+		$new_request_args = array(
784
+			'export'       => 'report',
785
+			'action'       => 'categories',
786
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
787
+		);
788
+		$this->_req_data  = array_merge($this->_req_data, $new_request_args);
789
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
790
+			require_once(EE_CLASSES . 'EE_Export.class.php');
791
+			$EE_Export = EE_Export::instance($this->_req_data);
792
+			$EE_Export->export();
793
+		}
794
+	}
795
+
796
+
797
+	/**
798
+	 * Creates a sample CSV file for importing
799
+	 */
800
+	protected function _sample_export_file()
801
+	{
802
+		//		require_once(EE_CLASSES . 'EE_Export.class.php');
803
+		EE_Export::instance()->export_sample();
804
+	}
805
+
806
+
807
+	/*************        Template Settings        *************/
808
+	/**
809
+	 * Generates template settings page output
810
+	 * @throws DomainException
811
+	 * @throws EE_Error
812
+	 */
813
+	protected function _template_settings()
814
+	{
815
+		$this->_template_args['values'] = $this->_yes_no_values;
816
+		/**
817
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
818
+		 * from General_Settings_Admin_Page to here.
819
+		 */
820
+		$this->_template_args = apply_filters(
821
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
822
+			$this->_template_args
823
+		);
824
+		$this->_set_add_edit_form_tags('update_template_settings');
825
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
826
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
827
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
828
+			$this->_template_args,
829
+			true
830
+		);
831
+		$this->display_admin_page_with_sidebar();
832
+	}
833
+
834
+
835
+	/**
836
+	 * Handler for updating template settings.
837
+	 */
838
+	protected function _update_template_settings()
839
+	{
840
+		/**
841
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
842
+		 * from General_Settings_Admin_Page to here.
843
+		 */
844
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
845
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
846
+			EE_Registry::instance()->CFG->template_settings,
847
+			$this->_req_data
848
+		);
849
+		//update custom post type slugs and detect if we need to flush rewrite rules
850
+		$old_slug                                          = EE_Registry::instance()->CFG->core->event_cpt_slug;
851
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
852
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
853
+			: sanitize_title_with_dashes($this->_req_data['event_cpt_slug']);
854
+		$what                                              = 'Template Settings';
855
+		$success                                           = $this->_update_espresso_configuration(
856
+			$what,
857
+			EE_Registry::instance()->CFG->template_settings,
858
+			__FILE__,
859
+			__FUNCTION__,
860
+			__LINE__
861
+		);
862
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
863
+			update_option('ee_flush_rewrite_rules', true);
864
+		}
865
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
866
+	}
867
+
868
+
869
+	/**
870
+	 * _premium_event_editor_meta_boxes
871
+	 * add all metaboxes related to the event_editor
872
+	 *
873
+	 * @access protected
874
+	 * @return void
875
+	 * @throws EE_Error
876
+	 */
877
+	protected function _premium_event_editor_meta_boxes()
878
+	{
879
+		$this->verify_cpt_object();
880
+		add_meta_box(
881
+			'espresso_event_editor_event_options',
882
+			esc_html__('Event Registration Options', 'event_espresso'),
883
+			array($this, 'registration_options_meta_box'),
884
+			$this->page_slug,
885
+			'side',
886
+			'core'
887
+		);
888
+	}
889
+
890
+
891
+	/**
892
+	 * override caf metabox
893
+	 *
894
+	 * @return void
895
+	 * @throws DomainException
896
+	 */
897
+	public function registration_options_meta_box()
898
+	{
899
+		$yes_no_values                                    = array(
900
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
901
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
902
+		);
903
+		$default_reg_status_values                        = EEM_Registration::reg_status_array(
904
+			array(
905
+				EEM_Registration::status_id_cancelled,
906
+				EEM_Registration::status_id_declined,
907
+				EEM_Registration::status_id_incomplete,
908
+				EEM_Registration::status_id_wait_list,
909
+			),
910
+			true
911
+		);
912
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
913
+		$template_args['_event']                          = $this->_cpt_model_obj;
914
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
915
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
916
+			'default_reg_status',
917
+			$default_reg_status_values,
918
+			$this->_cpt_model_obj->default_registration_status()
919
+		);
920
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
921
+			'display_desc',
922
+			$yes_no_values,
923
+			$this->_cpt_model_obj->display_description()
924
+		);
925
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
926
+			'display_ticket_selector',
927
+			$yes_no_values,
928
+			$this->_cpt_model_obj->display_ticket_selector(),
929
+			'',
930
+			'',
931
+			false
932
+		);
933
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
934
+			'EVT_default_registration_status',
935
+			$default_reg_status_values,
936
+			$this->_cpt_model_obj->default_registration_status()
937
+		);
938
+		$template_args['additional_registration_options'] = apply_filters(
939
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
940
+			'',
941
+			$template_args,
942
+			$yes_no_values,
943
+			$default_reg_status_values
944
+		);
945
+		EEH_Template::display_template(
946
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
947
+			$template_args
948
+		);
949
+	}
950
+
951
+
952
+
953
+	/**
954
+	 * wp_list_table_mods for caf
955
+	 * ============================
956
+	 */
957
+	/**
958
+	 * hook into list table filters and provide filters for caffeinated list table
959
+	 *
960
+	 * @param  array $old_filters    any existing filters present
961
+	 * @param  array $list_table_obj the list table object
962
+	 * @return array                  new filters
963
+	 */
964
+	public function list_table_filters($old_filters, $list_table_obj)
965
+	{
966
+		$filters = array();
967
+		//first month/year filters
968
+		$filters[] = $this->espresso_event_months_dropdown();
969
+		$status    = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
970
+		//active status dropdown
971
+		if ($status !== 'draft') {
972
+			$filters[] = $this->active_status_dropdown(
973
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
974
+			);
975
+		}
976
+		//category filter
977
+		$filters[] = $this->category_dropdown();
978
+		return array_merge($old_filters, $filters);
979
+	}
980
+
981
+
982
+	/**
983
+	 * espresso_event_months_dropdown
984
+	 *
985
+	 * @access public
986
+	 * @return string                dropdown listing month/year selections for events.
987
+	 */
988
+	public function espresso_event_months_dropdown()
989
+	{
990
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
991
+		// Note we need to include any other filters that are set!
992
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
993
+		//categories?
994
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
995
+			? $this->_req_data['EVT_CAT']
996
+			: null;
997
+		//active status?
998
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
999
+		$cur_date      = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1000
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1001
+	}
1002
+
1003
+
1004
+	/**
1005
+	 * returns a list of "active" statuses on the event
1006
+	 *
1007
+	 * @param  string $current_value whatever the current active status is
1008
+	 * @return string
1009
+	 */
1010
+	public function active_status_dropdown($current_value = '')
1011
+	{
1012
+		$select_name = 'active_status';
1013
+		$values      = array(
1014
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1015
+			'active'   => esc_html__('Active', 'event_espresso'),
1016
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1017
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1018
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1019
+		);
1020
+		$id          = 'id="espresso-active-status-dropdown-filter"';
1021
+		$class       = 'wide';
1022
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1023
+	}
1024
+
1025
+
1026
+	/**
1027
+	 * output a dropdown of the categories for the category filter on the event admin list table
1028
+	 *
1029
+	 * @access  public
1030
+	 * @return string html
1031
+	 */
1032
+	public function category_dropdown()
1033
+	{
1034
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1035
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+	 * get total number of events today
1041
+	 *
1042
+	 * @access public
1043
+	 * @return int
1044
+	 * @throws EE_Error
1045
+	 */
1046
+	public function total_events_today()
1047
+	{
1048
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1049
+			'DTT_EVT_start',
1050
+			date('Y-m-d') . ' 00:00:00',
1051
+			'Y-m-d H:i:s',
1052
+			'UTC'
1053
+		);
1054
+		$end   = EEM_Datetime::instance()->convert_datetime_for_query(
1055
+			'DTT_EVT_start',
1056
+			date('Y-m-d') . ' 23:59:59',
1057
+			'Y-m-d H:i:s',
1058
+			'UTC'
1059
+		);
1060
+		$where = array(
1061
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1062
+		);
1063
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1064
+		return $count;
1065
+	}
1066
+
1067
+
1068
+	/**
1069
+	 * get total number of events this month
1070
+	 *
1071
+	 * @access public
1072
+	 * @return int
1073
+	 * @throws EE_Error
1074
+	 */
1075
+	public function total_events_this_month()
1076
+	{
1077
+		//Dates
1078
+		$this_year_r     = date('Y');
1079
+		$this_month_r    = date('m');
1080
+		$days_this_month = date('t');
1081
+		$start           = EEM_Datetime::instance()->convert_datetime_for_query(
1082
+			'DTT_EVT_start',
1083
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1084
+			'Y-m-d H:i:s',
1085
+			'UTC'
1086
+		);
1087
+		$end             = EEM_Datetime::instance()->convert_datetime_for_query(
1088
+			'DTT_EVT_start',
1089
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1090
+			'Y-m-d H:i:s',
1091
+			'UTC'
1092
+		);
1093
+		$where           = array(
1094
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1095
+		);
1096
+		$count           = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1097
+		return $count;
1098
+	}
1099
+
1100
+
1101
+	/** DEFAULT TICKETS STUFF **/
1102
+
1103
+	/**
1104
+	 * Output default tickets list table view.
1105
+	 */
1106
+	public function _tickets_overview_list_table()
1107
+	{
1108
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1109
+		$this->display_admin_list_table_page_with_no_sidebar();
1110
+	}
1111
+
1112
+
1113
+	/**
1114
+	 * @param int  $per_page
1115
+	 * @param bool $count
1116
+	 * @param bool $trashed
1117
+	 * @return \EE_Soft_Delete_Base_Class[]|int
1118
+	 */
1119
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1120
+	{
1121
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1122
+		$order   = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1123
+		switch ($orderby) {
1124
+			case 'TKT_name':
1125
+				$orderby = array('TKT_name' => $order);
1126
+				break;
1127
+			case 'TKT_price':
1128
+				$orderby = array('TKT_price' => $order);
1129
+				break;
1130
+			case 'TKT_uses':
1131
+				$orderby = array('TKT_uses' => $order);
1132
+				break;
1133
+			case 'TKT_min':
1134
+				$orderby = array('TKT_min' => $order);
1135
+				break;
1136
+			case 'TKT_max':
1137
+				$orderby = array('TKT_max' => $order);
1138
+				break;
1139
+			case 'TKT_qty':
1140
+				$orderby = array('TKT_qty' => $order);
1141
+				break;
1142
+		}
1143
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1144
+			? $this->_req_data['paged']
1145
+			: 1;
1146
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1147
+			? $this->_req_data['perpage']
1148
+			: $per_page;
1149
+		$_where       = array(
1150
+			'TKT_is_default' => 1,
1151
+			'TKT_deleted'    => $trashed,
1152
+		);
1153
+		$offset       = ($current_page - 1) * $per_page;
1154
+		$limit        = array($offset, $per_page);
1155
+		if (isset($this->_req_data['s'])) {
1156
+			$sstr         = '%' . $this->_req_data['s'] . '%';
1157
+			$_where['OR'] = array(
1158
+				'TKT_name'        => array('LIKE', $sstr),
1159
+				'TKT_description' => array('LIKE', $sstr),
1160
+			);
1161
+		}
1162
+		$query_params = array(
1163
+			$_where,
1164
+			'order_by' => $orderby,
1165
+			'limit'    => $limit,
1166
+			'group_by' => 'TKT_ID',
1167
+		);
1168
+		if ($count) {
1169
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1170
+		} else {
1171
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1172
+		}
1173
+	}
1174
+
1175
+
1176
+	/**
1177
+	 * @param bool $trash
1178
+	 * @throws EE_Error
1179
+	 */
1180
+	protected function _trash_or_restore_ticket($trash = false)
1181
+	{
1182
+		$success = 1;
1183
+		$TKT     = EEM_Ticket::instance();
1184
+		//checkboxes?
1185
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1186
+			//if array has more than one element then success message should be plural
1187
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1188
+			//cycle thru the boxes
1189
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1190
+				if ($trash) {
1191
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1192
+						$success = 0;
1193
+					}
1194
+				} else {
1195
+					if (! $TKT->restore_by_ID($TKT_ID)) {
1196
+						$success = 0;
1197
+					}
1198
+				}
1199
+			}
1200
+		} else {
1201
+			//grab single id and trash
1202
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1203
+			if ($trash) {
1204
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1205
+					$success = 0;
1206
+				}
1207
+			} else {
1208
+				if (! $TKT->restore_by_ID($TKT_ID)) {
1209
+					$success = 0;
1210
+				}
1211
+			}
1212
+		}
1213
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1214
+		$query_args  = array(
1215
+			'action' => 'ticket_list_table',
1216
+			'status' => $trash ? '' : 'trashed',
1217
+		);
1218
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1219
+	}
1220
+
1221
+
1222
+	/**
1223
+	 * Handles trashing default ticket.
1224
+	 */
1225
+	protected function _delete_ticket()
1226
+	{
1227
+		$success = 1;
1228
+		//checkboxes?
1229
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1230
+			//if array has more than one element then success message should be plural
1231
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1232
+			//cycle thru the boxes
1233
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1234
+				//delete
1235
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1236
+					$success = 0;
1237
+				}
1238
+			}
1239
+		} else {
1240
+			//grab single id and trash
1241
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1242
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1243
+				$success = 0;
1244
+			}
1245
+		}
1246
+		$action_desc = 'deleted';
1247
+		$query_args  = array(
1248
+			'action' => 'ticket_list_table',
1249
+			'status' => 'trashed',
1250
+		);
1251
+		//fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1252
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1253
+			array(array('TKT_is_default' => 1)),
1254
+			'TKT_ID',
1255
+			true
1256
+		)
1257
+		) {
1258
+			$query_args = array();
1259
+		}
1260
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1261
+	}
1262
+
1263
+
1264
+	/**
1265
+	 * @param int $TKT_ID
1266
+	 * @return bool|int
1267
+	 * @throws EE_Error
1268
+	 */
1269
+	protected function _delete_the_ticket($TKT_ID)
1270
+	{
1271
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1272
+		$tkt->_remove_relations('Datetime');
1273
+		//delete all related prices first
1274
+		$tkt->delete_related_permanently('Price');
1275
+		return $tkt->delete_permanently();
1276
+	}
1277 1277
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -38,217 +38,217 @@
 block discarded – undo
38 38
  * @since       4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 
64 64
 } else {
65
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
-        /**
68
-         * espresso_minimum_php_version_error
69
-         *
70
-         * @return void
71
-         */
72
-        function espresso_minimum_php_version_error()
73
-        {
74
-            ?>
65
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
+		/**
68
+		 * espresso_minimum_php_version_error
69
+		 *
70
+		 * @return void
71
+		 */
72
+		function espresso_minimum_php_version_error()
73
+		{
74
+			?>
75 75
             <div class="error">
76 76
                 <p>
77 77
                     <?php
78
-                    printf(
79
-                        esc_html__(
80
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
-                            'event_espresso'
82
-                        ),
83
-                        EE_MIN_PHP_VER_REQUIRED,
84
-                        PHP_VERSION,
85
-                        '<br/>',
86
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
-                    );
88
-                    ?>
78
+					printf(
79
+						esc_html__(
80
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
+							'event_espresso'
82
+						),
83
+						EE_MIN_PHP_VER_REQUIRED,
84
+						PHP_VERSION,
85
+						'<br/>',
86
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
+					);
88
+					?>
89 89
                 </p>
90 90
             </div>
91 91
             <?php
92
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
93
-        }
92
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
93
+		}
94 94
 
95
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
-    } else {
97
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
-        /**
99
-         * espresso_version
100
-         * Returns the plugin version
101
-         *
102
-         * @return string
103
-         */
104
-        function espresso_version()
105
-        {
106
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.50.rc.014');
107
-        }
95
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
+	} else {
97
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
+		/**
99
+		 * espresso_version
100
+		 * Returns the plugin version
101
+		 *
102
+		 * @return string
103
+		 */
104
+		function espresso_version()
105
+		{
106
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.50.rc.014');
107
+		}
108 108
 
109
-        /**
110
-         * espresso_plugin_activation
111
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
-         */
113
-        function espresso_plugin_activation()
114
-        {
115
-            update_option('ee_espresso_activation', true);
116
-        }
109
+		/**
110
+		 * espresso_plugin_activation
111
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
+		 */
113
+		function espresso_plugin_activation()
114
+		{
115
+			update_option('ee_espresso_activation', true);
116
+		}
117 117
 
118
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
-        /**
120
-         *    espresso_load_error_handling
121
-         *    this function loads EE's class for handling exceptions and errors
122
-         */
123
-        function espresso_load_error_handling()
124
-        {
125
-            static $error_handling_loaded = false;
126
-            if ($error_handling_loaded) {
127
-                return;
128
-            }
129
-            // load debugging tools
130
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
-                require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
-                \EEH_Debug_Tools::instance();
133
-            }
134
-            // load error handling
135
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
-                require_once EE_CORE . 'EE_Error.core.php';
137
-            } else {
138
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
-            }
140
-            $error_handling_loaded = true;
141
-        }
118
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
+		/**
120
+		 *    espresso_load_error_handling
121
+		 *    this function loads EE's class for handling exceptions and errors
122
+		 */
123
+		function espresso_load_error_handling()
124
+		{
125
+			static $error_handling_loaded = false;
126
+			if ($error_handling_loaded) {
127
+				return;
128
+			}
129
+			// load debugging tools
130
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
+				require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
+				\EEH_Debug_Tools::instance();
133
+			}
134
+			// load error handling
135
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
+				require_once EE_CORE . 'EE_Error.core.php';
137
+			} else {
138
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
+			}
140
+			$error_handling_loaded = true;
141
+		}
142 142
 
143
-        /**
144
-         *    espresso_load_required
145
-         *    given a class name and path, this function will load that file or throw an exception
146
-         *
147
-         * @param    string $classname
148
-         * @param    string $full_path_to_file
149
-         * @throws    EE_Error
150
-         */
151
-        function espresso_load_required($classname, $full_path_to_file)
152
-        {
153
-            if (is_readable($full_path_to_file)) {
154
-                require_once $full_path_to_file;
155
-            } else {
156
-                throw new \EE_Error (
157
-                    sprintf(
158
-                        esc_html__(
159
-                            'The %s class file could not be located or is not readable due to file permissions.',
160
-                            'event_espresso'
161
-                        ),
162
-                        $classname
163
-                    )
164
-                );
165
-            }
166
-        }
143
+		/**
144
+		 *    espresso_load_required
145
+		 *    given a class name and path, this function will load that file or throw an exception
146
+		 *
147
+		 * @param    string $classname
148
+		 * @param    string $full_path_to_file
149
+		 * @throws    EE_Error
150
+		 */
151
+		function espresso_load_required($classname, $full_path_to_file)
152
+		{
153
+			if (is_readable($full_path_to_file)) {
154
+				require_once $full_path_to_file;
155
+			} else {
156
+				throw new \EE_Error (
157
+					sprintf(
158
+						esc_html__(
159
+							'The %s class file could not be located or is not readable due to file permissions.',
160
+							'event_espresso'
161
+						),
162
+						$classname
163
+					)
164
+				);
165
+			}
166
+		}
167 167
 
168
-        /**
169
-         * @since 4.9.27
170
-         * @throws \EE_Error
171
-         * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
-         * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
-         * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
-         * @throws \EventEspresso\core\exceptions\InvalidClassException
175
-         * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
-         * @throws \OutOfBoundsException
179
-         */
180
-        function bootstrap_espresso()
181
-        {
182
-            require_once __DIR__ . '/core/espresso_definitions.php';
183
-            try {
184
-                espresso_load_error_handling();
185
-                espresso_load_required(
186
-                    'EEH_Base',
187
-                    EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
-                );
189
-                espresso_load_required(
190
-                    'EEH_File',
191
-                    EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
-                );
193
-                espresso_load_required(
194
-                    'EEH_File',
195
-                    EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
-                );
197
-                espresso_load_required(
198
-                    'EEH_Array',
199
-                    EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
-                );
201
-                // instantiate and configure PSR4 autoloader
202
-                espresso_load_required(
203
-                    'Psr4Autoloader',
204
-                    EE_CORE . 'Psr4Autoloader.php'
205
-                );
206
-                espresso_load_required(
207
-                    'EE_Psr4AutoloaderInit',
208
-                    EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
-                );
210
-                $AutoloaderInit = new EE_Psr4AutoloaderInit();
211
-                $AutoloaderInit->initializeAutoloader();
212
-                espresso_load_required(
213
-                    'EE_Request',
214
-                    EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
-                );
216
-                espresso_load_required(
217
-                    'EE_Response',
218
-                    EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
-                );
220
-                espresso_load_required(
221
-                    'EE_Bootstrap',
222
-                    EE_CORE . 'EE_Bootstrap.core.php'
223
-                );
224
-                // bootstrap EE and the request stack
225
-                new EE_Bootstrap(
226
-                    new EE_Request($_GET, $_POST, $_COOKIE),
227
-                    new EE_Response()
228
-                );
229
-            } catch (Exception $e) {
230
-                require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
-                new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
-            }
233
-        }
234
-        bootstrap_espresso();
235
-    }
168
+		/**
169
+		 * @since 4.9.27
170
+		 * @throws \EE_Error
171
+		 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
+		 * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
+		 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
+		 * @throws \EventEspresso\core\exceptions\InvalidClassException
175
+		 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
+		 * @throws \OutOfBoundsException
179
+		 */
180
+		function bootstrap_espresso()
181
+		{
182
+			require_once __DIR__ . '/core/espresso_definitions.php';
183
+			try {
184
+				espresso_load_error_handling();
185
+				espresso_load_required(
186
+					'EEH_Base',
187
+					EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
+				);
189
+				espresso_load_required(
190
+					'EEH_File',
191
+					EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
+				);
193
+				espresso_load_required(
194
+					'EEH_File',
195
+					EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
+				);
197
+				espresso_load_required(
198
+					'EEH_Array',
199
+					EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
+				);
201
+				// instantiate and configure PSR4 autoloader
202
+				espresso_load_required(
203
+					'Psr4Autoloader',
204
+					EE_CORE . 'Psr4Autoloader.php'
205
+				);
206
+				espresso_load_required(
207
+					'EE_Psr4AutoloaderInit',
208
+					EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
+				);
210
+				$AutoloaderInit = new EE_Psr4AutoloaderInit();
211
+				$AutoloaderInit->initializeAutoloader();
212
+				espresso_load_required(
213
+					'EE_Request',
214
+					EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
+				);
216
+				espresso_load_required(
217
+					'EE_Response',
218
+					EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
+				);
220
+				espresso_load_required(
221
+					'EE_Bootstrap',
222
+					EE_CORE . 'EE_Bootstrap.core.php'
223
+				);
224
+				// bootstrap EE and the request stack
225
+				new EE_Bootstrap(
226
+					new EE_Request($_GET, $_POST, $_COOKIE),
227
+					new EE_Response()
228
+				);
229
+			} catch (Exception $e) {
230
+				require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
+				new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
+			}
233
+		}
234
+		bootstrap_espresso();
235
+	}
236 236
 }
237 237
 if (! function_exists('espresso_deactivate_plugin')) {
238
-    /**
239
-     *    deactivate_plugin
240
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
-     *
242
-     * @access public
243
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
-     * @return    void
245
-     */
246
-    function espresso_deactivate_plugin($plugin_basename = '')
247
-    {
248
-        if (! function_exists('deactivate_plugins')) {
249
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
-        }
251
-        unset($_GET['activate'], $_REQUEST['activate']);
252
-        deactivate_plugins($plugin_basename);
253
-    }
238
+	/**
239
+	 *    deactivate_plugin
240
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
+	 *
242
+	 * @access public
243
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
+	 * @return    void
245
+	 */
246
+	function espresso_deactivate_plugin($plugin_basename = '')
247
+	{
248
+		if (! function_exists('deactivate_plugins')) {
249
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
+		}
251
+		unset($_GET['activate'], $_REQUEST['activate']);
252
+		deactivate_plugins($plugin_basename);
253
+	}
254 254
 }
Please login to merge, or discard this patch.