Completed
Branch FET/reg-form-builder/main (0b1bec)
by
unknown
14:36 queued 15s
created
core/db_models/fields/EE_JSON_Field.php 1 patch
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -5,76 +5,76 @@
 block discarded – undo
5 5
 class EE_JSON_Field extends EE_Model_Field_Base
6 6
 {
7 7
 
8
-    /**
9
-     * @var JsonDataHandler
10
-     */
11
-    private $json_data_handler;
8
+	/**
9
+	 * @var JsonDataHandler
10
+	 */
11
+	private $json_data_handler;
12 12
 
13 13
 
14
-    /**
15
-     * @param string $table_column
16
-     * @param string $nicename
17
-     * @param bool   $nullable
18
-     * @param null   $default_value
19
-     */
20
-    public function __construct(
21
-        $table_column,
22
-        $nicename,
23
-        $nullable,
24
-        $default_value = null
25
-    ) {
26
-        $this->json_data_handler = new JsonDataHandler();
27
-        $this->json_data_handler->configure(
28
-            JsonDataHandler::DATA_TYPE_OBJECT
29
-        );
30
-        parent::__construct($table_column, $nicename, $nullable, $default_value);
31
-    }
14
+	/**
15
+	 * @param string $table_column
16
+	 * @param string $nicename
17
+	 * @param bool   $nullable
18
+	 * @param null   $default_value
19
+	 */
20
+	public function __construct(
21
+		$table_column,
22
+		$nicename,
23
+		$nullable,
24
+		$default_value = null
25
+	) {
26
+		$this->json_data_handler = new JsonDataHandler();
27
+		$this->json_data_handler->configure(
28
+			JsonDataHandler::DATA_TYPE_OBJECT
29
+		);
30
+		parent::__construct($table_column, $nicename, $nullable, $default_value);
31
+	}
32 32
 
33 33
 
34
-    // /**
35
-    //  * When get() is called on a model object (eg EE_Event), before returning its value,
36
-    //  * call this function on it, allowing us to customize the returned value based on
37
-    //  * the field's type. Eg, we may want to unserialize it, strip tags, etc. By default,
38
-    //  * we simply return it.
39
-    //  *
40
-    //  * @param mixed $value_of_field_on_model_object
41
-    //  * @return mixed
42
-    //  */
43
-    // public function prepare_for_get($value_of_field_on_model_object)
44
-    // {
45
-    //     // return $this->json_data_handler->decodeJson($value_of_field_on_model_object);
46
-    //     return $value_of_field_on_model_object;
47
-    // }
34
+	// /**
35
+	//  * When get() is called on a model object (eg EE_Event), before returning its value,
36
+	//  * call this function on it, allowing us to customize the returned value based on
37
+	//  * the field's type. Eg, we may want to unserialize it, strip tags, etc. By default,
38
+	//  * we simply return it.
39
+	//  *
40
+	//  * @param mixed $value_of_field_on_model_object
41
+	//  * @return mixed
42
+	//  */
43
+	// public function prepare_for_get($value_of_field_on_model_object)
44
+	// {
45
+	//     // return $this->json_data_handler->decodeJson($value_of_field_on_model_object);
46
+	//     return $value_of_field_on_model_object;
47
+	// }
48 48
 
49 49
 
50
-    /**
51
-     * When creating a brand-new model object, or setting a particular value for one of its fields, this function
52
-     * is called before setting it on the model object. We may want to strip slashes, unserialize the value, etc.
53
-     * By default, we do nothing.
54
-     *
55
-     * If the model field is going to perform any validation on the input, this is where it should be done
56
-     * (once the value is on the model object, it may be used in other ways besides putting it into the DB
57
-     * so it's best to validate it right away).
58
-     *
59
-     * @param mixed $value_inputted_for_field_on_model_object
60
-     * @return string
61
-     */
62
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
63
-    {
64
-        return $this->json_data_handler->encodeData($value_inputted_for_field_on_model_object);
65
-    }
50
+	/**
51
+	 * When creating a brand-new model object, or setting a particular value for one of its fields, this function
52
+	 * is called before setting it on the model object. We may want to strip slashes, unserialize the value, etc.
53
+	 * By default, we do nothing.
54
+	 *
55
+	 * If the model field is going to perform any validation on the input, this is where it should be done
56
+	 * (once the value is on the model object, it may be used in other ways besides putting it into the DB
57
+	 * so it's best to validate it right away).
58
+	 *
59
+	 * @param mixed $value_inputted_for_field_on_model_object
60
+	 * @return string
61
+	 */
62
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
63
+	{
64
+		return $this->json_data_handler->encodeData($value_inputted_for_field_on_model_object);
65
+	}
66 66
 
67 67
 
68
-    /**
69
-     * When inserting or updating a field on a model object, run this function on each
70
-     * value to prepare it for insertion into the db. Generally this converts
71
-     * the validated input on the model object into the format used in the DB.
72
-     *
73
-     * @param mixed $value_of_field_on_model_object
74
-     * @return string
75
-     */
76
-    public function prepare_for_use_in_db($value_of_field_on_model_object)
77
-    {
78
-        return $this->json_data_handler->encodeData($value_of_field_on_model_object);
79
-    }
68
+	/**
69
+	 * When inserting or updating a field on a model object, run this function on each
70
+	 * value to prepare it for insertion into the db. Generally this converts
71
+	 * the validated input on the model object into the format used in the DB.
72
+	 *
73
+	 * @param mixed $value_of_field_on_model_object
74
+	 * @return string
75
+	 */
76
+	public function prepare_for_use_in_db($value_of_field_on_model_object)
77
+	{
78
+		return $this->json_data_handler->encodeData($value_of_field_on_model_object);
79
+	}
80 80
 }
Please login to merge, or discard this patch.
core/db_models/fields/EE_Foreign_Key_String_Field.php 1 patch
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -2,41 +2,41 @@
 block discarded – undo
2 2
 
3 3
 class EE_Foreign_Key_String_Field extends EE_Foreign_Key_Field_Base
4 4
 {
5
-    /**
6
-     * Whether the value should be converted to uppercase on insertion.
7
-     *
8
-     * @var boolean
9
-     */
10
-    protected $is_uppercase;
5
+	/**
6
+	 * Whether the value should be converted to uppercase on insertion.
7
+	 *
8
+	 * @var boolean
9
+	 */
10
+	protected $is_uppercase;
11 11
 
12 12
 
13
-    /**
14
-     * @param string          $table_column  name of column for field
15
-     * @param string          $nicename      should be internationalized with __('blah','event_espresso')
16
-     * @param boolean         $nullable
17
-     * @param int|string      $default_value data type should match field type
18
-     * @param string|string[] $model_name    eg 'Event','Answer','Term', etc.
19
-     *                                       Basically its the model class's name without the "EEM_"
20
-     * @param boolean         $is_uppercase  Whether the value should be converted to uppercase on insertion.
21
-     */
22
-    public function __construct($table_column, $nicename, $nullable, $default_value, $model_name, $is_uppercase = true)
23
-    {
24
-        $this->is_uppercase = $is_uppercase;
25
-        parent::__construct($table_column, $nicename, $nullable, $default_value, $model_name);
26
-    }
13
+	/**
14
+	 * @param string          $table_column  name of column for field
15
+	 * @param string          $nicename      should be internationalized with __('blah','event_espresso')
16
+	 * @param boolean         $nullable
17
+	 * @param int|string      $default_value data type should match field type
18
+	 * @param string|string[] $model_name    eg 'Event','Answer','Term', etc.
19
+	 *                                       Basically its the model class's name without the "EEM_"
20
+	 * @param boolean         $is_uppercase  Whether the value should be converted to uppercase on insertion.
21
+	 */
22
+	public function __construct($table_column, $nicename, $nullable, $default_value, $model_name, $is_uppercase = true)
23
+	{
24
+		$this->is_uppercase = $is_uppercase;
25
+		parent::__construct($table_column, $nicename, $nullable, $default_value, $model_name);
26
+	}
27 27
 
28
-    /**
29
-     * removes all tags when setting
30
-     *
31
-     * @param string $value_inputted_for_field_on_model_object
32
-     * @return string
33
-     */
34
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
35
-    {
36
-        if ($this->is_model_obj_of_type_pointed_to($value_inputted_for_field_on_model_object)) {
37
-            $value_inputted_for_field_on_model_object = $value_inputted_for_field_on_model_object->ID();
38
-        }
39
-        $clean_value = wp_strip_all_tags($value_inputted_for_field_on_model_object);
40
-        return $this->is_uppercase ? strtoupper($clean_value) : $clean_value;
41
-    }
28
+	/**
29
+	 * removes all tags when setting
30
+	 *
31
+	 * @param string $value_inputted_for_field_on_model_object
32
+	 * @return string
33
+	 */
34
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
35
+	{
36
+		if ($this->is_model_obj_of_type_pointed_to($value_inputted_for_field_on_model_object)) {
37
+			$value_inputted_for_field_on_model_object = $value_inputted_for_field_on_model_object->ID();
38
+		}
39
+		$clean_value = wp_strip_all_tags($value_inputted_for_field_on_model_object);
40
+		return $this->is_uppercase ? strtoupper($clean_value) : $clean_value;
41
+	}
42 42
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Form_Element.class.php 2 patches
Indentation   +467 added lines, -467 removed lines patch added patch discarded remove patch
@@ -29,471 +29,471 @@
 block discarded – undo
29 29
 class EE_Form_Element extends EE_Base_Class
30 30
 {
31 31
 
32
-    /**
33
-     * @var Attributes
34
-     */
35
-    private $attributes;
36
-
37
-    /**
38
-     * @var FormLabel
39
-     */
40
-    private $label;
41
-
42
-    /**
43
-     * @var HelpText
44
-     */
45
-    private $helpText;
46
-
47
-    /**
48
-     * @var InputOptions
49
-     */
50
-    private $options;
51
-
52
-    /**
53
-     * @var Required
54
-     */
55
-    private $required;
56
-
57
-
58
-    /**
59
-     * @param array $props_n_values
60
-     * @return EE_Form_Element
61
-     * @throws EE_Error
62
-     * @throws ReflectionException
63
-     */
64
-    public static function new_instance(array $props_n_values = []): EE_Form_Element
65
-    {
66
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
67
-        return $has_object ?: new self($props_n_values);
68
-    }
69
-
70
-
71
-    /**
72
-     * @param array $props_n_values
73
-     * @return EE_Form_Element
74
-     * @throws EE_Error
75
-     * @throws ReflectionException
76
-     */
77
-    public static function new_instance_from_db(array $props_n_values = []): EE_Form_Element
78
-    {
79
-        return new self($props_n_values);
80
-    }
81
-
82
-
83
-    /**
84
-     * Form Element UUID (universally unique identifier)
85
-     *
86
-     * @return string
87
-     * @throws EE_Error
88
-     * @throws ReflectionException
89
-     */
90
-    public function UUID(): string
91
-    {
92
-        return $this->get('FIN_UUID');
93
-    }
94
-
95
-
96
-    /**
97
-     * @param string $UUID
98
-     * @throws EE_Error
99
-     * @throws ReflectionException
100
-     */
101
-    public function setUUID(string $UUID)
102
-    {
103
-        $this->set('FIN_UUID', $UUID);
104
-    }
105
-
106
-
107
-    /**
108
-     * Whether or not input is only displayed in the admin. If false, input will appear in public forms
109
-     *
110
-     * @return bool
111
-     * @throws EE_Error
112
-     * @throws ReflectionException
113
-     */
114
-    public function adminOnly(): ?bool
115
-    {
116
-        return $this->get('FIN_adminOnly');
117
-    }
118
-
119
-
120
-    /**
121
-     * @param bool $admin_only
122
-     * @throws EE_Error
123
-     * @throws ReflectionException
124
-     */
125
-    public function setAdminOnly(bool $admin_only)
126
-    {
127
-        $this->set('FIN_adminOnly', $admin_only);
128
-    }
129
-
130
-
131
-    /**
132
-     * JSON string of HTML attributes such as class, max, min, placeholder, type, etc.
133
-     *
134
-     * @return Attributes
135
-     * @throws EE_Error
136
-     * @throws ReflectionException
137
-     */
138
-    public function attributes(): ?Attributes
139
-    {
140
-        if (! $this->attributes instanceof Attributes) {
141
-            $this->attributes = Attributes::fromJson($this->get('FIN_attributes'));
142
-        }
143
-        return $this->attributes;
144
-    }
145
-
146
-
147
-    /**
148
-     * @param Attributes $attributes
149
-     * @throws EE_Error
150
-     * @throws ReflectionException
151
-     */
152
-    public function setAttributes(Attributes $attributes)
153
-    {
154
-        // set local object
155
-        $this->attributes = $attributes;
156
-        // then pass to model as an array which will get converted to JSON by the model field
157
-        $this->set('FIN_attributes', $attributes->toArray());
158
-    }
159
-
160
-
161
-    /**
162
-     * UUID of parent form section this form input belongs to.
163
-     *
164
-     * @return string
165
-     * @throws EE_Error
166
-     * @throws ReflectionException
167
-     */
168
-    public function belongsTo(): string
169
-    {
170
-        return $this->get('FSC_UUID');
171
-    }
172
-
173
-
174
-    /**
175
-     * @param string $relation_UUID
176
-     * @throws EE_Error
177
-     * @throws ReflectionException
178
-     */
179
-    public function setBelongsTo(string $relation_UUID)
180
-    {
181
-        $this->set('FSC_UUID', $relation_UUID);
182
-    }
183
-
184
-
185
-    /**
186
-     * returns a HelpText object for managing input help text
187
-     *
188
-     * @return HelpText
189
-     * @throws EE_Error
190
-     * @throws ReflectionException
191
-     */
192
-    public function helpText(): ?HelpText
193
-    {
194
-        if (! $this->helpText instanceof HelpText) {
195
-            $this->helpText = HelpText::fromJson($this->get('FIN_helpText'));
196
-        }
197
-        return $this->helpText;
198
-    }
199
-
200
-
201
-    /**
202
-     * @param HelpText $helpText
203
-     * @throws EE_Error
204
-     * @throws ReflectionException
205
-     */
206
-    public function setHelpText(HelpText $helpText)
207
-    {
208
-        // set local object
209
-        $this->helpText = $helpText;
210
-        // then pass to model as an array which will get converted to JSON by the model field
211
-        $this->set('FIN_helpText', $helpText->toArray());
212
-    }
213
-
214
-
215
-    /**
216
-     * returns a FormLabel object for managing input labels
217
-     *
218
-     * @return FormLabel
219
-     * @throws EE_Error
220
-     * @throws ReflectionException
221
-     */
222
-    public function label(): ?FormLabel
223
-    {
224
-        if (! $this->label instanceof FormLabel) {
225
-            $this->label = FormLabel::fromJson($this->get('FIN_label'));
226
-        }
227
-        return $this->label;
228
-    }
229
-
230
-
231
-    /**
232
-     * @param FormLabel $label
233
-     * @throws EE_Error
234
-     * @throws ReflectionException
235
-     */
236
-    public function setLabel(FormLabel $label)
237
-    {
238
-        // set local object
239
-        $this->label = $label;
240
-        // then pass to model as an array which will get converted to JSON by the model field
241
-        $this->set('FIN_label', $label->toArray());
242
-    }
243
-
244
-
245
-    /**
246
-     * Model and Fields name that this input maps to; ex: Attendee.email
247
-     *
248
-     * @return string
249
-     * @throws EE_Error
250
-     * @throws ReflectionException
251
-     */
252
-    public function mapsTo(): ?string
253
-    {
254
-        return $this->get('FIN_mapsTo');
255
-    }
256
-
257
-
258
-    /**
259
-     * @param string $model ex: Attendee
260
-     * @param string $field ex: email
261
-     * @throws EE_Error
262
-     * @throws ReflectionException
263
-     */
264
-    public function setMapsTo(string $model, string $field)
265
-    {
266
-        $model_name = strpos($model, 'EEM_') !== 0 ? "EEM_$model" : $model;
267
-        if (! class_exists($model_name)) {
268
-            throw new DomainException(
269
-                sprintf(
270
-                    esc_html__(
271
-                        'The %1$s model does not exist or can not be located. Please verify the spelling and whether it is loaded.',
272
-                        'event_espresso'
273
-                    ),
274
-                    $model_name
275
-                )
276
-            );
277
-        }
278
-        $this->set('FIN_mapsTo', "{$model}.{$field}");
279
-    }
280
-
281
-
282
-    /**
283
-     * Options for ENUM type inputs like checkboxes, radio buttons, select inputs, etc
284
-     *
285
-     * @return InputOptions
286
-     * @throws EE_Error
287
-     * @throws ReflectionException
288
-     */
289
-    public function options(): ?InputOptions
290
-    {
291
-        if (! $this->options instanceof InputOptions) {
292
-            $this->options = InputOptions::fromJson($this->get('FIN_options'));
293
-        }
294
-        return $this->options;
295
-    }
296
-
297
-
298
-    /**
299
-     * @param InputOptions $options
300
-     * @throws EE_Error
301
-     * @throws ReflectionException
302
-     */
303
-    public function setOptions(InputOptions $options)
304
-    {
305
-        // set local object
306
-        $this->options = $options;
307
-        // then pass to model as an array which will get converted to JSON by the model field
308
-        $this->set('FIN_options', $options->toArray());
309
-    }
310
-
311
-
312
-
313
-    /**
314
-     * Order in which form input appears in a form.
315
-     *
316
-     * @return int
317
-     * @throws EE_Error
318
-     * @throws ReflectionException
319
-     */
320
-    public function order(): int
321
-    {
322
-        return $this->get('FIN_order');
323
-    }
324
-
325
-
326
-    /**
327
-     * @param int $order
328
-     * @throws EE_Error
329
-     * @throws ReflectionException
330
-     */
331
-    public function setOrder(int $order)
332
-    {
333
-        $this->set('FIN_order', $order);
334
-    }
335
-
336
-
337
-    /**
338
-     * Example text displayed within an input to assist users with completing the form.
339
-     *
340
-     * @return string
341
-     * @throws EE_Error
342
-     * @throws ReflectionException
343
-     */
344
-    public function placeholder(): ?string
345
-    {
346
-        return $this->get('FIN_placeholder');
347
-    }
348
-
349
-
350
-    /**
351
-     * @param string $placeholder
352
-     * @throws EE_Error
353
-     * @throws ReflectionException
354
-     */
355
-    public function setPlaceholder(string $placeholder)
356
-    {
357
-        $this->set('FIN_placeholder', $placeholder);
358
-    }
359
-
360
-
361
-    /**
362
-     * Whether or not the input must be supplied with a value in order to complete the form.
363
-     *
364
-     * @return Required
365
-     * @throws EE_Error
366
-     * @throws ReflectionException
367
-     */
368
-    public function required(): ?Required
369
-    {
370
-        if (! $this->required instanceof Required) {
371
-            $this->required = Required::fromJson($this->get('FIN_required'));
372
-        }
373
-        return $this->required;
374
-    }
375
-
376
-
377
-    /**
378
-     * @param Required $required
379
-     * @throws EE_Error
380
-     * @throws ReflectionException
381
-     */
382
-    public function setRequired(Required $required)
383
-    {
384
-        // set local object
385
-        $this->required = $required;
386
-        // then pass to model as an array which will get converted to JSON by the model field
387
-        $this->set('FIN_required', $required->toArray());
388
-    }
389
-
390
-
391
-    /**
392
-     * version of public label for use in identifiers
393
-     *
394
-     * @return string
395
-     * @throws EE_Error
396
-     * @throws ReflectionException
397
-     */
398
-    public function slug(): ?string
399
-    {
400
-        return sanitize_title($this->label()->publicLabel());
401
-    }
402
-
403
-
404
-    /**
405
-     * Whether form input is active, archived, trashed, or used as a default on new forms.
406
-     * Values correspond to the EEM_Form_Element::STATUS_* constants.
407
-     *
408
-     * @return string
409
-     * @throws EE_Error
410
-     * @throws ReflectionException
411
-     */
412
-    public function status(): string
413
-    {
414
-        return $this->get('FIN_status');
415
-    }
416
-
417
-
418
-    /**
419
-     * Whether form input is active, archived, trashed, or used as a default on new forms.
420
-     * Values correspond to the EEM_Form_Element::STATUS_* constants.
421
-     *
422
-     * @param string $status
423
-     * @throws EE_Error
424
-     * @throws ReflectionException
425
-     */
426
-    public function setStatus(string $status)
427
-    {
428
-        $this->set('FIN_status', $status);
429
-    }
430
-
431
-
432
-    /**
433
-     * Form input type.
434
-     * Values correspond to the EventEspresso\core\domain\entities\form\Input::TYPE_* constants.
435
-     *
436
-     * @return string
437
-     * @throws EE_Error
438
-     * @throws ReflectionException
439
-     */
440
-    public function type(): ?string
441
-    {
442
-        return $this->get('FIN_type');
443
-    }
444
-
445
-
446
-    /**
447
-     * @param string $type
448
-     * @throws EE_Error
449
-     * @throws ReflectionException
450
-     */
451
-    public function setType(string $type)
452
-    {
453
-        $this->set('FIN_type', $type);
454
-    }
455
-
456
-
457
-    /**
458
-     * ID of the WP User that created this form input.
459
-     *
460
-     * @return int
461
-     * @throws EE_Error
462
-     * @throws ReflectionException
463
-     */
464
-    public function wp_user(): int
465
-    {
466
-        return $this->get('FIN_wpUser');
467
-    }
468
-
469
-
470
-    /**
471
-     * returns the id the wordpress user who created this question
472
-     *
473
-     * @param int $wp_user
474
-     * @throws EE_Error
475
-     * @throws ReflectionException
476
-     */
477
-    public function setWpUser(int $wp_user)
478
-    {
479
-        $this->set('FIN_wpUser', $wp_user);
480
-    }
481
-
482
-
483
-    /**
484
-     * @param array $set_cols_n_values
485
-     * @return bool|int|string
486
-     * @throws EE_Error
487
-     * @throws ReflectionException
488
-     */
489
-    public function save($set_cols_n_values = [])
490
-    {
491
-        // make sure internal versions for all composite objects are updated
492
-        $this->set('FIN_attributes', $this->attributes()->toArray());
493
-        $this->set('FIN_helpText', $this->helpText()->toArray());
494
-        $this->set('FIN_label', $this->label()->toArray());
495
-        $this->set('FIN_options', $this->options()->toArray());
496
-        $this->set('FIN_required', $this->required()->toArray());
497
-        return parent::save($set_cols_n_values);
498
-    }
32
+	/**
33
+	 * @var Attributes
34
+	 */
35
+	private $attributes;
36
+
37
+	/**
38
+	 * @var FormLabel
39
+	 */
40
+	private $label;
41
+
42
+	/**
43
+	 * @var HelpText
44
+	 */
45
+	private $helpText;
46
+
47
+	/**
48
+	 * @var InputOptions
49
+	 */
50
+	private $options;
51
+
52
+	/**
53
+	 * @var Required
54
+	 */
55
+	private $required;
56
+
57
+
58
+	/**
59
+	 * @param array $props_n_values
60
+	 * @return EE_Form_Element
61
+	 * @throws EE_Error
62
+	 * @throws ReflectionException
63
+	 */
64
+	public static function new_instance(array $props_n_values = []): EE_Form_Element
65
+	{
66
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
67
+		return $has_object ?: new self($props_n_values);
68
+	}
69
+
70
+
71
+	/**
72
+	 * @param array $props_n_values
73
+	 * @return EE_Form_Element
74
+	 * @throws EE_Error
75
+	 * @throws ReflectionException
76
+	 */
77
+	public static function new_instance_from_db(array $props_n_values = []): EE_Form_Element
78
+	{
79
+		return new self($props_n_values);
80
+	}
81
+
82
+
83
+	/**
84
+	 * Form Element UUID (universally unique identifier)
85
+	 *
86
+	 * @return string
87
+	 * @throws EE_Error
88
+	 * @throws ReflectionException
89
+	 */
90
+	public function UUID(): string
91
+	{
92
+		return $this->get('FIN_UUID');
93
+	}
94
+
95
+
96
+	/**
97
+	 * @param string $UUID
98
+	 * @throws EE_Error
99
+	 * @throws ReflectionException
100
+	 */
101
+	public function setUUID(string $UUID)
102
+	{
103
+		$this->set('FIN_UUID', $UUID);
104
+	}
105
+
106
+
107
+	/**
108
+	 * Whether or not input is only displayed in the admin. If false, input will appear in public forms
109
+	 *
110
+	 * @return bool
111
+	 * @throws EE_Error
112
+	 * @throws ReflectionException
113
+	 */
114
+	public function adminOnly(): ?bool
115
+	{
116
+		return $this->get('FIN_adminOnly');
117
+	}
118
+
119
+
120
+	/**
121
+	 * @param bool $admin_only
122
+	 * @throws EE_Error
123
+	 * @throws ReflectionException
124
+	 */
125
+	public function setAdminOnly(bool $admin_only)
126
+	{
127
+		$this->set('FIN_adminOnly', $admin_only);
128
+	}
129
+
130
+
131
+	/**
132
+	 * JSON string of HTML attributes such as class, max, min, placeholder, type, etc.
133
+	 *
134
+	 * @return Attributes
135
+	 * @throws EE_Error
136
+	 * @throws ReflectionException
137
+	 */
138
+	public function attributes(): ?Attributes
139
+	{
140
+		if (! $this->attributes instanceof Attributes) {
141
+			$this->attributes = Attributes::fromJson($this->get('FIN_attributes'));
142
+		}
143
+		return $this->attributes;
144
+	}
145
+
146
+
147
+	/**
148
+	 * @param Attributes $attributes
149
+	 * @throws EE_Error
150
+	 * @throws ReflectionException
151
+	 */
152
+	public function setAttributes(Attributes $attributes)
153
+	{
154
+		// set local object
155
+		$this->attributes = $attributes;
156
+		// then pass to model as an array which will get converted to JSON by the model field
157
+		$this->set('FIN_attributes', $attributes->toArray());
158
+	}
159
+
160
+
161
+	/**
162
+	 * UUID of parent form section this form input belongs to.
163
+	 *
164
+	 * @return string
165
+	 * @throws EE_Error
166
+	 * @throws ReflectionException
167
+	 */
168
+	public function belongsTo(): string
169
+	{
170
+		return $this->get('FSC_UUID');
171
+	}
172
+
173
+
174
+	/**
175
+	 * @param string $relation_UUID
176
+	 * @throws EE_Error
177
+	 * @throws ReflectionException
178
+	 */
179
+	public function setBelongsTo(string $relation_UUID)
180
+	{
181
+		$this->set('FSC_UUID', $relation_UUID);
182
+	}
183
+
184
+
185
+	/**
186
+	 * returns a HelpText object for managing input help text
187
+	 *
188
+	 * @return HelpText
189
+	 * @throws EE_Error
190
+	 * @throws ReflectionException
191
+	 */
192
+	public function helpText(): ?HelpText
193
+	{
194
+		if (! $this->helpText instanceof HelpText) {
195
+			$this->helpText = HelpText::fromJson($this->get('FIN_helpText'));
196
+		}
197
+		return $this->helpText;
198
+	}
199
+
200
+
201
+	/**
202
+	 * @param HelpText $helpText
203
+	 * @throws EE_Error
204
+	 * @throws ReflectionException
205
+	 */
206
+	public function setHelpText(HelpText $helpText)
207
+	{
208
+		// set local object
209
+		$this->helpText = $helpText;
210
+		// then pass to model as an array which will get converted to JSON by the model field
211
+		$this->set('FIN_helpText', $helpText->toArray());
212
+	}
213
+
214
+
215
+	/**
216
+	 * returns a FormLabel object for managing input labels
217
+	 *
218
+	 * @return FormLabel
219
+	 * @throws EE_Error
220
+	 * @throws ReflectionException
221
+	 */
222
+	public function label(): ?FormLabel
223
+	{
224
+		if (! $this->label instanceof FormLabel) {
225
+			$this->label = FormLabel::fromJson($this->get('FIN_label'));
226
+		}
227
+		return $this->label;
228
+	}
229
+
230
+
231
+	/**
232
+	 * @param FormLabel $label
233
+	 * @throws EE_Error
234
+	 * @throws ReflectionException
235
+	 */
236
+	public function setLabel(FormLabel $label)
237
+	{
238
+		// set local object
239
+		$this->label = $label;
240
+		// then pass to model as an array which will get converted to JSON by the model field
241
+		$this->set('FIN_label', $label->toArray());
242
+	}
243
+
244
+
245
+	/**
246
+	 * Model and Fields name that this input maps to; ex: Attendee.email
247
+	 *
248
+	 * @return string
249
+	 * @throws EE_Error
250
+	 * @throws ReflectionException
251
+	 */
252
+	public function mapsTo(): ?string
253
+	{
254
+		return $this->get('FIN_mapsTo');
255
+	}
256
+
257
+
258
+	/**
259
+	 * @param string $model ex: Attendee
260
+	 * @param string $field ex: email
261
+	 * @throws EE_Error
262
+	 * @throws ReflectionException
263
+	 */
264
+	public function setMapsTo(string $model, string $field)
265
+	{
266
+		$model_name = strpos($model, 'EEM_') !== 0 ? "EEM_$model" : $model;
267
+		if (! class_exists($model_name)) {
268
+			throw new DomainException(
269
+				sprintf(
270
+					esc_html__(
271
+						'The %1$s model does not exist or can not be located. Please verify the spelling and whether it is loaded.',
272
+						'event_espresso'
273
+					),
274
+					$model_name
275
+				)
276
+			);
277
+		}
278
+		$this->set('FIN_mapsTo', "{$model}.{$field}");
279
+	}
280
+
281
+
282
+	/**
283
+	 * Options for ENUM type inputs like checkboxes, radio buttons, select inputs, etc
284
+	 *
285
+	 * @return InputOptions
286
+	 * @throws EE_Error
287
+	 * @throws ReflectionException
288
+	 */
289
+	public function options(): ?InputOptions
290
+	{
291
+		if (! $this->options instanceof InputOptions) {
292
+			$this->options = InputOptions::fromJson($this->get('FIN_options'));
293
+		}
294
+		return $this->options;
295
+	}
296
+
297
+
298
+	/**
299
+	 * @param InputOptions $options
300
+	 * @throws EE_Error
301
+	 * @throws ReflectionException
302
+	 */
303
+	public function setOptions(InputOptions $options)
304
+	{
305
+		// set local object
306
+		$this->options = $options;
307
+		// then pass to model as an array which will get converted to JSON by the model field
308
+		$this->set('FIN_options', $options->toArray());
309
+	}
310
+
311
+
312
+
313
+	/**
314
+	 * Order in which form input appears in a form.
315
+	 *
316
+	 * @return int
317
+	 * @throws EE_Error
318
+	 * @throws ReflectionException
319
+	 */
320
+	public function order(): int
321
+	{
322
+		return $this->get('FIN_order');
323
+	}
324
+
325
+
326
+	/**
327
+	 * @param int $order
328
+	 * @throws EE_Error
329
+	 * @throws ReflectionException
330
+	 */
331
+	public function setOrder(int $order)
332
+	{
333
+		$this->set('FIN_order', $order);
334
+	}
335
+
336
+
337
+	/**
338
+	 * Example text displayed within an input to assist users with completing the form.
339
+	 *
340
+	 * @return string
341
+	 * @throws EE_Error
342
+	 * @throws ReflectionException
343
+	 */
344
+	public function placeholder(): ?string
345
+	{
346
+		return $this->get('FIN_placeholder');
347
+	}
348
+
349
+
350
+	/**
351
+	 * @param string $placeholder
352
+	 * @throws EE_Error
353
+	 * @throws ReflectionException
354
+	 */
355
+	public function setPlaceholder(string $placeholder)
356
+	{
357
+		$this->set('FIN_placeholder', $placeholder);
358
+	}
359
+
360
+
361
+	/**
362
+	 * Whether or not the input must be supplied with a value in order to complete the form.
363
+	 *
364
+	 * @return Required
365
+	 * @throws EE_Error
366
+	 * @throws ReflectionException
367
+	 */
368
+	public function required(): ?Required
369
+	{
370
+		if (! $this->required instanceof Required) {
371
+			$this->required = Required::fromJson($this->get('FIN_required'));
372
+		}
373
+		return $this->required;
374
+	}
375
+
376
+
377
+	/**
378
+	 * @param Required $required
379
+	 * @throws EE_Error
380
+	 * @throws ReflectionException
381
+	 */
382
+	public function setRequired(Required $required)
383
+	{
384
+		// set local object
385
+		$this->required = $required;
386
+		// then pass to model as an array which will get converted to JSON by the model field
387
+		$this->set('FIN_required', $required->toArray());
388
+	}
389
+
390
+
391
+	/**
392
+	 * version of public label for use in identifiers
393
+	 *
394
+	 * @return string
395
+	 * @throws EE_Error
396
+	 * @throws ReflectionException
397
+	 */
398
+	public function slug(): ?string
399
+	{
400
+		return sanitize_title($this->label()->publicLabel());
401
+	}
402
+
403
+
404
+	/**
405
+	 * Whether form input is active, archived, trashed, or used as a default on new forms.
406
+	 * Values correspond to the EEM_Form_Element::STATUS_* constants.
407
+	 *
408
+	 * @return string
409
+	 * @throws EE_Error
410
+	 * @throws ReflectionException
411
+	 */
412
+	public function status(): string
413
+	{
414
+		return $this->get('FIN_status');
415
+	}
416
+
417
+
418
+	/**
419
+	 * Whether form input is active, archived, trashed, or used as a default on new forms.
420
+	 * Values correspond to the EEM_Form_Element::STATUS_* constants.
421
+	 *
422
+	 * @param string $status
423
+	 * @throws EE_Error
424
+	 * @throws ReflectionException
425
+	 */
426
+	public function setStatus(string $status)
427
+	{
428
+		$this->set('FIN_status', $status);
429
+	}
430
+
431
+
432
+	/**
433
+	 * Form input type.
434
+	 * Values correspond to the EventEspresso\core\domain\entities\form\Input::TYPE_* constants.
435
+	 *
436
+	 * @return string
437
+	 * @throws EE_Error
438
+	 * @throws ReflectionException
439
+	 */
440
+	public function type(): ?string
441
+	{
442
+		return $this->get('FIN_type');
443
+	}
444
+
445
+
446
+	/**
447
+	 * @param string $type
448
+	 * @throws EE_Error
449
+	 * @throws ReflectionException
450
+	 */
451
+	public function setType(string $type)
452
+	{
453
+		$this->set('FIN_type', $type);
454
+	}
455
+
456
+
457
+	/**
458
+	 * ID of the WP User that created this form input.
459
+	 *
460
+	 * @return int
461
+	 * @throws EE_Error
462
+	 * @throws ReflectionException
463
+	 */
464
+	public function wp_user(): int
465
+	{
466
+		return $this->get('FIN_wpUser');
467
+	}
468
+
469
+
470
+	/**
471
+	 * returns the id the wordpress user who created this question
472
+	 *
473
+	 * @param int $wp_user
474
+	 * @throws EE_Error
475
+	 * @throws ReflectionException
476
+	 */
477
+	public function setWpUser(int $wp_user)
478
+	{
479
+		$this->set('FIN_wpUser', $wp_user);
480
+	}
481
+
482
+
483
+	/**
484
+	 * @param array $set_cols_n_values
485
+	 * @return bool|int|string
486
+	 * @throws EE_Error
487
+	 * @throws ReflectionException
488
+	 */
489
+	public function save($set_cols_n_values = [])
490
+	{
491
+		// make sure internal versions for all composite objects are updated
492
+		$this->set('FIN_attributes', $this->attributes()->toArray());
493
+		$this->set('FIN_helpText', $this->helpText()->toArray());
494
+		$this->set('FIN_label', $this->label()->toArray());
495
+		$this->set('FIN_options', $this->options()->toArray());
496
+		$this->set('FIN_required', $this->required()->toArray());
497
+		return parent::save($set_cols_n_values);
498
+	}
499 499
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
      */
138 138
     public function attributes(): ?Attributes
139 139
     {
140
-        if (! $this->attributes instanceof Attributes) {
140
+        if ( ! $this->attributes instanceof Attributes) {
141 141
             $this->attributes = Attributes::fromJson($this->get('FIN_attributes'));
142 142
         }
143 143
         return $this->attributes;
@@ -191,7 +191,7 @@  discard block
 block discarded – undo
191 191
      */
192 192
     public function helpText(): ?HelpText
193 193
     {
194
-        if (! $this->helpText instanceof HelpText) {
194
+        if ( ! $this->helpText instanceof HelpText) {
195 195
             $this->helpText = HelpText::fromJson($this->get('FIN_helpText'));
196 196
         }
197 197
         return $this->helpText;
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
      */
222 222
     public function label(): ?FormLabel
223 223
     {
224
-        if (! $this->label instanceof FormLabel) {
224
+        if ( ! $this->label instanceof FormLabel) {
225 225
             $this->label = FormLabel::fromJson($this->get('FIN_label'));
226 226
         }
227 227
         return $this->label;
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
     public function setMapsTo(string $model, string $field)
265 265
     {
266 266
         $model_name = strpos($model, 'EEM_') !== 0 ? "EEM_$model" : $model;
267
-        if (! class_exists($model_name)) {
267
+        if ( ! class_exists($model_name)) {
268 268
             throw new DomainException(
269 269
                 sprintf(
270 270
                     esc_html__(
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
      */
289 289
     public function options(): ?InputOptions
290 290
     {
291
-        if (! $this->options instanceof InputOptions) {
291
+        if ( ! $this->options instanceof InputOptions) {
292 292
             $this->options = InputOptions::fromJson($this->get('FIN_options'));
293 293
         }
294 294
         return $this->options;
@@ -367,7 +367,7 @@  discard block
 block discarded – undo
367 367
      */
368 368
     public function required(): ?Required
369 369
     {
370
-        if (! $this->required instanceof Required) {
370
+        if ( ! $this->required instanceof Required) {
371 371
             $this->required = Required::fromJson($this->get('FIN_required'));
372 372
         }
373 373
         return $this->required;
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/CopyAttendeeInfoForm.php 2 patches
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -12,77 +12,77 @@
 block discarded – undo
12 12
 
13 13
 class CopyAttendeeInfoForm extends EE_Form_Section_Proper
14 14
 {
15
-    /**
16
-     * CopyAttendeeInfoForm constructor.
17
-     *
18
-     * @param EE_Registration[] $registrations
19
-     * @param string            $slug
20
-     * @throws EE_Error
21
-     * @throws ReflectionException
22
-     */
23
-    public function __construct(array $registrations, string $slug)
24
-    {
25
-        parent::__construct(
26
-            [
27
-                'subsections'     => $this->copyAttendeeInfoInputs($registrations),
28
-                'layout_strategy' => new EE_Template_Layout(
29
-                    [
30
-                        'layout_template_file'     => SPCO_REG_STEPS_PATH
31
-                                                      . $slug
32
-                                                      . '/copy_attendee_info.template.php',
33
-                        'begin_template_file'      => null,
34
-                        'input_template_file'      => null,
35
-                        'subsection_template_file' => null,
36
-                        'end_template_file'        => null,
37
-                    ]
38
-                ),
39
-            ]
40
-        );
41
-    }
15
+	/**
16
+	 * CopyAttendeeInfoForm constructor.
17
+	 *
18
+	 * @param EE_Registration[] $registrations
19
+	 * @param string            $slug
20
+	 * @throws EE_Error
21
+	 * @throws ReflectionException
22
+	 */
23
+	public function __construct(array $registrations, string $slug)
24
+	{
25
+		parent::__construct(
26
+			[
27
+				'subsections'     => $this->copyAttendeeInfoInputs($registrations),
28
+				'layout_strategy' => new EE_Template_Layout(
29
+					[
30
+						'layout_template_file'     => SPCO_REG_STEPS_PATH
31
+													  . $slug
32
+													  . '/copy_attendee_info.template.php',
33
+						'begin_template_file'      => null,
34
+						'input_template_file'      => null,
35
+						'subsection_template_file' => null,
36
+						'end_template_file'        => null,
37
+					]
38
+				),
39
+			]
40
+		);
41
+	}
42 42
 
43 43
 
44
-    /**
45
-     * @param array $registrations
46
-     * @return array
47
-     * @throws EE_Error
48
-     * @throws ReflectionException
49
-     */
50
-    private function copyAttendeeInfoInputs(array $registrations): array
51
-    {
52
-        $copy_attendee_info_inputs = [];
53
-        $prev_ticket               = null;
54
-        foreach ($registrations as $registration) {
55
-            // for all  attendees other than the primary attendee
56
-            if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
57
-                // if this is a new ticket OR if this is the very first additional attendee after the primary attendee
58
-                if ($registration->ticket()->ID() !== $prev_ticket) {
59
-                    $item_name   = $registration->ticket()->name();
60
-                    $item_name   .= $registration->ticket()->description() !== ''
61
-                        ? ' - ' . $registration->ticket()->description()
62
-                        : '';
63
-                    $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']' ]
64
-                                 = new EE_Form_Section_HTML(
65
-                                     '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
66
-                                 );
67
-                    $prev_ticket = $registration->ticket()->ID();
68
-                }
44
+	/**
45
+	 * @param array $registrations
46
+	 * @return array
47
+	 * @throws EE_Error
48
+	 * @throws ReflectionException
49
+	 */
50
+	private function copyAttendeeInfoInputs(array $registrations): array
51
+	{
52
+		$copy_attendee_info_inputs = [];
53
+		$prev_ticket               = null;
54
+		foreach ($registrations as $registration) {
55
+			// for all  attendees other than the primary attendee
56
+			if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
57
+				// if this is a new ticket OR if this is the very first additional attendee after the primary attendee
58
+				if ($registration->ticket()->ID() !== $prev_ticket) {
59
+					$item_name   = $registration->ticket()->name();
60
+					$item_name   .= $registration->ticket()->description() !== ''
61
+						? ' - ' . $registration->ticket()->description()
62
+						: '';
63
+					$copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']' ]
64
+								 = new EE_Form_Section_HTML(
65
+									 '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
66
+								 );
67
+					$prev_ticket = $registration->ticket()->ID();
68
+				}
69 69
 
70
-                $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ]
71
-                    = new EE_Checkbox_Multi_Input(
72
-                        [
73
-                        $registration->ID() => sprintf(
74
-                            esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'),
75
-                            $registration->count()
76
-                        )
77
-                        ],
78
-                        [
79
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
80
-                            'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
81
-                            'display_html_label_text' => false,
82
-                        ]
83
-                    );
84
-            }
85
-        }
86
-        return $copy_attendee_info_inputs;
87
-    }
70
+				$copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ]
71
+					= new EE_Checkbox_Multi_Input(
72
+						[
73
+						$registration->ID() => sprintf(
74
+							esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'),
75
+							$registration->count()
76
+						)
77
+						],
78
+						[
79
+							'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
80
+							'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
81
+							'display_html_label_text' => false,
82
+						]
83
+					);
84
+			}
85
+		}
86
+		return $copy_attendee_info_inputs;
87
+	}
88 88
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -56,18 +56,18 @@  discard block
 block discarded – undo
56 56
             if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) {
57 57
                 // if this is a new ticket OR if this is the very first additional attendee after the primary attendee
58 58
                 if ($registration->ticket()->ID() !== $prev_ticket) {
59
-                    $item_name   = $registration->ticket()->name();
60
-                    $item_name   .= $registration->ticket()->description() !== ''
61
-                        ? ' - ' . $registration->ticket()->description()
59
+                    $item_name = $registration->ticket()->name();
60
+                    $item_name .= $registration->ticket()->description() !== ''
61
+                        ? ' - '.$registration->ticket()->description()
62 62
                         : '';
63
-                    $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID() . ']' ]
63
+                    $copy_attendee_info_inputs['spco_copy_attendee_chk[ticket-'.$registration->ticket()->ID().']']
64 64
                                  = new EE_Form_Section_HTML(
65
-                                     '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>'
65
+                                     '<h6 class="spco-copy-attendee-event-hdr">'.$item_name.'</h6>'
66 66
                                  );
67 67
                     $prev_ticket = $registration->ticket()->ID();
68 68
                 }
69 69
 
70
-                $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ]
70
+                $copy_attendee_info_inputs['spco_copy_attendee_chk['.$registration->ID().']']
71 71
                     = new EE_Checkbox_Multi_Input(
72 72
                         [
73 73
                         $registration->ID() => sprintf(
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
                         )
77 77
                         ],
78 78
                         [
79
-                            'html_id'                 => 'spco-copy-attendee-chk-' . $registration->reg_url_link(),
79
+                            'html_id'                 => 'spco-copy-attendee-chk-'.$registration->reg_url_link(),
80 80
                             'html_class'              => 'spco-copy-attendee-chk ee-do-not-validate',
81 81
                             'display_html_label_text' => false,
82 82
                         ]
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegForm.php 2 patches
Indentation   +220 added lines, -220 removed lines patch added patch discarded remove patch
@@ -32,251 +32,251 @@
 block discarded – undo
32 32
 class RegForm extends EE_Form_Section_Proper
33 33
 {
34 34
 
35
-    /**
36
-     * @var bool
37
-     */
38
-    private $print_copy_info = false;
35
+	/**
36
+	 * @var bool
37
+	 */
38
+	private $print_copy_info = false;
39 39
 
40
-    /**
41
-     * @var EE_Registration_Config
42
-     */
43
-    public $reg_config;
40
+	/**
41
+	 * @var EE_Registration_Config
42
+	 */
43
+	public $reg_config;
44 44
 
45
-    /**
46
-     * @var int
47
-     */
48
-    protected $reg_form_count = 0;
45
+	/**
46
+	 * @var int
47
+	 */
48
+	protected $reg_form_count = 0;
49 49
 
50
-    /**
51
-     * @var EE_SPCO_Reg_Step_Attendee_Information
52
-     */
53
-    public $reg_step;
50
+	/**
51
+	 * @var EE_SPCO_Reg_Step_Attendee_Information
52
+	 */
53
+	public $reg_step;
54 54
 
55
-    /**
56
-     * @var array
57
-     */
58
-    private $required_questions = [];
55
+	/**
56
+	 * @var array
57
+	 */
58
+	private $required_questions = [];
59 59
 
60
-    /**
61
-     * @var array
62
-     */
63
-    private $template_args = [];
60
+	/**
61
+	 * @var array
62
+	 */
63
+	private $template_args = [];
64 64
 
65 65
 
66
-    /**
67
-     * RegForm constructor.
68
-     *
69
-     * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
70
-     * @param EE_Registration_Config                $reg_config
71
-     * @throws ReflectionException
72
-     * @throws EE_Error
73
-     */
74
-    public function __construct(
75
-        EE_SPCO_Reg_Step_Attendee_Information $reg_step,
76
-        EE_Registration_Config $reg_config
77
-    ) {
78
-        $this->reg_step   = $reg_step;
79
-        $this->reg_config = $reg_config;
80
-        // setup some classes so that they are ready for loading during construction of other classes
81
-        LoaderFactory::getShared(CountryOptions::class, [$this->reg_step->checkout->action]);
82
-        LoaderFactory::getShared(StateOptions::class, [$this->reg_step->checkout->action]);
83
-        LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
84
-        parent::__construct(
85
-            [
86
-                'name'            => $this->reg_step->reg_form_name(),
87
-                'html_id'         => $this->reg_step->reg_form_name(),
88
-                'subsections'     => $this->generateSubsections(),
89
-                'layout_strategy' => new EE_Template_Layout(
90
-                    [
91
-                        'layout_template_file' => $this->reg_step->template(), // layout_template
92
-                        'template_args'        => $this->template_args,
93
-                    ]
94
-                ),
95
-            ]
96
-        );
97
-    }
66
+	/**
67
+	 * RegForm constructor.
68
+	 *
69
+	 * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
70
+	 * @param EE_Registration_Config                $reg_config
71
+	 * @throws ReflectionException
72
+	 * @throws EE_Error
73
+	 */
74
+	public function __construct(
75
+		EE_SPCO_Reg_Step_Attendee_Information $reg_step,
76
+		EE_Registration_Config $reg_config
77
+	) {
78
+		$this->reg_step   = $reg_step;
79
+		$this->reg_config = $reg_config;
80
+		// setup some classes so that they are ready for loading during construction of other classes
81
+		LoaderFactory::getShared(CountryOptions::class, [$this->reg_step->checkout->action]);
82
+		LoaderFactory::getShared(StateOptions::class, [$this->reg_step->checkout->action]);
83
+		LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
84
+		parent::__construct(
85
+			[
86
+				'name'            => $this->reg_step->reg_form_name(),
87
+				'html_id'         => $this->reg_step->reg_form_name(),
88
+				'subsections'     => $this->generateSubsections(),
89
+				'layout_strategy' => new EE_Template_Layout(
90
+					[
91
+						'layout_template_file' => $this->reg_step->template(), // layout_template
92
+						'template_args'        => $this->template_args,
93
+					]
94
+				),
95
+			]
96
+		);
97
+	}
98 98
 
99 99
 
100
-    /**
101
-     * @return void
102
-     */
103
-    public function enablePrintCopyInfo(): void
104
-    {
105
-        $this->print_copy_info = true;
106
-    }
100
+	/**
101
+	 * @return void
102
+	 */
103
+	public function enablePrintCopyInfo(): void
104
+	{
105
+		$this->print_copy_info = true;
106
+	}
107 107
 
108 108
 
109
-    /**
110
-     * @return bool
111
-     */
112
-    public function printCopyInfo(): bool
113
-    {
114
-        return $this->print_copy_info;
115
-    }
109
+	/**
110
+	 * @return bool
111
+	 */
112
+	public function printCopyInfo(): bool
113
+	{
114
+		return $this->print_copy_info;
115
+	}
116 116
 
117 117
 
118
-    /**
119
-     * @return int
120
-     */
121
-    public function regFormCount(): int
122
-    {
123
-        return $this->reg_form_count;
124
-    }
118
+	/**
119
+	 * @return int
120
+	 */
121
+	public function regFormCount(): int
122
+	{
123
+		return $this->reg_form_count;
124
+	}
125 125
 
126 126
 
127
-    /**
128
-     * @return array
129
-     */
130
-    public function requiredQuestions(): array
131
-    {
132
-        return $this->required_questions;
133
-    }
127
+	/**
128
+	 * @return array
129
+	 */
130
+	public function requiredQuestions(): array
131
+	{
132
+		return $this->required_questions;
133
+	}
134 134
 
135 135
 
136
-    /**
137
-     * @param string $identifier
138
-     * @param string $required_question
139
-     */
140
-    public function addRequiredQuestion(string $identifier, string $required_question): void
141
-    {
142
-        $this->required_questions[ $identifier ] = $required_question;
143
-    }
136
+	/**
137
+	 * @param string $identifier
138
+	 * @param string $required_question
139
+	 */
140
+	public function addRequiredQuestion(string $identifier, string $required_question): void
141
+	{
142
+		$this->required_questions[ $identifier ] = $required_question;
143
+	}
144 144
 
145 145
 
146
-    /**
147
-     * @return EE_Form_Section_Proper[]
148
-     * @throws DomainException
149
-     * @throws EE_Error
150
-     * @throws InvalidArgumentException
151
-     * @throws ReflectionException
152
-     * @throws EntityNotFoundException
153
-     * @throws InvalidDataTypeException
154
-     * @throws InvalidInterfaceException
155
-     */
156
-    private function generateSubsections(): array
157
-    {
158
-        // Init reg forms count.
159
-        $this->reg_form_count = 0;
146
+	/**
147
+	 * @return EE_Form_Section_Proper[]
148
+	 * @throws DomainException
149
+	 * @throws EE_Error
150
+	 * @throws InvalidArgumentException
151
+	 * @throws ReflectionException
152
+	 * @throws EntityNotFoundException
153
+	 * @throws InvalidDataTypeException
154
+	 * @throws InvalidInterfaceException
155
+	 */
156
+	private function generateSubsections(): array
157
+	{
158
+		// Init reg forms count.
159
+		$this->reg_form_count = 0;
160 160
 
161
-        $primary_registrant = null;
162
-        // autoload Line_Item_Display classes
163
-        EEH_Autoloader::register_line_item_display_autoloaders();
164
-        $Line_Item_Display = new EE_Line_Item_Display();
165
-        // calculate taxes
166
-        $Line_Item_Display->display_line_item(
167
-            $this->reg_step->checkout->cart->get_grand_total(),
168
-            ['set_tax_rate' => true]
169
-        );
170
-        $extra_inputs_section = $this->reg_step->reg_step_hidden_inputs();
171
-        $this->addPrivacyConsentCheckbox($extra_inputs_section);
172
-        $subsections = [
173
-            'default_hidden_inputs' => $extra_inputs_section,
174
-        ];
161
+		$primary_registrant = null;
162
+		// autoload Line_Item_Display classes
163
+		EEH_Autoloader::register_line_item_display_autoloaders();
164
+		$Line_Item_Display = new EE_Line_Item_Display();
165
+		// calculate taxes
166
+		$Line_Item_Display->display_line_item(
167
+			$this->reg_step->checkout->cart->get_grand_total(),
168
+			['set_tax_rate' => true]
169
+		);
170
+		$extra_inputs_section = $this->reg_step->reg_step_hidden_inputs();
171
+		$this->addPrivacyConsentCheckbox($extra_inputs_section);
172
+		$subsections = [
173
+			'default_hidden_inputs' => $extra_inputs_section,
174
+		];
175 175
 
176
-        $this->template_args = [
177
-            'revisit'       => $this->reg_step->checkout->revisit,
178
-            'registrations' => [],
179
-            'ticket_count'  => [],
180
-        ];
181
-        // grab the saved registrations from the transaction
182
-        $registrations = $this->reg_step->checkout->transaction->registrations(
183
-            $this->reg_step->checkout->reg_cache_where_params
184
-        );
185
-        if ($registrations) {
186
-            foreach ($registrations as $registration) {
187
-                // can this registration be processed during this visit ?
188
-                if (
189
-                    $registration instanceof EE_Registration
190
-                    && $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)
191
-                ) {
192
-                    $reg_url_link = $registration->reg_url_link();
193
-                    /** @var RegistrantForm $registrant_form */
194
-                    $registrant_form = LoaderFactory::getNew(
195
-                        RegistrantForm::class,
196
-                        [
197
-                            $registration,
198
-                            $this->reg_step->checkout->admin_request,
199
-                            $this->reg_config->copyAttendeeInfo(),
200
-                            [$this, 'enablePrintCopyInfo'],
201
-                        ]
202
-                    );
203
-                    // Increment the reg forms number if form is valid.
204
-                    if ($registrant_form->hasQuestions()) {
205
-                        $this->reg_form_count++;
206
-                        $subsections[ $reg_url_link ] = $registrant_form;
207
-                    } else {
208
-                        // or just add a blank section if there are no questions
209
-                        $subsections[ $reg_url_link ] = new EE_Form_Section_HTML();
210
-                    }
176
+		$this->template_args = [
177
+			'revisit'       => $this->reg_step->checkout->revisit,
178
+			'registrations' => [],
179
+			'ticket_count'  => [],
180
+		];
181
+		// grab the saved registrations from the transaction
182
+		$registrations = $this->reg_step->checkout->transaction->registrations(
183
+			$this->reg_step->checkout->reg_cache_where_params
184
+		);
185
+		if ($registrations) {
186
+			foreach ($registrations as $registration) {
187
+				// can this registration be processed during this visit ?
188
+				if (
189
+					$registration instanceof EE_Registration
190
+					&& $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)
191
+				) {
192
+					$reg_url_link = $registration->reg_url_link();
193
+					/** @var RegistrantForm $registrant_form */
194
+					$registrant_form = LoaderFactory::getNew(
195
+						RegistrantForm::class,
196
+						[
197
+							$registration,
198
+							$this->reg_step->checkout->admin_request,
199
+							$this->reg_config->copyAttendeeInfo(),
200
+							[$this, 'enablePrintCopyInfo'],
201
+						]
202
+					);
203
+					// Increment the reg forms number if form is valid.
204
+					if ($registrant_form->hasQuestions()) {
205
+						$this->reg_form_count++;
206
+						$subsections[ $reg_url_link ] = $registrant_form;
207
+					} else {
208
+						// or just add a blank section if there are no questions
209
+						$subsections[ $reg_url_link ] = new EE_Form_Section_HTML();
210
+					}
211 211
 
212
-                    $this->template_args['registrations'][ $reg_url_link ]                = $registration;
213
-                    $this->template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
214
-                        $this->template_args['ticket_count'][ $registration->ticket()->ID() ]
215
-                    )
216
-                        ? $this->template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
217
-                        : 1;
218
-                    $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
219
-                        $this->reg_step->checkout->cart->get_grand_total(),
220
-                        'Ticket',
221
-                        [$registration->ticket()->ID()]
222
-                    );
223
-                    $ticket_line_item = is_array($ticket_line_item)
224
-                        ? reset($ticket_line_item)
225
-                        : $ticket_line_item;
226
-                    $this->template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
227
-                        $Line_Item_Display->display_line_item($ticket_line_item);
228
-                    if ($registration->is_primary_registrant()) {
229
-                        $primary_registrant = $reg_url_link;
230
-                    }
231
-                }
232
-            }
212
+					$this->template_args['registrations'][ $reg_url_link ]                = $registration;
213
+					$this->template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
214
+						$this->template_args['ticket_count'][ $registration->ticket()->ID() ]
215
+					)
216
+						? $this->template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
217
+						: 1;
218
+					$ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
219
+						$this->reg_step->checkout->cart->get_grand_total(),
220
+						'Ticket',
221
+						[$registration->ticket()->ID()]
222
+					);
223
+					$ticket_line_item = is_array($ticket_line_item)
224
+						? reset($ticket_line_item)
225
+						: $ticket_line_item;
226
+					$this->template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
227
+						$Line_Item_Display->display_line_item($ticket_line_item);
228
+					if ($registration->is_primary_registrant()) {
229
+						$primary_registrant = $reg_url_link;
230
+					}
231
+				}
232
+			}
233 233
 
234
-            if ($primary_registrant && count($registrations) > 1) {
235
-                if (
236
-                    isset($subsections[ $primary_registrant ])
237
-                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
238
-                ) {
239
-                    $copy_options['spco_copy_attendee_chk'] = $this->print_copy_info
240
-                        ? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
241
-                        : new AutoCopyAttendeeInfoForm($this->reg_step->slug());
242
-                    $subsections[ $primary_registrant ]->add_subsections(
243
-                        $copy_options,
244
-                        'primary_registrant',
245
-                        false
246
-                    );
247
-                }
248
-            }
249
-        }
234
+			if ($primary_registrant && count($registrations) > 1) {
235
+				if (
236
+					isset($subsections[ $primary_registrant ])
237
+					&& $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
238
+				) {
239
+					$copy_options['spco_copy_attendee_chk'] = $this->print_copy_info
240
+						? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
241
+						: new AutoCopyAttendeeInfoForm($this->reg_step->slug());
242
+					$subsections[ $primary_registrant ]->add_subsections(
243
+						$copy_options,
244
+						'primary_registrant',
245
+						false
246
+					);
247
+				}
248
+			}
249
+		}
250 250
 
251
-        // Set the registration form template (default: one form per ticket details table).
252
-        // We decide the template to used based on the number of forms.
253
-        $template = $this->reg_form_count > 1
254
-            ? SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_main.template.php'
255
-            : SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_single.template.php';
256
-        $this->reg_step->setTemplate($template);
251
+		// Set the registration form template (default: one form per ticket details table).
252
+		// We decide the template to used based on the number of forms.
253
+		$template = $this->reg_form_count > 1
254
+			? SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_main.template.php'
255
+			: SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_single.template.php';
256
+		$this->reg_step->setTemplate($template);
257 257
 
258
-        return $subsections;
259
-    }
258
+		return $subsections;
259
+	}
260 260
 
261 261
 
262
-    /**
263
-     * @param EE_Form_Section_Proper $extra_inputs_section
264
-     * @throws EE_Error
265
-     */
266
-    private function addPrivacyConsentCheckbox(EE_Form_Section_Proper $extra_inputs_section)
267
-    {
268
-        // if this isn't a revisit, and they have the privacy consent box enabled, add it
269
-        if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
270
-            $extra_inputs_section->add_subsections(
271
-                [
272
-                    'consent_box' => new PrivacyConsentCheckboxForm(
273
-                        $this->reg_step->slug(),
274
-                        $this->reg_config->getConsentCheckboxLabelText()
275
-                    )
276
-                ],
277
-                null,
278
-                false
279
-            );
280
-        }
281
-    }
262
+	/**
263
+	 * @param EE_Form_Section_Proper $extra_inputs_section
264
+	 * @throws EE_Error
265
+	 */
266
+	private function addPrivacyConsentCheckbox(EE_Form_Section_Proper $extra_inputs_section)
267
+	{
268
+		// if this isn't a revisit, and they have the privacy consent box enabled, add it
269
+		if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
270
+			$extra_inputs_section->add_subsections(
271
+				[
272
+					'consent_box' => new PrivacyConsentCheckboxForm(
273
+						$this->reg_step->slug(),
274
+						$this->reg_config->getConsentCheckboxLabelText()
275
+					)
276
+				],
277
+				null,
278
+				false
279
+			);
280
+		}
281
+	}
282 282
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
      */
140 140
     public function addRequiredQuestion(string $identifier, string $required_question): void
141 141
     {
142
-        $this->required_questions[ $identifier ] = $required_question;
142
+        $this->required_questions[$identifier] = $required_question;
143 143
     }
144 144
 
145 145
 
@@ -203,17 +203,17 @@  discard block
 block discarded – undo
203 203
                     // Increment the reg forms number if form is valid.
204 204
                     if ($registrant_form->hasQuestions()) {
205 205
                         $this->reg_form_count++;
206
-                        $subsections[ $reg_url_link ] = $registrant_form;
206
+                        $subsections[$reg_url_link] = $registrant_form;
207 207
                     } else {
208 208
                         // or just add a blank section if there are no questions
209
-                        $subsections[ $reg_url_link ] = new EE_Form_Section_HTML();
209
+                        $subsections[$reg_url_link] = new EE_Form_Section_HTML();
210 210
                     }
211 211
 
212
-                    $this->template_args['registrations'][ $reg_url_link ]                = $registration;
213
-                    $this->template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
214
-                        $this->template_args['ticket_count'][ $registration->ticket()->ID() ]
212
+                    $this->template_args['registrations'][$reg_url_link]                = $registration;
213
+                    $this->template_args['ticket_count'][$registration->ticket()->ID()] = isset(
214
+                        $this->template_args['ticket_count'][$registration->ticket()->ID()]
215 215
                     )
216
-                        ? $this->template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
216
+                        ? $this->template_args['ticket_count'][$registration->ticket()->ID()] + 1
217 217
                         : 1;
218 218
                     $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
219 219
                         $this->reg_step->checkout->cart->get_grand_total(),
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
                     $ticket_line_item = is_array($ticket_line_item)
224 224
                         ? reset($ticket_line_item)
225 225
                         : $ticket_line_item;
226
-                    $this->template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
226
+                    $this->template_args['ticket_line_item'][$registration->ticket()->ID()] =
227 227
                         $Line_Item_Display->display_line_item($ticket_line_item);
228 228
                     if ($registration->is_primary_registrant()) {
229 229
                         $primary_registrant = $reg_url_link;
@@ -233,13 +233,13 @@  discard block
 block discarded – undo
233 233
 
234 234
             if ($primary_registrant && count($registrations) > 1) {
235 235
                 if (
236
-                    isset($subsections[ $primary_registrant ])
237
-                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
236
+                    isset($subsections[$primary_registrant])
237
+                    && $subsections[$primary_registrant] instanceof EE_Form_Section_Proper
238 238
                 ) {
239 239
                     $copy_options['spco_copy_attendee_chk'] = $this->print_copy_info
240 240
                         ? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
241 241
                         : new AutoCopyAttendeeInfoForm($this->reg_step->slug());
242
-                    $subsections[ $primary_registrant ]->add_subsections(
242
+                    $subsections[$primary_registrant]->add_subsections(
243 243
                         $copy_options,
244 244
                         'primary_registrant',
245 245
                         false
@@ -251,8 +251,8 @@  discard block
 block discarded – undo
251 251
         // Set the registration form template (default: one form per ticket details table).
252 252
         // We decide the template to used based on the number of forms.
253 253
         $template = $this->reg_form_count > 1
254
-            ? SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_main.template.php'
255
-            : SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_single.template.php';
254
+            ? SPCO_REG_STEPS_PATH . $this->reg_step->slug().'/attendee_info_main.template.php'
255
+            : SPCO_REG_STEPS_PATH.$this->reg_step->slug().'/attendee_info_single.template.php';
256 256
         $this->reg_step->setTemplate($template);
257 257
 
258 258
         return $subsections;
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
     private function addPrivacyConsentCheckbox(EE_Form_Section_Proper $extra_inputs_section)
267 267
     {
268 268
         // if this isn't a revisit, and they have the privacy consent box enabled, add it
269
-        if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
269
+        if ( ! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
270 270
             $extra_inputs_section->add_subsections(
271 271
                 [
272 272
                     'consent_box' => new PrivacyConsentCheckboxForm(
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 1 patch
Indentation   +2890 added lines, -2890 removed lines patch added patch discarded remove patch
@@ -17,2894 +17,2894 @@
 block discarded – undo
17 17
 class Events_Admin_Page extends EE_Admin_Page_CPT
18 18
 {
19 19
 
20
-    /**
21
-     * This will hold the event object for event_details screen.
22
-     *
23
-     * @access protected
24
-     * @var EE_Event $_event
25
-     */
26
-    protected $_event;
27
-
28
-
29
-    /**
30
-     * This will hold the category object for category_details screen.
31
-     *
32
-     * @var stdClass $_category
33
-     */
34
-    protected $_category;
35
-
36
-
37
-    /**
38
-     * This will hold the event model instance
39
-     *
40
-     * @var EEM_Event $_event_model
41
-     */
42
-    protected $_event_model;
43
-
44
-
45
-    /**
46
-     * @var EE_Event
47
-     */
48
-    protected $_cpt_model_obj = false;
49
-
50
-
51
-    /**
52
-     * @var NodeGroupDao
53
-     */
54
-    protected $model_obj_node_group_persister;
55
-
56
-
57
-    /**
58
-     * Initialize page props for this admin page group.
59
-     */
60
-    protected function _init_page_props()
61
-    {
62
-        $this->page_slug        = EVENTS_PG_SLUG;
63
-        $this->page_label       = EVENTS_LABEL;
64
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
65
-        $this->_admin_base_path = EVENTS_ADMIN;
66
-        $this->_cpt_model_names = [
67
-            'create_new' => 'EEM_Event',
68
-            'edit'       => 'EEM_Event',
69
-        ];
70
-        $this->_cpt_edit_routes = [
71
-            'espresso_events' => 'edit',
72
-        ];
73
-        add_action(
74
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
75
-            [$this, 'verify_event_edit'],
76
-            10,
77
-            2
78
-        );
79
-    }
80
-
81
-
82
-    /**
83
-     * Sets the ajax hooks used for this admin page group.
84
-     */
85
-    protected function _ajax_hooks()
86
-    {
87
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'save_timezonestring_setting']);
88
-    }
89
-
90
-
91
-    /**
92
-     * Sets the page properties for this admin page group.
93
-     */
94
-    protected function _define_page_props()
95
-    {
96
-        $this->_admin_page_title = EVENTS_LABEL;
97
-        $this->_labels           = [
98
-            'buttons'      => [
99
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
100
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
101
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
102
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
103
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
104
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
105
-            ],
106
-            'editor_title' => [
107
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
108
-            ],
109
-            'publishbox'   => [
110
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
111
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
112
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
113
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
114
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
115
-            ],
116
-        ];
117
-    }
118
-
119
-
120
-    /**
121
-     * Sets the page routes property for this admin page group.
122
-     */
123
-    protected function _set_page_routes()
124
-    {
125
-        // load formatter helper
126
-        // load field generator helper
127
-        // is there a evt_id in the request?
128
-        $evt_id             = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
129
-            ? $this->_req_data['EVT_ID']
130
-            : 0;
131
-        $evt_id             = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
132
-        $this->_page_routes = [
133
-            'default'                       => [
134
-                'func'       => '_events_overview_list_table',
135
-                'capability' => 'ee_read_events',
136
-            ],
137
-            'create_new'                    => [
138
-                'func'       => '_create_new_cpt_item',
139
-                'capability' => 'ee_edit_events',
140
-            ],
141
-            'edit'                          => [
142
-                'func'       => '_edit_cpt_item',
143
-                'capability' => 'ee_edit_event',
144
-                'obj_id'     => $evt_id,
145
-            ],
146
-            'copy_event'                    => [
147
-                'func'       => '_copy_events',
148
-                'capability' => 'ee_edit_event',
149
-                'obj_id'     => $evt_id,
150
-                'noheader'   => true,
151
-            ],
152
-            'trash_event'                   => [
153
-                'func'       => '_trash_or_restore_event',
154
-                'args'       => ['event_status' => 'trash'],
155
-                'capability' => 'ee_delete_event',
156
-                'obj_id'     => $evt_id,
157
-                'noheader'   => true,
158
-            ],
159
-            'trash_events'                  => [
160
-                'func'       => '_trash_or_restore_events',
161
-                'args'       => ['event_status' => 'trash'],
162
-                'capability' => 'ee_delete_events',
163
-                'noheader'   => true,
164
-            ],
165
-            'restore_event'                 => [
166
-                'func'       => '_trash_or_restore_event',
167
-                'args'       => ['event_status' => 'draft'],
168
-                'capability' => 'ee_delete_event',
169
-                'obj_id'     => $evt_id,
170
-                'noheader'   => true,
171
-            ],
172
-            'restore_events'                => [
173
-                'func'       => '_trash_or_restore_events',
174
-                'args'       => ['event_status' => 'draft'],
175
-                'capability' => 'ee_delete_events',
176
-                'noheader'   => true,
177
-            ],
178
-            'delete_event'                  => [
179
-                'func'       => '_delete_event',
180
-                'capability' => 'ee_delete_event',
181
-                'obj_id'     => $evt_id,
182
-                'noheader'   => true,
183
-            ],
184
-            'delete_events'                 => [
185
-                'func'       => '_delete_events',
186
-                'capability' => 'ee_delete_events',
187
-                'noheader'   => true,
188
-            ],
189
-            'view_report'                   => [
190
-                'func'       => '_view_report',
191
-                'capability' => 'ee_edit_events',
192
-            ],
193
-            'default_event_settings'        => [
194
-                'func'       => '_default_event_settings',
195
-                'capability' => 'manage_options',
196
-            ],
197
-            'update_default_event_settings' => [
198
-                'func'       => '_update_default_event_settings',
199
-                'capability' => 'manage_options',
200
-                'noheader'   => true,
201
-            ],
202
-            'template_settings'             => [
203
-                'func'       => '_template_settings',
204
-                'capability' => 'manage_options',
205
-            ],
206
-            // event category tab related
207
-            'add_category'                  => [
208
-                'func'       => '_category_details',
209
-                'capability' => 'ee_edit_event_category',
210
-                'args'       => ['add'],
211
-            ],
212
-            'edit_category'                 => [
213
-                'func'       => '_category_details',
214
-                'capability' => 'ee_edit_event_category',
215
-                'args'       => ['edit'],
216
-            ],
217
-            'delete_categories'             => [
218
-                'func'       => '_delete_categories',
219
-                'capability' => 'ee_delete_event_category',
220
-                'noheader'   => true,
221
-            ],
222
-            'delete_category'               => [
223
-                'func'       => '_delete_categories',
224
-                'capability' => 'ee_delete_event_category',
225
-                'noheader'   => true,
226
-            ],
227
-            'insert_category'               => [
228
-                'func'       => '_insert_or_update_category',
229
-                'args'       => ['new_category' => true],
230
-                'capability' => 'ee_edit_event_category',
231
-                'noheader'   => true,
232
-            ],
233
-            'update_category'               => [
234
-                'func'       => '_insert_or_update_category',
235
-                'args'       => ['new_category' => false],
236
-                'capability' => 'ee_edit_event_category',
237
-                'noheader'   => true,
238
-            ],
239
-            'category_list'                 => [
240
-                'func'       => '_category_list_table',
241
-                'capability' => 'ee_manage_event_categories',
242
-            ],
243
-            'preview_deletion'              => [
244
-                'func'       => 'previewDeletion',
245
-                'capability' => 'ee_delete_events',
246
-            ],
247
-            'confirm_deletion'              => [
248
-                'func'       => 'confirmDeletion',
249
-                'capability' => 'ee_delete_events',
250
-                'noheader'   => true,
251
-            ],
252
-        ];
253
-    }
254
-
255
-
256
-    /**
257
-     * Set the _page_config property for this admin page group.
258
-     */
259
-    protected function _set_page_config()
260
-    {
261
-        $this->_page_config = [
262
-            'default'                => [
263
-                'nav'           => [
264
-                    'label' => esc_html__('Overview', 'event_espresso'),
265
-                    'order' => 10,
266
-                ],
267
-                'list_table'    => 'Events_Admin_List_Table',
268
-                'help_tabs'     => [
269
-                    'events_overview_help_tab'                       => [
270
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
271
-                        'filename' => 'events_overview',
272
-                    ],
273
-                    'events_overview_table_column_headings_help_tab' => [
274
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
275
-                        'filename' => 'events_overview_table_column_headings',
276
-                    ],
277
-                    'events_overview_filters_help_tab'               => [
278
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
279
-                        'filename' => 'events_overview_filters',
280
-                    ],
281
-                    'events_overview_view_help_tab'                  => [
282
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
283
-                        'filename' => 'events_overview_views',
284
-                    ],
285
-                    'events_overview_other_help_tab'                 => [
286
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
287
-                        'filename' => 'events_overview_other',
288
-                    ],
289
-                ],
290
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
291
-                // 'help_tour'     => [
292
-                //     'Event_Overview_Help_Tour',
293
-                //     // 'New_Features_Test_Help_Tour' for testing multiple help tour
294
-                // ],
295
-                'require_nonce' => false,
296
-                'qtips'         => ['EE_Event_List_Table_Tips'],
297
-            ],
298
-            'create_new'             => [
299
-                'nav'           => [
300
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
301
-                    'order'      => 5,
302
-                    'persistent' => false,
303
-                ],
304
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
305
-                'help_tabs'     => [
306
-                    'event_editor_help_tab'                            => [
307
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
308
-                        'filename' => 'event_editor',
309
-                    ],
310
-                    'event_editor_title_richtexteditor_help_tab'       => [
311
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
312
-                        'filename' => 'event_editor_title_richtexteditor',
313
-                    ],
314
-                    'event_editor_venue_details_help_tab'              => [
315
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
316
-                        'filename' => 'event_editor_venue_details',
317
-                    ],
318
-                    'event_editor_event_datetimes_help_tab'            => [
319
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
320
-                        'filename' => 'event_editor_event_datetimes',
321
-                    ],
322
-                    'event_editor_event_tickets_help_tab'              => [
323
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
324
-                        'filename' => 'event_editor_event_tickets',
325
-                    ],
326
-                    'event_editor_event_registration_options_help_tab' => [
327
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
328
-                        'filename' => 'event_editor_event_registration_options',
329
-                    ],
330
-                    'event_editor_tags_categories_help_tab'            => [
331
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
332
-                        'filename' => 'event_editor_tags_categories',
333
-                    ],
334
-                    'event_editor_questions_registrants_help_tab'      => [
335
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
336
-                        'filename' => 'event_editor_questions_registrants',
337
-                    ],
338
-                    'event_editor_save_new_event_help_tab'             => [
339
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
340
-                        'filename' => 'event_editor_save_new_event',
341
-                    ],
342
-                    'event_editor_other_help_tab'                      => [
343
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
344
-                        'filename' => 'event_editor_other',
345
-                    ],
346
-                ],
347
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
348
-                // 'help_tour'     => [
349
-                //     'Event_Editor_Help_Tour',
350
-                // ],
351
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
352
-                'require_nonce' => false,
353
-            ],
354
-            'edit'                   => [
355
-                'nav'           => [
356
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
357
-                    'order'      => 5,
358
-                    'persistent' => false,
359
-                    'url'        => isset($this->_req_data['post'])
360
-                        ? EE_Admin_Page::add_query_args_and_nonce(
361
-                            ['post' => $this->_req_data['post'], 'action' => 'edit'],
362
-                            $this->_current_page_view_url
363
-                        )
364
-                        : $this->_admin_base_url,
365
-                ],
366
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
367
-                'help_tabs'     => [
368
-                    'event_editor_help_tab'                            => [
369
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
370
-                        'filename' => 'event_editor',
371
-                    ],
372
-                    'event_editor_title_richtexteditor_help_tab'       => [
373
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
374
-                        'filename' => 'event_editor_title_richtexteditor',
375
-                    ],
376
-                    'event_editor_venue_details_help_tab'              => [
377
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
378
-                        'filename' => 'event_editor_venue_details',
379
-                    ],
380
-                    'event_editor_event_datetimes_help_tab'            => [
381
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
382
-                        'filename' => 'event_editor_event_datetimes',
383
-                    ],
384
-                    'event_editor_event_tickets_help_tab'              => [
385
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
386
-                        'filename' => 'event_editor_event_tickets',
387
-                    ],
388
-                    'event_editor_event_registration_options_help_tab' => [
389
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
390
-                        'filename' => 'event_editor_event_registration_options',
391
-                    ],
392
-                    'event_editor_tags_categories_help_tab'            => [
393
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
394
-                        'filename' => 'event_editor_tags_categories',
395
-                    ],
396
-                    'event_editor_questions_registrants_help_tab'      => [
397
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
398
-                        'filename' => 'event_editor_questions_registrants',
399
-                    ],
400
-                    'event_editor_save_new_event_help_tab'             => [
401
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
402
-                        'filename' => 'event_editor_save_new_event',
403
-                    ],
404
-                    'event_editor_other_help_tab'                      => [
405
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
406
-                        'filename' => 'event_editor_other',
407
-                    ],
408
-                ],
409
-                'require_nonce' => false,
410
-            ],
411
-            'default_event_settings' => [
412
-                'nav'           => [
413
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
414
-                    'order' => 40,
415
-                ],
416
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
417
-                'labels'        => [
418
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
419
-                ],
420
-                'help_tabs'     => [
421
-                    'default_settings_help_tab'        => [
422
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
423
-                        'filename' => 'events_default_settings',
424
-                    ],
425
-                    'default_settings_status_help_tab' => [
426
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
427
-                        'filename' => 'events_default_settings_status',
428
-                    ],
429
-                    'default_maximum_tickets_help_tab' => [
430
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
431
-                        'filename' => 'events_default_settings_max_tickets',
432
-                    ],
433
-                ],
434
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
435
-                // 'help_tour'     => ['Event_Default_Settings_Help_Tour'],
436
-                'require_nonce' => false,
437
-            ],
438
-            // template settings
439
-            'template_settings'      => [
440
-                'nav'           => [
441
-                    'label' => esc_html__('Templates', 'event_espresso'),
442
-                    'order' => 30,
443
-                ],
444
-                'metaboxes'     => $this->_default_espresso_metaboxes,
445
-                'help_tabs'     => [
446
-                    'general_settings_templates_help_tab' => [
447
-                        'title'    => esc_html__('Templates', 'event_espresso'),
448
-                        'filename' => 'general_settings_templates',
449
-                    ],
450
-                ],
451
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
452
-                // 'help_tour'     => ['Templates_Help_Tour'],
453
-                'require_nonce' => false,
454
-            ],
455
-            // event category stuff
456
-            'add_category'           => [
457
-                'nav'           => [
458
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
459
-                    'order'      => 15,
460
-                    'persistent' => false,
461
-                ],
462
-                'help_tabs'     => [
463
-                    'add_category_help_tab' => [
464
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
465
-                        'filename' => 'events_add_category',
466
-                    ],
467
-                ],
468
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
469
-                // 'help_tour'     => ['Event_Add_Category_Help_Tour'],
470
-                'metaboxes'     => ['_publish_post_box'],
471
-                'require_nonce' => false,
472
-            ],
473
-            'edit_category'          => [
474
-                'nav'           => [
475
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
476
-                    'order'      => 15,
477
-                    'persistent' => false,
478
-                    'url'        => isset($this->_req_data['EVT_CAT_ID'])
479
-                        ? add_query_arg(
480
-                            ['EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']],
481
-                            $this->_current_page_view_url
482
-                        )
483
-                        : $this->_admin_base_url,
484
-                ],
485
-                'help_tabs'     => [
486
-                    'edit_category_help_tab' => [
487
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
488
-                        'filename' => 'events_edit_category',
489
-                    ],
490
-                ],
491
-                /*'help_tour' => ['Event_Edit_Category_Help_Tour'],*/
492
-                'metaboxes'     => ['_publish_post_box'],
493
-                'require_nonce' => false,
494
-            ],
495
-            'category_list'          => [
496
-                'nav'           => [
497
-                    'label' => esc_html__('Categories', 'event_espresso'),
498
-                    'order' => 20,
499
-                ],
500
-                'list_table'    => 'Event_Categories_Admin_List_Table',
501
-                'help_tabs'     => [
502
-                    'events_categories_help_tab'                       => [
503
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
504
-                        'filename' => 'events_categories',
505
-                    ],
506
-                    'events_categories_table_column_headings_help_tab' => [
507
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
508
-                        'filename' => 'events_categories_table_column_headings',
509
-                    ],
510
-                    'events_categories_view_help_tab'                  => [
511
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
512
-                        'filename' => 'events_categories_views',
513
-                    ],
514
-                    'events_categories_other_help_tab'                 => [
515
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
516
-                        'filename' => 'events_categories_other',
517
-                    ],
518
-                ],
519
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
520
-                // 'help_tour'     => [
521
-                //     'Event_Categories_Help_Tour',
522
-                // ],
523
-                'metaboxes'     => $this->_default_espresso_metaboxes,
524
-                'require_nonce' => false,
525
-            ],
526
-            'preview_deletion'       => [
527
-                'nav'           => [
528
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
529
-                    'order'      => 15,
530
-                    'persistent' => false,
531
-                    'url'        => '',
532
-                ],
533
-                'require_nonce' => false,
534
-            ],
535
-        ];
536
-        // only load EE_Event_Editor_Decaf_Tips if domain is not caffeinated
537
-        $domain = $this->loader->getShared('EventEspresso\core\domain\Domain');
538
-        if (! $domain->isCaffeinated()) {
539
-            $this->_page_config['create_new']['qtips'] = ['EE_Event_Editor_Decaf_Tips'];
540
-            $this->_page_config['edit']['qtips']       = ['EE_Event_Editor_Decaf_Tips'];
541
-        }
542
-    }
543
-
544
-
545
-    /**
546
-     * Used to register any global screen options if necessary for every route in this admin page group.
547
-     */
548
-    protected function _add_screen_options()
549
-    {
550
-    }
551
-
552
-
553
-    /**
554
-     * Implementing the screen options for the 'default' route.
555
-     *
556
-     * @throws InvalidArgumentException
557
-     * @throws InvalidDataTypeException
558
-     * @throws InvalidInterfaceException
559
-     */
560
-    protected function _add_screen_options_default()
561
-    {
562
-        $this->_per_page_screen_option();
563
-    }
564
-
565
-
566
-    /**
567
-     * Implementing screen options for the category list route.
568
-     *
569
-     * @throws InvalidArgumentException
570
-     * @throws InvalidDataTypeException
571
-     * @throws InvalidInterfaceException
572
-     */
573
-    protected function _add_screen_options_category_list()
574
-    {
575
-        $page_title              = $this->_admin_page_title;
576
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
577
-        $this->_per_page_screen_option();
578
-        $this->_admin_page_title = $page_title;
579
-    }
580
-
581
-
582
-    /**
583
-     * Used to register any global feature pointers for the admin page group.
584
-     */
585
-    protected function _add_feature_pointers()
586
-    {
587
-    }
588
-
589
-
590
-    /**
591
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
592
-     */
593
-    public function load_scripts_styles()
594
-    {
595
-        wp_register_style(
596
-            'events-admin-css',
597
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
598
-            [],
599
-            EVENT_ESPRESSO_VERSION
600
-        );
601
-        wp_register_style(
602
-            'ee-cat-admin',
603
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
604
-            [],
605
-            EVENT_ESPRESSO_VERSION
606
-        );
607
-        wp_enqueue_style('events-admin-css');
608
-        wp_enqueue_style('ee-cat-admin');
609
-        // scripts
610
-        wp_register_script(
611
-            'event_editor_js',
612
-            EVENTS_ASSETS_URL . 'event_editor.js',
613
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
614
-            EVENT_ESPRESSO_VERSION,
615
-            true
616
-        );
617
-    }
618
-
619
-
620
-    /**
621
-     * Enqueuing scripts and styles specific to this view
622
-     */
623
-    public function load_scripts_styles_create_new()
624
-    {
625
-        $this->load_scripts_styles_edit();
626
-    }
627
-
628
-
629
-    /**
630
-     * Enqueuing scripts and styles specific to this view
631
-     */
632
-    public function load_scripts_styles_edit()
633
-    {
634
-        // styles
635
-        wp_enqueue_style('espresso-ui-theme');
636
-        wp_register_style(
637
-            'event-editor-css',
638
-            EVENTS_ASSETS_URL . 'event-editor.css',
639
-            ['ee-admin-css'],
640
-            EVENT_ESPRESSO_VERSION
641
-        );
642
-        wp_enqueue_style('event-editor-css');
643
-        // scripts
644
-        if (! $this->admin_config->useAdvancedEditor()) {
645
-            wp_register_script(
646
-                'event-datetime-metabox',
647
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
648
-                ['event_editor_js', 'ee-datepicker'],
649
-                EVENT_ESPRESSO_VERSION
650
-            );
651
-            wp_enqueue_script('event-datetime-metabox');
652
-        }
653
-    }
654
-
655
-
656
-    /**
657
-     * Populating the _views property for the category list table view.
658
-     */
659
-    protected function _set_list_table_views_category_list()
660
-    {
661
-        $this->_views = [
662
-            'all' => [
663
-                'slug'        => 'all',
664
-                'label'       => esc_html__('All', 'event_espresso'),
665
-                'count'       => 0,
666
-                'bulk_action' => [
667
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
668
-                ],
669
-            ],
670
-        ];
671
-    }
672
-
673
-
674
-    /**
675
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
676
-     */
677
-    public function admin_init()
678
-    {
679
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
680
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
681
-            'event_espresso'
682
-        );
683
-    }
684
-
685
-
686
-    /**
687
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
688
-     * group.
689
-     */
690
-    public function admin_notices()
691
-    {
692
-    }
693
-
694
-
695
-    /**
696
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
697
-     * this admin page group.
698
-     */
699
-    public function admin_footer_scripts()
700
-    {
701
-    }
702
-
703
-
704
-    /**
705
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
706
-     * warning (via EE_Error::add_error());
707
-     *
708
-     * @param EE_Event $event Event object
709
-     * @param string   $req_type
710
-     * @return void
711
-     * @throws EE_Error
712
-     * @access public
713
-     */
714
-    public function verify_event_edit($event = null, $req_type = '')
715
-    {
716
-        // don't need to do this when processing
717
-        if (! empty($req_type)) {
718
-            return;
719
-        }
720
-        // no event?
721
-        if (! $event instanceof EE_Event) {
722
-            $event = $this->_cpt_model_obj;
723
-        }
724
-        // STILL no event?
725
-        if (! $event instanceof EE_Event) {
726
-            return;
727
-        }
728
-        $orig_status = $event->status();
729
-        // first check if event is active.
730
-        if (
731
-            $orig_status === EEM_Event::cancelled
732
-            || $orig_status === EEM_Event::postponed
733
-            || $event->is_expired()
734
-            || $event->is_inactive()
735
-        ) {
736
-            return;
737
-        }
738
-        // made it here so it IS active... next check that any of the tickets are sold.
739
-        if ($event->is_sold_out(true)) {
740
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
741
-                EE_Error::add_attention(
742
-                    sprintf(
743
-                        esc_html__(
744
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
745
-                            'event_espresso'
746
-                        ),
747
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
748
-                    )
749
-                );
750
-            }
751
-            return;
752
-        }
753
-        if ($orig_status === EEM_Event::sold_out) {
754
-            EE_Error::add_attention(
755
-                sprintf(
756
-                    esc_html__(
757
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
758
-                        'event_espresso'
759
-                    ),
760
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
761
-                )
762
-            );
763
-        }
764
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
765
-        if (! $event->tickets_on_sale()) {
766
-            return;
767
-        }
768
-        // made it here so show warning
769
-        $this->_edit_event_warning();
770
-    }
771
-
772
-
773
-    /**
774
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
775
-     * When needed, hook this into a EE_Error::add_error() notice.
776
-     *
777
-     * @access protected
778
-     * @return void
779
-     */
780
-    protected function _edit_event_warning()
781
-    {
782
-        // we don't want to add warnings during these requests
783
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
784
-            return;
785
-        }
786
-        EE_Error::add_attention(
787
-            sprintf(
788
-                esc_html__(
789
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
790
-                    'event_espresso'
791
-                ),
792
-                '<a class="espresso-help-tab-lnk">',
793
-                '</a>'
794
-            )
795
-        );
796
-    }
797
-
798
-
799
-    /**
800
-     * When a user is creating a new event, notify them if they haven't set their timezone.
801
-     * Otherwise, do the normal logic
802
-     *
803
-     * @return void
804
-     * @throws EE_Error
805
-     * @throws InvalidArgumentException
806
-     * @throws InvalidDataTypeException
807
-     * @throws InvalidInterfaceException
808
-     */
809
-    protected function _create_new_cpt_item()
810
-    {
811
-        $has_timezone_string = get_option('timezone_string');
812
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
813
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
814
-            EE_Error::add_attention(
815
-                sprintf(
816
-                    __(
817
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
818
-                        'event_espresso'
819
-                    ),
820
-                    '<br>',
821
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
822
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
823
-                    . '</select>',
824
-                    '<button class="button button-secondary timezone-submit">',
825
-                    '</button><span class="spinner"></span>'
826
-                ),
827
-                __FILE__,
828
-                __FUNCTION__,
829
-                __LINE__
830
-            );
831
-        }
832
-        parent::_create_new_cpt_item();
833
-    }
834
-
835
-
836
-    /**
837
-     * Sets the _views property for the default route in this admin page group.
838
-     */
839
-    protected function _set_list_table_views_default()
840
-    {
841
-        $this->_views = [
842
-            'all'   => [
843
-                'slug'        => 'all',
844
-                'label'       => esc_html__('View All Events', 'event_espresso'),
845
-                'count'       => 0,
846
-                'bulk_action' => [
847
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
848
-                ],
849
-            ],
850
-            'draft' => [
851
-                'slug'        => 'draft',
852
-                'label'       => esc_html__('Draft', 'event_espresso'),
853
-                'count'       => 0,
854
-                'bulk_action' => [
855
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
856
-                ],
857
-            ],
858
-        ];
859
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
860
-            $this->_views['trash'] = [
861
-                'slug'        => 'trash',
862
-                'label'       => esc_html__('Trash', 'event_espresso'),
863
-                'count'       => 0,
864
-                'bulk_action' => [
865
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
866
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
867
-                ],
868
-            ];
869
-        }
870
-    }
871
-
872
-
873
-    /**
874
-     * Provides the legend item array for the default list table view.
875
-     *
876
-     * @return array
877
-     */
878
-    protected function _event_legend_items()
879
-    {
880
-        $items    = [
881
-            'view_details'   => [
882
-                'class' => 'dashicons dashicons-search',
883
-                'desc'  => esc_html__('View Event', 'event_espresso'),
884
-            ],
885
-            'edit_event'     => [
886
-                'class' => 'ee-icon ee-icon-calendar-edit',
887
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
888
-            ],
889
-            'view_attendees' => [
890
-                'class' => 'dashicons dashicons-groups',
891
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
892
-            ],
893
-        ];
894
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
895
-        $statuses = [
896
-            'sold_out_status'  => [
897
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
898
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
899
-            ],
900
-            'active_status'    => [
901
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
902
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
903
-            ],
904
-            'upcoming_status'  => [
905
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
906
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
907
-            ],
908
-            'postponed_status' => [
909
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
910
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
911
-            ],
912
-            'cancelled_status' => [
913
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
914
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
915
-            ],
916
-            'expired_status'   => [
917
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
918
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
919
-            ],
920
-            'inactive_status'  => [
921
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
922
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
923
-            ],
924
-        ];
925
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
926
-        return array_merge($items, $statuses);
927
-    }
928
-
929
-
930
-    /**
931
-     * @return EEM_Event
932
-     * @throws EE_Error
933
-     * @throws InvalidArgumentException
934
-     * @throws InvalidDataTypeException
935
-     * @throws InvalidInterfaceException
936
-     * @throws ReflectionException
937
-     */
938
-    private function _event_model()
939
-    {
940
-        if (! $this->_event_model instanceof EEM_Event) {
941
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
942
-        }
943
-        return $this->_event_model;
944
-    }
945
-
946
-
947
-    /**
948
-     * Adds extra buttons to the WP CPT permalink field row.
949
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
950
-     *
951
-     * @param string $return    the current html
952
-     * @param int    $id        the post id for the page
953
-     * @param string $new_title What the title is
954
-     * @param string $new_slug  what the slug is
955
-     * @return string            The new html string for the permalink area
956
-     */
957
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
958
-    {
959
-        // make sure this is only when editing
960
-        if (! empty($id)) {
961
-            $post   = get_post($id);
962
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
963
-                       . esc_html__('Shortcode', 'event_espresso')
964
-                       . '</a> ';
965
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
966
-                       . $post->ID
967
-                       . ']">';
968
-        }
969
-        return $return;
970
-    }
971
-
972
-
973
-    /**
974
-     * _events_overview_list_table
975
-     * This contains the logic for showing the events_overview list
976
-     *
977
-     * @access protected
978
-     * @return void
979
-     * @throws DomainException
980
-     * @throws EE_Error
981
-     * @throws InvalidArgumentException
982
-     * @throws InvalidDataTypeException
983
-     * @throws InvalidInterfaceException
984
-     */
985
-    protected function _events_overview_list_table()
986
-    {
987
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
988
-        $this->_template_args['after_list_table']                           =
989
-            ! empty($this->_template_args['after_list_table'])
990
-                ? (array) $this->_template_args['after_list_table']
991
-                : [];
992
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
993
-            . EEH_Template::get_button_or_link(
994
-                get_post_type_archive_link('espresso_events'),
995
-                esc_html__('View Event Archive Page', 'event_espresso'),
996
-                'button'
997
-            );
998
-        $this->_template_args['after_list_table']['legend']                 =
999
-            $this->_display_legend($this->_event_legend_items());
1000
-        $this->_admin_page_title                                            .= ' '
1001
-            . $this->get_action_link_or_button(
1002
-                'create_new',
1003
-                'add',
1004
-                [],
1005
-                'add-new-h2'
1006
-            );
1007
-        $this->display_admin_list_table_page_with_no_sidebar();
1008
-    }
1009
-
1010
-
1011
-    /**
1012
-     * this allows for extra misc actions in the default WP publish box
1013
-     *
1014
-     * @return void
1015
-     * @throws DomainException
1016
-     * @throws EE_Error
1017
-     * @throws InvalidArgumentException
1018
-     * @throws InvalidDataTypeException
1019
-     * @throws InvalidInterfaceException
1020
-     * @throws ReflectionException
1021
-     */
1022
-    public function extra_misc_actions_publish_box()
1023
-    {
1024
-        $this->_generate_publish_box_extra_content();
1025
-    }
1026
-
1027
-
1028
-    /**
1029
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1030
-     * saved.
1031
-     * Typically you would use this to save any additional data.
1032
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1033
-     * ALSO very important.  When a post transitions from scheduled to published,
1034
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1035
-     * other meta saves. So MAKE sure that you handle this accordingly.
1036
-     *
1037
-     * @access protected
1038
-     * @abstract
1039
-     * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1040
-     * @param object $post    The post object of the cpt that was saved.
1041
-     * @return void
1042
-     * @throws EE_Error
1043
-     * @throws InvalidArgumentException
1044
-     * @throws InvalidDataTypeException
1045
-     * @throws InvalidInterfaceException
1046
-     * @throws ReflectionException
1047
-     */
1048
-    protected function _insert_update_cpt_item($post_id, $post)
1049
-    {
1050
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1051
-            // get out we're not processing an event save.
1052
-            return;
1053
-        }
1054
-        $event_values = [
1055
-            'EVT_member_only'     => ! empty($this->_req_data['member_only']) ? 1 : 0,
1056
-            'EVT_allow_overflow'  => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
1057
-            'EVT_timezone_string' => ! empty($this->_req_data['timezone_string'])
1058
-                ? sanitize_text_field($this->_req_data['timezone_string'])
1059
-                : null,
1060
-        ];
1061
-        /** @var FeatureFlags $flags */
1062
-        $flags = $this->loader->getShared('EventEspresso\core\domain\services\capabilities\FeatureFlags');
1063
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1064
-        if (! $this->admin_config->useAdvancedEditor() || ! $flags->featureAllowed('use_reg_options_meta_box')) {
1065
-            $event_values['EVT_display_ticket_selector']     =
1066
-                ! empty($this->_req_data['display_ticket_selector'])
1067
-                    ? 1
1068
-                    : 0;
1069
-            $event_values['EVT_additional_limit']            = min(
1070
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1071
-                ! empty($this->_req_data['additional_limit'])
1072
-                    ? absint($this->_req_data['additional_limit'])
1073
-                    : null
1074
-            );
1075
-            $event_values['EVT_default_registration_status'] =
1076
-                ! empty($this->_req_data['EVT_default_registration_status'])
1077
-                    ? sanitize_text_field($this->_req_data['EVT_default_registration_status'])
1078
-                    : EE_Registry::instance()->CFG->registration->default_STS_ID;
1079
-            $event_values['EVT_external_URL']                = ! empty($this->_req_data['externalURL'])
1080
-                ? esc_url_raw($this->_req_data['externalURL'])
1081
-                : null;
1082
-            $event_values['EVT_phone']                       = ! empty($this->_req_data['event_phone'])
1083
-                ? sanitize_text_field($this->_req_data['event_phone'])
1084
-                : null;
1085
-        }
1086
-        // update event
1087
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1088
-        // get event_object for other metaboxes...
1089
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1090
-        // i have to setup where conditions to override the filters in the model that filter out autodraft
1091
-        // and inherit statuses so we GET the inherit id!
1092
-        $get_one_where = [
1093
-            $this->_event_model()->primary_key_name() => $post_id,
1094
-            'OR'                                      => [
1095
-                'status'   => $post->post_status,
1096
-                // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1097
-                // but the returned object here has a status of "publish", so use the original post status as well
1098
-                'status*1' => $this->_req_data['original_post_status'],
1099
-            ],
1100
-        ];
1101
-        $event         = $this->_event_model()->get_one([$get_one_where]);
1102
-        // the following are default callbacks for event attachment updates
1103
-        // that can be overridden by caffeinated functionality and/or addons.
1104
-        $event_update_callbacks = apply_filters(
1105
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1106
-            [
1107
-                [$this, '_default_venue_update'],
1108
-                [$this, '_default_tickets_update'],
1109
-            ]
1110
-        );
1111
-        $att_success            = true;
1112
-        foreach ($event_update_callbacks as $e_callback) {
1113
-            $_success = is_callable($e_callback)
1114
-                ? $e_callback($event, $this->_req_data)
1115
-                : false;
1116
-            // if ANY of these updates fail then we want the appropriate global error message
1117
-            $att_success = ! $att_success ? $att_success : $_success;
1118
-        }
1119
-        // any errors?
1120
-        if ($success && false === $att_success) {
1121
-            EE_Error::add_error(
1122
-                esc_html__(
1123
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1124
-                    'event_espresso'
1125
-                ),
1126
-                __FILE__,
1127
-                __FUNCTION__,
1128
-                __LINE__
1129
-            );
1130
-        } elseif ($success === false) {
1131
-            EE_Error::add_error(
1132
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1133
-                __FILE__,
1134
-                __FUNCTION__,
1135
-                __LINE__
1136
-            );
1137
-        }
1138
-    }
1139
-
1140
-
1141
-    /**
1142
-     * @param int $post_id
1143
-     * @param int $revision_id
1144
-     * @throws EE_Error
1145
-     * @throws InvalidArgumentException
1146
-     * @throws InvalidDataTypeException
1147
-     * @throws InvalidInterfaceException
1148
-     * @throws ReflectionException
1149
-     * @see parent::restore_item()
1150
-     */
1151
-    protected function _restore_cpt_item($post_id, $revision_id)
1152
-    {
1153
-        // copy existing event meta to new post
1154
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1155
-        if ($post_evt instanceof EE_Event) {
1156
-            // meta revision restore
1157
-            $post_evt->restore_revision($revision_id);
1158
-            // related objs restore
1159
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1160
-        }
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * Attach the venue to the Event
1166
-     *
1167
-     * @param EE_Event $evtobj Event Object to add the venue to
1168
-     * @param array    $data   The request data from the form
1169
-     * @return bool           Success or fail.
1170
-     * @throws EE_Error
1171
-     * @throws InvalidArgumentException
1172
-     * @throws InvalidDataTypeException
1173
-     * @throws InvalidInterfaceException
1174
-     * @throws ReflectionException
1175
-     */
1176
-    protected function _default_venue_update(EE_Event $evtobj, $data)
1177
-    {
1178
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1179
-        $venue_model   = EE_Registry::instance()->load_model('Venue');
1180
-        $rows_affected = null;
1181
-        $venue_id      = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1182
-        // very important.  If we don't have a venue name...
1183
-        // then we'll get out because not necessary to create empty venue
1184
-        if (empty($data['venue_title'])) {
1185
-            return false;
1186
-        }
1187
-        $venue_array = [
1188
-            'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1189
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1190
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1191
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1192
-            'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1193
-                : null,
1194
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1195
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1196
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1197
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1198
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1199
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1200
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1201
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1202
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1203
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1204
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1205
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1206
-            'status'              => 'publish',
1207
-        ];
1208
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1209
-        if (! empty($venue_id)) {
1210
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1211
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1212
-            // we've gotta make sure that the venue is always attached to a revision..
1213
-            // add_relation_to should take care of making sure that the relation is already present.
1214
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1215
-            return $rows_affected > 0;
1216
-        }
1217
-        // we insert the venue
1218
-        $venue_id = $venue_model->insert($venue_array);
1219
-        $evtobj->_add_relation_to($venue_id, 'Venue');
1220
-        return ! empty($venue_id);
1221
-        // when we have the ancestor come in it's already been handled by the revision save.
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1227
-     *
1228
-     * @param EE_Event $evtobj The Event object we're attaching data to
1229
-     * @param array    $data   The request data from the form
1230
-     * @return array
1231
-     * @throws EE_Error
1232
-     * @throws InvalidArgumentException
1233
-     * @throws InvalidDataTypeException
1234
-     * @throws InvalidInterfaceException
1235
-     * @throws ReflectionException
1236
-     * @throws Exception
1237
-     */
1238
-    protected function _default_tickets_update(EE_Event $evtobj, $data)
1239
-    {
1240
-        if ($this->admin_config->useAdvancedEditor()) {
1241
-            return [];
1242
-        }
1243
-        $success               = true;
1244
-        $saved_dtt             = null;
1245
-        $saved_tickets         = [];
1246
-        $incoming_date_formats = ['Y-m-d', 'h:i a'];
1247
-        foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1248
-            // trim all values to ensure any excess whitespace is removed.
1249
-            $dtt                = array_map('trim', $dtt);
1250
-            $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1251
-                : $dtt['DTT_EVT_start'];
1252
-            $datetime_values    = [
1253
-                'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1254
-                'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1255
-                'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1256
-                'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1257
-                'DTT_order'     => $row,
1258
-            ];
1259
-            // if we have an id then let's get existing object first and then set the new values.
1260
-            //  Otherwise we instantiate a new object for save.
1261
-            if (! empty($dtt['DTT_ID'])) {
1262
-                $DTM = EE_Registry::instance()
1263
-                                  ->load_model('Datetime', [$evtobj->get_timezone()])
1264
-                                  ->get_one_by_ID($dtt['DTT_ID']);
1265
-                $DTM->set_date_format($incoming_date_formats[0]);
1266
-                $DTM->set_time_format($incoming_date_formats[1]);
1267
-                foreach ($datetime_values as $field => $value) {
1268
-                    $DTM->set($field, $value);
1269
-                }
1270
-                // make sure the $dtt_id here is saved in case after the add_relation_to() the autosave replaces it.
1271
-                // We need to do this so we dont' TRASH the parent DTT.
1272
-                $saved_dtts[ $DTM->ID() ] = $DTM;
1273
-            } else {
1274
-                $DTM = EE_Registry::instance()->load_class(
1275
-                    'Datetime',
1276
-                    [$datetime_values, $evtobj->get_timezone(), $incoming_date_formats],
1277
-                    false,
1278
-                    false
1279
-                );
1280
-                foreach ($datetime_values as $field => $value) {
1281
-                    $DTM->set($field, $value);
1282
-                }
1283
-            }
1284
-            $DTM->save();
1285
-            $DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1286
-            // load DTT helper
1287
-            // before going any further make sure our dates are setup correctly
1288
-            // so that the end date is always equal or greater than the start date.
1289
-            if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1290
-                $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1291
-                $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1292
-                $DTT->save();
1293
-            }
1294
-            // now we got to make sure we add the new DTT_ID to the $saved_dtts array
1295
-            //  because it is possible there was a new one created for the autosave.
1296
-            $saved_dtt = $DTT;
1297
-            $success   = ! $success ? $success : $DTT;
1298
-            // if ANY of these updates fail then we want the appropriate global error message.
1299
-            // //todo this is actually sucky we need a better error message but this is what it is for now.
1300
-        }
1301
-        // no dtts get deleted so we don't do any of that logic here.
1302
-        // update tickets next
1303
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1304
-        foreach ($data['edit_tickets'] as $row => $tkt) {
1305
-            $incoming_date_formats = ['Y-m-d', 'h:i a'];
1306
-            $update_prices         = false;
1307
-            $ticket_price          = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1308
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1309
-                : 0;
1310
-            // trim inputs to ensure any excess whitespace is removed.
1311
-            $tkt = array_map('trim', $tkt);
1312
-            if (empty($tkt['TKT_start_date'])) {
1313
-                // let's use now in the set timezone.
1314
-                $now                   = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1315
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1316
-            }
1317
-            if (empty($tkt['TKT_end_date'])) {
1318
-                // use the start date of the first datetime
1319
-                $dtt                 = $evtobj->first_datetime();
1320
-                $tkt['TKT_end_date'] = $dtt->start_date_and_time(
1321
-                    $incoming_date_formats[0],
1322
-                    $incoming_date_formats[1]
1323
-                );
1324
-            }
1325
-            $TKT_values = [
1326
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1327
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1328
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1329
-                'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1330
-                'TKT_start_date'  => $tkt['TKT_start_date'],
1331
-                'TKT_end_date'    => $tkt['TKT_end_date'],
1332
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1333
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1334
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1335
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1336
-                'TKT_row'         => $row,
1337
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1338
-                'TKT_price'       => $ticket_price,
1339
-            ];
1340
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
1341
-            // which means in turn that the prices will become new prices as well.
1342
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1343
-                $TKT_values['TKT_ID']         = 0;
1344
-                $TKT_values['TKT_is_default'] = 0;
1345
-                $TKT_values['TKT_price']      = $ticket_price;
1346
-                $update_prices                = true;
1347
-            }
1348
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1349
-            // we actually do our saves a head of doing any add_relations to because its entirely possible
1350
-            // that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
1351
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
1352
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1353
-            if (! empty($tkt['TKT_ID'])) {
1354
-                $TKT = EE_Registry::instance()
1355
-                                  ->load_model('Ticket', [$evtobj->get_timezone()])
1356
-                                  ->get_one_by_ID($tkt['TKT_ID']);
1357
-                if ($TKT instanceof EE_Ticket) {
1358
-                    $ticket_sold = $TKT->count_related(
1359
-                        'Registration',
1360
-                        [
1361
-                            [
1362
-                                'STS_ID' => [
1363
-                                    'NOT IN',
1364
-                                    [EEM_Registration::status_id_incomplete],
1365
-                                ],
1366
-                            ],
1367
-                        ]
1368
-                    ) > 0;
1369
-                    // let's just check the total price for the existing ticket and determine if it matches the new
1370
-                    // total price.  if they are different then we create a new ticket (if tickets sold)
1371
-                    // if they aren't different then we go ahead and modify existing ticket.
1372
-                    $create_new_TKT = $ticket_sold
1373
-                                      && ! $TKT->deleted()
1374
-                                      && EEH_Money::compare_floats(
1375
-                                          $ticket_price,
1376
-                                          $TKT->get('TKT_price'),
1377
-                                          '!=='
1378
-                                      );
1379
-                    $TKT->set_date_format($incoming_date_formats[0]);
1380
-                    $TKT->set_time_format($incoming_date_formats[1]);
1381
-                    // set new values
1382
-                    foreach ($TKT_values as $field => $value) {
1383
-                        if ($field === 'TKT_qty') {
1384
-                            $TKT->set_qty($value);
1385
-                        } else {
1386
-                            $TKT->set($field, $value);
1387
-                        }
1388
-                    }
1389
-                    // if $create_new_TKT is false then we can safely update the existing ticket.
1390
-                    //  Otherwise we have to create a new ticket.
1391
-                    if ($create_new_TKT) {
1392
-                        // archive the old ticket first
1393
-                        $TKT->set('TKT_deleted', 1);
1394
-                        $TKT->save();
1395
-                        // make sure this ticket is still recorded in our saved_tkts
1396
-                        // so we don't run it through the regular trash routine.
1397
-                        $saved_tickets[ $TKT->ID() ] = $TKT;
1398
-                        // create new ticket that's a copy of the existing except a new id of course
1399
-                        // (and not archived) AND has the new TKT_price associated with it.
1400
-                        $TKT = clone $TKT;
1401
-                        $TKT->set('TKT_ID', 0);
1402
-                        $TKT->set('TKT_deleted', 0);
1403
-                        $TKT->set('TKT_price', $ticket_price);
1404
-                        $TKT->set('TKT_sold', 0);
1405
-                        // now we need to make sure that $new prices are created as well and attached to new ticket.
1406
-                        $update_prices = true;
1407
-                    }
1408
-                    // make sure price is set if it hasn't been already
1409
-                    $TKT->set('TKT_price', $ticket_price);
1410
-                }
1411
-            } else {
1412
-                // no TKT_id so a new TKT
1413
-                $TKT_values['TKT_price'] = $ticket_price;
1414
-                $TKT                     = EE_Registry::instance()->load_class('Ticket', [$TKT_values], false, false);
1415
-                if ($TKT instanceof EE_Ticket) {
1416
-                    // need to reset values to properly account for the date formats
1417
-                    $TKT->set_date_format($incoming_date_formats[0]);
1418
-                    $TKT->set_time_format($incoming_date_formats[1]);
1419
-                    $TKT->set_timezone($evtobj->get_timezone());
1420
-                    // set new values
1421
-                    foreach ($TKT_values as $field => $value) {
1422
-                        if ($field === 'TKT_qty') {
1423
-                            $TKT->set_qty($value);
1424
-                        } else {
1425
-                            $TKT->set($field, $value);
1426
-                        }
1427
-                    }
1428
-                    $update_prices = true;
1429
-                }
1430
-            }
1431
-            // cap ticket qty by datetime reg limits
1432
-            $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1433
-            // update ticket.
1434
-            $TKT->save();
1435
-            // before going any further make sure our dates are setup correctly
1436
-            // so that the end date is always equal or greater than the start date.
1437
-            if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1438
-                $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1439
-                $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1440
-                $TKT->save();
1441
-            }
1442
-            // initially let's add the ticket to the dtt
1443
-            $saved_dtt->_add_relation_to($TKT, 'Ticket');
1444
-            $saved_tickets[ $TKT->ID() ] = $TKT;
1445
-            // add prices to ticket
1446
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1447
-        }
1448
-        // however now we need to handle permanently deleting tickets via the ui.
1449
-        //  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1450
-        //  However, it does allow for deleting tickets that have no tickets sold,
1451
-        // in which case we want to get rid of permanently because there is no need to save in db.
1452
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1453
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1454
-        foreach ($tickets_removed as $id) {
1455
-            $id = absint($id);
1456
-            // get the ticket for this id
1457
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1458
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1459
-            // (remember this process can ONLY kick off if there are NO tkts_sold)
1460
-            $dtts = $tkt_to_remove->get_many_related('Datetime');
1461
-            foreach ($dtts as $dtt) {
1462
-                $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1463
-            }
1464
-            // need to do the same for prices (except these prices can also be deleted because again,
1465
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1466
-            $tkt_to_remove->delete_related_permanently('Price');
1467
-            // finally let's delete this ticket
1468
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1469
-            $tkt_to_remove->delete_permanently();
1470
-        }
1471
-        return [$saved_dtt, $saved_tickets];
1472
-    }
1473
-
1474
-
1475
-    /**
1476
-     * This attaches a list of given prices to a ticket.
1477
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1478
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1479
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1480
-     *
1481
-     * @access  private
1482
-     * @param array     $prices     Array of prices from the form.
1483
-     * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1484
-     * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1485
-     * @return  void
1486
-     * @throws EE_Error
1487
-     * @throws InvalidArgumentException
1488
-     * @throws InvalidDataTypeException
1489
-     * @throws InvalidInterfaceException
1490
-     * @throws ReflectionException
1491
-     */
1492
-    private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1493
-    {
1494
-        foreach ($prices as $row => $prc) {
1495
-            $PRC_values = [
1496
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1497
-                'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1498
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1499
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1500
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1501
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1502
-                'PRC_order'      => $row,
1503
-            ];
1504
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
1505
-                $PRC_values['PRC_ID'] = 0;
1506
-                $PRC                  = EE_Registry::instance()->load_class('Price', [$PRC_values], false, false);
1507
-            } else {
1508
-                $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1509
-                // update this price with new values
1510
-                foreach ($PRC_values as $field => $newprc) {
1511
-                    $PRC->set($field, $newprc);
1512
-                }
1513
-                $PRC->save();
1514
-            }
1515
-            $ticket->_add_relation_to($PRC, 'Price');
1516
-        }
1517
-    }
1518
-
1519
-
1520
-    /**
1521
-     * Add in our autosave ajax handlers
1522
-     *
1523
-     */
1524
-    protected function _ee_autosave_create_new()
1525
-    {
1526
-    }
1527
-
1528
-
1529
-    /**
1530
-     * More autosave handlers.
1531
-     */
1532
-    protected function _ee_autosave_edit()
1533
-    {
1534
-    }
1535
-
1536
-
1537
-    /**
1538
-     *    _generate_publish_box_extra_content
1539
-     *
1540
-     * @throws DomainException
1541
-     * @throws EE_Error
1542
-     * @throws InvalidArgumentException
1543
-     * @throws InvalidDataTypeException
1544
-     * @throws InvalidInterfaceException
1545
-     * @throws ReflectionException
1546
-     */
1547
-    private function _generate_publish_box_extra_content()
1548
-    {
1549
-        // load formatter helper
1550
-        // args for getting related registrations
1551
-        $approved_query_args        = [
1552
-            [
1553
-                'REG_deleted' => 0,
1554
-                'STS_ID'      => EEM_Registration::status_id_approved,
1555
-            ],
1556
-        ];
1557
-        $not_approved_query_args    = [
1558
-            [
1559
-                'REG_deleted' => 0,
1560
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1561
-            ],
1562
-        ];
1563
-        $pending_payment_query_args = [
1564
-            [
1565
-                'REG_deleted' => 0,
1566
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1567
-            ],
1568
-        ];
1569
-        // publish box
1570
-        $publish_box_extra_args = [
1571
-            'view_approved_reg_url'        => add_query_arg(
1572
-                [
1573
-                    'action'      => 'default',
1574
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1575
-                    '_reg_status' => EEM_Registration::status_id_approved,
1576
-                ],
1577
-                REG_ADMIN_URL
1578
-            ),
1579
-            'view_not_approved_reg_url'    => add_query_arg(
1580
-                [
1581
-                    'action'      => 'default',
1582
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1583
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1584
-                ],
1585
-                REG_ADMIN_URL
1586
-            ),
1587
-            'view_pending_payment_reg_url' => add_query_arg(
1588
-                [
1589
-                    'action'      => 'default',
1590
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1591
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1592
-                ],
1593
-                REG_ADMIN_URL
1594
-            ),
1595
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1596
-                'Registration',
1597
-                $approved_query_args
1598
-            ),
1599
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1600
-                'Registration',
1601
-                $not_approved_query_args
1602
-            ),
1603
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1604
-                'Registration',
1605
-                $pending_payment_query_args
1606
-            ),
1607
-            'misc_pub_section_class'       => apply_filters(
1608
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1609
-                'misc-pub-section'
1610
-            ),
1611
-        ];
1612
-        ob_start();
1613
-        do_action(
1614
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1615
-            $this->_cpt_model_obj
1616
-        );
1617
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1618
-        // load template
1619
-        EEH_Template::display_template(
1620
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1621
-            $publish_box_extra_args
1622
-        );
1623
-    }
1624
-
1625
-
1626
-    /**
1627
-     * @return EE_Event
1628
-     */
1629
-    public function get_event_object()
1630
-    {
1631
-        return $this->_cpt_model_obj;
1632
-    }
1633
-
1634
-
1635
-
1636
-
1637
-    /** METABOXES * */
1638
-    /**
1639
-     * _register_event_editor_meta_boxes
1640
-     * add all metaboxes related to the event_editor
1641
-     *
1642
-     * @return void
1643
-     * @throws EE_Error
1644
-     * @throws InvalidArgumentException
1645
-     * @throws InvalidDataTypeException
1646
-     * @throws InvalidInterfaceException
1647
-     * @throws ReflectionException
1648
-     */
1649
-    protected function _register_event_editor_meta_boxes()
1650
-    {
1651
-        $this->verify_cpt_object();
1652
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1653
-        /** @var FeatureFlags $flags */
1654
-        $flags = $this->loader->getShared('EventEspresso\core\domain\services\capabilities\FeatureFlags');
1655
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1656
-        if (! $use_advanced_editor || ! $flags->featureAllowed('use_reg_options_meta_box')) {
1657
-            add_meta_box(
1658
-                'espresso_event_editor_event_options',
1659
-                esc_html__('Event Registration Options', 'event_espresso'),
1660
-                [$this, 'registration_options_meta_box'],
1661
-                $this->page_slug,
1662
-                'side'
1663
-            );
1664
-        }
1665
-        if (! $use_advanced_editor) {
1666
-            add_meta_box(
1667
-                'espresso_event_editor_tickets',
1668
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1669
-                [$this, 'ticket_metabox'],
1670
-                $this->page_slug,
1671
-                'normal',
1672
-                'high'
1673
-            );
1674
-        } else {
1675
-            if ($flags->featureAllowed('use_reg_options_meta_box')) {
1676
-                add_action(
1677
-                    'add_meta_boxes_espresso_events',
1678
-                    function () {
1679
-                        global $current_screen;
1680
-                        remove_meta_box('authordiv', $current_screen, 'normal');
1681
-                    },
1682
-                    99
1683
-                );
1684
-            }
1685
-        }
1686
-        // NOTE: if you're looking for other metaboxes in here,
1687
-        // where a metabox has a related management page in the admin
1688
-        // you will find it setup in the related management page's "_Hooks" file.
1689
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1690
-    }
1691
-
1692
-
1693
-    /**
1694
-     * @throws DomainException
1695
-     * @throws EE_Error
1696
-     * @throws InvalidArgumentException
1697
-     * @throws InvalidDataTypeException
1698
-     * @throws InvalidInterfaceException
1699
-     * @throws ReflectionException
1700
-     */
1701
-    public function ticket_metabox()
1702
-    {
1703
-        $existing_datetime_ids = $existing_ticket_ids = [];
1704
-        // defaults for template args
1705
-        $template_args = [
1706
-            'existing_datetime_ids'    => '',
1707
-            'event_datetime_help_link' => '',
1708
-            'ticket_options_help_link' => '',
1709
-            'time'                     => null,
1710
-            'ticket_rows'              => '',
1711
-            'existing_ticket_ids'      => '',
1712
-            'total_ticket_rows'        => 1,
1713
-            'ticket_js_structure'      => '',
1714
-            'trash_icon'               => 'ee-lock-icon',
1715
-            'disabled'                 => '',
1716
-        ];
1717
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1718
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1719
-        /**
1720
-         * 1. Start with retrieving Datetimes
1721
-         * 2. Fore each datetime get related tickets
1722
-         * 3. For each ticket get related prices
1723
-         */
1724
-        $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1725
-        /** @type EE_Datetime $first_datetime */
1726
-        $first_datetime = reset($times);
1727
-        // do we get related tickets?
1728
-        if (
1729
-            $first_datetime instanceof EE_Datetime
1730
-            && $first_datetime->ID() !== 0
1731
-        ) {
1732
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1733
-            $template_args['time']   = $first_datetime;
1734
-            $related_tickets         = $first_datetime->tickets(
1735
-                [
1736
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1737
-                    'default_where_conditions' => 'none',
1738
-                ]
1739
-            );
1740
-            if (! empty($related_tickets)) {
1741
-                $template_args['total_ticket_rows'] = count($related_tickets);
1742
-                $row                                = 0;
1743
-                foreach ($related_tickets as $ticket) {
1744
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1745
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1746
-                    $row++;
1747
-                }
1748
-            } else {
1749
-                $template_args['total_ticket_rows'] = 1;
1750
-                /** @type EE_Ticket $ticket */
1751
-                $ticket                       = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1752
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1753
-            }
1754
-        } else {
1755
-            $template_args['time'] = $times[0];
1756
-            /** @type EE_Ticket $ticket */
1757
-            $ticket                       = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1758
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1759
-            // NOTE: we're just sending the first default row
1760
-            // (decaf can't manage default tickets so this should be sufficient);
1761
-        }
1762
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1763
-            'event_editor_event_datetimes_help_tab'
1764
-        );
1765
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1766
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1767
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1768
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1769
-            EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1770
-            true
1771
-        );
1772
-        $template                                  = apply_filters(
1773
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1774
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1775
-        );
1776
-        EEH_Template::display_template($template, $template_args);
1777
-    }
1778
-
1779
-
1780
-    /**
1781
-     * Setup an individual ticket form for the decaf event editor page
1782
-     *
1783
-     * @access private
1784
-     * @param EE_Ticket $ticket   the ticket object
1785
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1786
-     * @param int       $row
1787
-     * @return string generated html for the ticket row.
1788
-     * @throws DomainException
1789
-     * @throws EE_Error
1790
-     * @throws InvalidArgumentException
1791
-     * @throws InvalidDataTypeException
1792
-     * @throws InvalidInterfaceException
1793
-     * @throws ReflectionException
1794
-     */
1795
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1796
-    {
1797
-        $template_args = [
1798
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1799
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1800
-                : '',
1801
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1802
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1803
-            'TKT_name'            => $ticket->get('TKT_name'),
1804
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1805
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1806
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1807
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1808
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1809
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1810
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1811
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1812
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1813
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1814
-                : ' disabled=disabled',
1815
-        ];
1816
-        $price         = $ticket->ID() !== 0
1817
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1818
-            : EE_Registry::instance()->load_model('Price')->create_default_object();
1819
-        $price_args    = [
1820
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1821
-            'PRC_amount'            => $price->get('PRC_amount'),
1822
-            'PRT_ID'                => $price->get('PRT_ID'),
1823
-            'PRC_ID'                => $price->get('PRC_ID'),
1824
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1825
-        ];
1826
-        // make sure we have default start and end dates if skeleton
1827
-        // handle rows that should NOT be empty
1828
-        if (empty($template_args['TKT_start_date'])) {
1829
-            // if empty then the start date will be now.
1830
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1831
-        }
1832
-        if (empty($template_args['TKT_end_date'])) {
1833
-            // get the earliest datetime (if present);
1834
-            $earliest_dtt = $this->_cpt_model_obj->ID() > 0
1835
-                ? $this->_cpt_model_obj->get_first_related(
1836
-                    'Datetime',
1837
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1838
-                )
1839
-                : null;
1840
-            if (! empty($earliest_dtt)) {
1841
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1842
-            } else {
1843
-                $template_args['TKT_end_date'] = date(
1844
-                    'Y-m-d h:i a',
1845
-                    mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))
1846
-                );
1847
-            }
1848
-        }
1849
-        $template_args = array_merge($template_args, $price_args);
1850
-        $template      = apply_filters(
1851
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1852
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1853
-            $ticket
1854
-        );
1855
-        return EEH_Template::display_template($template, $template_args, true);
1856
-    }
1857
-
1858
-
1859
-    /**
1860
-     * @throws DomainException
1861
-     * @throws EE_Error
1862
-     */
1863
-    public function registration_options_meta_box()
1864
-    {
1865
-        $yes_no_values             = [
1866
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1867
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1868
-        ];
1869
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1870
-            [
1871
-                EEM_Registration::status_id_cancelled,
1872
-                EEM_Registration::status_id_declined,
1873
-                EEM_Registration::status_id_incomplete,
1874
-            ],
1875
-            true
1876
-        );
1877
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1878
-        $template_args['_event']                          = $this->_cpt_model_obj;
1879
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1880
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1881
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1882
-            'default_reg_status',
1883
-            $default_reg_status_values,
1884
-            $this->_cpt_model_obj->default_registration_status()
1885
-        );
1886
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1887
-            'display_desc',
1888
-            $yes_no_values,
1889
-            $this->_cpt_model_obj->display_description()
1890
-        );
1891
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1892
-            'display_ticket_selector',
1893
-            $yes_no_values,
1894
-            $this->_cpt_model_obj->display_ticket_selector(),
1895
-            '',
1896
-            '',
1897
-            false
1898
-        );
1899
-        $template_args['additional_registration_options'] = apply_filters(
1900
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1901
-            '',
1902
-            $template_args,
1903
-            $yes_no_values,
1904
-            $default_reg_status_values
1905
-        );
1906
-        EEH_Template::display_template(
1907
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1908
-            $template_args
1909
-        );
1910
-    }
1911
-
1912
-
1913
-    /**
1914
-     * _get_events()
1915
-     * This method simply returns all the events (for the given _view and paging)
1916
-     *
1917
-     * @access public
1918
-     * @param int  $per_page     count of items per page (20 default);
1919
-     * @param int  $current_page what is the current page being viewed.
1920
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1921
-     *                           If FALSE then we return an array of event objects
1922
-     *                           that match the given _view and paging parameters.
1923
-     * @return array|int an array of event objects.
1924
-     * @throws EE_Error
1925
-     * @throws InvalidArgumentException
1926
-     * @throws InvalidDataTypeException
1927
-     * @throws InvalidInterfaceException
1928
-     * @throws ReflectionException
1929
-     * @throws Exception
1930
-     * @throws Exception
1931
-     * @throws Exception
1932
-     */
1933
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1934
-    {
1935
-        $EEME    = $this->_event_model();
1936
-        $offset  = ($current_page - 1) * $per_page;
1937
-        $limit   = $count ? null : $offset . ',' . $per_page;
1938
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1939
-        $order   = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
1940
-        if (isset($this->_req_data['month_range'])) {
1941
-            $pieces = explode(' ', $this->_req_data['month_range'], 3);
1942
-            // simulate the FIRST day of the month, that fixes issues for months like February
1943
-            // where PHP doesn't know what to assume for date.
1944
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1945
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1946
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1947
-        }
1948
-        $where  = [];
1949
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1950
-        // determine what post_status our condition will have for the query.
1951
-        switch ($status) {
1952
-            case 'month':
1953
-            case 'today':
1954
-            case null:
1955
-            case 'all':
1956
-                break;
1957
-            case 'draft':
1958
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1959
-                break;
1960
-            default:
1961
-                $where['status'] = $status;
1962
-        }
1963
-        // categories?
1964
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1965
-            ? $this->_req_data['EVT_CAT'] : null;
1966
-        if (! empty($category)) {
1967
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1968
-            $where['Term_Taxonomy.term_id']  = $category;
1969
-        }
1970
-        // date where conditions
1971
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1972
-        if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] !== '') {
1973
-            $DateTime = new DateTime(
1974
-                $year_r . '-' . $month_r . '-01 00:00:00',
1975
-                new DateTimeZone('UTC')
1976
-            );
1977
-            $start    = $DateTime->getTimestamp();
1978
-            // set the datetime to be the end of the month
1979
-            $DateTime->setDate(
1980
-                $year_r,
1981
-                $month_r,
1982
-                $DateTime->format('t')
1983
-            )->setTime(23, 59, 59);
1984
-            $end                             = $DateTime->getTimestamp();
1985
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1986
-        } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'today') {
1987
-            $DateTime                        =
1988
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1989
-            $start                           = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1990
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1991
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1992
-        } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'month') {
1993
-            $now                             = date('Y-m-01');
1994
-            $DateTime                        =
1995
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1996
-            $start                           = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1997
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1998
-                                                        ->setTime(23, 59, 59)
1999
-                                                        ->format(implode(' ', $start_formats));
2000
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
2001
-        }
2002
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
2003
-            $where['EVT_wp_user'] = get_current_user_id();
2004
-        } elseif (
2005
-            ! isset($where['status'])
2006
-            && ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')
2007
-        ) {
2008
-            $where['OR'] = [
2009
-                'status*restrict_private' => ['!=', 'private'],
2010
-                'AND'                     => [
2011
-                    'status*inclusive' => ['=', 'private'],
2012
-                    'EVT_wp_user'      => get_current_user_id(),
2013
-                ],
2014
-            ];
2015
-        }
2016
-
2017
-        if (
2018
-            isset($this->_req_data['EVT_wp_user'])
2019
-            && (int) $this->_req_data['EVT_wp_user'] !== (int) get_current_user_id()
2020
-            && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
2021
-        ) {
2022
-            $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
2023
-        }
2024
-        // search query handling
2025
-        if (isset($this->_req_data['s'])) {
2026
-            $search_string = '%' . $this->_req_data['s'] . '%';
2027
-            $where['OR']   = [
2028
-                'EVT_name'       => ['LIKE', $search_string],
2029
-                'EVT_desc'       => ['LIKE', $search_string],
2030
-                'EVT_short_desc' => ['LIKE', $search_string],
2031
-            ];
2032
-        }
2033
-        // filter events by venue.
2034
-        if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) {
2035
-            $where['Venue.VNU_ID'] = absint($this->_req_data['venue']);
2036
-        }
2037
-        $where        = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
2038
-        $query_params = apply_filters(
2039
-            'FHEE__Events_Admin_Page__get_events__query_params',
2040
-            [
2041
-                $where,
2042
-                'limit'    => $limit,
2043
-                'order_by' => $orderby,
2044
-                'order'    => $order,
2045
-                'group_by' => 'EVT_ID',
2046
-            ],
2047
-            $this->_req_data
2048
-        );
2049
-
2050
-        // let's first check if we have special requests coming in.
2051
-        if (isset($this->_req_data['active_status'])) {
2052
-            switch ($this->_req_data['active_status']) {
2053
-                case 'upcoming':
2054
-                    return $EEME->get_upcoming_events($query_params, $count);
2055
-                case 'expired':
2056
-                    return $EEME->get_expired_events($query_params, $count);
2057
-                case 'active':
2058
-                    return $EEME->get_active_events($query_params, $count);
2059
-                case 'inactive':
2060
-                    return $EEME->get_inactive_events($query_params, $count);
2061
-            }
2062
-        }
2063
-
2064
-        return $count ? $EEME->count([$where], 'EVT_ID', true) : $EEME->get_all($query_params);
2065
-    }
2066
-
2067
-
2068
-    /**
2069
-     * handling for WordPress CPT actions (trash, restore, delete)
2070
-     *
2071
-     * @param string $post_id
2072
-     * @throws EE_Error
2073
-     * @throws InvalidArgumentException
2074
-     * @throws InvalidDataTypeException
2075
-     * @throws InvalidInterfaceException
2076
-     * @throws ReflectionException
2077
-     */
2078
-    public function trash_cpt_item($post_id)
2079
-    {
2080
-        $this->_req_data['EVT_ID'] = $post_id;
2081
-        $this->_trash_or_restore_event('trash', false);
2082
-    }
2083
-
2084
-
2085
-    /**
2086
-     * @param string $post_id
2087
-     * @throws EE_Error
2088
-     * @throws InvalidArgumentException
2089
-     * @throws InvalidDataTypeException
2090
-     * @throws InvalidInterfaceException
2091
-     * @throws ReflectionException
2092
-     */
2093
-    public function restore_cpt_item($post_id)
2094
-    {
2095
-        $this->_req_data['EVT_ID'] = $post_id;
2096
-        $this->_trash_or_restore_event('draft', false);
2097
-    }
2098
-
2099
-
2100
-    /**
2101
-     * @param string $post_id
2102
-     * @throws EE_Error
2103
-     * @throws InvalidArgumentException
2104
-     * @throws InvalidDataTypeException
2105
-     * @throws InvalidInterfaceException
2106
-     * @throws ReflectionException
2107
-     */
2108
-    public function delete_cpt_item($post_id)
2109
-    {
2110
-        throw new EE_Error(
2111
-            esc_html__(
2112
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2113
-                'event_espresso'
2114
-            )
2115
-        );
2116
-        $this->_req_data['EVT_ID'] = $post_id;
2117
-        $this->_delete_event();
2118
-    }
2119
-
2120
-
2121
-    /**
2122
-     * _trash_or_restore_event
2123
-     *
2124
-     * @access protected
2125
-     * @param string $event_status
2126
-     * @param bool   $redirect_after
2127
-     * @throws EE_Error
2128
-     * @throws InvalidArgumentException
2129
-     * @throws InvalidDataTypeException
2130
-     * @throws InvalidInterfaceException
2131
-     * @throws ReflectionException
2132
-     */
2133
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2134
-    {
2135
-        // determine the event id and set to array.
2136
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
2137
-        // loop thru events
2138
-        if ($EVT_ID) {
2139
-            // clean status
2140
-            $event_status = sanitize_key($event_status);
2141
-            // grab status
2142
-            if (! empty($event_status)) {
2143
-                $success = $this->_change_event_status($EVT_ID, $event_status);
2144
-            } else {
2145
-                $success = false;
2146
-                $msg     = esc_html__(
2147
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2148
-                    'event_espresso'
2149
-                );
2150
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2151
-            }
2152
-        } else {
2153
-            $success = false;
2154
-            $msg     = esc_html__(
2155
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2156
-                'event_espresso'
2157
-            );
2158
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2159
-        }
2160
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2161
-        if ($redirect_after) {
2162
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2163
-        }
2164
-    }
2165
-
2166
-
2167
-    /**
2168
-     * _trash_or_restore_events
2169
-     *
2170
-     * @access protected
2171
-     * @param string $event_status
2172
-     * @return void
2173
-     * @throws EE_Error
2174
-     * @throws InvalidArgumentException
2175
-     * @throws InvalidDataTypeException
2176
-     * @throws InvalidInterfaceException
2177
-     * @throws ReflectionException
2178
-     */
2179
-    protected function _trash_or_restore_events($event_status = 'trash')
2180
-    {
2181
-        // clean status
2182
-        $event_status = sanitize_key($event_status);
2183
-        // grab status
2184
-        if (! empty($event_status)) {
2185
-            $success = true;
2186
-            // determine the event id and set to array.
2187
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : [];
2188
-            // loop thru events
2189
-            foreach ($EVT_IDs as $EVT_ID) {
2190
-                if ($EVT_ID = absint($EVT_ID)) {
2191
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2192
-                    $success = $results !== false ? $success : false;
2193
-                } else {
2194
-                    $msg = sprintf(
2195
-                        esc_html__(
2196
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2197
-                            'event_espresso'
2198
-                        ),
2199
-                        $EVT_ID
2200
-                    );
2201
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2202
-                    $success = false;
2203
-                }
2204
-            }
2205
-        } else {
2206
-            $success = false;
2207
-            $msg     = esc_html__(
2208
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2209
-                'event_espresso'
2210
-            );
2211
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2212
-        }
2213
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2214
-        $success = $success ? 2 : false;
2215
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2216
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2217
-    }
2218
-
2219
-
2220
-    /**
2221
-     * _trash_or_restore_events
2222
-     *
2223
-     * @access  private
2224
-     * @param int    $EVT_ID
2225
-     * @param string $event_status
2226
-     * @return bool
2227
-     * @throws EE_Error
2228
-     * @throws InvalidArgumentException
2229
-     * @throws InvalidDataTypeException
2230
-     * @throws InvalidInterfaceException
2231
-     * @throws ReflectionException
2232
-     */
2233
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2234
-    {
2235
-        // grab event id
2236
-        if (! $EVT_ID) {
2237
-            $msg = esc_html__(
2238
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2239
-                'event_espresso'
2240
-            );
2241
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2242
-            return false;
2243
-        }
2244
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2245
-        // clean status
2246
-        $event_status = sanitize_key($event_status);
2247
-        // grab status
2248
-        if (empty($event_status)) {
2249
-            $msg = esc_html__(
2250
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2251
-                'event_espresso'
2252
-            );
2253
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2254
-            return false;
2255
-        }
2256
-        // was event trashed or restored ?
2257
-        switch ($event_status) {
2258
-            case 'draft':
2259
-                $action = 'restored from the trash';
2260
-                $hook   = 'AHEE_event_restored_from_trash';
2261
-                break;
2262
-            case 'trash':
2263
-                $action = 'moved to the trash';
2264
-                $hook   = 'AHEE_event_moved_to_trash';
2265
-                break;
2266
-            default:
2267
-                $action = 'updated';
2268
-                $hook   = false;
2269
-        }
2270
-        // use class to change status
2271
-        $this->_cpt_model_obj->set_status($event_status);
2272
-        $success = $this->_cpt_model_obj->save();
2273
-        if ($success === false) {
2274
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2275
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2276
-            return false;
2277
-        }
2278
-        if ($hook) {
2279
-            do_action($hook);
2280
-        }
2281
-        return true;
2282
-    }
2283
-
2284
-
2285
-    /**
2286
-     * _delete_event
2287
-     *
2288
-     * @throws InvalidArgumentException
2289
-     * @throws InvalidDataTypeException
2290
-     * @throws InvalidInterfaceException
2291
-     */
2292
-    protected function _delete_event()
2293
-    {
2294
-        $this->generateDeletionPreview(isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : []);
2295
-    }
2296
-
2297
-
2298
-    /**
2299
-     * Gets the tree traversal batch persister.
2300
-     *
2301
-     * @return NodeGroupDao
2302
-     * @throws InvalidArgumentException
2303
-     * @throws InvalidDataTypeException
2304
-     * @throws InvalidInterfaceException
2305
-     * @since 4.10.12.p
2306
-     */
2307
-    protected function getModelObjNodeGroupPersister()
2308
-    {
2309
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2310
-            $this->model_obj_node_group_persister =
2311
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2312
-        }
2313
-        return $this->model_obj_node_group_persister;
2314
-    }
2315
-
2316
-
2317
-    /**
2318
-     * _delete_events
2319
-     *
2320
-     * @access protected
2321
-     * @return void
2322
-     * @throws InvalidArgumentException
2323
-     * @throws InvalidDataTypeException
2324
-     * @throws InvalidInterfaceException
2325
-     */
2326
-    protected function _delete_events()
2327
-    {
2328
-        $this->generateDeletionPreview(isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : []);
2329
-    }
2330
-
2331
-
2332
-    protected function generateDeletionPreview($event_ids)
2333
-    {
2334
-        $event_ids = (array) $event_ids;
2335
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2336
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2337
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2338
-            [
2339
-                'action'            => 'preview_deletion',
2340
-                'deletion_job_code' => $deletion_job_code,
2341
-            ],
2342
-            $this->_admin_base_url
2343
-        );
2344
-        $event_ids         = array_map(
2345
-            'intval',
2346
-            $event_ids
2347
-        );
2348
-
2349
-        EEH_URL::safeRedirectAndExit(
2350
-            EE_Admin_Page::add_query_args_and_nonce(
2351
-                [
2352
-                    'page'              => 'espresso_batch',
2353
-                    'batch'             => EED_Batch::batch_job,
2354
-                    'EVT_IDs'           => $event_ids,
2355
-                    'deletion_job_code' => $deletion_job_code,
2356
-                    'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2357
-                    'return_url'        => urlencode($return_url),
2358
-                ],
2359
-                admin_url()
2360
-            )
2361
-        );
2362
-    }
2363
-
2364
-
2365
-    /**
2366
-     * Checks for a POST submission
2367
-     *
2368
-     * @since 4.10.12.p
2369
-     */
2370
-    protected function confirmDeletion()
2371
-    {
2372
-        $deletion_redirect_logic =
2373
-            $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion');
2374
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2375
-    }
2376
-
2377
-
2378
-    /**
2379
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2380
-     *
2381
-     * @throws EE_Error
2382
-     * @since 4.10.12.p
2383
-     */
2384
-    protected function previewDeletion()
2385
-    {
2386
-        $preview_deletion_logic =
2387
-            $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion');
2388
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2389
-        $this->display_admin_page_with_no_sidebar();
2390
-    }
2391
-
2392
-
2393
-    /**
2394
-     * get total number of events
2395
-     *
2396
-     * @access public
2397
-     * @return int
2398
-     * @throws EE_Error
2399
-     * @throws InvalidArgumentException
2400
-     * @throws InvalidDataTypeException
2401
-     * @throws InvalidInterfaceException
2402
-     */
2403
-    public function total_events()
2404
-    {
2405
-        return EEM_Event::instance()->count(['caps' => 'read_admin'], 'EVT_ID', true);
2406
-    }
2407
-
2408
-
2409
-    /**
2410
-     * get total number of draft events
2411
-     *
2412
-     * @access public
2413
-     * @return int
2414
-     * @throws EE_Error
2415
-     * @throws InvalidArgumentException
2416
-     * @throws InvalidDataTypeException
2417
-     * @throws InvalidInterfaceException
2418
-     */
2419
-    public function total_events_draft()
2420
-    {
2421
-        $where = [
2422
-            'status' => ['IN', ['draft', 'auto-draft']],
2423
-        ];
2424
-        return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
2425
-    }
2426
-
2427
-
2428
-    /**
2429
-     * get total number of trashed events
2430
-     *
2431
-     * @access public
2432
-     * @return int
2433
-     * @throws EE_Error
2434
-     * @throws InvalidArgumentException
2435
-     * @throws InvalidDataTypeException
2436
-     * @throws InvalidInterfaceException
2437
-     */
2438
-    public function total_trashed_events()
2439
-    {
2440
-        $where = [
2441
-            'status' => 'trash',
2442
-        ];
2443
-        return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
2444
-    }
2445
-
2446
-
2447
-    /**
2448
-     *    _default_event_settings
2449
-     *    This generates the Default Settings Tab
2450
-     *
2451
-     * @return void
2452
-     * @throws DomainException
2453
-     * @throws EE_Error
2454
-     * @throws InvalidArgumentException
2455
-     * @throws InvalidDataTypeException
2456
-     * @throws InvalidInterfaceException
2457
-     */
2458
-    protected function _default_event_settings()
2459
-    {
2460
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2461
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2462
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2463
-        $this->display_admin_page_with_sidebar();
2464
-    }
2465
-
2466
-
2467
-    /**
2468
-     * Return the form for event settings.
2469
-     *
2470
-     * @return EE_Form_Section_Proper
2471
-     * @throws EE_Error
2472
-     */
2473
-    protected function _default_event_settings_form()
2474
-    {
2475
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2476
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2477
-        // exclude
2478
-            [
2479
-                EEM_Registration::status_id_cancelled,
2480
-                EEM_Registration::status_id_declined,
2481
-                EEM_Registration::status_id_incomplete,
2482
-                EEM_Registration::status_id_wait_list,
2483
-            ],
2484
-            true
2485
-        );
2486
-        return new EE_Form_Section_Proper(
2487
-            [
2488
-                'name'            => 'update_default_event_settings',
2489
-                'html_id'         => 'update_default_event_settings',
2490
-                'html_class'      => 'form-table',
2491
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2492
-                'subsections'     => apply_filters(
2493
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2494
-                    [
2495
-                        'default_reg_status'  => new EE_Select_Input(
2496
-                            $registration_stati_for_selection,
2497
-                            [
2498
-                                'default'         => isset($registration_config->default_STS_ID)
2499
-                                                     && array_key_exists(
2500
-                                                         $registration_config->default_STS_ID,
2501
-                                                         $registration_stati_for_selection
2502
-                                                     )
2503
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2504
-                                    : EEM_Registration::status_id_pending_payment,
2505
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2506
-                                                        . EEH_Template::get_help_tab_link(
2507
-                                                            'default_settings_status_help_tab'
2508
-                                                        ),
2509
-                                'html_help_text'  => esc_html__(
2510
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2511
-                                    'event_espresso'
2512
-                                ),
2513
-                            ]
2514
-                        ),
2515
-                        'default_max_tickets' => new EE_Integer_Input(
2516
-                            [
2517
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2518
-                                    ? $registration_config->default_maximum_number_of_tickets
2519
-                                    : EEM_Event::get_default_additional_limit(),
2520
-                                'html_label_text' => esc_html__(
2521
-                                    'Default Maximum Tickets Allowed Per Order:',
2522
-                                    'event_espresso'
2523
-                                )
2524
-                                . EEH_Template::get_help_tab_link(
2525
-                                    'default_maximum_tickets_help_tab"'
2526
-                                ),
2527
-                                'html_help_text'  => esc_html__(
2528
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2529
-                                    'event_espresso'
2530
-                                ),
2531
-                            ]
2532
-                        ),
2533
-                    ]
2534
-                ),
2535
-            ]
2536
-        );
2537
-    }
2538
-
2539
-
2540
-    /**
2541
-     * @return void
2542
-     * @throws EE_Error
2543
-     * @throws InvalidArgumentException
2544
-     * @throws InvalidDataTypeException
2545
-     * @throws InvalidInterfaceException
2546
-     */
2547
-    protected function _update_default_event_settings()
2548
-    {
2549
-        $form = $this->_default_event_settings_form();
2550
-        if ($form->was_submitted()) {
2551
-            $form->receive_form_submission();
2552
-            if ($form->is_valid()) {
2553
-                $registration_config = EE_Registry::instance()->CFG->registration;
2554
-                $valid_data          = $form->valid_data();
2555
-                if (isset($valid_data['default_reg_status'])) {
2556
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2557
-                }
2558
-                if (isset($valid_data['default_max_tickets'])) {
2559
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2560
-                }
2561
-                do_action(
2562
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2563
-                    $valid_data,
2564
-                    EE_Registry::instance()->CFG,
2565
-                    $this
2566
-                );
2567
-                // update because data was valid!
2568
-                EE_Registry::instance()->CFG->update_espresso_config();
2569
-                EE_Error::overwrite_success();
2570
-                EE_Error::add_success(
2571
-                    __('Default Event Settings were updated', 'event_espresso')
2572
-                );
2573
-            }
2574
-        }
2575
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2576
-    }
2577
-
2578
-
2579
-    /*************        Templates        *************/
2580
-    protected function _template_settings()
2581
-    {
2582
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2583
-        $this->_template_args['preview_img']  = '<img src="'
2584
-                                                . EVENTS_ASSETS_URL
2585
-                                                . '/images/'
2586
-                                                . 'caffeinated_template_features.jpg" alt="'
2587
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2588
-                                                . '" />';
2589
-        $this->_template_args['preview_text'] = '<strong>'
2590
-                                                . esc_html__(
2591
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2592
-                                                    'event_espresso'
2593
-                                                ) . '</strong>';
2594
-        $this->display_admin_caf_preview_page('template_settings_tab');
2595
-    }
2596
-
2597
-
2598
-    /** Event Category Stuff **/
2599
-    /**
2600
-     * set the _category property with the category object for the loaded page.
2601
-     *
2602
-     * @access private
2603
-     * @return void
2604
-     */
2605
-    private function _set_category_object()
2606
-    {
2607
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2608
-            return;
2609
-        } //already have the category object so get out.
2610
-        // set default category object
2611
-        $this->_set_empty_category_object();
2612
-        // only set if we've got an id
2613
-        if (! isset($this->_req_data['EVT_CAT_ID'])) {
2614
-            return;
2615
-        }
2616
-        $category_id = absint($this->_req_data['EVT_CAT_ID']);
2617
-        $term        = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2618
-        if (! empty($term)) {
2619
-            $this->_category->category_name       = $term->name;
2620
-            $this->_category->category_identifier = $term->slug;
2621
-            $this->_category->category_desc       = $term->description;
2622
-            $this->_category->id                  = $term->term_id;
2623
-            $this->_category->parent              = $term->parent;
2624
-        }
2625
-    }
2626
-
2627
-
2628
-    /**
2629
-     * Clears out category properties.
2630
-     */
2631
-    private function _set_empty_category_object()
2632
-    {
2633
-        $this->_category                = new stdClass();
2634
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2635
-        $this->_category->id            = $this->_category->parent = 0;
2636
-    }
2637
-
2638
-
2639
-    /**
2640
-     * @throws DomainException
2641
-     * @throws EE_Error
2642
-     * @throws InvalidArgumentException
2643
-     * @throws InvalidDataTypeException
2644
-     * @throws InvalidInterfaceException
2645
-     */
2646
-    protected function _category_list_table()
2647
-    {
2648
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2649
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2650
-        $this->_admin_page_title .= ' ';
2651
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2652
-            'add_category',
2653
-            'add_category',
2654
-            [],
2655
-            'add-new-h2'
2656
-        );
2657
-        $this->display_admin_list_table_page_with_sidebar();
2658
-    }
2659
-
2660
-
2661
-    /**
2662
-     * Output category details view.
2663
-     *
2664
-     * @param string $view
2665
-     * @throws DomainException
2666
-     * @throws EE_Error
2667
-     * @throws InvalidArgumentException
2668
-     * @throws InvalidDataTypeException
2669
-     * @throws InvalidInterfaceException
2670
-     */
2671
-    protected function _category_details($view)
2672
-    {
2673
-        // load formatter helper
2674
-        // load field generator helper
2675
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2676
-        $this->_set_add_edit_form_tags($route);
2677
-        $this->_set_category_object();
2678
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2679
-        $delete_action = 'delete_category';
2680
-        // custom redirect
2681
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2682
-            ['action' => 'category_list'],
2683
-            $this->_admin_base_url
2684
-        );
2685
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2686
-        // take care of contents
2687
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2688
-        $this->display_admin_page_with_sidebar();
2689
-    }
2690
-
2691
-
2692
-    /**
2693
-     * Output category details content.
2694
-     *
2695
-     * @throws DomainException
2696
-     */
2697
-    protected function _category_details_content()
2698
-    {
2699
-        $editor_args['category_desc'] = [
2700
-            'type'          => 'wp_editor',
2701
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2702
-            'class'         => 'my_editor_custom',
2703
-            'wpeditor_args' => ['media_buttons' => false],
2704
-        ];
2705
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2706
-        $all_terms                    = get_terms(
2707
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2708
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2709
-        );
2710
-        // setup category select for term parents.
2711
-        $category_select_values[] = [
2712
-            'text' => esc_html__('No Parent', 'event_espresso'),
2713
-            'id'   => 0,
2714
-        ];
2715
-        foreach ($all_terms as $term) {
2716
-            $category_select_values[] = [
2717
-                'text' => $term->name,
2718
-                'id'   => $term->term_id,
2719
-            ];
2720
-        }
2721
-        $category_select = EEH_Form_Fields::select_input(
2722
-            'category_parent',
2723
-            $category_select_values,
2724
-            $this->_category->parent
2725
-        );
2726
-        $template_args   = [
2727
-            'category'                 => $this->_category,
2728
-            'category_select'          => $category_select,
2729
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2730
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2731
-            'disable'                  => '',
2732
-            'disabled_message'         => false,
2733
-        ];
2734
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2735
-        return EEH_Template::display_template($template, $template_args, true);
2736
-    }
2737
-
2738
-
2739
-    /**
2740
-     * Handles deleting categories.
2741
-     */
2742
-    protected function _delete_categories()
2743
-    {
2744
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2745
-            : (array) $this->_req_data['category_id'];
2746
-        foreach ($cat_ids as $cat_id) {
2747
-            $this->_delete_category($cat_id);
2748
-        }
2749
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2750
-        $query_args = [
2751
-            'action' => 'category_list',
2752
-        ];
2753
-        $this->_redirect_after_action(0, '', '', $query_args);
2754
-    }
2755
-
2756
-
2757
-    /**
2758
-     * Handles deleting specific category.
2759
-     *
2760
-     * @param int $cat_id
2761
-     */
2762
-    protected function _delete_category($cat_id)
2763
-    {
2764
-        $cat_id = absint($cat_id);
2765
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2766
-    }
2767
-
2768
-
2769
-    /**
2770
-     * Handles triggering the update or insertion of a new category.
2771
-     *
2772
-     * @param bool $new_category true means we're triggering the insert of a new category.
2773
-     * @throws EE_Error
2774
-     * @throws InvalidArgumentException
2775
-     * @throws InvalidDataTypeException
2776
-     * @throws InvalidInterfaceException
2777
-     */
2778
-    protected function _insert_or_update_category($new_category)
2779
-    {
2780
-        $cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2781
-        $success = 0; // we already have a success message so lets not send another.
2782
-        if ($cat_id) {
2783
-            $query_args = [
2784
-                'action'     => 'edit_category',
2785
-                'EVT_CAT_ID' => $cat_id,
2786
-            ];
2787
-        } else {
2788
-            $query_args = ['action' => 'add_category'];
2789
-        }
2790
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2791
-    }
2792
-
2793
-
2794
-    /**
2795
-     * Inserts or updates category
2796
-     *
2797
-     * @param bool $update (true indicates we're updating a category).
2798
-     * @return bool|mixed|string
2799
-     */
2800
-    private function _insert_category($update = false)
2801
-    {
2802
-        $cat_id          = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2803
-        $category_name   = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2804
-        $category_desc   = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2805
-        $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2806
-        if (empty($category_name)) {
2807
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2808
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2809
-            return false;
2810
-        }
2811
-        $term_args = [
2812
-            'name'        => $category_name,
2813
-            'description' => $category_desc,
2814
-            'parent'      => $category_parent,
2815
-        ];
2816
-        // was the category_identifier input disabled?
2817
-        if (isset($this->_req_data['category_identifier'])) {
2818
-            $term_args['slug'] = $this->_req_data['category_identifier'];
2819
-        }
2820
-        $insert_ids = $update
2821
-            ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2822
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2823
-        if (! is_array($insert_ids)) {
2824
-            $msg = esc_html__(
2825
-                'An error occurred and the category has not been saved to the database.',
2826
-                'event_espresso'
2827
-            );
2828
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2829
-        } else {
2830
-            $cat_id = $insert_ids['term_id'];
2831
-            $msg    = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2832
-            EE_Error::add_success($msg);
2833
-        }
2834
-        return $cat_id;
2835
-    }
2836
-
2837
-
2838
-    /**
2839
-     * Gets categories or count of categories matching the arguments in the request.
2840
-     *
2841
-     * @param int  $per_page
2842
-     * @param int  $current_page
2843
-     * @param bool $count
2844
-     * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int
2845
-     * @throws EE_Error
2846
-     * @throws InvalidArgumentException
2847
-     * @throws InvalidDataTypeException
2848
-     * @throws InvalidInterfaceException
2849
-     */
2850
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2851
-    {
2852
-        // testing term stuff
2853
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2854
-        $order   = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2855
-        $limit   = ($current_page - 1) * $per_page;
2856
-        $where   = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2857
-        if (isset($this->_req_data['s'])) {
2858
-            $sstr        = '%' . $this->_req_data['s'] . '%';
2859
-            $where['OR'] = [
2860
-                'Term.name'   => ['LIKE', $sstr],
2861
-                'description' => ['LIKE', $sstr],
2862
-            ];
2863
-        }
2864
-        $query_params = [
2865
-            $where,
2866
-            'order_by'   => [$orderby => $order],
2867
-            'limit'      => $limit . ',' . $per_page,
2868
-            'force_join' => ['Term'],
2869
-        ];
2870
-        return $count
2871
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2872
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2873
-    }
2874
-
2875
-    /* end category stuff */
2876
-    /**************/
2877
-
2878
-
2879
-    /**
2880
-     * Callback for the `ee_save_timezone_setting` ajax action.
2881
-     *
2882
-     * @throws EE_Error
2883
-     * @throws InvalidArgumentException
2884
-     * @throws InvalidDataTypeException
2885
-     * @throws InvalidInterfaceException
2886
-     */
2887
-    public function save_timezonestring_setting()
2888
-    {
2889
-        $timezone_string = isset($this->_req_data['timezone_selected'])
2890
-            ? $this->_req_data['timezone_selected']
2891
-            : '';
2892
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2893
-            EE_Error::add_error(
2894
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2895
-                __FILE__,
2896
-                __FUNCTION__,
2897
-                __LINE__
2898
-            );
2899
-            $this->_template_args['error'] = true;
2900
-            $this->_return_json();
2901
-        }
2902
-
2903
-        update_option('timezone_string', $timezone_string);
2904
-        EE_Error::add_success(
2905
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2906
-        );
2907
-        $this->_template_args['success'] = true;
2908
-        $this->_return_json(true, ['action' => 'create_new']);
2909
-    }
20
+	/**
21
+	 * This will hold the event object for event_details screen.
22
+	 *
23
+	 * @access protected
24
+	 * @var EE_Event $_event
25
+	 */
26
+	protected $_event;
27
+
28
+
29
+	/**
30
+	 * This will hold the category object for category_details screen.
31
+	 *
32
+	 * @var stdClass $_category
33
+	 */
34
+	protected $_category;
35
+
36
+
37
+	/**
38
+	 * This will hold the event model instance
39
+	 *
40
+	 * @var EEM_Event $_event_model
41
+	 */
42
+	protected $_event_model;
43
+
44
+
45
+	/**
46
+	 * @var EE_Event
47
+	 */
48
+	protected $_cpt_model_obj = false;
49
+
50
+
51
+	/**
52
+	 * @var NodeGroupDao
53
+	 */
54
+	protected $model_obj_node_group_persister;
55
+
56
+
57
+	/**
58
+	 * Initialize page props for this admin page group.
59
+	 */
60
+	protected function _init_page_props()
61
+	{
62
+		$this->page_slug        = EVENTS_PG_SLUG;
63
+		$this->page_label       = EVENTS_LABEL;
64
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
65
+		$this->_admin_base_path = EVENTS_ADMIN;
66
+		$this->_cpt_model_names = [
67
+			'create_new' => 'EEM_Event',
68
+			'edit'       => 'EEM_Event',
69
+		];
70
+		$this->_cpt_edit_routes = [
71
+			'espresso_events' => 'edit',
72
+		];
73
+		add_action(
74
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
75
+			[$this, 'verify_event_edit'],
76
+			10,
77
+			2
78
+		);
79
+	}
80
+
81
+
82
+	/**
83
+	 * Sets the ajax hooks used for this admin page group.
84
+	 */
85
+	protected function _ajax_hooks()
86
+	{
87
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'save_timezonestring_setting']);
88
+	}
89
+
90
+
91
+	/**
92
+	 * Sets the page properties for this admin page group.
93
+	 */
94
+	protected function _define_page_props()
95
+	{
96
+		$this->_admin_page_title = EVENTS_LABEL;
97
+		$this->_labels           = [
98
+			'buttons'      => [
99
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
100
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
101
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
102
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
103
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
104
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
105
+			],
106
+			'editor_title' => [
107
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
108
+			],
109
+			'publishbox'   => [
110
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
111
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
112
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
113
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
114
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
115
+			],
116
+		];
117
+	}
118
+
119
+
120
+	/**
121
+	 * Sets the page routes property for this admin page group.
122
+	 */
123
+	protected function _set_page_routes()
124
+	{
125
+		// load formatter helper
126
+		// load field generator helper
127
+		// is there a evt_id in the request?
128
+		$evt_id             = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
129
+			? $this->_req_data['EVT_ID']
130
+			: 0;
131
+		$evt_id             = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
132
+		$this->_page_routes = [
133
+			'default'                       => [
134
+				'func'       => '_events_overview_list_table',
135
+				'capability' => 'ee_read_events',
136
+			],
137
+			'create_new'                    => [
138
+				'func'       => '_create_new_cpt_item',
139
+				'capability' => 'ee_edit_events',
140
+			],
141
+			'edit'                          => [
142
+				'func'       => '_edit_cpt_item',
143
+				'capability' => 'ee_edit_event',
144
+				'obj_id'     => $evt_id,
145
+			],
146
+			'copy_event'                    => [
147
+				'func'       => '_copy_events',
148
+				'capability' => 'ee_edit_event',
149
+				'obj_id'     => $evt_id,
150
+				'noheader'   => true,
151
+			],
152
+			'trash_event'                   => [
153
+				'func'       => '_trash_or_restore_event',
154
+				'args'       => ['event_status' => 'trash'],
155
+				'capability' => 'ee_delete_event',
156
+				'obj_id'     => $evt_id,
157
+				'noheader'   => true,
158
+			],
159
+			'trash_events'                  => [
160
+				'func'       => '_trash_or_restore_events',
161
+				'args'       => ['event_status' => 'trash'],
162
+				'capability' => 'ee_delete_events',
163
+				'noheader'   => true,
164
+			],
165
+			'restore_event'                 => [
166
+				'func'       => '_trash_or_restore_event',
167
+				'args'       => ['event_status' => 'draft'],
168
+				'capability' => 'ee_delete_event',
169
+				'obj_id'     => $evt_id,
170
+				'noheader'   => true,
171
+			],
172
+			'restore_events'                => [
173
+				'func'       => '_trash_or_restore_events',
174
+				'args'       => ['event_status' => 'draft'],
175
+				'capability' => 'ee_delete_events',
176
+				'noheader'   => true,
177
+			],
178
+			'delete_event'                  => [
179
+				'func'       => '_delete_event',
180
+				'capability' => 'ee_delete_event',
181
+				'obj_id'     => $evt_id,
182
+				'noheader'   => true,
183
+			],
184
+			'delete_events'                 => [
185
+				'func'       => '_delete_events',
186
+				'capability' => 'ee_delete_events',
187
+				'noheader'   => true,
188
+			],
189
+			'view_report'                   => [
190
+				'func'       => '_view_report',
191
+				'capability' => 'ee_edit_events',
192
+			],
193
+			'default_event_settings'        => [
194
+				'func'       => '_default_event_settings',
195
+				'capability' => 'manage_options',
196
+			],
197
+			'update_default_event_settings' => [
198
+				'func'       => '_update_default_event_settings',
199
+				'capability' => 'manage_options',
200
+				'noheader'   => true,
201
+			],
202
+			'template_settings'             => [
203
+				'func'       => '_template_settings',
204
+				'capability' => 'manage_options',
205
+			],
206
+			// event category tab related
207
+			'add_category'                  => [
208
+				'func'       => '_category_details',
209
+				'capability' => 'ee_edit_event_category',
210
+				'args'       => ['add'],
211
+			],
212
+			'edit_category'                 => [
213
+				'func'       => '_category_details',
214
+				'capability' => 'ee_edit_event_category',
215
+				'args'       => ['edit'],
216
+			],
217
+			'delete_categories'             => [
218
+				'func'       => '_delete_categories',
219
+				'capability' => 'ee_delete_event_category',
220
+				'noheader'   => true,
221
+			],
222
+			'delete_category'               => [
223
+				'func'       => '_delete_categories',
224
+				'capability' => 'ee_delete_event_category',
225
+				'noheader'   => true,
226
+			],
227
+			'insert_category'               => [
228
+				'func'       => '_insert_or_update_category',
229
+				'args'       => ['new_category' => true],
230
+				'capability' => 'ee_edit_event_category',
231
+				'noheader'   => true,
232
+			],
233
+			'update_category'               => [
234
+				'func'       => '_insert_or_update_category',
235
+				'args'       => ['new_category' => false],
236
+				'capability' => 'ee_edit_event_category',
237
+				'noheader'   => true,
238
+			],
239
+			'category_list'                 => [
240
+				'func'       => '_category_list_table',
241
+				'capability' => 'ee_manage_event_categories',
242
+			],
243
+			'preview_deletion'              => [
244
+				'func'       => 'previewDeletion',
245
+				'capability' => 'ee_delete_events',
246
+			],
247
+			'confirm_deletion'              => [
248
+				'func'       => 'confirmDeletion',
249
+				'capability' => 'ee_delete_events',
250
+				'noheader'   => true,
251
+			],
252
+		];
253
+	}
254
+
255
+
256
+	/**
257
+	 * Set the _page_config property for this admin page group.
258
+	 */
259
+	protected function _set_page_config()
260
+	{
261
+		$this->_page_config = [
262
+			'default'                => [
263
+				'nav'           => [
264
+					'label' => esc_html__('Overview', 'event_espresso'),
265
+					'order' => 10,
266
+				],
267
+				'list_table'    => 'Events_Admin_List_Table',
268
+				'help_tabs'     => [
269
+					'events_overview_help_tab'                       => [
270
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
271
+						'filename' => 'events_overview',
272
+					],
273
+					'events_overview_table_column_headings_help_tab' => [
274
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
275
+						'filename' => 'events_overview_table_column_headings',
276
+					],
277
+					'events_overview_filters_help_tab'               => [
278
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
279
+						'filename' => 'events_overview_filters',
280
+					],
281
+					'events_overview_view_help_tab'                  => [
282
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
283
+						'filename' => 'events_overview_views',
284
+					],
285
+					'events_overview_other_help_tab'                 => [
286
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
287
+						'filename' => 'events_overview_other',
288
+					],
289
+				],
290
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
291
+				// 'help_tour'     => [
292
+				//     'Event_Overview_Help_Tour',
293
+				//     // 'New_Features_Test_Help_Tour' for testing multiple help tour
294
+				// ],
295
+				'require_nonce' => false,
296
+				'qtips'         => ['EE_Event_List_Table_Tips'],
297
+			],
298
+			'create_new'             => [
299
+				'nav'           => [
300
+					'label'      => esc_html__('Add Event', 'event_espresso'),
301
+					'order'      => 5,
302
+					'persistent' => false,
303
+				],
304
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
305
+				'help_tabs'     => [
306
+					'event_editor_help_tab'                            => [
307
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
308
+						'filename' => 'event_editor',
309
+					],
310
+					'event_editor_title_richtexteditor_help_tab'       => [
311
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
312
+						'filename' => 'event_editor_title_richtexteditor',
313
+					],
314
+					'event_editor_venue_details_help_tab'              => [
315
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
316
+						'filename' => 'event_editor_venue_details',
317
+					],
318
+					'event_editor_event_datetimes_help_tab'            => [
319
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
320
+						'filename' => 'event_editor_event_datetimes',
321
+					],
322
+					'event_editor_event_tickets_help_tab'              => [
323
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
324
+						'filename' => 'event_editor_event_tickets',
325
+					],
326
+					'event_editor_event_registration_options_help_tab' => [
327
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
328
+						'filename' => 'event_editor_event_registration_options',
329
+					],
330
+					'event_editor_tags_categories_help_tab'            => [
331
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
332
+						'filename' => 'event_editor_tags_categories',
333
+					],
334
+					'event_editor_questions_registrants_help_tab'      => [
335
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
336
+						'filename' => 'event_editor_questions_registrants',
337
+					],
338
+					'event_editor_save_new_event_help_tab'             => [
339
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
340
+						'filename' => 'event_editor_save_new_event',
341
+					],
342
+					'event_editor_other_help_tab'                      => [
343
+						'title'    => esc_html__('Event Other', 'event_espresso'),
344
+						'filename' => 'event_editor_other',
345
+					],
346
+				],
347
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
348
+				// 'help_tour'     => [
349
+				//     'Event_Editor_Help_Tour',
350
+				// ],
351
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
352
+				'require_nonce' => false,
353
+			],
354
+			'edit'                   => [
355
+				'nav'           => [
356
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
357
+					'order'      => 5,
358
+					'persistent' => false,
359
+					'url'        => isset($this->_req_data['post'])
360
+						? EE_Admin_Page::add_query_args_and_nonce(
361
+							['post' => $this->_req_data['post'], 'action' => 'edit'],
362
+							$this->_current_page_view_url
363
+						)
364
+						: $this->_admin_base_url,
365
+				],
366
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
367
+				'help_tabs'     => [
368
+					'event_editor_help_tab'                            => [
369
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
370
+						'filename' => 'event_editor',
371
+					],
372
+					'event_editor_title_richtexteditor_help_tab'       => [
373
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
374
+						'filename' => 'event_editor_title_richtexteditor',
375
+					],
376
+					'event_editor_venue_details_help_tab'              => [
377
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
378
+						'filename' => 'event_editor_venue_details',
379
+					],
380
+					'event_editor_event_datetimes_help_tab'            => [
381
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
382
+						'filename' => 'event_editor_event_datetimes',
383
+					],
384
+					'event_editor_event_tickets_help_tab'              => [
385
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
386
+						'filename' => 'event_editor_event_tickets',
387
+					],
388
+					'event_editor_event_registration_options_help_tab' => [
389
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
390
+						'filename' => 'event_editor_event_registration_options',
391
+					],
392
+					'event_editor_tags_categories_help_tab'            => [
393
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
394
+						'filename' => 'event_editor_tags_categories',
395
+					],
396
+					'event_editor_questions_registrants_help_tab'      => [
397
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
398
+						'filename' => 'event_editor_questions_registrants',
399
+					],
400
+					'event_editor_save_new_event_help_tab'             => [
401
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
402
+						'filename' => 'event_editor_save_new_event',
403
+					],
404
+					'event_editor_other_help_tab'                      => [
405
+						'title'    => esc_html__('Event Other', 'event_espresso'),
406
+						'filename' => 'event_editor_other',
407
+					],
408
+				],
409
+				'require_nonce' => false,
410
+			],
411
+			'default_event_settings' => [
412
+				'nav'           => [
413
+					'label' => esc_html__('Default Settings', 'event_espresso'),
414
+					'order' => 40,
415
+				],
416
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
417
+				'labels'        => [
418
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
419
+				],
420
+				'help_tabs'     => [
421
+					'default_settings_help_tab'        => [
422
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
423
+						'filename' => 'events_default_settings',
424
+					],
425
+					'default_settings_status_help_tab' => [
426
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
427
+						'filename' => 'events_default_settings_status',
428
+					],
429
+					'default_maximum_tickets_help_tab' => [
430
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
431
+						'filename' => 'events_default_settings_max_tickets',
432
+					],
433
+				],
434
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
435
+				// 'help_tour'     => ['Event_Default_Settings_Help_Tour'],
436
+				'require_nonce' => false,
437
+			],
438
+			// template settings
439
+			'template_settings'      => [
440
+				'nav'           => [
441
+					'label' => esc_html__('Templates', 'event_espresso'),
442
+					'order' => 30,
443
+				],
444
+				'metaboxes'     => $this->_default_espresso_metaboxes,
445
+				'help_tabs'     => [
446
+					'general_settings_templates_help_tab' => [
447
+						'title'    => esc_html__('Templates', 'event_espresso'),
448
+						'filename' => 'general_settings_templates',
449
+					],
450
+				],
451
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
452
+				// 'help_tour'     => ['Templates_Help_Tour'],
453
+				'require_nonce' => false,
454
+			],
455
+			// event category stuff
456
+			'add_category'           => [
457
+				'nav'           => [
458
+					'label'      => esc_html__('Add Category', 'event_espresso'),
459
+					'order'      => 15,
460
+					'persistent' => false,
461
+				],
462
+				'help_tabs'     => [
463
+					'add_category_help_tab' => [
464
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
465
+						'filename' => 'events_add_category',
466
+					],
467
+				],
468
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
469
+				// 'help_tour'     => ['Event_Add_Category_Help_Tour'],
470
+				'metaboxes'     => ['_publish_post_box'],
471
+				'require_nonce' => false,
472
+			],
473
+			'edit_category'          => [
474
+				'nav'           => [
475
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
476
+					'order'      => 15,
477
+					'persistent' => false,
478
+					'url'        => isset($this->_req_data['EVT_CAT_ID'])
479
+						? add_query_arg(
480
+							['EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']],
481
+							$this->_current_page_view_url
482
+						)
483
+						: $this->_admin_base_url,
484
+				],
485
+				'help_tabs'     => [
486
+					'edit_category_help_tab' => [
487
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
488
+						'filename' => 'events_edit_category',
489
+					],
490
+				],
491
+				/*'help_tour' => ['Event_Edit_Category_Help_Tour'],*/
492
+				'metaboxes'     => ['_publish_post_box'],
493
+				'require_nonce' => false,
494
+			],
495
+			'category_list'          => [
496
+				'nav'           => [
497
+					'label' => esc_html__('Categories', 'event_espresso'),
498
+					'order' => 20,
499
+				],
500
+				'list_table'    => 'Event_Categories_Admin_List_Table',
501
+				'help_tabs'     => [
502
+					'events_categories_help_tab'                       => [
503
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
504
+						'filename' => 'events_categories',
505
+					],
506
+					'events_categories_table_column_headings_help_tab' => [
507
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
508
+						'filename' => 'events_categories_table_column_headings',
509
+					],
510
+					'events_categories_view_help_tab'                  => [
511
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
512
+						'filename' => 'events_categories_views',
513
+					],
514
+					'events_categories_other_help_tab'                 => [
515
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
516
+						'filename' => 'events_categories_other',
517
+					],
518
+				],
519
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
520
+				// 'help_tour'     => [
521
+				//     'Event_Categories_Help_Tour',
522
+				// ],
523
+				'metaboxes'     => $this->_default_espresso_metaboxes,
524
+				'require_nonce' => false,
525
+			],
526
+			'preview_deletion'       => [
527
+				'nav'           => [
528
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
529
+					'order'      => 15,
530
+					'persistent' => false,
531
+					'url'        => '',
532
+				],
533
+				'require_nonce' => false,
534
+			],
535
+		];
536
+		// only load EE_Event_Editor_Decaf_Tips if domain is not caffeinated
537
+		$domain = $this->loader->getShared('EventEspresso\core\domain\Domain');
538
+		if (! $domain->isCaffeinated()) {
539
+			$this->_page_config['create_new']['qtips'] = ['EE_Event_Editor_Decaf_Tips'];
540
+			$this->_page_config['edit']['qtips']       = ['EE_Event_Editor_Decaf_Tips'];
541
+		}
542
+	}
543
+
544
+
545
+	/**
546
+	 * Used to register any global screen options if necessary for every route in this admin page group.
547
+	 */
548
+	protected function _add_screen_options()
549
+	{
550
+	}
551
+
552
+
553
+	/**
554
+	 * Implementing the screen options for the 'default' route.
555
+	 *
556
+	 * @throws InvalidArgumentException
557
+	 * @throws InvalidDataTypeException
558
+	 * @throws InvalidInterfaceException
559
+	 */
560
+	protected function _add_screen_options_default()
561
+	{
562
+		$this->_per_page_screen_option();
563
+	}
564
+
565
+
566
+	/**
567
+	 * Implementing screen options for the category list route.
568
+	 *
569
+	 * @throws InvalidArgumentException
570
+	 * @throws InvalidDataTypeException
571
+	 * @throws InvalidInterfaceException
572
+	 */
573
+	protected function _add_screen_options_category_list()
574
+	{
575
+		$page_title              = $this->_admin_page_title;
576
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
577
+		$this->_per_page_screen_option();
578
+		$this->_admin_page_title = $page_title;
579
+	}
580
+
581
+
582
+	/**
583
+	 * Used to register any global feature pointers for the admin page group.
584
+	 */
585
+	protected function _add_feature_pointers()
586
+	{
587
+	}
588
+
589
+
590
+	/**
591
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
592
+	 */
593
+	public function load_scripts_styles()
594
+	{
595
+		wp_register_style(
596
+			'events-admin-css',
597
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
598
+			[],
599
+			EVENT_ESPRESSO_VERSION
600
+		);
601
+		wp_register_style(
602
+			'ee-cat-admin',
603
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
604
+			[],
605
+			EVENT_ESPRESSO_VERSION
606
+		);
607
+		wp_enqueue_style('events-admin-css');
608
+		wp_enqueue_style('ee-cat-admin');
609
+		// scripts
610
+		wp_register_script(
611
+			'event_editor_js',
612
+			EVENTS_ASSETS_URL . 'event_editor.js',
613
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
614
+			EVENT_ESPRESSO_VERSION,
615
+			true
616
+		);
617
+	}
618
+
619
+
620
+	/**
621
+	 * Enqueuing scripts and styles specific to this view
622
+	 */
623
+	public function load_scripts_styles_create_new()
624
+	{
625
+		$this->load_scripts_styles_edit();
626
+	}
627
+
628
+
629
+	/**
630
+	 * Enqueuing scripts and styles specific to this view
631
+	 */
632
+	public function load_scripts_styles_edit()
633
+	{
634
+		// styles
635
+		wp_enqueue_style('espresso-ui-theme');
636
+		wp_register_style(
637
+			'event-editor-css',
638
+			EVENTS_ASSETS_URL . 'event-editor.css',
639
+			['ee-admin-css'],
640
+			EVENT_ESPRESSO_VERSION
641
+		);
642
+		wp_enqueue_style('event-editor-css');
643
+		// scripts
644
+		if (! $this->admin_config->useAdvancedEditor()) {
645
+			wp_register_script(
646
+				'event-datetime-metabox',
647
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
648
+				['event_editor_js', 'ee-datepicker'],
649
+				EVENT_ESPRESSO_VERSION
650
+			);
651
+			wp_enqueue_script('event-datetime-metabox');
652
+		}
653
+	}
654
+
655
+
656
+	/**
657
+	 * Populating the _views property for the category list table view.
658
+	 */
659
+	protected function _set_list_table_views_category_list()
660
+	{
661
+		$this->_views = [
662
+			'all' => [
663
+				'slug'        => 'all',
664
+				'label'       => esc_html__('All', 'event_espresso'),
665
+				'count'       => 0,
666
+				'bulk_action' => [
667
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
668
+				],
669
+			],
670
+		];
671
+	}
672
+
673
+
674
+	/**
675
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
676
+	 */
677
+	public function admin_init()
678
+	{
679
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
680
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
681
+			'event_espresso'
682
+		);
683
+	}
684
+
685
+
686
+	/**
687
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
688
+	 * group.
689
+	 */
690
+	public function admin_notices()
691
+	{
692
+	}
693
+
694
+
695
+	/**
696
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
697
+	 * this admin page group.
698
+	 */
699
+	public function admin_footer_scripts()
700
+	{
701
+	}
702
+
703
+
704
+	/**
705
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
706
+	 * warning (via EE_Error::add_error());
707
+	 *
708
+	 * @param EE_Event $event Event object
709
+	 * @param string   $req_type
710
+	 * @return void
711
+	 * @throws EE_Error
712
+	 * @access public
713
+	 */
714
+	public function verify_event_edit($event = null, $req_type = '')
715
+	{
716
+		// don't need to do this when processing
717
+		if (! empty($req_type)) {
718
+			return;
719
+		}
720
+		// no event?
721
+		if (! $event instanceof EE_Event) {
722
+			$event = $this->_cpt_model_obj;
723
+		}
724
+		// STILL no event?
725
+		if (! $event instanceof EE_Event) {
726
+			return;
727
+		}
728
+		$orig_status = $event->status();
729
+		// first check if event is active.
730
+		if (
731
+			$orig_status === EEM_Event::cancelled
732
+			|| $orig_status === EEM_Event::postponed
733
+			|| $event->is_expired()
734
+			|| $event->is_inactive()
735
+		) {
736
+			return;
737
+		}
738
+		// made it here so it IS active... next check that any of the tickets are sold.
739
+		if ($event->is_sold_out(true)) {
740
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
741
+				EE_Error::add_attention(
742
+					sprintf(
743
+						esc_html__(
744
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
745
+							'event_espresso'
746
+						),
747
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
748
+					)
749
+				);
750
+			}
751
+			return;
752
+		}
753
+		if ($orig_status === EEM_Event::sold_out) {
754
+			EE_Error::add_attention(
755
+				sprintf(
756
+					esc_html__(
757
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
758
+						'event_espresso'
759
+					),
760
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
761
+				)
762
+			);
763
+		}
764
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
765
+		if (! $event->tickets_on_sale()) {
766
+			return;
767
+		}
768
+		// made it here so show warning
769
+		$this->_edit_event_warning();
770
+	}
771
+
772
+
773
+	/**
774
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
775
+	 * When needed, hook this into a EE_Error::add_error() notice.
776
+	 *
777
+	 * @access protected
778
+	 * @return void
779
+	 */
780
+	protected function _edit_event_warning()
781
+	{
782
+		// we don't want to add warnings during these requests
783
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
784
+			return;
785
+		}
786
+		EE_Error::add_attention(
787
+			sprintf(
788
+				esc_html__(
789
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
790
+					'event_espresso'
791
+				),
792
+				'<a class="espresso-help-tab-lnk">',
793
+				'</a>'
794
+			)
795
+		);
796
+	}
797
+
798
+
799
+	/**
800
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
801
+	 * Otherwise, do the normal logic
802
+	 *
803
+	 * @return void
804
+	 * @throws EE_Error
805
+	 * @throws InvalidArgumentException
806
+	 * @throws InvalidDataTypeException
807
+	 * @throws InvalidInterfaceException
808
+	 */
809
+	protected function _create_new_cpt_item()
810
+	{
811
+		$has_timezone_string = get_option('timezone_string');
812
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
813
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
814
+			EE_Error::add_attention(
815
+				sprintf(
816
+					__(
817
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
818
+						'event_espresso'
819
+					),
820
+					'<br>',
821
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
822
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
823
+					. '</select>',
824
+					'<button class="button button-secondary timezone-submit">',
825
+					'</button><span class="spinner"></span>'
826
+				),
827
+				__FILE__,
828
+				__FUNCTION__,
829
+				__LINE__
830
+			);
831
+		}
832
+		parent::_create_new_cpt_item();
833
+	}
834
+
835
+
836
+	/**
837
+	 * Sets the _views property for the default route in this admin page group.
838
+	 */
839
+	protected function _set_list_table_views_default()
840
+	{
841
+		$this->_views = [
842
+			'all'   => [
843
+				'slug'        => 'all',
844
+				'label'       => esc_html__('View All Events', 'event_espresso'),
845
+				'count'       => 0,
846
+				'bulk_action' => [
847
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
848
+				],
849
+			],
850
+			'draft' => [
851
+				'slug'        => 'draft',
852
+				'label'       => esc_html__('Draft', 'event_espresso'),
853
+				'count'       => 0,
854
+				'bulk_action' => [
855
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
856
+				],
857
+			],
858
+		];
859
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
860
+			$this->_views['trash'] = [
861
+				'slug'        => 'trash',
862
+				'label'       => esc_html__('Trash', 'event_espresso'),
863
+				'count'       => 0,
864
+				'bulk_action' => [
865
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
866
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
867
+				],
868
+			];
869
+		}
870
+	}
871
+
872
+
873
+	/**
874
+	 * Provides the legend item array for the default list table view.
875
+	 *
876
+	 * @return array
877
+	 */
878
+	protected function _event_legend_items()
879
+	{
880
+		$items    = [
881
+			'view_details'   => [
882
+				'class' => 'dashicons dashicons-search',
883
+				'desc'  => esc_html__('View Event', 'event_espresso'),
884
+			],
885
+			'edit_event'     => [
886
+				'class' => 'ee-icon ee-icon-calendar-edit',
887
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
888
+			],
889
+			'view_attendees' => [
890
+				'class' => 'dashicons dashicons-groups',
891
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
892
+			],
893
+		];
894
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
895
+		$statuses = [
896
+			'sold_out_status'  => [
897
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
898
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
899
+			],
900
+			'active_status'    => [
901
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
902
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
903
+			],
904
+			'upcoming_status'  => [
905
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
906
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
907
+			],
908
+			'postponed_status' => [
909
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
910
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
911
+			],
912
+			'cancelled_status' => [
913
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
914
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
915
+			],
916
+			'expired_status'   => [
917
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
918
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
919
+			],
920
+			'inactive_status'  => [
921
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
922
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
923
+			],
924
+		];
925
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
926
+		return array_merge($items, $statuses);
927
+	}
928
+
929
+
930
+	/**
931
+	 * @return EEM_Event
932
+	 * @throws EE_Error
933
+	 * @throws InvalidArgumentException
934
+	 * @throws InvalidDataTypeException
935
+	 * @throws InvalidInterfaceException
936
+	 * @throws ReflectionException
937
+	 */
938
+	private function _event_model()
939
+	{
940
+		if (! $this->_event_model instanceof EEM_Event) {
941
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
942
+		}
943
+		return $this->_event_model;
944
+	}
945
+
946
+
947
+	/**
948
+	 * Adds extra buttons to the WP CPT permalink field row.
949
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
950
+	 *
951
+	 * @param string $return    the current html
952
+	 * @param int    $id        the post id for the page
953
+	 * @param string $new_title What the title is
954
+	 * @param string $new_slug  what the slug is
955
+	 * @return string            The new html string for the permalink area
956
+	 */
957
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
958
+	{
959
+		// make sure this is only when editing
960
+		if (! empty($id)) {
961
+			$post   = get_post($id);
962
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
963
+					   . esc_html__('Shortcode', 'event_espresso')
964
+					   . '</a> ';
965
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
966
+					   . $post->ID
967
+					   . ']">';
968
+		}
969
+		return $return;
970
+	}
971
+
972
+
973
+	/**
974
+	 * _events_overview_list_table
975
+	 * This contains the logic for showing the events_overview list
976
+	 *
977
+	 * @access protected
978
+	 * @return void
979
+	 * @throws DomainException
980
+	 * @throws EE_Error
981
+	 * @throws InvalidArgumentException
982
+	 * @throws InvalidDataTypeException
983
+	 * @throws InvalidInterfaceException
984
+	 */
985
+	protected function _events_overview_list_table()
986
+	{
987
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
988
+		$this->_template_args['after_list_table']                           =
989
+			! empty($this->_template_args['after_list_table'])
990
+				? (array) $this->_template_args['after_list_table']
991
+				: [];
992
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
993
+			. EEH_Template::get_button_or_link(
994
+				get_post_type_archive_link('espresso_events'),
995
+				esc_html__('View Event Archive Page', 'event_espresso'),
996
+				'button'
997
+			);
998
+		$this->_template_args['after_list_table']['legend']                 =
999
+			$this->_display_legend($this->_event_legend_items());
1000
+		$this->_admin_page_title                                            .= ' '
1001
+			. $this->get_action_link_or_button(
1002
+				'create_new',
1003
+				'add',
1004
+				[],
1005
+				'add-new-h2'
1006
+			);
1007
+		$this->display_admin_list_table_page_with_no_sidebar();
1008
+	}
1009
+
1010
+
1011
+	/**
1012
+	 * this allows for extra misc actions in the default WP publish box
1013
+	 *
1014
+	 * @return void
1015
+	 * @throws DomainException
1016
+	 * @throws EE_Error
1017
+	 * @throws InvalidArgumentException
1018
+	 * @throws InvalidDataTypeException
1019
+	 * @throws InvalidInterfaceException
1020
+	 * @throws ReflectionException
1021
+	 */
1022
+	public function extra_misc_actions_publish_box()
1023
+	{
1024
+		$this->_generate_publish_box_extra_content();
1025
+	}
1026
+
1027
+
1028
+	/**
1029
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1030
+	 * saved.
1031
+	 * Typically you would use this to save any additional data.
1032
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1033
+	 * ALSO very important.  When a post transitions from scheduled to published,
1034
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1035
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1036
+	 *
1037
+	 * @access protected
1038
+	 * @abstract
1039
+	 * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1040
+	 * @param object $post    The post object of the cpt that was saved.
1041
+	 * @return void
1042
+	 * @throws EE_Error
1043
+	 * @throws InvalidArgumentException
1044
+	 * @throws InvalidDataTypeException
1045
+	 * @throws InvalidInterfaceException
1046
+	 * @throws ReflectionException
1047
+	 */
1048
+	protected function _insert_update_cpt_item($post_id, $post)
1049
+	{
1050
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1051
+			// get out we're not processing an event save.
1052
+			return;
1053
+		}
1054
+		$event_values = [
1055
+			'EVT_member_only'     => ! empty($this->_req_data['member_only']) ? 1 : 0,
1056
+			'EVT_allow_overflow'  => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
1057
+			'EVT_timezone_string' => ! empty($this->_req_data['timezone_string'])
1058
+				? sanitize_text_field($this->_req_data['timezone_string'])
1059
+				: null,
1060
+		];
1061
+		/** @var FeatureFlags $flags */
1062
+		$flags = $this->loader->getShared('EventEspresso\core\domain\services\capabilities\FeatureFlags');
1063
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1064
+		if (! $this->admin_config->useAdvancedEditor() || ! $flags->featureAllowed('use_reg_options_meta_box')) {
1065
+			$event_values['EVT_display_ticket_selector']     =
1066
+				! empty($this->_req_data['display_ticket_selector'])
1067
+					? 1
1068
+					: 0;
1069
+			$event_values['EVT_additional_limit']            = min(
1070
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1071
+				! empty($this->_req_data['additional_limit'])
1072
+					? absint($this->_req_data['additional_limit'])
1073
+					: null
1074
+			);
1075
+			$event_values['EVT_default_registration_status'] =
1076
+				! empty($this->_req_data['EVT_default_registration_status'])
1077
+					? sanitize_text_field($this->_req_data['EVT_default_registration_status'])
1078
+					: EE_Registry::instance()->CFG->registration->default_STS_ID;
1079
+			$event_values['EVT_external_URL']                = ! empty($this->_req_data['externalURL'])
1080
+				? esc_url_raw($this->_req_data['externalURL'])
1081
+				: null;
1082
+			$event_values['EVT_phone']                       = ! empty($this->_req_data['event_phone'])
1083
+				? sanitize_text_field($this->_req_data['event_phone'])
1084
+				: null;
1085
+		}
1086
+		// update event
1087
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1088
+		// get event_object for other metaboxes...
1089
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1090
+		// i have to setup where conditions to override the filters in the model that filter out autodraft
1091
+		// and inherit statuses so we GET the inherit id!
1092
+		$get_one_where = [
1093
+			$this->_event_model()->primary_key_name() => $post_id,
1094
+			'OR'                                      => [
1095
+				'status'   => $post->post_status,
1096
+				// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1097
+				// but the returned object here has a status of "publish", so use the original post status as well
1098
+				'status*1' => $this->_req_data['original_post_status'],
1099
+			],
1100
+		];
1101
+		$event         = $this->_event_model()->get_one([$get_one_where]);
1102
+		// the following are default callbacks for event attachment updates
1103
+		// that can be overridden by caffeinated functionality and/or addons.
1104
+		$event_update_callbacks = apply_filters(
1105
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1106
+			[
1107
+				[$this, '_default_venue_update'],
1108
+				[$this, '_default_tickets_update'],
1109
+			]
1110
+		);
1111
+		$att_success            = true;
1112
+		foreach ($event_update_callbacks as $e_callback) {
1113
+			$_success = is_callable($e_callback)
1114
+				? $e_callback($event, $this->_req_data)
1115
+				: false;
1116
+			// if ANY of these updates fail then we want the appropriate global error message
1117
+			$att_success = ! $att_success ? $att_success : $_success;
1118
+		}
1119
+		// any errors?
1120
+		if ($success && false === $att_success) {
1121
+			EE_Error::add_error(
1122
+				esc_html__(
1123
+					'Event Details saved successfully but something went wrong with saving attachments.',
1124
+					'event_espresso'
1125
+				),
1126
+				__FILE__,
1127
+				__FUNCTION__,
1128
+				__LINE__
1129
+			);
1130
+		} elseif ($success === false) {
1131
+			EE_Error::add_error(
1132
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1133
+				__FILE__,
1134
+				__FUNCTION__,
1135
+				__LINE__
1136
+			);
1137
+		}
1138
+	}
1139
+
1140
+
1141
+	/**
1142
+	 * @param int $post_id
1143
+	 * @param int $revision_id
1144
+	 * @throws EE_Error
1145
+	 * @throws InvalidArgumentException
1146
+	 * @throws InvalidDataTypeException
1147
+	 * @throws InvalidInterfaceException
1148
+	 * @throws ReflectionException
1149
+	 * @see parent::restore_item()
1150
+	 */
1151
+	protected function _restore_cpt_item($post_id, $revision_id)
1152
+	{
1153
+		// copy existing event meta to new post
1154
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1155
+		if ($post_evt instanceof EE_Event) {
1156
+			// meta revision restore
1157
+			$post_evt->restore_revision($revision_id);
1158
+			// related objs restore
1159
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1160
+		}
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * Attach the venue to the Event
1166
+	 *
1167
+	 * @param EE_Event $evtobj Event Object to add the venue to
1168
+	 * @param array    $data   The request data from the form
1169
+	 * @return bool           Success or fail.
1170
+	 * @throws EE_Error
1171
+	 * @throws InvalidArgumentException
1172
+	 * @throws InvalidDataTypeException
1173
+	 * @throws InvalidInterfaceException
1174
+	 * @throws ReflectionException
1175
+	 */
1176
+	protected function _default_venue_update(EE_Event $evtobj, $data)
1177
+	{
1178
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1179
+		$venue_model   = EE_Registry::instance()->load_model('Venue');
1180
+		$rows_affected = null;
1181
+		$venue_id      = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1182
+		// very important.  If we don't have a venue name...
1183
+		// then we'll get out because not necessary to create empty venue
1184
+		if (empty($data['venue_title'])) {
1185
+			return false;
1186
+		}
1187
+		$venue_array = [
1188
+			'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1189
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1190
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1191
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1192
+			'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1193
+				: null,
1194
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1195
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1196
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1197
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1198
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1199
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1200
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1201
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1202
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1203
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1204
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1205
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1206
+			'status'              => 'publish',
1207
+		];
1208
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1209
+		if (! empty($venue_id)) {
1210
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1211
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1212
+			// we've gotta make sure that the venue is always attached to a revision..
1213
+			// add_relation_to should take care of making sure that the relation is already present.
1214
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1215
+			return $rows_affected > 0;
1216
+		}
1217
+		// we insert the venue
1218
+		$venue_id = $venue_model->insert($venue_array);
1219
+		$evtobj->_add_relation_to($venue_id, 'Venue');
1220
+		return ! empty($venue_id);
1221
+		// when we have the ancestor come in it's already been handled by the revision save.
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1227
+	 *
1228
+	 * @param EE_Event $evtobj The Event object we're attaching data to
1229
+	 * @param array    $data   The request data from the form
1230
+	 * @return array
1231
+	 * @throws EE_Error
1232
+	 * @throws InvalidArgumentException
1233
+	 * @throws InvalidDataTypeException
1234
+	 * @throws InvalidInterfaceException
1235
+	 * @throws ReflectionException
1236
+	 * @throws Exception
1237
+	 */
1238
+	protected function _default_tickets_update(EE_Event $evtobj, $data)
1239
+	{
1240
+		if ($this->admin_config->useAdvancedEditor()) {
1241
+			return [];
1242
+		}
1243
+		$success               = true;
1244
+		$saved_dtt             = null;
1245
+		$saved_tickets         = [];
1246
+		$incoming_date_formats = ['Y-m-d', 'h:i a'];
1247
+		foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1248
+			// trim all values to ensure any excess whitespace is removed.
1249
+			$dtt                = array_map('trim', $dtt);
1250
+			$dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1251
+				: $dtt['DTT_EVT_start'];
1252
+			$datetime_values    = [
1253
+				'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1254
+				'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1255
+				'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1256
+				'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1257
+				'DTT_order'     => $row,
1258
+			];
1259
+			// if we have an id then let's get existing object first and then set the new values.
1260
+			//  Otherwise we instantiate a new object for save.
1261
+			if (! empty($dtt['DTT_ID'])) {
1262
+				$DTM = EE_Registry::instance()
1263
+								  ->load_model('Datetime', [$evtobj->get_timezone()])
1264
+								  ->get_one_by_ID($dtt['DTT_ID']);
1265
+				$DTM->set_date_format($incoming_date_formats[0]);
1266
+				$DTM->set_time_format($incoming_date_formats[1]);
1267
+				foreach ($datetime_values as $field => $value) {
1268
+					$DTM->set($field, $value);
1269
+				}
1270
+				// make sure the $dtt_id here is saved in case after the add_relation_to() the autosave replaces it.
1271
+				// We need to do this so we dont' TRASH the parent DTT.
1272
+				$saved_dtts[ $DTM->ID() ] = $DTM;
1273
+			} else {
1274
+				$DTM = EE_Registry::instance()->load_class(
1275
+					'Datetime',
1276
+					[$datetime_values, $evtobj->get_timezone(), $incoming_date_formats],
1277
+					false,
1278
+					false
1279
+				);
1280
+				foreach ($datetime_values as $field => $value) {
1281
+					$DTM->set($field, $value);
1282
+				}
1283
+			}
1284
+			$DTM->save();
1285
+			$DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1286
+			// load DTT helper
1287
+			// before going any further make sure our dates are setup correctly
1288
+			// so that the end date is always equal or greater than the start date.
1289
+			if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1290
+				$DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1291
+				$DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1292
+				$DTT->save();
1293
+			}
1294
+			// now we got to make sure we add the new DTT_ID to the $saved_dtts array
1295
+			//  because it is possible there was a new one created for the autosave.
1296
+			$saved_dtt = $DTT;
1297
+			$success   = ! $success ? $success : $DTT;
1298
+			// if ANY of these updates fail then we want the appropriate global error message.
1299
+			// //todo this is actually sucky we need a better error message but this is what it is for now.
1300
+		}
1301
+		// no dtts get deleted so we don't do any of that logic here.
1302
+		// update tickets next
1303
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1304
+		foreach ($data['edit_tickets'] as $row => $tkt) {
1305
+			$incoming_date_formats = ['Y-m-d', 'h:i a'];
1306
+			$update_prices         = false;
1307
+			$ticket_price          = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1308
+				? $data['edit_prices'][ $row ][1]['PRC_amount']
1309
+				: 0;
1310
+			// trim inputs to ensure any excess whitespace is removed.
1311
+			$tkt = array_map('trim', $tkt);
1312
+			if (empty($tkt['TKT_start_date'])) {
1313
+				// let's use now in the set timezone.
1314
+				$now                   = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1315
+				$tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1316
+			}
1317
+			if (empty($tkt['TKT_end_date'])) {
1318
+				// use the start date of the first datetime
1319
+				$dtt                 = $evtobj->first_datetime();
1320
+				$tkt['TKT_end_date'] = $dtt->start_date_and_time(
1321
+					$incoming_date_formats[0],
1322
+					$incoming_date_formats[1]
1323
+				);
1324
+			}
1325
+			$TKT_values = [
1326
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1327
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1328
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1329
+				'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1330
+				'TKT_start_date'  => $tkt['TKT_start_date'],
1331
+				'TKT_end_date'    => $tkt['TKT_end_date'],
1332
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1333
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1334
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1335
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1336
+				'TKT_row'         => $row,
1337
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1338
+				'TKT_price'       => $ticket_price,
1339
+			];
1340
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
1341
+			// which means in turn that the prices will become new prices as well.
1342
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1343
+				$TKT_values['TKT_ID']         = 0;
1344
+				$TKT_values['TKT_is_default'] = 0;
1345
+				$TKT_values['TKT_price']      = $ticket_price;
1346
+				$update_prices                = true;
1347
+			}
1348
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1349
+			// we actually do our saves a head of doing any add_relations to because its entirely possible
1350
+			// that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
1351
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
1352
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1353
+			if (! empty($tkt['TKT_ID'])) {
1354
+				$TKT = EE_Registry::instance()
1355
+								  ->load_model('Ticket', [$evtobj->get_timezone()])
1356
+								  ->get_one_by_ID($tkt['TKT_ID']);
1357
+				if ($TKT instanceof EE_Ticket) {
1358
+					$ticket_sold = $TKT->count_related(
1359
+						'Registration',
1360
+						[
1361
+							[
1362
+								'STS_ID' => [
1363
+									'NOT IN',
1364
+									[EEM_Registration::status_id_incomplete],
1365
+								],
1366
+							],
1367
+						]
1368
+					) > 0;
1369
+					// let's just check the total price for the existing ticket and determine if it matches the new
1370
+					// total price.  if they are different then we create a new ticket (if tickets sold)
1371
+					// if they aren't different then we go ahead and modify existing ticket.
1372
+					$create_new_TKT = $ticket_sold
1373
+									  && ! $TKT->deleted()
1374
+									  && EEH_Money::compare_floats(
1375
+										  $ticket_price,
1376
+										  $TKT->get('TKT_price'),
1377
+										  '!=='
1378
+									  );
1379
+					$TKT->set_date_format($incoming_date_formats[0]);
1380
+					$TKT->set_time_format($incoming_date_formats[1]);
1381
+					// set new values
1382
+					foreach ($TKT_values as $field => $value) {
1383
+						if ($field === 'TKT_qty') {
1384
+							$TKT->set_qty($value);
1385
+						} else {
1386
+							$TKT->set($field, $value);
1387
+						}
1388
+					}
1389
+					// if $create_new_TKT is false then we can safely update the existing ticket.
1390
+					//  Otherwise we have to create a new ticket.
1391
+					if ($create_new_TKT) {
1392
+						// archive the old ticket first
1393
+						$TKT->set('TKT_deleted', 1);
1394
+						$TKT->save();
1395
+						// make sure this ticket is still recorded in our saved_tkts
1396
+						// so we don't run it through the regular trash routine.
1397
+						$saved_tickets[ $TKT->ID() ] = $TKT;
1398
+						// create new ticket that's a copy of the existing except a new id of course
1399
+						// (and not archived) AND has the new TKT_price associated with it.
1400
+						$TKT = clone $TKT;
1401
+						$TKT->set('TKT_ID', 0);
1402
+						$TKT->set('TKT_deleted', 0);
1403
+						$TKT->set('TKT_price', $ticket_price);
1404
+						$TKT->set('TKT_sold', 0);
1405
+						// now we need to make sure that $new prices are created as well and attached to new ticket.
1406
+						$update_prices = true;
1407
+					}
1408
+					// make sure price is set if it hasn't been already
1409
+					$TKT->set('TKT_price', $ticket_price);
1410
+				}
1411
+			} else {
1412
+				// no TKT_id so a new TKT
1413
+				$TKT_values['TKT_price'] = $ticket_price;
1414
+				$TKT                     = EE_Registry::instance()->load_class('Ticket', [$TKT_values], false, false);
1415
+				if ($TKT instanceof EE_Ticket) {
1416
+					// need to reset values to properly account for the date formats
1417
+					$TKT->set_date_format($incoming_date_formats[0]);
1418
+					$TKT->set_time_format($incoming_date_formats[1]);
1419
+					$TKT->set_timezone($evtobj->get_timezone());
1420
+					// set new values
1421
+					foreach ($TKT_values as $field => $value) {
1422
+						if ($field === 'TKT_qty') {
1423
+							$TKT->set_qty($value);
1424
+						} else {
1425
+							$TKT->set($field, $value);
1426
+						}
1427
+					}
1428
+					$update_prices = true;
1429
+				}
1430
+			}
1431
+			// cap ticket qty by datetime reg limits
1432
+			$TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1433
+			// update ticket.
1434
+			$TKT->save();
1435
+			// before going any further make sure our dates are setup correctly
1436
+			// so that the end date is always equal or greater than the start date.
1437
+			if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1438
+				$TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1439
+				$TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1440
+				$TKT->save();
1441
+			}
1442
+			// initially let's add the ticket to the dtt
1443
+			$saved_dtt->_add_relation_to($TKT, 'Ticket');
1444
+			$saved_tickets[ $TKT->ID() ] = $TKT;
1445
+			// add prices to ticket
1446
+			$this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1447
+		}
1448
+		// however now we need to handle permanently deleting tickets via the ui.
1449
+		//  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1450
+		//  However, it does allow for deleting tickets that have no tickets sold,
1451
+		// in which case we want to get rid of permanently because there is no need to save in db.
1452
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1453
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1454
+		foreach ($tickets_removed as $id) {
1455
+			$id = absint($id);
1456
+			// get the ticket for this id
1457
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1458
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1459
+			// (remember this process can ONLY kick off if there are NO tkts_sold)
1460
+			$dtts = $tkt_to_remove->get_many_related('Datetime');
1461
+			foreach ($dtts as $dtt) {
1462
+				$tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1463
+			}
1464
+			// need to do the same for prices (except these prices can also be deleted because again,
1465
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1466
+			$tkt_to_remove->delete_related_permanently('Price');
1467
+			// finally let's delete this ticket
1468
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1469
+			$tkt_to_remove->delete_permanently();
1470
+		}
1471
+		return [$saved_dtt, $saved_tickets];
1472
+	}
1473
+
1474
+
1475
+	/**
1476
+	 * This attaches a list of given prices to a ticket.
1477
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1478
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1479
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1480
+	 *
1481
+	 * @access  private
1482
+	 * @param array     $prices     Array of prices from the form.
1483
+	 * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1484
+	 * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1485
+	 * @return  void
1486
+	 * @throws EE_Error
1487
+	 * @throws InvalidArgumentException
1488
+	 * @throws InvalidDataTypeException
1489
+	 * @throws InvalidInterfaceException
1490
+	 * @throws ReflectionException
1491
+	 */
1492
+	private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1493
+	{
1494
+		foreach ($prices as $row => $prc) {
1495
+			$PRC_values = [
1496
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1497
+				'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1498
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1499
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1500
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1501
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1502
+				'PRC_order'      => $row,
1503
+			];
1504
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
1505
+				$PRC_values['PRC_ID'] = 0;
1506
+				$PRC                  = EE_Registry::instance()->load_class('Price', [$PRC_values], false, false);
1507
+			} else {
1508
+				$PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1509
+				// update this price with new values
1510
+				foreach ($PRC_values as $field => $newprc) {
1511
+					$PRC->set($field, $newprc);
1512
+				}
1513
+				$PRC->save();
1514
+			}
1515
+			$ticket->_add_relation_to($PRC, 'Price');
1516
+		}
1517
+	}
1518
+
1519
+
1520
+	/**
1521
+	 * Add in our autosave ajax handlers
1522
+	 *
1523
+	 */
1524
+	protected function _ee_autosave_create_new()
1525
+	{
1526
+	}
1527
+
1528
+
1529
+	/**
1530
+	 * More autosave handlers.
1531
+	 */
1532
+	protected function _ee_autosave_edit()
1533
+	{
1534
+	}
1535
+
1536
+
1537
+	/**
1538
+	 *    _generate_publish_box_extra_content
1539
+	 *
1540
+	 * @throws DomainException
1541
+	 * @throws EE_Error
1542
+	 * @throws InvalidArgumentException
1543
+	 * @throws InvalidDataTypeException
1544
+	 * @throws InvalidInterfaceException
1545
+	 * @throws ReflectionException
1546
+	 */
1547
+	private function _generate_publish_box_extra_content()
1548
+	{
1549
+		// load formatter helper
1550
+		// args for getting related registrations
1551
+		$approved_query_args        = [
1552
+			[
1553
+				'REG_deleted' => 0,
1554
+				'STS_ID'      => EEM_Registration::status_id_approved,
1555
+			],
1556
+		];
1557
+		$not_approved_query_args    = [
1558
+			[
1559
+				'REG_deleted' => 0,
1560
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1561
+			],
1562
+		];
1563
+		$pending_payment_query_args = [
1564
+			[
1565
+				'REG_deleted' => 0,
1566
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1567
+			],
1568
+		];
1569
+		// publish box
1570
+		$publish_box_extra_args = [
1571
+			'view_approved_reg_url'        => add_query_arg(
1572
+				[
1573
+					'action'      => 'default',
1574
+					'event_id'    => $this->_cpt_model_obj->ID(),
1575
+					'_reg_status' => EEM_Registration::status_id_approved,
1576
+				],
1577
+				REG_ADMIN_URL
1578
+			),
1579
+			'view_not_approved_reg_url'    => add_query_arg(
1580
+				[
1581
+					'action'      => 'default',
1582
+					'event_id'    => $this->_cpt_model_obj->ID(),
1583
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1584
+				],
1585
+				REG_ADMIN_URL
1586
+			),
1587
+			'view_pending_payment_reg_url' => add_query_arg(
1588
+				[
1589
+					'action'      => 'default',
1590
+					'event_id'    => $this->_cpt_model_obj->ID(),
1591
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1592
+				],
1593
+				REG_ADMIN_URL
1594
+			),
1595
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1596
+				'Registration',
1597
+				$approved_query_args
1598
+			),
1599
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1600
+				'Registration',
1601
+				$not_approved_query_args
1602
+			),
1603
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1604
+				'Registration',
1605
+				$pending_payment_query_args
1606
+			),
1607
+			'misc_pub_section_class'       => apply_filters(
1608
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1609
+				'misc-pub-section'
1610
+			),
1611
+		];
1612
+		ob_start();
1613
+		do_action(
1614
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1615
+			$this->_cpt_model_obj
1616
+		);
1617
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1618
+		// load template
1619
+		EEH_Template::display_template(
1620
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1621
+			$publish_box_extra_args
1622
+		);
1623
+	}
1624
+
1625
+
1626
+	/**
1627
+	 * @return EE_Event
1628
+	 */
1629
+	public function get_event_object()
1630
+	{
1631
+		return $this->_cpt_model_obj;
1632
+	}
1633
+
1634
+
1635
+
1636
+
1637
+	/** METABOXES * */
1638
+	/**
1639
+	 * _register_event_editor_meta_boxes
1640
+	 * add all metaboxes related to the event_editor
1641
+	 *
1642
+	 * @return void
1643
+	 * @throws EE_Error
1644
+	 * @throws InvalidArgumentException
1645
+	 * @throws InvalidDataTypeException
1646
+	 * @throws InvalidInterfaceException
1647
+	 * @throws ReflectionException
1648
+	 */
1649
+	protected function _register_event_editor_meta_boxes()
1650
+	{
1651
+		$this->verify_cpt_object();
1652
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1653
+		/** @var FeatureFlags $flags */
1654
+		$flags = $this->loader->getShared('EventEspresso\core\domain\services\capabilities\FeatureFlags');
1655
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1656
+		if (! $use_advanced_editor || ! $flags->featureAllowed('use_reg_options_meta_box')) {
1657
+			add_meta_box(
1658
+				'espresso_event_editor_event_options',
1659
+				esc_html__('Event Registration Options', 'event_espresso'),
1660
+				[$this, 'registration_options_meta_box'],
1661
+				$this->page_slug,
1662
+				'side'
1663
+			);
1664
+		}
1665
+		if (! $use_advanced_editor) {
1666
+			add_meta_box(
1667
+				'espresso_event_editor_tickets',
1668
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1669
+				[$this, 'ticket_metabox'],
1670
+				$this->page_slug,
1671
+				'normal',
1672
+				'high'
1673
+			);
1674
+		} else {
1675
+			if ($flags->featureAllowed('use_reg_options_meta_box')) {
1676
+				add_action(
1677
+					'add_meta_boxes_espresso_events',
1678
+					function () {
1679
+						global $current_screen;
1680
+						remove_meta_box('authordiv', $current_screen, 'normal');
1681
+					},
1682
+					99
1683
+				);
1684
+			}
1685
+		}
1686
+		// NOTE: if you're looking for other metaboxes in here,
1687
+		// where a metabox has a related management page in the admin
1688
+		// you will find it setup in the related management page's "_Hooks" file.
1689
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1690
+	}
1691
+
1692
+
1693
+	/**
1694
+	 * @throws DomainException
1695
+	 * @throws EE_Error
1696
+	 * @throws InvalidArgumentException
1697
+	 * @throws InvalidDataTypeException
1698
+	 * @throws InvalidInterfaceException
1699
+	 * @throws ReflectionException
1700
+	 */
1701
+	public function ticket_metabox()
1702
+	{
1703
+		$existing_datetime_ids = $existing_ticket_ids = [];
1704
+		// defaults for template args
1705
+		$template_args = [
1706
+			'existing_datetime_ids'    => '',
1707
+			'event_datetime_help_link' => '',
1708
+			'ticket_options_help_link' => '',
1709
+			'time'                     => null,
1710
+			'ticket_rows'              => '',
1711
+			'existing_ticket_ids'      => '',
1712
+			'total_ticket_rows'        => 1,
1713
+			'ticket_js_structure'      => '',
1714
+			'trash_icon'               => 'ee-lock-icon',
1715
+			'disabled'                 => '',
1716
+		];
1717
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1718
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1719
+		/**
1720
+		 * 1. Start with retrieving Datetimes
1721
+		 * 2. Fore each datetime get related tickets
1722
+		 * 3. For each ticket get related prices
1723
+		 */
1724
+		$times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1725
+		/** @type EE_Datetime $first_datetime */
1726
+		$first_datetime = reset($times);
1727
+		// do we get related tickets?
1728
+		if (
1729
+			$first_datetime instanceof EE_Datetime
1730
+			&& $first_datetime->ID() !== 0
1731
+		) {
1732
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1733
+			$template_args['time']   = $first_datetime;
1734
+			$related_tickets         = $first_datetime->tickets(
1735
+				[
1736
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1737
+					'default_where_conditions' => 'none',
1738
+				]
1739
+			);
1740
+			if (! empty($related_tickets)) {
1741
+				$template_args['total_ticket_rows'] = count($related_tickets);
1742
+				$row                                = 0;
1743
+				foreach ($related_tickets as $ticket) {
1744
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1745
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1746
+					$row++;
1747
+				}
1748
+			} else {
1749
+				$template_args['total_ticket_rows'] = 1;
1750
+				/** @type EE_Ticket $ticket */
1751
+				$ticket                       = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1752
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1753
+			}
1754
+		} else {
1755
+			$template_args['time'] = $times[0];
1756
+			/** @type EE_Ticket $ticket */
1757
+			$ticket                       = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1758
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1759
+			// NOTE: we're just sending the first default row
1760
+			// (decaf can't manage default tickets so this should be sufficient);
1761
+		}
1762
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1763
+			'event_editor_event_datetimes_help_tab'
1764
+		);
1765
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1766
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1767
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1768
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1769
+			EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1770
+			true
1771
+		);
1772
+		$template                                  = apply_filters(
1773
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1774
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1775
+		);
1776
+		EEH_Template::display_template($template, $template_args);
1777
+	}
1778
+
1779
+
1780
+	/**
1781
+	 * Setup an individual ticket form for the decaf event editor page
1782
+	 *
1783
+	 * @access private
1784
+	 * @param EE_Ticket $ticket   the ticket object
1785
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1786
+	 * @param int       $row
1787
+	 * @return string generated html for the ticket row.
1788
+	 * @throws DomainException
1789
+	 * @throws EE_Error
1790
+	 * @throws InvalidArgumentException
1791
+	 * @throws InvalidDataTypeException
1792
+	 * @throws InvalidInterfaceException
1793
+	 * @throws ReflectionException
1794
+	 */
1795
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1796
+	{
1797
+		$template_args = [
1798
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1799
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1800
+				: '',
1801
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1802
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1803
+			'TKT_name'            => $ticket->get('TKT_name'),
1804
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1805
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1806
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1807
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1808
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1809
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1810
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1811
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1812
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1813
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1814
+				: ' disabled=disabled',
1815
+		];
1816
+		$price         = $ticket->ID() !== 0
1817
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1818
+			: EE_Registry::instance()->load_model('Price')->create_default_object();
1819
+		$price_args    = [
1820
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1821
+			'PRC_amount'            => $price->get('PRC_amount'),
1822
+			'PRT_ID'                => $price->get('PRT_ID'),
1823
+			'PRC_ID'                => $price->get('PRC_ID'),
1824
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1825
+		];
1826
+		// make sure we have default start and end dates if skeleton
1827
+		// handle rows that should NOT be empty
1828
+		if (empty($template_args['TKT_start_date'])) {
1829
+			// if empty then the start date will be now.
1830
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1831
+		}
1832
+		if (empty($template_args['TKT_end_date'])) {
1833
+			// get the earliest datetime (if present);
1834
+			$earliest_dtt = $this->_cpt_model_obj->ID() > 0
1835
+				? $this->_cpt_model_obj->get_first_related(
1836
+					'Datetime',
1837
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1838
+				)
1839
+				: null;
1840
+			if (! empty($earliest_dtt)) {
1841
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1842
+			} else {
1843
+				$template_args['TKT_end_date'] = date(
1844
+					'Y-m-d h:i a',
1845
+					mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))
1846
+				);
1847
+			}
1848
+		}
1849
+		$template_args = array_merge($template_args, $price_args);
1850
+		$template      = apply_filters(
1851
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1852
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1853
+			$ticket
1854
+		);
1855
+		return EEH_Template::display_template($template, $template_args, true);
1856
+	}
1857
+
1858
+
1859
+	/**
1860
+	 * @throws DomainException
1861
+	 * @throws EE_Error
1862
+	 */
1863
+	public function registration_options_meta_box()
1864
+	{
1865
+		$yes_no_values             = [
1866
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1867
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1868
+		];
1869
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1870
+			[
1871
+				EEM_Registration::status_id_cancelled,
1872
+				EEM_Registration::status_id_declined,
1873
+				EEM_Registration::status_id_incomplete,
1874
+			],
1875
+			true
1876
+		);
1877
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1878
+		$template_args['_event']                          = $this->_cpt_model_obj;
1879
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1880
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1881
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1882
+			'default_reg_status',
1883
+			$default_reg_status_values,
1884
+			$this->_cpt_model_obj->default_registration_status()
1885
+		);
1886
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1887
+			'display_desc',
1888
+			$yes_no_values,
1889
+			$this->_cpt_model_obj->display_description()
1890
+		);
1891
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1892
+			'display_ticket_selector',
1893
+			$yes_no_values,
1894
+			$this->_cpt_model_obj->display_ticket_selector(),
1895
+			'',
1896
+			'',
1897
+			false
1898
+		);
1899
+		$template_args['additional_registration_options'] = apply_filters(
1900
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1901
+			'',
1902
+			$template_args,
1903
+			$yes_no_values,
1904
+			$default_reg_status_values
1905
+		);
1906
+		EEH_Template::display_template(
1907
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1908
+			$template_args
1909
+		);
1910
+	}
1911
+
1912
+
1913
+	/**
1914
+	 * _get_events()
1915
+	 * This method simply returns all the events (for the given _view and paging)
1916
+	 *
1917
+	 * @access public
1918
+	 * @param int  $per_page     count of items per page (20 default);
1919
+	 * @param int  $current_page what is the current page being viewed.
1920
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1921
+	 *                           If FALSE then we return an array of event objects
1922
+	 *                           that match the given _view and paging parameters.
1923
+	 * @return array|int an array of event objects.
1924
+	 * @throws EE_Error
1925
+	 * @throws InvalidArgumentException
1926
+	 * @throws InvalidDataTypeException
1927
+	 * @throws InvalidInterfaceException
1928
+	 * @throws ReflectionException
1929
+	 * @throws Exception
1930
+	 * @throws Exception
1931
+	 * @throws Exception
1932
+	 */
1933
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1934
+	{
1935
+		$EEME    = $this->_event_model();
1936
+		$offset  = ($current_page - 1) * $per_page;
1937
+		$limit   = $count ? null : $offset . ',' . $per_page;
1938
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1939
+		$order   = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
1940
+		if (isset($this->_req_data['month_range'])) {
1941
+			$pieces = explode(' ', $this->_req_data['month_range'], 3);
1942
+			// simulate the FIRST day of the month, that fixes issues for months like February
1943
+			// where PHP doesn't know what to assume for date.
1944
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1945
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1946
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1947
+		}
1948
+		$where  = [];
1949
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1950
+		// determine what post_status our condition will have for the query.
1951
+		switch ($status) {
1952
+			case 'month':
1953
+			case 'today':
1954
+			case null:
1955
+			case 'all':
1956
+				break;
1957
+			case 'draft':
1958
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1959
+				break;
1960
+			default:
1961
+				$where['status'] = $status;
1962
+		}
1963
+		// categories?
1964
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1965
+			? $this->_req_data['EVT_CAT'] : null;
1966
+		if (! empty($category)) {
1967
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1968
+			$where['Term_Taxonomy.term_id']  = $category;
1969
+		}
1970
+		// date where conditions
1971
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1972
+		if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] !== '') {
1973
+			$DateTime = new DateTime(
1974
+				$year_r . '-' . $month_r . '-01 00:00:00',
1975
+				new DateTimeZone('UTC')
1976
+			);
1977
+			$start    = $DateTime->getTimestamp();
1978
+			// set the datetime to be the end of the month
1979
+			$DateTime->setDate(
1980
+				$year_r,
1981
+				$month_r,
1982
+				$DateTime->format('t')
1983
+			)->setTime(23, 59, 59);
1984
+			$end                             = $DateTime->getTimestamp();
1985
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1986
+		} elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'today') {
1987
+			$DateTime                        =
1988
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1989
+			$start                           = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1990
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1991
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1992
+		} elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'month') {
1993
+			$now                             = date('Y-m-01');
1994
+			$DateTime                        =
1995
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1996
+			$start                           = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1997
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1998
+														->setTime(23, 59, 59)
1999
+														->format(implode(' ', $start_formats));
2000
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
2001
+		}
2002
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
2003
+			$where['EVT_wp_user'] = get_current_user_id();
2004
+		} elseif (
2005
+			! isset($where['status'])
2006
+			&& ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')
2007
+		) {
2008
+			$where['OR'] = [
2009
+				'status*restrict_private' => ['!=', 'private'],
2010
+				'AND'                     => [
2011
+					'status*inclusive' => ['=', 'private'],
2012
+					'EVT_wp_user'      => get_current_user_id(),
2013
+				],
2014
+			];
2015
+		}
2016
+
2017
+		if (
2018
+			isset($this->_req_data['EVT_wp_user'])
2019
+			&& (int) $this->_req_data['EVT_wp_user'] !== (int) get_current_user_id()
2020
+			&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
2021
+		) {
2022
+			$where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
2023
+		}
2024
+		// search query handling
2025
+		if (isset($this->_req_data['s'])) {
2026
+			$search_string = '%' . $this->_req_data['s'] . '%';
2027
+			$where['OR']   = [
2028
+				'EVT_name'       => ['LIKE', $search_string],
2029
+				'EVT_desc'       => ['LIKE', $search_string],
2030
+				'EVT_short_desc' => ['LIKE', $search_string],
2031
+			];
2032
+		}
2033
+		// filter events by venue.
2034
+		if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) {
2035
+			$where['Venue.VNU_ID'] = absint($this->_req_data['venue']);
2036
+		}
2037
+		$where        = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
2038
+		$query_params = apply_filters(
2039
+			'FHEE__Events_Admin_Page__get_events__query_params',
2040
+			[
2041
+				$where,
2042
+				'limit'    => $limit,
2043
+				'order_by' => $orderby,
2044
+				'order'    => $order,
2045
+				'group_by' => 'EVT_ID',
2046
+			],
2047
+			$this->_req_data
2048
+		);
2049
+
2050
+		// let's first check if we have special requests coming in.
2051
+		if (isset($this->_req_data['active_status'])) {
2052
+			switch ($this->_req_data['active_status']) {
2053
+				case 'upcoming':
2054
+					return $EEME->get_upcoming_events($query_params, $count);
2055
+				case 'expired':
2056
+					return $EEME->get_expired_events($query_params, $count);
2057
+				case 'active':
2058
+					return $EEME->get_active_events($query_params, $count);
2059
+				case 'inactive':
2060
+					return $EEME->get_inactive_events($query_params, $count);
2061
+			}
2062
+		}
2063
+
2064
+		return $count ? $EEME->count([$where], 'EVT_ID', true) : $EEME->get_all($query_params);
2065
+	}
2066
+
2067
+
2068
+	/**
2069
+	 * handling for WordPress CPT actions (trash, restore, delete)
2070
+	 *
2071
+	 * @param string $post_id
2072
+	 * @throws EE_Error
2073
+	 * @throws InvalidArgumentException
2074
+	 * @throws InvalidDataTypeException
2075
+	 * @throws InvalidInterfaceException
2076
+	 * @throws ReflectionException
2077
+	 */
2078
+	public function trash_cpt_item($post_id)
2079
+	{
2080
+		$this->_req_data['EVT_ID'] = $post_id;
2081
+		$this->_trash_or_restore_event('trash', false);
2082
+	}
2083
+
2084
+
2085
+	/**
2086
+	 * @param string $post_id
2087
+	 * @throws EE_Error
2088
+	 * @throws InvalidArgumentException
2089
+	 * @throws InvalidDataTypeException
2090
+	 * @throws InvalidInterfaceException
2091
+	 * @throws ReflectionException
2092
+	 */
2093
+	public function restore_cpt_item($post_id)
2094
+	{
2095
+		$this->_req_data['EVT_ID'] = $post_id;
2096
+		$this->_trash_or_restore_event('draft', false);
2097
+	}
2098
+
2099
+
2100
+	/**
2101
+	 * @param string $post_id
2102
+	 * @throws EE_Error
2103
+	 * @throws InvalidArgumentException
2104
+	 * @throws InvalidDataTypeException
2105
+	 * @throws InvalidInterfaceException
2106
+	 * @throws ReflectionException
2107
+	 */
2108
+	public function delete_cpt_item($post_id)
2109
+	{
2110
+		throw new EE_Error(
2111
+			esc_html__(
2112
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2113
+				'event_espresso'
2114
+			)
2115
+		);
2116
+		$this->_req_data['EVT_ID'] = $post_id;
2117
+		$this->_delete_event();
2118
+	}
2119
+
2120
+
2121
+	/**
2122
+	 * _trash_or_restore_event
2123
+	 *
2124
+	 * @access protected
2125
+	 * @param string $event_status
2126
+	 * @param bool   $redirect_after
2127
+	 * @throws EE_Error
2128
+	 * @throws InvalidArgumentException
2129
+	 * @throws InvalidDataTypeException
2130
+	 * @throws InvalidInterfaceException
2131
+	 * @throws ReflectionException
2132
+	 */
2133
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2134
+	{
2135
+		// determine the event id and set to array.
2136
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
2137
+		// loop thru events
2138
+		if ($EVT_ID) {
2139
+			// clean status
2140
+			$event_status = sanitize_key($event_status);
2141
+			// grab status
2142
+			if (! empty($event_status)) {
2143
+				$success = $this->_change_event_status($EVT_ID, $event_status);
2144
+			} else {
2145
+				$success = false;
2146
+				$msg     = esc_html__(
2147
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2148
+					'event_espresso'
2149
+				);
2150
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2151
+			}
2152
+		} else {
2153
+			$success = false;
2154
+			$msg     = esc_html__(
2155
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2156
+				'event_espresso'
2157
+			);
2158
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2159
+		}
2160
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2161
+		if ($redirect_after) {
2162
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2163
+		}
2164
+	}
2165
+
2166
+
2167
+	/**
2168
+	 * _trash_or_restore_events
2169
+	 *
2170
+	 * @access protected
2171
+	 * @param string $event_status
2172
+	 * @return void
2173
+	 * @throws EE_Error
2174
+	 * @throws InvalidArgumentException
2175
+	 * @throws InvalidDataTypeException
2176
+	 * @throws InvalidInterfaceException
2177
+	 * @throws ReflectionException
2178
+	 */
2179
+	protected function _trash_or_restore_events($event_status = 'trash')
2180
+	{
2181
+		// clean status
2182
+		$event_status = sanitize_key($event_status);
2183
+		// grab status
2184
+		if (! empty($event_status)) {
2185
+			$success = true;
2186
+			// determine the event id and set to array.
2187
+			$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : [];
2188
+			// loop thru events
2189
+			foreach ($EVT_IDs as $EVT_ID) {
2190
+				if ($EVT_ID = absint($EVT_ID)) {
2191
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2192
+					$success = $results !== false ? $success : false;
2193
+				} else {
2194
+					$msg = sprintf(
2195
+						esc_html__(
2196
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2197
+							'event_espresso'
2198
+						),
2199
+						$EVT_ID
2200
+					);
2201
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2202
+					$success = false;
2203
+				}
2204
+			}
2205
+		} else {
2206
+			$success = false;
2207
+			$msg     = esc_html__(
2208
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2209
+				'event_espresso'
2210
+			);
2211
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2212
+		}
2213
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2214
+		$success = $success ? 2 : false;
2215
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2216
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2217
+	}
2218
+
2219
+
2220
+	/**
2221
+	 * _trash_or_restore_events
2222
+	 *
2223
+	 * @access  private
2224
+	 * @param int    $EVT_ID
2225
+	 * @param string $event_status
2226
+	 * @return bool
2227
+	 * @throws EE_Error
2228
+	 * @throws InvalidArgumentException
2229
+	 * @throws InvalidDataTypeException
2230
+	 * @throws InvalidInterfaceException
2231
+	 * @throws ReflectionException
2232
+	 */
2233
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2234
+	{
2235
+		// grab event id
2236
+		if (! $EVT_ID) {
2237
+			$msg = esc_html__(
2238
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2239
+				'event_espresso'
2240
+			);
2241
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2242
+			return false;
2243
+		}
2244
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2245
+		// clean status
2246
+		$event_status = sanitize_key($event_status);
2247
+		// grab status
2248
+		if (empty($event_status)) {
2249
+			$msg = esc_html__(
2250
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2251
+				'event_espresso'
2252
+			);
2253
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2254
+			return false;
2255
+		}
2256
+		// was event trashed or restored ?
2257
+		switch ($event_status) {
2258
+			case 'draft':
2259
+				$action = 'restored from the trash';
2260
+				$hook   = 'AHEE_event_restored_from_trash';
2261
+				break;
2262
+			case 'trash':
2263
+				$action = 'moved to the trash';
2264
+				$hook   = 'AHEE_event_moved_to_trash';
2265
+				break;
2266
+			default:
2267
+				$action = 'updated';
2268
+				$hook   = false;
2269
+		}
2270
+		// use class to change status
2271
+		$this->_cpt_model_obj->set_status($event_status);
2272
+		$success = $this->_cpt_model_obj->save();
2273
+		if ($success === false) {
2274
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2275
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2276
+			return false;
2277
+		}
2278
+		if ($hook) {
2279
+			do_action($hook);
2280
+		}
2281
+		return true;
2282
+	}
2283
+
2284
+
2285
+	/**
2286
+	 * _delete_event
2287
+	 *
2288
+	 * @throws InvalidArgumentException
2289
+	 * @throws InvalidDataTypeException
2290
+	 * @throws InvalidInterfaceException
2291
+	 */
2292
+	protected function _delete_event()
2293
+	{
2294
+		$this->generateDeletionPreview(isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : []);
2295
+	}
2296
+
2297
+
2298
+	/**
2299
+	 * Gets the tree traversal batch persister.
2300
+	 *
2301
+	 * @return NodeGroupDao
2302
+	 * @throws InvalidArgumentException
2303
+	 * @throws InvalidDataTypeException
2304
+	 * @throws InvalidInterfaceException
2305
+	 * @since 4.10.12.p
2306
+	 */
2307
+	protected function getModelObjNodeGroupPersister()
2308
+	{
2309
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2310
+			$this->model_obj_node_group_persister =
2311
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2312
+		}
2313
+		return $this->model_obj_node_group_persister;
2314
+	}
2315
+
2316
+
2317
+	/**
2318
+	 * _delete_events
2319
+	 *
2320
+	 * @access protected
2321
+	 * @return void
2322
+	 * @throws InvalidArgumentException
2323
+	 * @throws InvalidDataTypeException
2324
+	 * @throws InvalidInterfaceException
2325
+	 */
2326
+	protected function _delete_events()
2327
+	{
2328
+		$this->generateDeletionPreview(isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : []);
2329
+	}
2330
+
2331
+
2332
+	protected function generateDeletionPreview($event_ids)
2333
+	{
2334
+		$event_ids = (array) $event_ids;
2335
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2336
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2337
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2338
+			[
2339
+				'action'            => 'preview_deletion',
2340
+				'deletion_job_code' => $deletion_job_code,
2341
+			],
2342
+			$this->_admin_base_url
2343
+		);
2344
+		$event_ids         = array_map(
2345
+			'intval',
2346
+			$event_ids
2347
+		);
2348
+
2349
+		EEH_URL::safeRedirectAndExit(
2350
+			EE_Admin_Page::add_query_args_and_nonce(
2351
+				[
2352
+					'page'              => 'espresso_batch',
2353
+					'batch'             => EED_Batch::batch_job,
2354
+					'EVT_IDs'           => $event_ids,
2355
+					'deletion_job_code' => $deletion_job_code,
2356
+					'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2357
+					'return_url'        => urlencode($return_url),
2358
+				],
2359
+				admin_url()
2360
+			)
2361
+		);
2362
+	}
2363
+
2364
+
2365
+	/**
2366
+	 * Checks for a POST submission
2367
+	 *
2368
+	 * @since 4.10.12.p
2369
+	 */
2370
+	protected function confirmDeletion()
2371
+	{
2372
+		$deletion_redirect_logic =
2373
+			$this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion');
2374
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2375
+	}
2376
+
2377
+
2378
+	/**
2379
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2380
+	 *
2381
+	 * @throws EE_Error
2382
+	 * @since 4.10.12.p
2383
+	 */
2384
+	protected function previewDeletion()
2385
+	{
2386
+		$preview_deletion_logic =
2387
+			$this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion');
2388
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2389
+		$this->display_admin_page_with_no_sidebar();
2390
+	}
2391
+
2392
+
2393
+	/**
2394
+	 * get total number of events
2395
+	 *
2396
+	 * @access public
2397
+	 * @return int
2398
+	 * @throws EE_Error
2399
+	 * @throws InvalidArgumentException
2400
+	 * @throws InvalidDataTypeException
2401
+	 * @throws InvalidInterfaceException
2402
+	 */
2403
+	public function total_events()
2404
+	{
2405
+		return EEM_Event::instance()->count(['caps' => 'read_admin'], 'EVT_ID', true);
2406
+	}
2407
+
2408
+
2409
+	/**
2410
+	 * get total number of draft events
2411
+	 *
2412
+	 * @access public
2413
+	 * @return int
2414
+	 * @throws EE_Error
2415
+	 * @throws InvalidArgumentException
2416
+	 * @throws InvalidDataTypeException
2417
+	 * @throws InvalidInterfaceException
2418
+	 */
2419
+	public function total_events_draft()
2420
+	{
2421
+		$where = [
2422
+			'status' => ['IN', ['draft', 'auto-draft']],
2423
+		];
2424
+		return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
2425
+	}
2426
+
2427
+
2428
+	/**
2429
+	 * get total number of trashed events
2430
+	 *
2431
+	 * @access public
2432
+	 * @return int
2433
+	 * @throws EE_Error
2434
+	 * @throws InvalidArgumentException
2435
+	 * @throws InvalidDataTypeException
2436
+	 * @throws InvalidInterfaceException
2437
+	 */
2438
+	public function total_trashed_events()
2439
+	{
2440
+		$where = [
2441
+			'status' => 'trash',
2442
+		];
2443
+		return EEM_Event::instance()->count([$where, 'caps' => 'read_admin'], 'EVT_ID', true);
2444
+	}
2445
+
2446
+
2447
+	/**
2448
+	 *    _default_event_settings
2449
+	 *    This generates the Default Settings Tab
2450
+	 *
2451
+	 * @return void
2452
+	 * @throws DomainException
2453
+	 * @throws EE_Error
2454
+	 * @throws InvalidArgumentException
2455
+	 * @throws InvalidDataTypeException
2456
+	 * @throws InvalidInterfaceException
2457
+	 */
2458
+	protected function _default_event_settings()
2459
+	{
2460
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2461
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2462
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2463
+		$this->display_admin_page_with_sidebar();
2464
+	}
2465
+
2466
+
2467
+	/**
2468
+	 * Return the form for event settings.
2469
+	 *
2470
+	 * @return EE_Form_Section_Proper
2471
+	 * @throws EE_Error
2472
+	 */
2473
+	protected function _default_event_settings_form()
2474
+	{
2475
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2476
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2477
+		// exclude
2478
+			[
2479
+				EEM_Registration::status_id_cancelled,
2480
+				EEM_Registration::status_id_declined,
2481
+				EEM_Registration::status_id_incomplete,
2482
+				EEM_Registration::status_id_wait_list,
2483
+			],
2484
+			true
2485
+		);
2486
+		return new EE_Form_Section_Proper(
2487
+			[
2488
+				'name'            => 'update_default_event_settings',
2489
+				'html_id'         => 'update_default_event_settings',
2490
+				'html_class'      => 'form-table',
2491
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2492
+				'subsections'     => apply_filters(
2493
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2494
+					[
2495
+						'default_reg_status'  => new EE_Select_Input(
2496
+							$registration_stati_for_selection,
2497
+							[
2498
+								'default'         => isset($registration_config->default_STS_ID)
2499
+													 && array_key_exists(
2500
+														 $registration_config->default_STS_ID,
2501
+														 $registration_stati_for_selection
2502
+													 )
2503
+									? sanitize_text_field($registration_config->default_STS_ID)
2504
+									: EEM_Registration::status_id_pending_payment,
2505
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2506
+														. EEH_Template::get_help_tab_link(
2507
+															'default_settings_status_help_tab'
2508
+														),
2509
+								'html_help_text'  => esc_html__(
2510
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2511
+									'event_espresso'
2512
+								),
2513
+							]
2514
+						),
2515
+						'default_max_tickets' => new EE_Integer_Input(
2516
+							[
2517
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2518
+									? $registration_config->default_maximum_number_of_tickets
2519
+									: EEM_Event::get_default_additional_limit(),
2520
+								'html_label_text' => esc_html__(
2521
+									'Default Maximum Tickets Allowed Per Order:',
2522
+									'event_espresso'
2523
+								)
2524
+								. EEH_Template::get_help_tab_link(
2525
+									'default_maximum_tickets_help_tab"'
2526
+								),
2527
+								'html_help_text'  => esc_html__(
2528
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2529
+									'event_espresso'
2530
+								),
2531
+							]
2532
+						),
2533
+					]
2534
+				),
2535
+			]
2536
+		);
2537
+	}
2538
+
2539
+
2540
+	/**
2541
+	 * @return void
2542
+	 * @throws EE_Error
2543
+	 * @throws InvalidArgumentException
2544
+	 * @throws InvalidDataTypeException
2545
+	 * @throws InvalidInterfaceException
2546
+	 */
2547
+	protected function _update_default_event_settings()
2548
+	{
2549
+		$form = $this->_default_event_settings_form();
2550
+		if ($form->was_submitted()) {
2551
+			$form->receive_form_submission();
2552
+			if ($form->is_valid()) {
2553
+				$registration_config = EE_Registry::instance()->CFG->registration;
2554
+				$valid_data          = $form->valid_data();
2555
+				if (isset($valid_data['default_reg_status'])) {
2556
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2557
+				}
2558
+				if (isset($valid_data['default_max_tickets'])) {
2559
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2560
+				}
2561
+				do_action(
2562
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2563
+					$valid_data,
2564
+					EE_Registry::instance()->CFG,
2565
+					$this
2566
+				);
2567
+				// update because data was valid!
2568
+				EE_Registry::instance()->CFG->update_espresso_config();
2569
+				EE_Error::overwrite_success();
2570
+				EE_Error::add_success(
2571
+					__('Default Event Settings were updated', 'event_espresso')
2572
+				);
2573
+			}
2574
+		}
2575
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2576
+	}
2577
+
2578
+
2579
+	/*************        Templates        *************/
2580
+	protected function _template_settings()
2581
+	{
2582
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2583
+		$this->_template_args['preview_img']  = '<img src="'
2584
+												. EVENTS_ASSETS_URL
2585
+												. '/images/'
2586
+												. 'caffeinated_template_features.jpg" alt="'
2587
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2588
+												. '" />';
2589
+		$this->_template_args['preview_text'] = '<strong>'
2590
+												. esc_html__(
2591
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2592
+													'event_espresso'
2593
+												) . '</strong>';
2594
+		$this->display_admin_caf_preview_page('template_settings_tab');
2595
+	}
2596
+
2597
+
2598
+	/** Event Category Stuff **/
2599
+	/**
2600
+	 * set the _category property with the category object for the loaded page.
2601
+	 *
2602
+	 * @access private
2603
+	 * @return void
2604
+	 */
2605
+	private function _set_category_object()
2606
+	{
2607
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2608
+			return;
2609
+		} //already have the category object so get out.
2610
+		// set default category object
2611
+		$this->_set_empty_category_object();
2612
+		// only set if we've got an id
2613
+		if (! isset($this->_req_data['EVT_CAT_ID'])) {
2614
+			return;
2615
+		}
2616
+		$category_id = absint($this->_req_data['EVT_CAT_ID']);
2617
+		$term        = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2618
+		if (! empty($term)) {
2619
+			$this->_category->category_name       = $term->name;
2620
+			$this->_category->category_identifier = $term->slug;
2621
+			$this->_category->category_desc       = $term->description;
2622
+			$this->_category->id                  = $term->term_id;
2623
+			$this->_category->parent              = $term->parent;
2624
+		}
2625
+	}
2626
+
2627
+
2628
+	/**
2629
+	 * Clears out category properties.
2630
+	 */
2631
+	private function _set_empty_category_object()
2632
+	{
2633
+		$this->_category                = new stdClass();
2634
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2635
+		$this->_category->id            = $this->_category->parent = 0;
2636
+	}
2637
+
2638
+
2639
+	/**
2640
+	 * @throws DomainException
2641
+	 * @throws EE_Error
2642
+	 * @throws InvalidArgumentException
2643
+	 * @throws InvalidDataTypeException
2644
+	 * @throws InvalidInterfaceException
2645
+	 */
2646
+	protected function _category_list_table()
2647
+	{
2648
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2649
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2650
+		$this->_admin_page_title .= ' ';
2651
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2652
+			'add_category',
2653
+			'add_category',
2654
+			[],
2655
+			'add-new-h2'
2656
+		);
2657
+		$this->display_admin_list_table_page_with_sidebar();
2658
+	}
2659
+
2660
+
2661
+	/**
2662
+	 * Output category details view.
2663
+	 *
2664
+	 * @param string $view
2665
+	 * @throws DomainException
2666
+	 * @throws EE_Error
2667
+	 * @throws InvalidArgumentException
2668
+	 * @throws InvalidDataTypeException
2669
+	 * @throws InvalidInterfaceException
2670
+	 */
2671
+	protected function _category_details($view)
2672
+	{
2673
+		// load formatter helper
2674
+		// load field generator helper
2675
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2676
+		$this->_set_add_edit_form_tags($route);
2677
+		$this->_set_category_object();
2678
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2679
+		$delete_action = 'delete_category';
2680
+		// custom redirect
2681
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2682
+			['action' => 'category_list'],
2683
+			$this->_admin_base_url
2684
+		);
2685
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2686
+		// take care of contents
2687
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2688
+		$this->display_admin_page_with_sidebar();
2689
+	}
2690
+
2691
+
2692
+	/**
2693
+	 * Output category details content.
2694
+	 *
2695
+	 * @throws DomainException
2696
+	 */
2697
+	protected function _category_details_content()
2698
+	{
2699
+		$editor_args['category_desc'] = [
2700
+			'type'          => 'wp_editor',
2701
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2702
+			'class'         => 'my_editor_custom',
2703
+			'wpeditor_args' => ['media_buttons' => false],
2704
+		];
2705
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2706
+		$all_terms                    = get_terms(
2707
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2708
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2709
+		);
2710
+		// setup category select for term parents.
2711
+		$category_select_values[] = [
2712
+			'text' => esc_html__('No Parent', 'event_espresso'),
2713
+			'id'   => 0,
2714
+		];
2715
+		foreach ($all_terms as $term) {
2716
+			$category_select_values[] = [
2717
+				'text' => $term->name,
2718
+				'id'   => $term->term_id,
2719
+			];
2720
+		}
2721
+		$category_select = EEH_Form_Fields::select_input(
2722
+			'category_parent',
2723
+			$category_select_values,
2724
+			$this->_category->parent
2725
+		);
2726
+		$template_args   = [
2727
+			'category'                 => $this->_category,
2728
+			'category_select'          => $category_select,
2729
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2730
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2731
+			'disable'                  => '',
2732
+			'disabled_message'         => false,
2733
+		];
2734
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2735
+		return EEH_Template::display_template($template, $template_args, true);
2736
+	}
2737
+
2738
+
2739
+	/**
2740
+	 * Handles deleting categories.
2741
+	 */
2742
+	protected function _delete_categories()
2743
+	{
2744
+		$cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2745
+			: (array) $this->_req_data['category_id'];
2746
+		foreach ($cat_ids as $cat_id) {
2747
+			$this->_delete_category($cat_id);
2748
+		}
2749
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2750
+		$query_args = [
2751
+			'action' => 'category_list',
2752
+		];
2753
+		$this->_redirect_after_action(0, '', '', $query_args);
2754
+	}
2755
+
2756
+
2757
+	/**
2758
+	 * Handles deleting specific category.
2759
+	 *
2760
+	 * @param int $cat_id
2761
+	 */
2762
+	protected function _delete_category($cat_id)
2763
+	{
2764
+		$cat_id = absint($cat_id);
2765
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2766
+	}
2767
+
2768
+
2769
+	/**
2770
+	 * Handles triggering the update or insertion of a new category.
2771
+	 *
2772
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2773
+	 * @throws EE_Error
2774
+	 * @throws InvalidArgumentException
2775
+	 * @throws InvalidDataTypeException
2776
+	 * @throws InvalidInterfaceException
2777
+	 */
2778
+	protected function _insert_or_update_category($new_category)
2779
+	{
2780
+		$cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2781
+		$success = 0; // we already have a success message so lets not send another.
2782
+		if ($cat_id) {
2783
+			$query_args = [
2784
+				'action'     => 'edit_category',
2785
+				'EVT_CAT_ID' => $cat_id,
2786
+			];
2787
+		} else {
2788
+			$query_args = ['action' => 'add_category'];
2789
+		}
2790
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2791
+	}
2792
+
2793
+
2794
+	/**
2795
+	 * Inserts or updates category
2796
+	 *
2797
+	 * @param bool $update (true indicates we're updating a category).
2798
+	 * @return bool|mixed|string
2799
+	 */
2800
+	private function _insert_category($update = false)
2801
+	{
2802
+		$cat_id          = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2803
+		$category_name   = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2804
+		$category_desc   = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2805
+		$category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2806
+		if (empty($category_name)) {
2807
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2808
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2809
+			return false;
2810
+		}
2811
+		$term_args = [
2812
+			'name'        => $category_name,
2813
+			'description' => $category_desc,
2814
+			'parent'      => $category_parent,
2815
+		];
2816
+		// was the category_identifier input disabled?
2817
+		if (isset($this->_req_data['category_identifier'])) {
2818
+			$term_args['slug'] = $this->_req_data['category_identifier'];
2819
+		}
2820
+		$insert_ids = $update
2821
+			? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2822
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2823
+		if (! is_array($insert_ids)) {
2824
+			$msg = esc_html__(
2825
+				'An error occurred and the category has not been saved to the database.',
2826
+				'event_espresso'
2827
+			);
2828
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2829
+		} else {
2830
+			$cat_id = $insert_ids['term_id'];
2831
+			$msg    = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2832
+			EE_Error::add_success($msg);
2833
+		}
2834
+		return $cat_id;
2835
+	}
2836
+
2837
+
2838
+	/**
2839
+	 * Gets categories or count of categories matching the arguments in the request.
2840
+	 *
2841
+	 * @param int  $per_page
2842
+	 * @param int  $current_page
2843
+	 * @param bool $count
2844
+	 * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int
2845
+	 * @throws EE_Error
2846
+	 * @throws InvalidArgumentException
2847
+	 * @throws InvalidDataTypeException
2848
+	 * @throws InvalidInterfaceException
2849
+	 */
2850
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2851
+	{
2852
+		// testing term stuff
2853
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2854
+		$order   = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2855
+		$limit   = ($current_page - 1) * $per_page;
2856
+		$where   = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2857
+		if (isset($this->_req_data['s'])) {
2858
+			$sstr        = '%' . $this->_req_data['s'] . '%';
2859
+			$where['OR'] = [
2860
+				'Term.name'   => ['LIKE', $sstr],
2861
+				'description' => ['LIKE', $sstr],
2862
+			];
2863
+		}
2864
+		$query_params = [
2865
+			$where,
2866
+			'order_by'   => [$orderby => $order],
2867
+			'limit'      => $limit . ',' . $per_page,
2868
+			'force_join' => ['Term'],
2869
+		];
2870
+		return $count
2871
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2872
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2873
+	}
2874
+
2875
+	/* end category stuff */
2876
+	/**************/
2877
+
2878
+
2879
+	/**
2880
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2881
+	 *
2882
+	 * @throws EE_Error
2883
+	 * @throws InvalidArgumentException
2884
+	 * @throws InvalidDataTypeException
2885
+	 * @throws InvalidInterfaceException
2886
+	 */
2887
+	public function save_timezonestring_setting()
2888
+	{
2889
+		$timezone_string = isset($this->_req_data['timezone_selected'])
2890
+			? $this->_req_data['timezone_selected']
2891
+			: '';
2892
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2893
+			EE_Error::add_error(
2894
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2895
+				__FILE__,
2896
+				__FUNCTION__,
2897
+				__LINE__
2898
+			);
2899
+			$this->_template_args['error'] = true;
2900
+			$this->_return_json();
2901
+		}
2902
+
2903
+		update_option('timezone_string', $timezone_string);
2904
+		EE_Error::add_success(
2905
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2906
+		);
2907
+		$this->_template_args['success'] = true;
2908
+		$this->_return_json(true, ['action' => 'create_new']);
2909
+	}
2910 2910
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Event.model.php 1 patch
Indentation   +920 added lines, -920 removed lines patch added patch discarded remove patch
@@ -14,924 +14,924 @@
 block discarded – undo
14 14
 class EEM_Event extends EEM_CPT_Base
15 15
 {
16 16
 
17
-    /**
18
-     * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
19
-     * event
20
-     */
21
-    const sold_out = 'sold_out';
22
-
23
-    /**
24
-     * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
25
-     * date)
26
-     */
27
-    const postponed = 'postponed';
28
-
29
-    /**
30
-     * constant used by status(), indicating that the event will no longer occur
31
-     */
32
-    const cancelled = 'cancelled';
33
-
34
-
35
-    /**
36
-     * @var string
37
-     */
38
-    protected static $_default_reg_status;
39
-
40
-
41
-    /**
42
-     * This is the default for the additional limit field.
43
-     * @var int
44
-     */
45
-    protected static $_default_additional_limit = 10;
46
-
47
-
48
-    /**
49
-     * private instance of the Event object
50
-     *
51
-     * @var EEM_Event
52
-     */
53
-    protected static $_instance;
54
-
55
-
56
-    /**
57
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
58
-     *
59
-     * @param string $timezone
60
-     * @throws EE_Error
61
-     * @throws ReflectionException
62
-     */
63
-    protected function __construct($timezone = null)
64
-    {
65
-        EE_Registry::instance()->load_model('Registration');
66
-        $this->singular_item = esc_html__('Event', 'event_espresso');
67
-        $this->plural_item = esc_html__('Events', 'event_espresso');
68
-        // to remove Cancelled events from the frontend, copy the following filter to your functions.php file
69
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
70
-        // to remove Postponed events from the frontend, copy the following filter to your functions.php file
71
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
72
-        // to remove Sold Out events from the frontend, copy the following filter to your functions.php file
73
-        //  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
74
-        $this->_custom_stati = apply_filters(
75
-            'AFEE__EEM_Event__construct___custom_stati',
76
-            array(
77
-                EEM_Event::cancelled => array(
78
-                    'label'  => esc_html__('Cancelled', 'event_espresso'),
79
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
80
-                ),
81
-                EEM_Event::postponed => array(
82
-                    'label'  => esc_html__('Postponed', 'event_espresso'),
83
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
84
-                ),
85
-                EEM_Event::sold_out  => array(
86
-                    'label'  => esc_html__('Sold Out', 'event_espresso'),
87
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
88
-                ),
89
-            )
90
-        );
91
-        self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
92
-            : self::$_default_reg_status;
93
-        $this->_tables = array(
94
-            'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
95
-            'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
96
-        );
97
-        $this->_fields = array(
98
-            'Event_CPT'  => array(
99
-                'EVT_ID'         => new EE_Primary_Key_Int_Field(
100
-                    'ID',
101
-                    esc_html__('Post ID for Event', 'event_espresso')
102
-                ),
103
-                'EVT_name'       => new EE_Plain_Text_Field(
104
-                    'post_title',
105
-                    esc_html__('Event Name', 'event_espresso'),
106
-                    false,
107
-                    ''
108
-                ),
109
-                'EVT_desc'       => new EE_Post_Content_Field(
110
-                    'post_content',
111
-                    esc_html__('Event Description', 'event_espresso'),
112
-                    false,
113
-                    ''
114
-                ),
115
-                'EVT_slug'       => new EE_Slug_Field(
116
-                    'post_name',
117
-                    esc_html__('Event Slug', 'event_espresso'),
118
-                    false,
119
-                    ''
120
-                ),
121
-                'EVT_created'    => new EE_Datetime_Field(
122
-                    'post_date',
123
-                    esc_html__('Date/Time Event Created', 'event_espresso'),
124
-                    false,
125
-                    EE_Datetime_Field::now
126
-                ),
127
-                'EVT_short_desc' => new EE_Simple_HTML_Field(
128
-                    'post_excerpt',
129
-                    esc_html__('Event Short Description', 'event_espresso'),
130
-                    false,
131
-                    ''
132
-                ),
133
-                'EVT_modified'   => new EE_Datetime_Field(
134
-                    'post_modified',
135
-                    esc_html__('Date/Time Event Modified', 'event_espresso'),
136
-                    false,
137
-                    EE_Datetime_Field::now
138
-                ),
139
-                'EVT_wp_user'    => new EE_WP_User_Field(
140
-                    'post_author',
141
-                    esc_html__('Event Creator ID', 'event_espresso'),
142
-                    false
143
-                ),
144
-                'parent'         => new EE_Integer_Field(
145
-                    'post_parent',
146
-                    esc_html__('Event Parent ID', 'event_espresso'),
147
-                    false,
148
-                    0
149
-                ),
150
-                'EVT_order'      => new EE_Integer_Field(
151
-                    'menu_order',
152
-                    esc_html__('Event Menu Order', 'event_espresso'),
153
-                    false,
154
-                    1
155
-                ),
156
-                'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
157
-                // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
158
-                'status'         => new EE_WP_Post_Status_Field(
159
-                    'post_status',
160
-                    esc_html__('Event Status', 'event_espresso'),
161
-                    false,
162
-                    'draft',
163
-                    $this->_custom_stati
164
-                ),
165
-                'password' => new EE_Password_Field(
166
-                    'post_password',
167
-                    __('Password', 'event_espresso'),
168
-                    false,
169
-                    '',
170
-                    array(
171
-                        'EVT_desc',
172
-                        'EVT_short_desc',
173
-                        'EVT_display_desc',
174
-                        'EVT_display_ticket_selector',
175
-                        'EVT_visible_on',
176
-                        'EVT_additional_limit',
177
-                        'EVT_default_registration_status',
178
-                        'EVT_member_only',
179
-                        'EVT_phone',
180
-                        'EVT_allow_overflow',
181
-                        'EVT_timezone_string',
182
-                        'EVT_external_URL',
183
-                        'EVT_donations'
184
-                    )
185
-                )
186
-            ),
187
-            'Event_Meta' => array(
188
-                'EVTM_ID'                         => new EE_DB_Only_Float_Field(
189
-                    'EVTM_ID',
190
-                    esc_html__('Event Meta Row ID', 'event_espresso'),
191
-                    false
192
-                ),
193
-                'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
194
-                    'EVT_ID',
195
-                    esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
196
-                    false
197
-                ),
198
-                'EVT_display_desc'                => new EE_Boolean_Field(
199
-                    'EVT_display_desc',
200
-                    esc_html__('Display Description Flag', 'event_espresso'),
201
-                    false,
202
-                    true
203
-                ),
204
-                'EVT_display_ticket_selector'     => new EE_Boolean_Field(
205
-                    'EVT_display_ticket_selector',
206
-                    esc_html__('Display Ticket Selector Flag', 'event_espresso'),
207
-                    false,
208
-                    true
209
-                ),
210
-                'EVT_visible_on'                  => new EE_Datetime_Field(
211
-                    'EVT_visible_on',
212
-                    esc_html__('Event Visible Date', 'event_espresso'),
213
-                    true,
214
-                    EE_Datetime_Field::now
215
-                ),
216
-                'EVT_additional_limit'            => new EE_Integer_Field(
217
-                    'EVT_additional_limit',
218
-                    esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
219
-                    true,
220
-                    self::$_default_additional_limit
221
-                ),
222
-                'EVT_default_registration_status' => new EE_Enum_Text_Field(
223
-                    'EVT_default_registration_status',
224
-                    esc_html__('Default Registration Status on this Event', 'event_espresso'),
225
-                    false,
226
-                    EEM_Event::$_default_reg_status,
227
-                    EEM_Registration::reg_status_array()
228
-                ),
229
-                'EVT_member_only'                 => new EE_Boolean_Field(
230
-                    'EVT_member_only',
231
-                    esc_html__('Member-Only Event Flag', 'event_espresso'),
232
-                    false,
233
-                    false
234
-                ),
235
-                'EVT_phone'                       => new EE_Plain_Text_Field(
236
-                    'EVT_phone',
237
-                    esc_html__('Event Phone Number', 'event_espresso'),
238
-                    false,
239
-                    ''
240
-                ),
241
-                'EVT_allow_overflow'              => new EE_Boolean_Field(
242
-                    'EVT_allow_overflow',
243
-                    esc_html__('Allow Overflow on Event', 'event_espresso'),
244
-                    false,
245
-                    false
246
-                ),
247
-                'EVT_timezone_string'             => new EE_Plain_Text_Field(
248
-                    'EVT_timezone_string',
249
-                    esc_html__('Timezone (name) for Event times', 'event_espresso'),
250
-                    false,
251
-                    ''
252
-                ),
253
-                'EVT_external_URL'                => new EE_Plain_Text_Field(
254
-                    'EVT_external_URL',
255
-                    esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
256
-                    true
257
-                ),
258
-                'EVT_donations'                   => new EE_Boolean_Field(
259
-                    'EVT_donations',
260
-                    esc_html__('Accept Donations?', 'event_espresso'),
261
-                    false,
262
-                    false
263
-                ),
264
-                'FSC_UUID'                        => new EE_Foreign_Key_String_Field(
265
-                    'FSC_UUID',
266
-                    esc_html__('Registration Form UUID (universally unique identifier)', 'event_espresso'),
267
-                    true,
268
-                    null,
269
-                    'Form_Section',
270
-                    false
271
-                ),
272
-            ),
273
-        );
274
-        $this->_model_relations = array(
275
-            'Attendee'               => new EE_HABTM_Relation('Registration'),
276
-            'Datetime'               => new EE_Has_Many_Relation(),
277
-            'Event_Question_Group'   => new EE_Has_Many_Relation(),
278
-            'Form_Section'           => new EE_Belongs_To_Relation(),
279
-            'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
280
-            'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
281
-            'Registration'           => new EE_Has_Many_Relation(),
282
-            'Term_Relationship'      => new EE_Has_Many_Relation(),
283
-            'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
284
-            'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
285
-            'WP_User'                => new EE_Belongs_To_Relation(),
286
-        );
287
-        // this model is generally available for reading
288
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
289
-        $this->model_chain_to_password = '';
290
-        parent::__construct($timezone);
291
-    }
292
-
293
-
294
-    /**
295
-     * @param string $default_reg_status
296
-     * @throws EE_Error
297
-     * @throws EE_Error
298
-     */
299
-    public static function set_default_reg_status($default_reg_status)
300
-    {
301
-        self::$_default_reg_status = $default_reg_status;
302
-        // if EEM_Event has already been instantiated,
303
-        // then we need to reset the `EVT_default_reg_status` field to use the new default.
304
-        if (self::$_instance instanceof EEM_Event) {
305
-            $default_reg_status = new EE_Enum_Text_Field(
306
-                'EVT_default_registration_status',
307
-                esc_html__('Default Registration Status on this Event', 'event_espresso'),
308
-                false,
309
-                $default_reg_status,
310
-                EEM_Registration::reg_status_array()
311
-            );
312
-            $default_reg_status->_construct_finalize(
313
-                'Event_Meta',
314
-                'EVT_default_registration_status',
315
-                'EEM_Event'
316
-            );
317
-            self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
318
-        }
319
-    }
320
-
321
-
322
-    /**
323
-     * Used to override the default for the additional limit field.
324
-     * @param $additional_limit
325
-     */
326
-    public static function set_default_additional_limit($additional_limit)
327
-    {
328
-        self::$_default_additional_limit = (int) $additional_limit;
329
-        if (self::$_instance instanceof EEM_Event) {
330
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
331
-                'EVT_additional_limit',
332
-                __('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
333
-                true,
334
-                self::$_default_additional_limit
335
-            );
336
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
337
-                'Event_Meta',
338
-                'EVT_additional_limit',
339
-                'EEM_Event'
340
-            );
341
-        }
342
-    }
343
-
344
-
345
-    /**
346
-     * Return what is currently set as the default additional limit for the event.
347
-     * @return int
348
-     */
349
-    public static function get_default_additional_limit()
350
-    {
351
-        return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
352
-    }
353
-
354
-
355
-    /**
356
-     * get_question_groups
357
-     *
358
-     * @return array
359
-     * @throws EE_Error
360
-     * @throws ReflectionException
361
-     */
362
-    public function get_all_question_groups()
363
-    {
364
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
365
-            array(
366
-                array('QSG_deleted' => false),
367
-                'order_by' => array('QSG_order' => 'ASC'),
368
-            )
369
-        );
370
-    }
371
-
372
-
373
-    /**
374
-     * get_question_groups
375
-     *
376
-     * @param int $EVT_ID
377
-     * @return array|bool
378
-     * @throws EE_Error
379
-     * @throws ReflectionException
380
-     */
381
-    public function get_all_event_question_groups($EVT_ID = 0)
382
-    {
383
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
384
-            EE_Error::add_error(
385
-                esc_html__(
386
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
387
-                    'event_espresso'
388
-                ),
389
-                __FILE__,
390
-                __FUNCTION__,
391
-                __LINE__
392
-            );
393
-            return false;
394
-        }
395
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
396
-            array(
397
-                array('EVT_ID' => $EVT_ID),
398
-            )
399
-        );
400
-    }
401
-
402
-
403
-    /**
404
-     * get_question_groups
405
-     *
406
-     * @param int $EVT_ID
407
-     * @param boolean $for_primary_attendee
408
-     * @return array|bool
409
-     * @throws EE_Error
410
-     * @throws InvalidArgumentException
411
-     * @throws ReflectionException
412
-     * @throws InvalidDataTypeException
413
-     * @throws InvalidInterfaceException
414
-     */
415
-    public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
416
-    {
417
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
418
-            EE_Error::add_error(
419
-                esc_html__(
420
-                    // @codingStandardsIgnoreStart
421
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
422
-                    // @codingStandardsIgnoreEnd
423
-                    'event_espresso'
424
-                ),
425
-                __FILE__,
426
-                __FUNCTION__,
427
-                __LINE__
428
-            );
429
-            return false;
430
-        }
431
-        $query_params = [
432
-            [
433
-                'EVT_ID' => $EVT_ID,
434
-                EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true
435
-            ]
436
-        ];
437
-        if ($for_primary_attendee) {
438
-            $query_params[0]['EQG_primary'] = true;
439
-        } else {
440
-            $query_params[0]['EQG_additional'] = true;
441
-        }
442
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params);
443
-    }
444
-
445
-
446
-    /**
447
-     * get_question_groups
448
-     *
449
-     * @param int $EVT_ID
450
-     * @param EE_Registration $registration
451
-     * @return array|bool
452
-     * @throws EE_Error
453
-     * @throws InvalidArgumentException
454
-     * @throws InvalidDataTypeException
455
-     * @throws InvalidInterfaceException
456
-     * @throws ReflectionException
457
-     */
458
-    public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
459
-    {
460
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
461
-            EE_Error::add_error(
462
-                esc_html__(
463
-                    'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
464
-                    'event_espresso'
465
-                ),
466
-                __FILE__,
467
-                __FUNCTION__,
468
-                __LINE__
469
-            );
470
-            return false;
471
-        }
472
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
473
-            [
474
-                [
475
-                    'Event_Question_Group.EVT_ID'      => $EVT_ID,
476
-                    'Event_Question_Group.'
477
-                        . EEM_Event_Question_Group::instance()->fieldNameForContext(
478
-                            $registration->is_primary_registrant()
479
-                        ) => true
480
-                ],
481
-                'order_by' => ['QSG_order' => 'ASC'],
482
-            ]
483
-        );
484
-    }
485
-
486
-
487
-    /**
488
-     * get_question_target_db_column
489
-     *
490
-     * @param string $QSG_IDs csv list of $QSG IDs
491
-     * @return array|bool
492
-     * @throws EE_Error
493
-     * @throws ReflectionException
494
-     */
495
-    public function get_questions_in_groups($QSG_IDs = '')
496
-    {
497
-        if (empty($QSG_IDs)) {
498
-            EE_Error::add_error(
499
-                esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
500
-                __FILE__,
501
-                __FUNCTION__,
502
-                __LINE__
503
-            );
504
-            return false;
505
-        }
506
-        return EE_Registry::instance()->load_model('Question')->get_all(
507
-            array(
508
-                array(
509
-                    'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
510
-                    'QST_deleted'           => false,
511
-                    'QST_admin_only'        => is_admin(),
512
-                ),
513
-                'order_by' => 'QST_order',
514
-            )
515
-        );
516
-    }
517
-
518
-
519
-    /**
520
-     * get_options_for_question
521
-     *
522
-     * @param string $QST_IDs csv list of $QST IDs
523
-     * @return array|bool
524
-     * @throws EE_Error
525
-     * @throws ReflectionException
526
-     */
527
-    public function get_options_for_question($QST_IDs)
528
-    {
529
-        if (empty($QST_IDs)) {
530
-            EE_Error::add_error(
531
-                esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
532
-                __FILE__,
533
-                __FUNCTION__,
534
-                __LINE__
535
-            );
536
-            return false;
537
-        }
538
-        return EE_Registry::instance()->load_model('Question_Option')->get_all(
539
-            array(
540
-                array(
541
-                    'Question.QST_ID' => array('IN', $QST_IDs),
542
-                    'QSO_deleted'     => false,
543
-                ),
544
-                'order_by' => 'QSO_ID',
545
-            )
546
-        );
547
-    }
548
-
549
-
550
-    /**
551
-     * Gets all events that are published
552
-     * and have event start time earlier than now and an event end time later than now
553
-     *
554
-     * @param array $query_params  An array of query params to further filter on
555
-     *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
556
-     * @param bool  $count         whether to return the count or not (default FALSE)
557
-     * @return EE_Event[]|int
558
-     * @throws EE_Error
559
-     * @throws ReflectionException
560
-     */
561
-    public function get_active_events($query_params, $count = false)
562
-    {
563
-        if (array_key_exists(0, $query_params)) {
564
-            $where_params = $query_params[0];
565
-            unset($query_params[0]);
566
-        } else {
567
-            $where_params = array();
568
-        }
569
-        // if we have count make sure we don't include group by
570
-        if ($count && isset($query_params['group_by'])) {
571
-            unset($query_params['group_by']);
572
-        }
573
-        // let's add specific query_params for active_events
574
-        // keep in mind this will override any sent status in the query AND any date queries.
575
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
576
-        // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
577
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
578
-            $where_params['Datetime.DTT_EVT_start******'] = array(
579
-                '<',
580
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
581
-            );
582
-        } else {
583
-            $where_params['Datetime.DTT_EVT_start'] = array(
584
-                '<',
585
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
586
-            );
587
-        }
588
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
589
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
590
-                '>',
591
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
592
-            );
593
-        } else {
594
-            $where_params['Datetime.DTT_EVT_end'] = array(
595
-                '>',
596
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
597
-            );
598
-        }
599
-        $query_params[0] = $where_params;
600
-        // don't use $query_params with count()
601
-        // because we don't want to include additional query clauses like "GROUP BY"
602
-        return $count
603
-            ? $this->count(array($where_params), 'EVT_ID', true)
604
-            : $this->get_all($query_params);
605
-    }
606
-
607
-
608
-    /**
609
-     * get all events that are published and have an event start time later than now
610
-     *
611
-     * @param array $query_params  An array of query params to further filter on
612
-     *                             (Note that status and DTT_EVT_start will be overridden)
613
-     * @param bool  $count         whether to return the count or not (default FALSE)
614
-     * @return EE_Event[]|int
615
-     * @throws EE_Error
616
-     * @throws ReflectionException
617
-     */
618
-    public function get_upcoming_events($query_params, $count = false)
619
-    {
620
-        if (array_key_exists(0, $query_params)) {
621
-            $where_params = $query_params[0];
622
-            unset($query_params[0]);
623
-        } else {
624
-            $where_params = array();
625
-        }
626
-        // if we have count make sure we don't include group by
627
-        if ($count && isset($query_params['group_by'])) {
628
-            unset($query_params['group_by']);
629
-        }
630
-        // let's add specific query_params for active_events
631
-        // keep in mind this will override any sent status in the query AND any date queries.
632
-        // we need to pull events with a status of publish and sold_out
633
-        $event_status = array('publish', EEM_Event::sold_out);
634
-        // check if the user can read private events and if so add the 'private status to the were params'
635
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_upcoming_events')) {
636
-            $event_status[] = 'private';
637
-        }
638
-        $where_params['status'] = array('IN', $event_status);
639
-        // if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
640
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
641
-            $where_params['Datetime.DTT_EVT_start*****'] = array(
642
-                '>',
643
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
644
-            );
645
-        } else {
646
-            $where_params['Datetime.DTT_EVT_start'] = array(
647
-                '>',
648
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
649
-            );
650
-        }
651
-        $query_params[0] = $where_params;
652
-        // don't use $query_params with count()
653
-        // because we don't want to include additional query clauses like "GROUP BY"
654
-        return $count
655
-            ? $this->count(array($where_params), 'EVT_ID', true)
656
-            : $this->get_all($query_params);
657
-    }
658
-
659
-
660
-    /**
661
-     * Gets all events that are published
662
-     * and have an event end time later than now
663
-     *
664
-     * @param array $query_params  An array of query params to further filter on
665
-     *                             (note that status and DTT_EVT_end will be overridden)
666
-     * @param bool  $count         whether to return the count or not (default FALSE)
667
-     * @return EE_Event[]|int
668
-     * @throws EE_Error
669
-     * @throws ReflectionException
670
-     */
671
-    public function get_active_and_upcoming_events($query_params, $count = false)
672
-    {
673
-        if (array_key_exists(0, $query_params)) {
674
-            $where_params = $query_params[0];
675
-            unset($query_params[0]);
676
-        } else {
677
-            $where_params = array();
678
-        }
679
-        // if we have count make sure we don't include group by
680
-        if ($count && isset($query_params['group_by'])) {
681
-            unset($query_params['group_by']);
682
-        }
683
-        // let's add specific query_params for active_events
684
-        // keep in mind this will override any sent status in the query AND any date queries.
685
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
686
-        // add where params for DTT_EVT_end
687
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
688
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
689
-                '>',
690
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
691
-            );
692
-        } else {
693
-            $where_params['Datetime.DTT_EVT_end'] = array(
694
-                '>',
695
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
696
-            );
697
-        }
698
-        $query_params[0] = $where_params;
699
-        // don't use $query_params with count()
700
-        // because we don't want to include additional query clauses like "GROUP BY"
701
-        return $count
702
-            ? $this->count(array($where_params), 'EVT_ID', true)
703
-            : $this->get_all($query_params);
704
-    }
705
-
706
-
707
-    /**
708
-     * This only returns events that are expired.
709
-     * They may still be published but all their datetimes have expired.
710
-     *
711
-     * @param array $query_params  An array of query params to further filter on
712
-     *                             (note that status and DTT_EVT_end will be overridden)
713
-     * @param bool  $count         whether to return the count or not (default FALSE)
714
-     * @return EE_Event[]|int
715
-     * @throws EE_Error
716
-     * @throws ReflectionException
717
-     */
718
-    public function get_expired_events($query_params, $count = false)
719
-    {
720
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
721
-        // if we have count make sure we don't include group by
722
-        if ($count && isset($query_params['group_by'])) {
723
-            unset($query_params['group_by']);
724
-        }
725
-        // let's add specific query_params for active_events
726
-        // keep in mind this will override any sent status in the query AND any date queries.
727
-        if (isset($where_params['status'])) {
728
-            unset($where_params['status']);
729
-        }
730
-        $exclude_query = $query_params;
731
-        if (isset($exclude_query[0])) {
732
-            unset($exclude_query[0]);
733
-        }
734
-        $exclude_query[0] = array(
735
-            'Datetime.DTT_EVT_end' => array(
736
-                '>',
737
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
738
-            ),
739
-        );
740
-        // first get all events that have datetimes where its not expired.
741
-        $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
742
-        $event_ids = array_keys($event_ids);
743
-        // if we have any additional query_params, let's add them to the 'AND' condition
744
-        $and_condition = array(
745
-            'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
746
-            'EVT_ID'               => array('NOT IN', $event_ids),
747
-        );
748
-        if (isset($where_params['OR'])) {
749
-            $and_condition['OR'] = $where_params['OR'];
750
-            unset($where_params['OR']);
751
-        }
752
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
753
-            $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
754
-            unset($where_params['Datetime.DTT_EVT_end']);
755
-        }
756
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
757
-            $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
758
-            unset($where_params['Datetime.DTT_EVT_start']);
759
-        }
760
-        // merge remaining $where params with the and conditions.
761
-        $where_params['AND'] = array_merge($and_condition, $where_params);
762
-        $query_params[0] = $where_params;
763
-        // don't use $query_params with count()
764
-        // because we don't want to include additional query clauses like "GROUP BY"
765
-        return $count
766
-            ? $this->count(array($where_params), 'EVT_ID', true)
767
-            : $this->get_all($query_params);
768
-    }
769
-
770
-
771
-
772
-    /**
773
-     * This basically just returns the events that do not have the publish status.
774
-     *
775
-     * @param  array   $query_params An array of query params to further filter on
776
-     *                               (note that status will be overwritten)
777
-     * @param  boolean $count        whether to return the count or not (default FALSE)
778
-     * @return EE_Event[]|int
779
-     * @throws EE_Error
780
-     */
781
-    public function get_inactive_events($query_params, $count = false)
782
-    {
783
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
784
-        // let's add in specific query_params for inactive events.
785
-        if (isset($where_params['status'])) {
786
-            unset($where_params['status']);
787
-        }
788
-        // if we have count make sure we don't include group by
789
-        if ($count && isset($query_params['group_by'])) {
790
-            unset($query_params['group_by']);
791
-        }
792
-        // if we have any additional query_params, let's add them to the 'AND' condition
793
-        $where_params['AND']['status'] = array('!=', 'publish');
794
-        if (isset($where_params['OR'])) {
795
-            $where_params['AND']['OR'] = $where_params['OR'];
796
-            unset($where_params['OR']);
797
-        }
798
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
799
-            $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
800
-            unset($where_params['Datetime.DTT_EVT_end']);
801
-        }
802
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
803
-            $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
804
-            unset($where_params['Datetime.DTT_EVT_start']);
805
-        }
806
-        $query_params[0] = $where_params;
807
-        // don't use $query_params with count()
808
-        // because we don't want to include additional query clauses like "GROUP BY"
809
-        return $count
810
-            ? $this->count(array($where_params), 'EVT_ID', true)
811
-            : $this->get_all($query_params);
812
-    }
813
-
814
-
815
-    /**
816
-     * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
817
-     * because we don't want to override any existing global default prices but instead insert NEW prices that get
818
-     * attached to the event. See parent for param descriptions
819
-     *
820
-     * @param        $id_or_obj
821
-     * @param        $other_model_id_or_obj
822
-     * @param string $relationName
823
-     * @param array  $where_query
824
-     * @return EE_Base_Class
825
-     * @throws EE_Error
826
-     * @throws ReflectionException
827
-     */
828
-    public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
829
-    {
830
-        if ($relationName === 'Price') {
831
-            // let's get the PRC object for the given ID to make sure that we aren't dealing with a default
832
-            $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
833
-            // if EVT_ID = 0, then this is a default
834
-            if ((int) $prc_chk->get('EVT_ID') === 0) {
835
-                // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
836
-                $prc_chk->set('PRC_ID', 0);
837
-            }
838
-            // run parent
839
-            return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
840
-        }
841
-        // otherwise carry on as normal
842
-        return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
843
-    }
844
-
845
-
846
-
847
-    /******************** DEPRECATED METHODS ********************/
848
-
849
-
850
-    /**
851
-     * _get_question_target_db_column
852
-     *
853
-     * @param EE_Registration $registration    (so existing answers for registration are included)
854
-     * @param int             $EVT_ID          so all question groups are included for event (not just answers from
855
-     *                                         registration).
856
-     * @return    array
857
-     * @throws ReflectionException
858
-     * @throws EE_Error*@deprecated as of 4.8.32.rc.001. Instead consider using
859
-     *                                         EE_Registration_Custom_Questions_Form located in
860
-     *                                         admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
861
-     * @access     public
862
-     */
863
-    public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
864
-    {
865
-        if (empty($EVT_ID)) {
866
-            throw new EE_Error(__(
867
-                'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
868
-                'event_espresso'
869
-            ));
870
-        }
871
-        $questions = array();
872
-        // get all question groups for event
873
-        $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
874
-        if (! empty($qgs)) {
875
-            foreach ($qgs as $qg) {
876
-                $qsts = $qg->questions();
877
-                $questions[ $qg->ID() ] = $qg->model_field_array();
878
-                $questions[ $qg->ID() ]['QSG_questions'] = array();
879
-                foreach ($qsts as $qst) {
880
-                    if ($qst->is_system_question()) {
881
-                        continue;
882
-                    }
883
-                    $answer = EEM_Answer::instance()->get_one(array(
884
-                        array(
885
-                            'QST_ID' => $qst->ID(),
886
-                            'REG_ID' => $registration->ID(),
887
-                        ),
888
-                    ));
889
-                    $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
890
-                    $qst_name = $qstn_id = $qst->ID();
891
-                    $ans_id = $answer->ID();
892
-                    $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
893
-                    $input_name = '';
894
-                    $input_id = sanitize_key($qst->display_text());
895
-                    $input_class = '';
896
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
897
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
898
-                                                                                           . $input_name
899
-                                                                                           . $qst_name;
900
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
901
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
902
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
903
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
904
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
905
-                    // leave responses as-is, don't convert stuff into html entities please!
906
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
907
-                    if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
908
-                        $QSOs = $qst->options(true, $answer->value());
909
-                        if (is_array($QSOs)) {
910
-                            foreach ($QSOs as $QSO_ID => $QSO) {
911
-                                $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
912
-                            }
913
-                        }
914
-                    }
915
-                }
916
-            }
917
-        }
918
-        return $questions;
919
-    }
920
-
921
-
922
-    /**
923
-     * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
924
-     *                             or an stdClass where each property is the name of a column,
925
-     * @return EE_Base_Class
926
-     * @throws EE_Error
927
-     */
928
-    public function instantiate_class_from_array_or_object($cols_n_values)
929
-    {
930
-        $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
931
-        if ($classInstance instanceof EE_Event) {
932
-            // events have their timezone defined in the DB, so use it immediately
933
-            $this->set_timezone($classInstance->get_timezone());
934
-        }
935
-        return $classInstance;
936
-    }
17
+	/**
18
+	 * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
19
+	 * event
20
+	 */
21
+	const sold_out = 'sold_out';
22
+
23
+	/**
24
+	 * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
25
+	 * date)
26
+	 */
27
+	const postponed = 'postponed';
28
+
29
+	/**
30
+	 * constant used by status(), indicating that the event will no longer occur
31
+	 */
32
+	const cancelled = 'cancelled';
33
+
34
+
35
+	/**
36
+	 * @var string
37
+	 */
38
+	protected static $_default_reg_status;
39
+
40
+
41
+	/**
42
+	 * This is the default for the additional limit field.
43
+	 * @var int
44
+	 */
45
+	protected static $_default_additional_limit = 10;
46
+
47
+
48
+	/**
49
+	 * private instance of the Event object
50
+	 *
51
+	 * @var EEM_Event
52
+	 */
53
+	protected static $_instance;
54
+
55
+
56
+	/**
57
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
58
+	 *
59
+	 * @param string $timezone
60
+	 * @throws EE_Error
61
+	 * @throws ReflectionException
62
+	 */
63
+	protected function __construct($timezone = null)
64
+	{
65
+		EE_Registry::instance()->load_model('Registration');
66
+		$this->singular_item = esc_html__('Event', 'event_espresso');
67
+		$this->plural_item = esc_html__('Events', 'event_espresso');
68
+		// to remove Cancelled events from the frontend, copy the following filter to your functions.php file
69
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
70
+		// to remove Postponed events from the frontend, copy the following filter to your functions.php file
71
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
72
+		// to remove Sold Out events from the frontend, copy the following filter to your functions.php file
73
+		//  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
74
+		$this->_custom_stati = apply_filters(
75
+			'AFEE__EEM_Event__construct___custom_stati',
76
+			array(
77
+				EEM_Event::cancelled => array(
78
+					'label'  => esc_html__('Cancelled', 'event_espresso'),
79
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
80
+				),
81
+				EEM_Event::postponed => array(
82
+					'label'  => esc_html__('Postponed', 'event_espresso'),
83
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
84
+				),
85
+				EEM_Event::sold_out  => array(
86
+					'label'  => esc_html__('Sold Out', 'event_espresso'),
87
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
88
+				),
89
+			)
90
+		);
91
+		self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
92
+			: self::$_default_reg_status;
93
+		$this->_tables = array(
94
+			'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
95
+			'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
96
+		);
97
+		$this->_fields = array(
98
+			'Event_CPT'  => array(
99
+				'EVT_ID'         => new EE_Primary_Key_Int_Field(
100
+					'ID',
101
+					esc_html__('Post ID for Event', 'event_espresso')
102
+				),
103
+				'EVT_name'       => new EE_Plain_Text_Field(
104
+					'post_title',
105
+					esc_html__('Event Name', 'event_espresso'),
106
+					false,
107
+					''
108
+				),
109
+				'EVT_desc'       => new EE_Post_Content_Field(
110
+					'post_content',
111
+					esc_html__('Event Description', 'event_espresso'),
112
+					false,
113
+					''
114
+				),
115
+				'EVT_slug'       => new EE_Slug_Field(
116
+					'post_name',
117
+					esc_html__('Event Slug', 'event_espresso'),
118
+					false,
119
+					''
120
+				),
121
+				'EVT_created'    => new EE_Datetime_Field(
122
+					'post_date',
123
+					esc_html__('Date/Time Event Created', 'event_espresso'),
124
+					false,
125
+					EE_Datetime_Field::now
126
+				),
127
+				'EVT_short_desc' => new EE_Simple_HTML_Field(
128
+					'post_excerpt',
129
+					esc_html__('Event Short Description', 'event_espresso'),
130
+					false,
131
+					''
132
+				),
133
+				'EVT_modified'   => new EE_Datetime_Field(
134
+					'post_modified',
135
+					esc_html__('Date/Time Event Modified', 'event_espresso'),
136
+					false,
137
+					EE_Datetime_Field::now
138
+				),
139
+				'EVT_wp_user'    => new EE_WP_User_Field(
140
+					'post_author',
141
+					esc_html__('Event Creator ID', 'event_espresso'),
142
+					false
143
+				),
144
+				'parent'         => new EE_Integer_Field(
145
+					'post_parent',
146
+					esc_html__('Event Parent ID', 'event_espresso'),
147
+					false,
148
+					0
149
+				),
150
+				'EVT_order'      => new EE_Integer_Field(
151
+					'menu_order',
152
+					esc_html__('Event Menu Order', 'event_espresso'),
153
+					false,
154
+					1
155
+				),
156
+				'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
157
+				// EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
158
+				'status'         => new EE_WP_Post_Status_Field(
159
+					'post_status',
160
+					esc_html__('Event Status', 'event_espresso'),
161
+					false,
162
+					'draft',
163
+					$this->_custom_stati
164
+				),
165
+				'password' => new EE_Password_Field(
166
+					'post_password',
167
+					__('Password', 'event_espresso'),
168
+					false,
169
+					'',
170
+					array(
171
+						'EVT_desc',
172
+						'EVT_short_desc',
173
+						'EVT_display_desc',
174
+						'EVT_display_ticket_selector',
175
+						'EVT_visible_on',
176
+						'EVT_additional_limit',
177
+						'EVT_default_registration_status',
178
+						'EVT_member_only',
179
+						'EVT_phone',
180
+						'EVT_allow_overflow',
181
+						'EVT_timezone_string',
182
+						'EVT_external_URL',
183
+						'EVT_donations'
184
+					)
185
+				)
186
+			),
187
+			'Event_Meta' => array(
188
+				'EVTM_ID'                         => new EE_DB_Only_Float_Field(
189
+					'EVTM_ID',
190
+					esc_html__('Event Meta Row ID', 'event_espresso'),
191
+					false
192
+				),
193
+				'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
194
+					'EVT_ID',
195
+					esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
196
+					false
197
+				),
198
+				'EVT_display_desc'                => new EE_Boolean_Field(
199
+					'EVT_display_desc',
200
+					esc_html__('Display Description Flag', 'event_espresso'),
201
+					false,
202
+					true
203
+				),
204
+				'EVT_display_ticket_selector'     => new EE_Boolean_Field(
205
+					'EVT_display_ticket_selector',
206
+					esc_html__('Display Ticket Selector Flag', 'event_espresso'),
207
+					false,
208
+					true
209
+				),
210
+				'EVT_visible_on'                  => new EE_Datetime_Field(
211
+					'EVT_visible_on',
212
+					esc_html__('Event Visible Date', 'event_espresso'),
213
+					true,
214
+					EE_Datetime_Field::now
215
+				),
216
+				'EVT_additional_limit'            => new EE_Integer_Field(
217
+					'EVT_additional_limit',
218
+					esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
219
+					true,
220
+					self::$_default_additional_limit
221
+				),
222
+				'EVT_default_registration_status' => new EE_Enum_Text_Field(
223
+					'EVT_default_registration_status',
224
+					esc_html__('Default Registration Status on this Event', 'event_espresso'),
225
+					false,
226
+					EEM_Event::$_default_reg_status,
227
+					EEM_Registration::reg_status_array()
228
+				),
229
+				'EVT_member_only'                 => new EE_Boolean_Field(
230
+					'EVT_member_only',
231
+					esc_html__('Member-Only Event Flag', 'event_espresso'),
232
+					false,
233
+					false
234
+				),
235
+				'EVT_phone'                       => new EE_Plain_Text_Field(
236
+					'EVT_phone',
237
+					esc_html__('Event Phone Number', 'event_espresso'),
238
+					false,
239
+					''
240
+				),
241
+				'EVT_allow_overflow'              => new EE_Boolean_Field(
242
+					'EVT_allow_overflow',
243
+					esc_html__('Allow Overflow on Event', 'event_espresso'),
244
+					false,
245
+					false
246
+				),
247
+				'EVT_timezone_string'             => new EE_Plain_Text_Field(
248
+					'EVT_timezone_string',
249
+					esc_html__('Timezone (name) for Event times', 'event_espresso'),
250
+					false,
251
+					''
252
+				),
253
+				'EVT_external_URL'                => new EE_Plain_Text_Field(
254
+					'EVT_external_URL',
255
+					esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
256
+					true
257
+				),
258
+				'EVT_donations'                   => new EE_Boolean_Field(
259
+					'EVT_donations',
260
+					esc_html__('Accept Donations?', 'event_espresso'),
261
+					false,
262
+					false
263
+				),
264
+				'FSC_UUID'                        => new EE_Foreign_Key_String_Field(
265
+					'FSC_UUID',
266
+					esc_html__('Registration Form UUID (universally unique identifier)', 'event_espresso'),
267
+					true,
268
+					null,
269
+					'Form_Section',
270
+					false
271
+				),
272
+			),
273
+		);
274
+		$this->_model_relations = array(
275
+			'Attendee'               => new EE_HABTM_Relation('Registration'),
276
+			'Datetime'               => new EE_Has_Many_Relation(),
277
+			'Event_Question_Group'   => new EE_Has_Many_Relation(),
278
+			'Form_Section'           => new EE_Belongs_To_Relation(),
279
+			'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
280
+			'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
281
+			'Registration'           => new EE_Has_Many_Relation(),
282
+			'Term_Relationship'      => new EE_Has_Many_Relation(),
283
+			'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
284
+			'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
285
+			'WP_User'                => new EE_Belongs_To_Relation(),
286
+		);
287
+		// this model is generally available for reading
288
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
289
+		$this->model_chain_to_password = '';
290
+		parent::__construct($timezone);
291
+	}
292
+
293
+
294
+	/**
295
+	 * @param string $default_reg_status
296
+	 * @throws EE_Error
297
+	 * @throws EE_Error
298
+	 */
299
+	public static function set_default_reg_status($default_reg_status)
300
+	{
301
+		self::$_default_reg_status = $default_reg_status;
302
+		// if EEM_Event has already been instantiated,
303
+		// then we need to reset the `EVT_default_reg_status` field to use the new default.
304
+		if (self::$_instance instanceof EEM_Event) {
305
+			$default_reg_status = new EE_Enum_Text_Field(
306
+				'EVT_default_registration_status',
307
+				esc_html__('Default Registration Status on this Event', 'event_espresso'),
308
+				false,
309
+				$default_reg_status,
310
+				EEM_Registration::reg_status_array()
311
+			);
312
+			$default_reg_status->_construct_finalize(
313
+				'Event_Meta',
314
+				'EVT_default_registration_status',
315
+				'EEM_Event'
316
+			);
317
+			self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
318
+		}
319
+	}
320
+
321
+
322
+	/**
323
+	 * Used to override the default for the additional limit field.
324
+	 * @param $additional_limit
325
+	 */
326
+	public static function set_default_additional_limit($additional_limit)
327
+	{
328
+		self::$_default_additional_limit = (int) $additional_limit;
329
+		if (self::$_instance instanceof EEM_Event) {
330
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
331
+				'EVT_additional_limit',
332
+				__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
333
+				true,
334
+				self::$_default_additional_limit
335
+			);
336
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
337
+				'Event_Meta',
338
+				'EVT_additional_limit',
339
+				'EEM_Event'
340
+			);
341
+		}
342
+	}
343
+
344
+
345
+	/**
346
+	 * Return what is currently set as the default additional limit for the event.
347
+	 * @return int
348
+	 */
349
+	public static function get_default_additional_limit()
350
+	{
351
+		return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
352
+	}
353
+
354
+
355
+	/**
356
+	 * get_question_groups
357
+	 *
358
+	 * @return array
359
+	 * @throws EE_Error
360
+	 * @throws ReflectionException
361
+	 */
362
+	public function get_all_question_groups()
363
+	{
364
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
365
+			array(
366
+				array('QSG_deleted' => false),
367
+				'order_by' => array('QSG_order' => 'ASC'),
368
+			)
369
+		);
370
+	}
371
+
372
+
373
+	/**
374
+	 * get_question_groups
375
+	 *
376
+	 * @param int $EVT_ID
377
+	 * @return array|bool
378
+	 * @throws EE_Error
379
+	 * @throws ReflectionException
380
+	 */
381
+	public function get_all_event_question_groups($EVT_ID = 0)
382
+	{
383
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
384
+			EE_Error::add_error(
385
+				esc_html__(
386
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
387
+					'event_espresso'
388
+				),
389
+				__FILE__,
390
+				__FUNCTION__,
391
+				__LINE__
392
+			);
393
+			return false;
394
+		}
395
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
396
+			array(
397
+				array('EVT_ID' => $EVT_ID),
398
+			)
399
+		);
400
+	}
401
+
402
+
403
+	/**
404
+	 * get_question_groups
405
+	 *
406
+	 * @param int $EVT_ID
407
+	 * @param boolean $for_primary_attendee
408
+	 * @return array|bool
409
+	 * @throws EE_Error
410
+	 * @throws InvalidArgumentException
411
+	 * @throws ReflectionException
412
+	 * @throws InvalidDataTypeException
413
+	 * @throws InvalidInterfaceException
414
+	 */
415
+	public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
416
+	{
417
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
418
+			EE_Error::add_error(
419
+				esc_html__(
420
+					// @codingStandardsIgnoreStart
421
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
422
+					// @codingStandardsIgnoreEnd
423
+					'event_espresso'
424
+				),
425
+				__FILE__,
426
+				__FUNCTION__,
427
+				__LINE__
428
+			);
429
+			return false;
430
+		}
431
+		$query_params = [
432
+			[
433
+				'EVT_ID' => $EVT_ID,
434
+				EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true
435
+			]
436
+		];
437
+		if ($for_primary_attendee) {
438
+			$query_params[0]['EQG_primary'] = true;
439
+		} else {
440
+			$query_params[0]['EQG_additional'] = true;
441
+		}
442
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params);
443
+	}
444
+
445
+
446
+	/**
447
+	 * get_question_groups
448
+	 *
449
+	 * @param int $EVT_ID
450
+	 * @param EE_Registration $registration
451
+	 * @return array|bool
452
+	 * @throws EE_Error
453
+	 * @throws InvalidArgumentException
454
+	 * @throws InvalidDataTypeException
455
+	 * @throws InvalidInterfaceException
456
+	 * @throws ReflectionException
457
+	 */
458
+	public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
459
+	{
460
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
461
+			EE_Error::add_error(
462
+				esc_html__(
463
+					'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
464
+					'event_espresso'
465
+				),
466
+				__FILE__,
467
+				__FUNCTION__,
468
+				__LINE__
469
+			);
470
+			return false;
471
+		}
472
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
473
+			[
474
+				[
475
+					'Event_Question_Group.EVT_ID'      => $EVT_ID,
476
+					'Event_Question_Group.'
477
+						. EEM_Event_Question_Group::instance()->fieldNameForContext(
478
+							$registration->is_primary_registrant()
479
+						) => true
480
+				],
481
+				'order_by' => ['QSG_order' => 'ASC'],
482
+			]
483
+		);
484
+	}
485
+
486
+
487
+	/**
488
+	 * get_question_target_db_column
489
+	 *
490
+	 * @param string $QSG_IDs csv list of $QSG IDs
491
+	 * @return array|bool
492
+	 * @throws EE_Error
493
+	 * @throws ReflectionException
494
+	 */
495
+	public function get_questions_in_groups($QSG_IDs = '')
496
+	{
497
+		if (empty($QSG_IDs)) {
498
+			EE_Error::add_error(
499
+				esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
500
+				__FILE__,
501
+				__FUNCTION__,
502
+				__LINE__
503
+			);
504
+			return false;
505
+		}
506
+		return EE_Registry::instance()->load_model('Question')->get_all(
507
+			array(
508
+				array(
509
+					'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
510
+					'QST_deleted'           => false,
511
+					'QST_admin_only'        => is_admin(),
512
+				),
513
+				'order_by' => 'QST_order',
514
+			)
515
+		);
516
+	}
517
+
518
+
519
+	/**
520
+	 * get_options_for_question
521
+	 *
522
+	 * @param string $QST_IDs csv list of $QST IDs
523
+	 * @return array|bool
524
+	 * @throws EE_Error
525
+	 * @throws ReflectionException
526
+	 */
527
+	public function get_options_for_question($QST_IDs)
528
+	{
529
+		if (empty($QST_IDs)) {
530
+			EE_Error::add_error(
531
+				esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
532
+				__FILE__,
533
+				__FUNCTION__,
534
+				__LINE__
535
+			);
536
+			return false;
537
+		}
538
+		return EE_Registry::instance()->load_model('Question_Option')->get_all(
539
+			array(
540
+				array(
541
+					'Question.QST_ID' => array('IN', $QST_IDs),
542
+					'QSO_deleted'     => false,
543
+				),
544
+				'order_by' => 'QSO_ID',
545
+			)
546
+		);
547
+	}
548
+
549
+
550
+	/**
551
+	 * Gets all events that are published
552
+	 * and have event start time earlier than now and an event end time later than now
553
+	 *
554
+	 * @param array $query_params  An array of query params to further filter on
555
+	 *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
556
+	 * @param bool  $count         whether to return the count or not (default FALSE)
557
+	 * @return EE_Event[]|int
558
+	 * @throws EE_Error
559
+	 * @throws ReflectionException
560
+	 */
561
+	public function get_active_events($query_params, $count = false)
562
+	{
563
+		if (array_key_exists(0, $query_params)) {
564
+			$where_params = $query_params[0];
565
+			unset($query_params[0]);
566
+		} else {
567
+			$where_params = array();
568
+		}
569
+		// if we have count make sure we don't include group by
570
+		if ($count && isset($query_params['group_by'])) {
571
+			unset($query_params['group_by']);
572
+		}
573
+		// let's add specific query_params for active_events
574
+		// keep in mind this will override any sent status in the query AND any date queries.
575
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
576
+		// if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
577
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
578
+			$where_params['Datetime.DTT_EVT_start******'] = array(
579
+				'<',
580
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
581
+			);
582
+		} else {
583
+			$where_params['Datetime.DTT_EVT_start'] = array(
584
+				'<',
585
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
586
+			);
587
+		}
588
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
589
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
590
+				'>',
591
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
592
+			);
593
+		} else {
594
+			$where_params['Datetime.DTT_EVT_end'] = array(
595
+				'>',
596
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
597
+			);
598
+		}
599
+		$query_params[0] = $where_params;
600
+		// don't use $query_params with count()
601
+		// because we don't want to include additional query clauses like "GROUP BY"
602
+		return $count
603
+			? $this->count(array($where_params), 'EVT_ID', true)
604
+			: $this->get_all($query_params);
605
+	}
606
+
607
+
608
+	/**
609
+	 * get all events that are published and have an event start time later than now
610
+	 *
611
+	 * @param array $query_params  An array of query params to further filter on
612
+	 *                             (Note that status and DTT_EVT_start will be overridden)
613
+	 * @param bool  $count         whether to return the count or not (default FALSE)
614
+	 * @return EE_Event[]|int
615
+	 * @throws EE_Error
616
+	 * @throws ReflectionException
617
+	 */
618
+	public function get_upcoming_events($query_params, $count = false)
619
+	{
620
+		if (array_key_exists(0, $query_params)) {
621
+			$where_params = $query_params[0];
622
+			unset($query_params[0]);
623
+		} else {
624
+			$where_params = array();
625
+		}
626
+		// if we have count make sure we don't include group by
627
+		if ($count && isset($query_params['group_by'])) {
628
+			unset($query_params['group_by']);
629
+		}
630
+		// let's add specific query_params for active_events
631
+		// keep in mind this will override any sent status in the query AND any date queries.
632
+		// we need to pull events with a status of publish and sold_out
633
+		$event_status = array('publish', EEM_Event::sold_out);
634
+		// check if the user can read private events and if so add the 'private status to the were params'
635
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_upcoming_events')) {
636
+			$event_status[] = 'private';
637
+		}
638
+		$where_params['status'] = array('IN', $event_status);
639
+		// if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
640
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
641
+			$where_params['Datetime.DTT_EVT_start*****'] = array(
642
+				'>',
643
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
644
+			);
645
+		} else {
646
+			$where_params['Datetime.DTT_EVT_start'] = array(
647
+				'>',
648
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
649
+			);
650
+		}
651
+		$query_params[0] = $where_params;
652
+		// don't use $query_params with count()
653
+		// because we don't want to include additional query clauses like "GROUP BY"
654
+		return $count
655
+			? $this->count(array($where_params), 'EVT_ID', true)
656
+			: $this->get_all($query_params);
657
+	}
658
+
659
+
660
+	/**
661
+	 * Gets all events that are published
662
+	 * and have an event end time later than now
663
+	 *
664
+	 * @param array $query_params  An array of query params to further filter on
665
+	 *                             (note that status and DTT_EVT_end will be overridden)
666
+	 * @param bool  $count         whether to return the count or not (default FALSE)
667
+	 * @return EE_Event[]|int
668
+	 * @throws EE_Error
669
+	 * @throws ReflectionException
670
+	 */
671
+	public function get_active_and_upcoming_events($query_params, $count = false)
672
+	{
673
+		if (array_key_exists(0, $query_params)) {
674
+			$where_params = $query_params[0];
675
+			unset($query_params[0]);
676
+		} else {
677
+			$where_params = array();
678
+		}
679
+		// if we have count make sure we don't include group by
680
+		if ($count && isset($query_params['group_by'])) {
681
+			unset($query_params['group_by']);
682
+		}
683
+		// let's add specific query_params for active_events
684
+		// keep in mind this will override any sent status in the query AND any date queries.
685
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
686
+		// add where params for DTT_EVT_end
687
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
688
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
689
+				'>',
690
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
691
+			);
692
+		} else {
693
+			$where_params['Datetime.DTT_EVT_end'] = array(
694
+				'>',
695
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
696
+			);
697
+		}
698
+		$query_params[0] = $where_params;
699
+		// don't use $query_params with count()
700
+		// because we don't want to include additional query clauses like "GROUP BY"
701
+		return $count
702
+			? $this->count(array($where_params), 'EVT_ID', true)
703
+			: $this->get_all($query_params);
704
+	}
705
+
706
+
707
+	/**
708
+	 * This only returns events that are expired.
709
+	 * They may still be published but all their datetimes have expired.
710
+	 *
711
+	 * @param array $query_params  An array of query params to further filter on
712
+	 *                             (note that status and DTT_EVT_end will be overridden)
713
+	 * @param bool  $count         whether to return the count or not (default FALSE)
714
+	 * @return EE_Event[]|int
715
+	 * @throws EE_Error
716
+	 * @throws ReflectionException
717
+	 */
718
+	public function get_expired_events($query_params, $count = false)
719
+	{
720
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
721
+		// if we have count make sure we don't include group by
722
+		if ($count && isset($query_params['group_by'])) {
723
+			unset($query_params['group_by']);
724
+		}
725
+		// let's add specific query_params for active_events
726
+		// keep in mind this will override any sent status in the query AND any date queries.
727
+		if (isset($where_params['status'])) {
728
+			unset($where_params['status']);
729
+		}
730
+		$exclude_query = $query_params;
731
+		if (isset($exclude_query[0])) {
732
+			unset($exclude_query[0]);
733
+		}
734
+		$exclude_query[0] = array(
735
+			'Datetime.DTT_EVT_end' => array(
736
+				'>',
737
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
738
+			),
739
+		);
740
+		// first get all events that have datetimes where its not expired.
741
+		$event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
742
+		$event_ids = array_keys($event_ids);
743
+		// if we have any additional query_params, let's add them to the 'AND' condition
744
+		$and_condition = array(
745
+			'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
746
+			'EVT_ID'               => array('NOT IN', $event_ids),
747
+		);
748
+		if (isset($where_params['OR'])) {
749
+			$and_condition['OR'] = $where_params['OR'];
750
+			unset($where_params['OR']);
751
+		}
752
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
753
+			$and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
754
+			unset($where_params['Datetime.DTT_EVT_end']);
755
+		}
756
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
757
+			$and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
758
+			unset($where_params['Datetime.DTT_EVT_start']);
759
+		}
760
+		// merge remaining $where params with the and conditions.
761
+		$where_params['AND'] = array_merge($and_condition, $where_params);
762
+		$query_params[0] = $where_params;
763
+		// don't use $query_params with count()
764
+		// because we don't want to include additional query clauses like "GROUP BY"
765
+		return $count
766
+			? $this->count(array($where_params), 'EVT_ID', true)
767
+			: $this->get_all($query_params);
768
+	}
769
+
770
+
771
+
772
+	/**
773
+	 * This basically just returns the events that do not have the publish status.
774
+	 *
775
+	 * @param  array   $query_params An array of query params to further filter on
776
+	 *                               (note that status will be overwritten)
777
+	 * @param  boolean $count        whether to return the count or not (default FALSE)
778
+	 * @return EE_Event[]|int
779
+	 * @throws EE_Error
780
+	 */
781
+	public function get_inactive_events($query_params, $count = false)
782
+	{
783
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
784
+		// let's add in specific query_params for inactive events.
785
+		if (isset($where_params['status'])) {
786
+			unset($where_params['status']);
787
+		}
788
+		// if we have count make sure we don't include group by
789
+		if ($count && isset($query_params['group_by'])) {
790
+			unset($query_params['group_by']);
791
+		}
792
+		// if we have any additional query_params, let's add them to the 'AND' condition
793
+		$where_params['AND']['status'] = array('!=', 'publish');
794
+		if (isset($where_params['OR'])) {
795
+			$where_params['AND']['OR'] = $where_params['OR'];
796
+			unset($where_params['OR']);
797
+		}
798
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
799
+			$where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
800
+			unset($where_params['Datetime.DTT_EVT_end']);
801
+		}
802
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
803
+			$where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
804
+			unset($where_params['Datetime.DTT_EVT_start']);
805
+		}
806
+		$query_params[0] = $where_params;
807
+		// don't use $query_params with count()
808
+		// because we don't want to include additional query clauses like "GROUP BY"
809
+		return $count
810
+			? $this->count(array($where_params), 'EVT_ID', true)
811
+			: $this->get_all($query_params);
812
+	}
813
+
814
+
815
+	/**
816
+	 * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
817
+	 * because we don't want to override any existing global default prices but instead insert NEW prices that get
818
+	 * attached to the event. See parent for param descriptions
819
+	 *
820
+	 * @param        $id_or_obj
821
+	 * @param        $other_model_id_or_obj
822
+	 * @param string $relationName
823
+	 * @param array  $where_query
824
+	 * @return EE_Base_Class
825
+	 * @throws EE_Error
826
+	 * @throws ReflectionException
827
+	 */
828
+	public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
829
+	{
830
+		if ($relationName === 'Price') {
831
+			// let's get the PRC object for the given ID to make sure that we aren't dealing with a default
832
+			$prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
833
+			// if EVT_ID = 0, then this is a default
834
+			if ((int) $prc_chk->get('EVT_ID') === 0) {
835
+				// let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
836
+				$prc_chk->set('PRC_ID', 0);
837
+			}
838
+			// run parent
839
+			return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
840
+		}
841
+		// otherwise carry on as normal
842
+		return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
843
+	}
844
+
845
+
846
+
847
+	/******************** DEPRECATED METHODS ********************/
848
+
849
+
850
+	/**
851
+	 * _get_question_target_db_column
852
+	 *
853
+	 * @param EE_Registration $registration    (so existing answers for registration are included)
854
+	 * @param int             $EVT_ID          so all question groups are included for event (not just answers from
855
+	 *                                         registration).
856
+	 * @return    array
857
+	 * @throws ReflectionException
858
+	 * @throws EE_Error*@deprecated as of 4.8.32.rc.001. Instead consider using
859
+	 *                                         EE_Registration_Custom_Questions_Form located in
860
+	 *                                         admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
861
+	 * @access     public
862
+	 */
863
+	public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
864
+	{
865
+		if (empty($EVT_ID)) {
866
+			throw new EE_Error(__(
867
+				'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
868
+				'event_espresso'
869
+			));
870
+		}
871
+		$questions = array();
872
+		// get all question groups for event
873
+		$qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
874
+		if (! empty($qgs)) {
875
+			foreach ($qgs as $qg) {
876
+				$qsts = $qg->questions();
877
+				$questions[ $qg->ID() ] = $qg->model_field_array();
878
+				$questions[ $qg->ID() ]['QSG_questions'] = array();
879
+				foreach ($qsts as $qst) {
880
+					if ($qst->is_system_question()) {
881
+						continue;
882
+					}
883
+					$answer = EEM_Answer::instance()->get_one(array(
884
+						array(
885
+							'QST_ID' => $qst->ID(),
886
+							'REG_ID' => $registration->ID(),
887
+						),
888
+					));
889
+					$answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
890
+					$qst_name = $qstn_id = $qst->ID();
891
+					$ans_id = $answer->ID();
892
+					$qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
893
+					$input_name = '';
894
+					$input_id = sanitize_key($qst->display_text());
895
+					$input_class = '';
896
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
897
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
898
+																						   . $input_name
899
+																						   . $qst_name;
900
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
901
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
902
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
903
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
904
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
905
+					// leave responses as-is, don't convert stuff into html entities please!
906
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
907
+					if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
908
+						$QSOs = $qst->options(true, $answer->value());
909
+						if (is_array($QSOs)) {
910
+							foreach ($QSOs as $QSO_ID => $QSO) {
911
+								$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
912
+							}
913
+						}
914
+					}
915
+				}
916
+			}
917
+		}
918
+		return $questions;
919
+	}
920
+
921
+
922
+	/**
923
+	 * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
924
+	 *                             or an stdClass where each property is the name of a column,
925
+	 * @return EE_Base_Class
926
+	 * @throws EE_Error
927
+	 */
928
+	public function instantiate_class_from_array_or_object($cols_n_values)
929
+	{
930
+		$classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
931
+		if ($classInstance instanceof EE_Event) {
932
+			// events have their timezone defined in the DB, so use it immediately
933
+			$this->set_timezone($classInstance->get_timezone());
934
+		}
935
+		return $classInstance;
936
+	}
937 937
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Form_Element.model.php 1 patch
Indentation   +217 added lines, -217 removed lines patch added patch discarded remove patch
@@ -28,237 +28,237 @@
 block discarded – undo
28 28
 class EEM_Form_Element extends EEM_Base
29 29
 {
30 30
 
31
-    /**
32
-     * @var EEM_Form_Element
33
-     */
34
-    protected static $_instance;
31
+	/**
32
+	 * @var EEM_Form_Element
33
+	 */
34
+	protected static $_instance;
35 35
 
36
-    /**
37
-     * @var RequestInterface
38
-     */
39
-    private $request;
36
+	/**
37
+	 * @var RequestInterface
38
+	 */
39
+	private $request;
40 40
 
41
-    /**
42
-     * @var InputTypes
43
-     */
44
-    private $input_types;
41
+	/**
42
+	 * @var InputTypes
43
+	 */
44
+	private $input_types;
45 45
 
46 46
 
47
-    /**
48
-     * EEM_Form_Element constructor.
49
-     *
50
-     * @param FormStatus  $form_status
51
-     * @param InputTypes  $input_types
52
-     * @param string|null $timezone
53
-     * @throws EE_Error
54
-     */
55
-    protected function __construct(FormStatus $form_status, InputTypes $input_types, ?string $timezone)
56
-    {
57
-        $this->input_types   = $input_types;
58
-        $this->singular_item = esc_html__('Form Element', 'event_espresso');
59
-        $this->plural_item   = esc_html__('Form Elements', 'event_espresso');
47
+	/**
48
+	 * EEM_Form_Element constructor.
49
+	 *
50
+	 * @param FormStatus  $form_status
51
+	 * @param InputTypes  $input_types
52
+	 * @param string|null $timezone
53
+	 * @throws EE_Error
54
+	 */
55
+	protected function __construct(FormStatus $form_status, InputTypes $input_types, ?string $timezone)
56
+	{
57
+		$this->input_types   = $input_types;
58
+		$this->singular_item = esc_html__('Form Element', 'event_espresso');
59
+		$this->plural_item   = esc_html__('Form Elements', 'event_espresso');
60 60
 
61
-        $this->_tables          = [
62
-            'Form_Element' => new EE_Primary_Table('esp_form_element', 'FIN_UUID'),
63
-        ];
64
-        $this->_fields          = [
65
-            'Form_Element' => [
66
-                'FIN_UUID'      => new EE_Primary_Key_String_Field(
67
-                    'FIN_UUID',
68
-                    esc_html__('Form Element UUID (universally unique identifier)', 'event_espresso')
69
-                ),
70
-                'FSC_UUID' => new EE_Foreign_Key_String_Field(
71
-                    'FSC_UUID',
72
-                    esc_html__('UUID of parent form section this form input belongs to.', 'event_espresso'),
73
-                    false,
74
-                    null,
75
-                    ['Form_Section'],
76
-                    false
77
-                ),
78
-                'FIN_adminOnly' => new EE_Boolean_Field(
79
-                    'FIN_adminOnly',
80
-                    esc_html__(
81
-                        'Whether or not input is only displayed in the admin. If false, input will appear in public forms',
82
-                        'event_espresso'
83
-                    ),
84
-                    false,
85
-                    false
86
-                ),
87
-                'FIN_attributes' => new EE_JSON_Field(
88
-                    'FIN_attributes',
89
-                    esc_html__(
90
-                        'JSON string of HTML attributes such as class, max, min, placeholder, type, etc.',
91
-                        'event_espresso'
92
-                    ),
93
-                    true,
94
-                    '{}'
95
-                ),
96
-                'FIN_helpText' => new EE_JSON_Field(
97
-                    'FIN_helpText',
98
-                    esc_html__(
99
-                        'JSON string of properties pertaining to any help text required for an input.',
100
-                        'event_espresso'
101
-                    ),
102
-                    true,
103
-                    '{}'
104
-                ),
105
-                'FIN_label' => new EE_JSON_Field(
106
-                    'FIN_label',
107
-                    esc_html__(
108
-                        'JSON string of properties pertaining to an element\'s label.',
109
-                        'event_espresso'
110
-                    ),
111
-                    true,
112
-                    '{}'
113
-                ),
114
-                'FIN_mapsTo'     => new EE_Plain_Text_Field(
115
-                    'FIN_mapsTo',
116
-                    esc_html__(
117
-                        'Model and Fields name that this element maps to; ex: Attendee.email',
118
-                        'event_espresso'
119
-                    ),
120
-                    true,
121
-                    null
122
-                ),
123
-                'FIN_options'     => new EE_JSON_Field(
124
-                    'FIN_options',
125
-                    esc_html__(
126
-                        'JSON string of options for ENUM type inputs like checkboxes, radio buttons, select inputs, etc.',
127
-                        'event_espresso'
128
-                    ),
129
-                    true,
130
-                    '[]'
131
-                ),
132
-                'FIN_order'     => new EE_Integer_Field(
133
-                    'FIN_order',
134
-                    esc_html__('Order in which form input appears in a form.', 'event_espresso'),
135
-                    false,
136
-                    0
137
-                ),
138
-                'FIN_required' => new EE_JSON_Field(
139
-                    'FIN_required',
140
-                    esc_html__(
141
-                        'properties pertaining to an input\'s required status and the validation text to display.',
142
-                        'event_espresso'
143
-                    ),
144
-                    false,
145
-                    false
146
-                ),
147
-                'FIN_status'    => new EE_Enum_Text_Field(
148
-                    'FIN_status',
149
-                    esc_html(
150
-                        sprintf(
151
-                            /* translators: 1 class name */
152
-                            __(
153
-                                'Whether form element is active, archived, trashed, or used as a default on new forms. Values correspond to the %1$s class constants.',
154
-                                'event_espresso'
155
-                            ),
156
-                            'EventEspresso\core\services\form\meta\FormStatus'
157
-                        )
158
-                    ),
159
-                    false,
160
-                    FormStatus::ACTIVE,
161
-                    $form_status->validStatusOptions()
162
-                ),
163
-                'FIN_type'    => new EE_Enum_Text_Field(
164
-                    'FIN_type',
165
-                    esc_html__('Form element type.', 'event_espresso'),
166
-                    false,
167
-                    null,
168
-                    $input_types->validTypeOptions()
169
-                ),
170
-                'FIN_wpUser'    => new EE_WP_User_Field(
171
-                    'FIN_wpUser',
172
-                    esc_html__('ID of the WP User that created this form input.', 'event_espresso'),
173
-                    false
174
-                ),
175
-            ],
176
-        ];
61
+		$this->_tables          = [
62
+			'Form_Element' => new EE_Primary_Table('esp_form_element', 'FIN_UUID'),
63
+		];
64
+		$this->_fields          = [
65
+			'Form_Element' => [
66
+				'FIN_UUID'      => new EE_Primary_Key_String_Field(
67
+					'FIN_UUID',
68
+					esc_html__('Form Element UUID (universally unique identifier)', 'event_espresso')
69
+				),
70
+				'FSC_UUID' => new EE_Foreign_Key_String_Field(
71
+					'FSC_UUID',
72
+					esc_html__('UUID of parent form section this form input belongs to.', 'event_espresso'),
73
+					false,
74
+					null,
75
+					['Form_Section'],
76
+					false
77
+				),
78
+				'FIN_adminOnly' => new EE_Boolean_Field(
79
+					'FIN_adminOnly',
80
+					esc_html__(
81
+						'Whether or not input is only displayed in the admin. If false, input will appear in public forms',
82
+						'event_espresso'
83
+					),
84
+					false,
85
+					false
86
+				),
87
+				'FIN_attributes' => new EE_JSON_Field(
88
+					'FIN_attributes',
89
+					esc_html__(
90
+						'JSON string of HTML attributes such as class, max, min, placeholder, type, etc.',
91
+						'event_espresso'
92
+					),
93
+					true,
94
+					'{}'
95
+				),
96
+				'FIN_helpText' => new EE_JSON_Field(
97
+					'FIN_helpText',
98
+					esc_html__(
99
+						'JSON string of properties pertaining to any help text required for an input.',
100
+						'event_espresso'
101
+					),
102
+					true,
103
+					'{}'
104
+				),
105
+				'FIN_label' => new EE_JSON_Field(
106
+					'FIN_label',
107
+					esc_html__(
108
+						'JSON string of properties pertaining to an element\'s label.',
109
+						'event_espresso'
110
+					),
111
+					true,
112
+					'{}'
113
+				),
114
+				'FIN_mapsTo'     => new EE_Plain_Text_Field(
115
+					'FIN_mapsTo',
116
+					esc_html__(
117
+						'Model and Fields name that this element maps to; ex: Attendee.email',
118
+						'event_espresso'
119
+					),
120
+					true,
121
+					null
122
+				),
123
+				'FIN_options'     => new EE_JSON_Field(
124
+					'FIN_options',
125
+					esc_html__(
126
+						'JSON string of options for ENUM type inputs like checkboxes, radio buttons, select inputs, etc.',
127
+						'event_espresso'
128
+					),
129
+					true,
130
+					'[]'
131
+				),
132
+				'FIN_order'     => new EE_Integer_Field(
133
+					'FIN_order',
134
+					esc_html__('Order in which form input appears in a form.', 'event_espresso'),
135
+					false,
136
+					0
137
+				),
138
+				'FIN_required' => new EE_JSON_Field(
139
+					'FIN_required',
140
+					esc_html__(
141
+						'properties pertaining to an input\'s required status and the validation text to display.',
142
+						'event_espresso'
143
+					),
144
+					false,
145
+					false
146
+				),
147
+				'FIN_status'    => new EE_Enum_Text_Field(
148
+					'FIN_status',
149
+					esc_html(
150
+						sprintf(
151
+							/* translators: 1 class name */
152
+							__(
153
+								'Whether form element is active, archived, trashed, or used as a default on new forms. Values correspond to the %1$s class constants.',
154
+								'event_espresso'
155
+							),
156
+							'EventEspresso\core\services\form\meta\FormStatus'
157
+						)
158
+					),
159
+					false,
160
+					FormStatus::ACTIVE,
161
+					$form_status->validStatusOptions()
162
+				),
163
+				'FIN_type'    => new EE_Enum_Text_Field(
164
+					'FIN_type',
165
+					esc_html__('Form element type.', 'event_espresso'),
166
+					false,
167
+					null,
168
+					$input_types->validTypeOptions()
169
+				),
170
+				'FIN_wpUser'    => new EE_WP_User_Field(
171
+					'FIN_wpUser',
172
+					esc_html__('ID of the WP User that created this form input.', 'event_espresso'),
173
+					false
174
+				),
175
+			],
176
+		];
177 177
 
178
-        $this->_model_relations = [
179
-            'Form_Section' => new EE_Belongs_To_Relation(),
180
-            'WP_User'      => new EE_Belongs_To_Relation(),
181
-        ];
182
-        // this model is generally available for reading
183
-        $this->_cap_restriction_generators = [
184
-            EEM_Base::caps_read       => new EE_Restriction_Generator_Public(),
185
-            EEM_Base::caps_read_admin => new EE_Restriction_Generator_Reg_Form('FIN_applies_to'),
186
-            EEM_Base::caps_edit       => new EE_Restriction_Generator_Reg_Form('FIN_applies_to'),
187
-            EEM_Base::caps_delete     => new EE_Restriction_Generator_Reg_Form('FIN_applies_to'),
188
-        ];
189
-        parent::__construct($timezone);
190
-        $this->request = $this->getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
191
-    }
178
+		$this->_model_relations = [
179
+			'Form_Section' => new EE_Belongs_To_Relation(),
180
+			'WP_User'      => new EE_Belongs_To_Relation(),
181
+		];
182
+		// this model is generally available for reading
183
+		$this->_cap_restriction_generators = [
184
+			EEM_Base::caps_read       => new EE_Restriction_Generator_Public(),
185
+			EEM_Base::caps_read_admin => new EE_Restriction_Generator_Reg_Form('FIN_applies_to'),
186
+			EEM_Base::caps_edit       => new EE_Restriction_Generator_Reg_Form('FIN_applies_to'),
187
+			EEM_Base::caps_delete     => new EE_Restriction_Generator_Reg_Form('FIN_applies_to'),
188
+		];
189
+		parent::__construct($timezone);
190
+		$this->request = $this->getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
191
+	}
192 192
 
193 193
 
194
-    /**
195
-     * @param array $query_params
196
-     * @return array
197
-     */
198
-    private function addDefaultWhereConditions(array $query_params): array
199
-    {
200
-        // might need to add a way to identify GQL requests for admin domains
201
-        $admin_request                            = $this->request->isAdmin() || $this->request->isAdminAjax();
202
-        $query_params['default_where_conditions'] = $admin_request
203
-            ? EEM_Base::default_where_conditions_none
204
-            : EEM_Base::default_where_conditions_all;
205
-        return $query_params;
206
-    }
194
+	/**
195
+	 * @param array $query_params
196
+	 * @return array
197
+	 */
198
+	private function addDefaultWhereConditions(array $query_params): array
199
+	{
200
+		// might need to add a way to identify GQL requests for admin domains
201
+		$admin_request                            = $this->request->isAdmin() || $this->request->isAdminAjax();
202
+		$query_params['default_where_conditions'] = $admin_request
203
+			? EEM_Base::default_where_conditions_none
204
+			: EEM_Base::default_where_conditions_all;
205
+		return $query_params;
206
+	}
207 207
 
208 208
 
209
-    /**
210
-     * form inputs should always be sorted in ascending order via the FIN_order field
211
-     *
212
-     * @param array $query_params
213
-     * @return array
214
-     */
215
-    private function addOrderByQueryParams(array $query_params): array
216
-    {
217
-        $query_params['order_by'] = ['FIN_order' => 'ASC'];
218
-        return $query_params;
219
-    }
209
+	/**
210
+	 * form inputs should always be sorted in ascending order via the FIN_order field
211
+	 *
212
+	 * @param array $query_params
213
+	 * @return array
214
+	 */
215
+	private function addOrderByQueryParams(array $query_params): array
216
+	{
217
+		$query_params['order_by'] = ['FIN_order' => 'ASC'];
218
+		return $query_params;
219
+	}
220 220
 
221 221
 
222
-    /**
223
-     * @param EE_Form_Section $form_section
224
-     * @param EE_Form_Element[] $all_form_elements
225
-     * @return EE_Form_Element[]
226
-     * @throws EE_Error
227
-     * @throws ReflectionException
228
-     */
229
-    public function filterFormElementsForFormSection(EE_Form_Section $form_section, array $all_form_elements): array
230
-    {
231
-        return array_filter($all_form_elements, $form_section->formElementFilter());
232
-    }
222
+	/**
223
+	 * @param EE_Form_Section $form_section
224
+	 * @param EE_Form_Element[] $all_form_elements
225
+	 * @return EE_Form_Element[]
226
+	 * @throws EE_Error
227
+	 * @throws ReflectionException
228
+	 */
229
+	public function filterFormElementsForFormSection(EE_Form_Section $form_section, array $all_form_elements): array
230
+	{
231
+		return array_filter($all_form_elements, $form_section->formElementFilter());
232
+	}
233 233
 
234 234
 
235
-    /**
236
-     * @param EE_Form_Section[] $form_sections
237
-     * @return EE_Form_Element[]
238
-     * @throws EE_Error
239
-     * @throws ReflectionException
240
-     */
241
-    public function getAllFormElementsForFormSections(array $form_sections): array
242
-    {
243
-        $FSC_UUIDs = [];
244
-        foreach ($form_sections as $form_section) {
245
-            if ($form_section instanceof EE_Form_Section) {
246
-                $FSC_UUIDs[] = $form_section->UUID();
247
-            }
248
-        }
249
-        $where_params = ['FSC_UUID' => ['IN', $FSC_UUIDs]];
250
-        $query_params = $this->addDefaultWhereConditions([$where_params]);
251
-        $query_params = $this->addOrderByQueryParams($query_params);
252
-        return $this->get_all($query_params);
253
-    }
235
+	/**
236
+	 * @param EE_Form_Section[] $form_sections
237
+	 * @return EE_Form_Element[]
238
+	 * @throws EE_Error
239
+	 * @throws ReflectionException
240
+	 */
241
+	public function getAllFormElementsForFormSections(array $form_sections): array
242
+	{
243
+		$FSC_UUIDs = [];
244
+		foreach ($form_sections as $form_section) {
245
+			if ($form_section instanceof EE_Form_Section) {
246
+				$FSC_UUIDs[] = $form_section->UUID();
247
+			}
248
+		}
249
+		$where_params = ['FSC_UUID' => ['IN', $FSC_UUIDs]];
250
+		$query_params = $this->addDefaultWhereConditions([$where_params]);
251
+		$query_params = $this->addOrderByQueryParams($query_params);
252
+		return $this->get_all($query_params);
253
+	}
254 254
 
255 255
 
256
-    /**
257
-     * @param bool $constants_only
258
-     * @return array
259
-     */
260
-    public function validTypeOptions(bool $constants_only = false): array
261
-    {
262
-        return $this->input_types->validTypeOptions($constants_only);
263
-    }
256
+	/**
257
+	 * @param bool $constants_only
258
+	 * @return array
259
+	 */
260
+	public function validTypeOptions(bool $constants_only = false): array
261
+	{
262
+		return $this->input_types->validTypeOptions($constants_only);
263
+	}
264 264
 }
Please login to merge, or discard this patch.
core/db_models/EEM_Form_Submission.model.php 1 patch
Indentation   +114 added lines, -114 removed lines patch added patch discarded remove patch
@@ -11,130 +11,130 @@
 block discarded – undo
11 11
  */
12 12
 class EEM_Form_Submission extends EEM_Base
13 13
 {
14
-    /**
15
-     * @var EEM_Form_Submission
16
-     */
17
-    protected static $_instance;
14
+	/**
15
+	 * @var EEM_Form_Submission
16
+	 */
17
+	protected static $_instance;
18 18
 
19
-    /**
20
-     * @var RequestInterface
21
-     */
22
-    private $request;
19
+	/**
20
+	 * @var RequestInterface
21
+	 */
22
+	private $request;
23 23
 
24 24
 
25
-    /**
26
-     * EEM_Form_Submission constructor.
27
-     *
28
-     * @param string|null $timezone
29
-     * @throws EE_Error
30
-     */
31
-    protected function __construct(?string $timezone)
32
-    {
33
-        $this->singular_item = esc_html__('Form Submission', 'event_espresso');
34
-        $this->plural_item   = esc_html__('Form Submissions', 'event_espresso');
25
+	/**
26
+	 * EEM_Form_Submission constructor.
27
+	 *
28
+	 * @param string|null $timezone
29
+	 * @throws EE_Error
30
+	 */
31
+	protected function __construct(?string $timezone)
32
+	{
33
+		$this->singular_item = esc_html__('Form Submission', 'event_espresso');
34
+		$this->plural_item   = esc_html__('Form Submissions', 'event_espresso');
35 35
 
36
-        $this->_tables          = [
37
-            'Form_Submission' => new EE_Primary_Table('esp_form_submission', 'FSB_UUID'),
38
-        ];
39
-        $this->_fields          = [
40
-            'Form_Submission' => [
41
-                'FSB_UUID'      => new EE_Primary_Key_String_Field(
42
-                    'FSB_UUID',
43
-                    esc_html__('Form Submission UUID (universally unique identifier)', 'event_espresso')
44
-                ),
45
-                'FSC_UUID'      => new EE_Foreign_Key_String_Field(
46
-                    'FSC_UUID',
47
-                    esc_html__('Form Section UUID (universally unique identifier)', 'event_espresso'),
48
-                    false,
49
-                    '',
50
-                    'Form_Section',
51
-                    false
52
-                ),
53
-                'TXN_ID'        => new EE_Foreign_Key_Int_Field(
54
-                    'TXN_ID',
55
-                    esc_html__('Transaction ID', 'event_espresso'),
56
-                    false,
57
-                    0,
58
-                    'Transaction'
59
-                ),
60
-                'FSB_data'      => new EE_JSON_Field(
61
-                    'FSB_data',
62
-                    esc_html__('Serialized form submission data', 'event_espresso'),
63
-                    true,
64
-                    null
65
-                ),
66
-                'FSB_submitted' => new EE_Datetime_Field(
67
-                    'FSB_submitted',
68
-                    esc_html__('Form submission timestamp', 'event_espresso'),
69
-                    false,
70
-                    EE_Datetime_Field::now,
71
-                    $timezone
72
-                ),
73
-            ],
74
-        ];
75
-        $this->_model_relations = [
76
-            'Form_Section' => new EE_Belongs_To_Relation(),
77
-            'Transaction'  => new EE_Belongs_To_Relation(),
78
-        ];
79
-        parent::__construct($timezone);
80
-        $this->request = $this->getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
81
-    }
36
+		$this->_tables          = [
37
+			'Form_Submission' => new EE_Primary_Table('esp_form_submission', 'FSB_UUID'),
38
+		];
39
+		$this->_fields          = [
40
+			'Form_Submission' => [
41
+				'FSB_UUID'      => new EE_Primary_Key_String_Field(
42
+					'FSB_UUID',
43
+					esc_html__('Form Submission UUID (universally unique identifier)', 'event_espresso')
44
+				),
45
+				'FSC_UUID'      => new EE_Foreign_Key_String_Field(
46
+					'FSC_UUID',
47
+					esc_html__('Form Section UUID (universally unique identifier)', 'event_espresso'),
48
+					false,
49
+					'',
50
+					'Form_Section',
51
+					false
52
+				),
53
+				'TXN_ID'        => new EE_Foreign_Key_Int_Field(
54
+					'TXN_ID',
55
+					esc_html__('Transaction ID', 'event_espresso'),
56
+					false,
57
+					0,
58
+					'Transaction'
59
+				),
60
+				'FSB_data'      => new EE_JSON_Field(
61
+					'FSB_data',
62
+					esc_html__('Serialized form submission data', 'event_espresso'),
63
+					true,
64
+					null
65
+				),
66
+				'FSB_submitted' => new EE_Datetime_Field(
67
+					'FSB_submitted',
68
+					esc_html__('Form submission timestamp', 'event_espresso'),
69
+					false,
70
+					EE_Datetime_Field::now,
71
+					$timezone
72
+				),
73
+			],
74
+		];
75
+		$this->_model_relations = [
76
+			'Form_Section' => new EE_Belongs_To_Relation(),
77
+			'Transaction'  => new EE_Belongs_To_Relation(),
78
+		];
79
+		parent::__construct($timezone);
80
+		$this->request = $this->getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
81
+	}
82 82
 
83 83
 
84
-    /**
85
-     * adds all default where conditions unless the current request originates from the admin
86
-     *
87
-     * @param array $query_params
88
-     * @return array
89
-     */
90
-    private function addDefaultWhereConditions(array $query_params): array
91
-    {
92
-        // might need to add a way to identify GQL requests for admin domains
93
-        $query_params['default_where_conditions'] = $this->request->isAdmin() || $this->request->isAdminAjax()
94
-            ? EEM_Base::default_where_conditions_none
95
-            : EEM_Base::default_where_conditions_all;
96
-        return $query_params;
97
-    }
84
+	/**
85
+	 * adds all default where conditions unless the current request originates from the admin
86
+	 *
87
+	 * @param array $query_params
88
+	 * @return array
89
+	 */
90
+	private function addDefaultWhereConditions(array $query_params): array
91
+	{
92
+		// might need to add a way to identify GQL requests for admin domains
93
+		$query_params['default_where_conditions'] = $this->request->isAdmin() || $this->request->isAdminAjax()
94
+			? EEM_Base::default_where_conditions_none
95
+			: EEM_Base::default_where_conditions_all;
96
+		return $query_params;
97
+	}
98 98
 
99 99
 
100
-    /**
101
-     * form sections should always be sorted in ascending order via the FSC_order field
102
-     *
103
-     * @param array $query_params
104
-     * @return array
105
-     */
106
-    private function addOrderByQueryParams(array $query_params): array
107
-    {
108
-        $query_params['order_by'] = ['FSB_submitted' => 'ASC'];
109
-        return $query_params;
110
-    }
100
+	/**
101
+	 * form sections should always be sorted in ascending order via the FSC_order field
102
+	 *
103
+	 * @param array $query_params
104
+	 * @return array
105
+	 */
106
+	private function addOrderByQueryParams(array $query_params): array
107
+	{
108
+		$query_params['order_by'] = ['FSB_submitted' => 'ASC'];
109
+		return $query_params;
110
+	}
111 111
 
112 112
 
113
-    /**
114
-     * @param EE_Event $event
115
-     * @return EE_Form_Submission[]|null
116
-     * @throws EE_Error
117
-     * @throws ReflectionException
118
-     */
119
-    public function getAllFormSubmissionsForEvent(EE_Event $event): ?array
120
-    {
121
-        $query_params = [['FSC_UUID' => $event->registrationFormUuid()]];
122
-        $query_params = $this->addDefaultWhereConditions($query_params);
123
-        $query_params = $this->addOrderByQueryParams($query_params);
124
-        return $this->get_all($query_params);
125
-    }
113
+	/**
114
+	 * @param EE_Event $event
115
+	 * @return EE_Form_Submission[]|null
116
+	 * @throws EE_Error
117
+	 * @throws ReflectionException
118
+	 */
119
+	public function getAllFormSubmissionsForEvent(EE_Event $event): ?array
120
+	{
121
+		$query_params = [['FSC_UUID' => $event->registrationFormUuid()]];
122
+		$query_params = $this->addDefaultWhereConditions($query_params);
123
+		$query_params = $this->addOrderByQueryParams($query_params);
124
+		return $this->get_all($query_params);
125
+	}
126 126
 
127 127
 
128
-    /**
129
-     * @param EE_Transaction $transaction
130
-     * @return EE_Form_Submission|null
131
-     * @throws EE_Error
132
-     * @throws ReflectionException
133
-     */
134
-    public function getFormSubmissionForTransaction(EE_Transaction $transaction): ?EE_Form_Submission
135
-    {
136
-        $query_params = [['TXN_ID' => $transaction->ID()]];
137
-        $query_params = $this->addDefaultWhereConditions($query_params);
138
-        return $this->get_one($query_params);
139
-    }
128
+	/**
129
+	 * @param EE_Transaction $transaction
130
+	 * @return EE_Form_Submission|null
131
+	 * @throws EE_Error
132
+	 * @throws ReflectionException
133
+	 */
134
+	public function getFormSubmissionForTransaction(EE_Transaction $transaction): ?EE_Form_Submission
135
+	{
136
+		$query_params = [['TXN_ID' => $transaction->ID()]];
137
+		$query_params = $this->addDefaultWhereConditions($query_params);
138
+		return $this->get_one($query_params);
139
+	}
140 140
 }
Please login to merge, or discard this patch.