Completed
Branch FET/reg-form-builder/main (69a760)
by
unknown
04:39 queued 02:08
created
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_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.
core/db_classes/EE_Event.class.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public function getAvailableSpacesCalculator()
74 74
     {
75
-        if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
75
+        if ( ! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
76 76
             $this->available_spaces_calculator = new EventSpacesCalculator($this);
77 77
         }
78 78
         return $this->available_spaces_calculator;
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
      */
215 215
     public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
216 216
     {
217
-        if (! empty($this->_Primary_Datetime)) {
217
+        if ( ! empty($this->_Primary_Datetime)) {
218 218
             return $this->_Primary_Datetime;
219 219
         }
220 220
         $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
     {
238 238
         // first get all datetimes
239 239
         $datetimes = $this->datetimes_ordered();
240
-        if (! $datetimes) {
240
+        if ( ! $datetimes) {
241 241
             return array();
242 242
         }
243 243
         $datetime_ids = array();
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
     public function short_description($num_words = 55, $more = null, $not_full_desc = false)
431 431
     {
432 432
         $short_desc = $this->get('EVT_short_desc');
433
-        if (! empty($short_desc) || $not_full_desc) {
433
+        if ( ! empty($short_desc) || $not_full_desc) {
434 434
             return $short_desc;
435 435
         }
436 436
         $full_desc = $this->get('EVT_desc');
@@ -884,7 +884,7 @@  discard block
 block discarded – undo
884 884
         );
885 885
         $all_expired = true;
886 886
         foreach ($tickets as $ticket) {
887
-            if (! $ticket->is_expired()) {
887
+            if ( ! $ticket->is_expired()) {
888 888
                 $all_expired = false;
889 889
                 break;
890 890
             }
@@ -975,7 +975,7 @@  discard block
 block discarded – undo
975 975
      */
976 976
     public function is_sold_out($actual = false)
977 977
     {
978
-        if (! $actual) {
978
+        if ( ! $actual) {
979 979
             return $this->status() === EEM_Event::sold_out;
980 980
         }
981 981
         return $this->perform_sold_out_status_check();
@@ -1020,11 +1020,11 @@  discard block
 block discarded – undo
1020 1020
     public function get_active_status($reset = false)
1021 1021
     {
1022 1022
         // if the active status has already been set, then just use that value (unless we are resetting it)
1023
-        if (! empty($this->_active_status) && ! $reset) {
1023
+        if ( ! empty($this->_active_status) && ! $reset) {
1024 1024
             return $this->_active_status;
1025 1025
         }
1026 1026
         // first check if event id is present on this object
1027
-        if (! $this->ID()) {
1027
+        if ( ! $this->ID()) {
1028 1028
             return false;
1029 1029
         }
1030 1030
         $where_params_for_event = array(array('EVT_ID' => $this->ID()));
@@ -1114,7 +1114,7 @@  discard block
 block discarded – undo
1114 1114
     public function get_number_of_tickets_sold()
1115 1115
     {
1116 1116
         $tkt_sold = 0;
1117
-        if (! $this->ID()) {
1117
+        if ( ! $this->ID()) {
1118 1118
             return 0;
1119 1119
         }
1120 1120
         $datetimes = $this->datetimes();
@@ -1298,7 +1298,7 @@  discard block
 block discarded – undo
1298 1298
             ]
1299 1299
         );
1300 1300
         $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1301
-        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1301
+        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext( ! $for_primary);
1302 1302
         if ($existing_relation->get($other_field) === false) {
1303 1303
             // Delete it. It's now no longer for primary or additional question groups.
1304 1304
             return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
@@ -1451,7 +1451,7 @@  discard block
 block discarded – undo
1451 1451
      */
1452 1452
     public function setRegistrationFormUuid(string $UUID): void
1453 1453
     {
1454
-        if (! Cuid::isCuid($UUID)) {
1454
+        if ( ! Cuid::isCuid($UUID)) {
1455 1455
             throw new InvalidArgumentException(
1456 1456
                 sprintf(
1457 1457
                 /* translators: 1: UUID value, 2: UUID generator function. */
Please login to merge, or discard this patch.
Indentation   +1482 added lines, -1482 removed lines patch added patch discarded remove patch
@@ -16,1486 +16,1486 @@
 block discarded – undo
16 16
 class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon, EEI_Event
17 17
 {
18 18
 
19
-    /**
20
-     * cached value for the the logical active status for the event
21
-     *
22
-     * @see get_active_status()
23
-     * @var string
24
-     */
25
-    protected $_active_status = '';
26
-
27
-    /**
28
-     * This is just used for caching the Primary Datetime for the Event on initial retrieval
29
-     *
30
-     * @var EE_Datetime
31
-     */
32
-    protected $_Primary_Datetime;
33
-
34
-    /**
35
-     * @var EventSpacesCalculator $available_spaces_calculator
36
-     */
37
-    protected $available_spaces_calculator;
38
-
39
-
40
-    /**
41
-     * @param array  $props_n_values          incoming values
42
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
43
-     *                                        used.)
44
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
45
-     *                                        date_format and the second value is the time format
46
-     * @return EE_Event
47
-     * @throws EE_Error
48
-     */
49
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
50
-    {
51
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
52
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
53
-    }
54
-
55
-
56
-    /**
57
-     * @param array  $props_n_values  incoming values from the database
58
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
59
-     *                                the website will be used.
60
-     * @return EE_Event
61
-     * @throws EE_Error
62
-     */
63
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
64
-    {
65
-        return new self($props_n_values, true, $timezone);
66
-    }
67
-
68
-
69
-    /**
70
-     * @return EventSpacesCalculator
71
-     * @throws \EE_Error
72
-     */
73
-    public function getAvailableSpacesCalculator()
74
-    {
75
-        if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
76
-            $this->available_spaces_calculator = new EventSpacesCalculator($this);
77
-        }
78
-        return $this->available_spaces_calculator;
79
-    }
80
-
81
-
82
-    /**
83
-     * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
84
-     *
85
-     * @param string $field_name
86
-     * @param mixed  $field_value
87
-     * @param bool   $use_default
88
-     * @throws EE_Error
89
-     */
90
-    public function set($field_name, $field_value, $use_default = false)
91
-    {
92
-        switch ($field_name) {
93
-            case 'status':
94
-                $this->set_status($field_value, $use_default);
95
-                break;
96
-            default:
97
-                parent::set($field_name, $field_value, $use_default);
98
-        }
99
-    }
100
-
101
-
102
-    /**
103
-     *    set_status
104
-     * Checks if event status is being changed to SOLD OUT
105
-     * and updates event meta data with previous event status
106
-     * so that we can revert things if/when the event is no longer sold out
107
-     *
108
-     * @access public
109
-     * @param string $new_status
110
-     * @param bool   $use_default
111
-     * @return void
112
-     * @throws EE_Error
113
-     */
114
-    public function set_status($new_status = null, $use_default = false)
115
-    {
116
-        // if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
117
-        if (empty($new_status) && ! $use_default) {
118
-            return;
119
-        }
120
-        // get current Event status
121
-        $old_status = $this->status();
122
-        // if status has changed
123
-        if ($old_status !== $new_status) {
124
-            // TO sold_out
125
-            if ($new_status === EEM_Event::sold_out) {
126
-                // save the previous event status so that we can revert if the event is no longer sold out
127
-                $this->add_post_meta('_previous_event_status', $old_status);
128
-                do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
129
-            // OR FROM  sold_out
130
-            } elseif ($old_status === EEM_Event::sold_out) {
131
-                $this->delete_post_meta('_previous_event_status');
132
-                do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
133
-            }
134
-            // clear out the active status so that it gets reset the next time it is requested
135
-            $this->_active_status = null;
136
-            // update status
137
-            parent::set('status', $new_status, $use_default);
138
-            do_action('AHEE__EE_Event__set_status__after_update', $this);
139
-            return;
140
-        }
141
-        // even though the old value matches the new value, it's still good to
142
-        // allow the parent set method to have a say
143
-        parent::set('status', $new_status, $use_default);
144
-    }
145
-
146
-
147
-    /**
148
-     * Gets all the datetimes for this event
149
-     *
150
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
151
-     * @return EE_Base_Class[]|EE_Datetime[]
152
-     * @throws EE_Error
153
-     */
154
-    public function datetimes($query_params = array())
155
-    {
156
-        return $this->get_many_related('Datetime', $query_params);
157
-    }
158
-
159
-
160
-    /**
161
-     * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
162
-     *
163
-     * @return EE_Base_Class[]|EE_Datetime[]
164
-     * @throws EE_Error
165
-     */
166
-    public function datetimes_in_chronological_order()
167
-    {
168
-        return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
169
-    }
170
-
171
-
172
-    /**
173
-     * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
174
-     * @darren, we should probably UNSET timezone on the EEM_Datetime model
175
-     * after running our query, so that this timezone isn't set for EVERY query
176
-     * on EEM_Datetime for the rest of the request, no?
177
-     *
178
-     * @param boolean $show_expired whether or not to include expired events
179
-     * @param boolean $show_deleted whether or not to include deleted events
180
-     * @param null    $limit
181
-     * @return EE_Datetime[]
182
-     * @throws EE_Error
183
-     */
184
-    public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
185
-    {
186
-        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
187
-            $this->ID(),
188
-            $show_expired,
189
-            $show_deleted,
190
-            $limit
191
-        );
192
-    }
193
-
194
-
195
-    /**
196
-     * Returns one related datetime. Mostly only used by some legacy code.
197
-     *
198
-     * @return EE_Base_Class|EE_Datetime
199
-     * @throws EE_Error
200
-     */
201
-    public function first_datetime()
202
-    {
203
-        return $this->get_first_related('Datetime');
204
-    }
205
-
206
-
207
-    /**
208
-     * Returns the 'primary' datetime for the event
209
-     *
210
-     * @param bool $try_to_exclude_expired
211
-     * @param bool $try_to_exclude_deleted
212
-     * @return EE_Datetime
213
-     * @throws EE_Error
214
-     */
215
-    public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
216
-    {
217
-        if (! empty($this->_Primary_Datetime)) {
218
-            return $this->_Primary_Datetime;
219
-        }
220
-        $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
221
-            $this->ID(),
222
-            $try_to_exclude_expired,
223
-            $try_to_exclude_deleted
224
-        );
225
-        return $this->_Primary_Datetime;
226
-    }
227
-
228
-
229
-    /**
230
-     * Gets all the tickets available for purchase of this event
231
-     *
232
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
233
-     * @return EE_Base_Class[]|EE_Ticket[]
234
-     * @throws EE_Error
235
-     */
236
-    public function tickets($query_params = array())
237
-    {
238
-        // first get all datetimes
239
-        $datetimes = $this->datetimes_ordered();
240
-        if (! $datetimes) {
241
-            return array();
242
-        }
243
-        $datetime_ids = array();
244
-        foreach ($datetimes as $datetime) {
245
-            $datetime_ids[] = $datetime->ID();
246
-        }
247
-        $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
248
-        // if incoming $query_params has where conditions let's merge but not override existing.
249
-        if (is_array($query_params) && isset($query_params[0])) {
250
-            $where_params = array_merge($query_params[0], $where_params);
251
-            unset($query_params[0]);
252
-        }
253
-        // now add $where_params to $query_params
254
-        $query_params[0] = $where_params;
255
-        return EEM_Ticket::instance()->get_all($query_params);
256
-    }
257
-
258
-
259
-    /**
260
-     * get all unexpired untrashed tickets
261
-     *
262
-     * @return EE_Ticket[]
263
-     * @throws EE_Error
264
-     */
265
-    public function active_tickets()
266
-    {
267
-        return $this->tickets(
268
-            array(
269
-                array(
270
-                    'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
271
-                    'TKT_deleted'  => false,
272
-                ),
273
-            )
274
-        );
275
-    }
276
-
277
-
278
-    /**
279
-     * @return bool
280
-     * @throws EE_Error
281
-     */
282
-    public function additional_limit()
283
-    {
284
-        return $this->get('EVT_additional_limit');
285
-    }
286
-
287
-
288
-    /**
289
-     * @return bool
290
-     * @throws EE_Error
291
-     */
292
-    public function allow_overflow()
293
-    {
294
-        return $this->get('EVT_allow_overflow');
295
-    }
296
-
297
-
298
-    /**
299
-     * @return bool
300
-     * @throws EE_Error
301
-     */
302
-    public function created()
303
-    {
304
-        return $this->get('EVT_created');
305
-    }
306
-
307
-
308
-    /**
309
-     * @return bool
310
-     * @throws EE_Error
311
-     */
312
-    public function description()
313
-    {
314
-        return $this->get('EVT_desc');
315
-    }
316
-
317
-
318
-    /**
319
-     * Runs do_shortcode and wpautop on the description
320
-     *
321
-     * @return string of html
322
-     * @throws EE_Error
323
-     */
324
-    public function description_filtered()
325
-    {
326
-        return $this->get_pretty('EVT_desc');
327
-    }
328
-
329
-
330
-    /**
331
-     * @return bool
332
-     * @throws EE_Error
333
-     */
334
-    public function display_description()
335
-    {
336
-        return $this->get('EVT_display_desc');
337
-    }
338
-
339
-
340
-    /**
341
-     * @return bool
342
-     * @throws EE_Error
343
-     */
344
-    public function display_ticket_selector()
345
-    {
346
-        return (bool) $this->get('EVT_display_ticket_selector');
347
-    }
348
-
349
-
350
-    /**
351
-     * @return bool
352
-     * @throws EE_Error
353
-     */
354
-    public function external_url()
355
-    {
356
-        return $this->get('EVT_external_URL');
357
-    }
358
-
359
-
360
-    /**
361
-     * @return bool
362
-     * @throws EE_Error
363
-     */
364
-    public function member_only()
365
-    {
366
-        return $this->get('EVT_member_only');
367
-    }
368
-
369
-
370
-    /**
371
-     * @return bool
372
-     * @throws EE_Error
373
-     */
374
-    public function phone()
375
-    {
376
-        return $this->get('EVT_phone');
377
-    }
378
-
379
-
380
-    /**
381
-     * @return bool
382
-     * @throws EE_Error
383
-     */
384
-    public function modified()
385
-    {
386
-        return $this->get('EVT_modified');
387
-    }
388
-
389
-
390
-    /**
391
-     * @return bool
392
-     * @throws EE_Error
393
-     */
394
-    public function name()
395
-    {
396
-        return $this->get('EVT_name');
397
-    }
398
-
399
-
400
-    /**
401
-     * @return bool
402
-     * @throws EE_Error
403
-     */
404
-    public function order()
405
-    {
406
-        return $this->get('EVT_order');
407
-    }
408
-
409
-
410
-    /**
411
-     * @return bool|string
412
-     * @throws EE_Error
413
-     */
414
-    public function default_registration_status()
415
-    {
416
-        $event_default_registration_status = $this->get('EVT_default_registration_status');
417
-        return ! empty($event_default_registration_status)
418
-            ? $event_default_registration_status
419
-            : EE_Registry::instance()->CFG->registration->default_STS_ID;
420
-    }
421
-
422
-
423
-    /**
424
-     * @param int  $num_words
425
-     * @param null $more
426
-     * @param bool $not_full_desc
427
-     * @return bool|string
428
-     * @throws EE_Error
429
-     */
430
-    public function short_description($num_words = 55, $more = null, $not_full_desc = false)
431
-    {
432
-        $short_desc = $this->get('EVT_short_desc');
433
-        if (! empty($short_desc) || $not_full_desc) {
434
-            return $short_desc;
435
-        }
436
-        $full_desc = $this->get('EVT_desc');
437
-        return wp_trim_words($full_desc, $num_words, $more);
438
-    }
439
-
440
-
441
-    /**
442
-     * @return bool
443
-     * @throws EE_Error
444
-     */
445
-    public function slug()
446
-    {
447
-        return $this->get('EVT_slug');
448
-    }
449
-
450
-
451
-    /**
452
-     * @return bool
453
-     * @throws EE_Error
454
-     */
455
-    public function timezone_string()
456
-    {
457
-        return $this->get('EVT_timezone_string');
458
-    }
459
-
460
-
461
-    /**
462
-     * @return bool
463
-     * @throws EE_Error
464
-     */
465
-    public function visible_on()
466
-    {
467
-        return $this->get('EVT_visible_on');
468
-    }
469
-
470
-
471
-    /**
472
-     * @return int
473
-     * @throws EE_Error
474
-     */
475
-    public function wp_user()
476
-    {
477
-        return $this->get('EVT_wp_user');
478
-    }
479
-
480
-
481
-    /**
482
-     * @return bool
483
-     * @throws EE_Error
484
-     */
485
-    public function donations()
486
-    {
487
-        return $this->get('EVT_donations');
488
-    }
489
-
490
-
491
-    /**
492
-     * @param $limit
493
-     * @throws EE_Error
494
-     */
495
-    public function set_additional_limit($limit)
496
-    {
497
-        $this->set('EVT_additional_limit', $limit);
498
-    }
499
-
500
-
501
-    /**
502
-     * @param $created
503
-     * @throws EE_Error
504
-     */
505
-    public function set_created($created)
506
-    {
507
-        $this->set('EVT_created', $created);
508
-    }
509
-
510
-
511
-    /**
512
-     * @param $desc
513
-     * @throws EE_Error
514
-     */
515
-    public function set_description($desc)
516
-    {
517
-        $this->set('EVT_desc', $desc);
518
-    }
519
-
520
-
521
-    /**
522
-     * @param $display_desc
523
-     * @throws EE_Error
524
-     */
525
-    public function set_display_description($display_desc)
526
-    {
527
-        $this->set('EVT_display_desc', $display_desc);
528
-    }
529
-
530
-
531
-    /**
532
-     * @param $display_ticket_selector
533
-     * @throws EE_Error
534
-     */
535
-    public function set_display_ticket_selector($display_ticket_selector)
536
-    {
537
-        $this->set('EVT_display_ticket_selector', $display_ticket_selector);
538
-    }
539
-
540
-
541
-    /**
542
-     * @param $external_url
543
-     * @throws EE_Error
544
-     */
545
-    public function set_external_url($external_url)
546
-    {
547
-        $this->set('EVT_external_URL', $external_url);
548
-    }
549
-
550
-
551
-    /**
552
-     * @param $member_only
553
-     * @throws EE_Error
554
-     */
555
-    public function set_member_only($member_only)
556
-    {
557
-        $this->set('EVT_member_only', $member_only);
558
-    }
559
-
560
-
561
-    /**
562
-     * @param $event_phone
563
-     * @throws EE_Error
564
-     */
565
-    public function set_event_phone($event_phone)
566
-    {
567
-        $this->set('EVT_phone', $event_phone);
568
-    }
569
-
570
-
571
-    /**
572
-     * @param $modified
573
-     * @throws EE_Error
574
-     */
575
-    public function set_modified($modified)
576
-    {
577
-        $this->set('EVT_modified', $modified);
578
-    }
579
-
580
-
581
-    /**
582
-     * @param $name
583
-     * @throws EE_Error
584
-     */
585
-    public function set_name($name)
586
-    {
587
-        $this->set('EVT_name', $name);
588
-    }
589
-
590
-
591
-    /**
592
-     * @param $order
593
-     * @throws EE_Error
594
-     */
595
-    public function set_order($order)
596
-    {
597
-        $this->set('EVT_order', $order);
598
-    }
599
-
600
-
601
-    /**
602
-     * @param $short_desc
603
-     * @throws EE_Error
604
-     */
605
-    public function set_short_description($short_desc)
606
-    {
607
-        $this->set('EVT_short_desc', $short_desc);
608
-    }
609
-
610
-
611
-    /**
612
-     * @param $slug
613
-     * @throws EE_Error
614
-     */
615
-    public function set_slug($slug)
616
-    {
617
-        $this->set('EVT_slug', $slug);
618
-    }
619
-
620
-
621
-    /**
622
-     * @param $timezone_string
623
-     * @throws EE_Error
624
-     */
625
-    public function set_timezone_string($timezone_string)
626
-    {
627
-        $this->set('EVT_timezone_string', $timezone_string);
628
-    }
629
-
630
-
631
-    /**
632
-     * @param $visible_on
633
-     * @throws EE_Error
634
-     */
635
-    public function set_visible_on($visible_on)
636
-    {
637
-        $this->set('EVT_visible_on', $visible_on);
638
-    }
639
-
640
-
641
-    /**
642
-     * @param $wp_user
643
-     * @throws EE_Error
644
-     */
645
-    public function set_wp_user($wp_user)
646
-    {
647
-        $this->set('EVT_wp_user', $wp_user);
648
-    }
649
-
650
-
651
-    /**
652
-     * @param $default_registration_status
653
-     * @throws EE_Error
654
-     */
655
-    public function set_default_registration_status($default_registration_status)
656
-    {
657
-        $this->set('EVT_default_registration_status', $default_registration_status);
658
-    }
659
-
660
-
661
-    /**
662
-     * @param $donations
663
-     * @throws EE_Error
664
-     */
665
-    public function set_donations($donations)
666
-    {
667
-        $this->set('EVT_donations', $donations);
668
-    }
669
-
670
-
671
-    /**
672
-     * Adds a venue to this event
673
-     *
674
-     * @param int|EE_Venue /int $venue_id_or_obj
675
-     * @return EE_Base_Class|EE_Venue
676
-     * @throws EE_Error
677
-     * @throws ReflectionException
678
-     */
679
-    public function add_venue($venue_id_or_obj): EE_Venue
680
-    {
681
-        return $this->_add_relation_to($venue_id_or_obj, 'Venue');
682
-    }
683
-
684
-
685
-    /**
686
-     * Removes a venue from the event
687
-     *
688
-     * @param EE_Venue /int $venue_id_or_obj
689
-     * @return EE_Base_Class|EE_Venue
690
-     * @throws EE_Error
691
-     * @throws ReflectionException
692
-     */
693
-    public function remove_venue($venue_id_or_obj): EE_Venue
694
-    {
695
-        $venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue();
696
-        return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
697
-    }
698
-
699
-
700
-    /**
701
-     * Gets the venue related to the event. May provide additional $query_params if desired
702
-     *
703
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
704
-     * @return int
705
-     * @throws EE_Error
706
-     * @throws ReflectionException
707
-     */
708
-    public function venue_ID(array $query_params = array()): int
709
-    {
710
-        $venue = $this->get_first_related('Venue', $query_params);
711
-        return $venue instanceof EE_Venue ? $venue->ID() : 0;
712
-    }
713
-
714
-
715
-    /**
716
-     * Gets the venue related to the event. May provide additional $query_params if desired
717
-     *
718
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
719
-     * @return EE_Base_Class|EE_Venue
720
-     * @throws EE_Error
721
-     * @throws ReflectionException
722
-     */
723
-    public function venue(array $query_params = array())
724
-    {
725
-        return $this->get_first_related('Venue', $query_params);
726
-    }
727
-
728
-
729
-    /**
730
-     * @param array $query_params
731
-     * @return EE_Base_Class[]|EE_Venue[]
732
-     * @throws EE_Error
733
-     * @throws ReflectionException
734
-     * @deprecated $VID:$
735
-     */
736
-    public function venues(array $query_params = array()): array
737
-    {
738
-        return (array) $this->venue($query_params);
739
-    }
740
-
741
-
742
-    /**
743
-     * check if event id is present and if event is published
744
-     *
745
-     * @access public
746
-     * @return boolean true yes, false no
747
-     * @throws EE_Error
748
-     */
749
-    private function _has_ID_and_is_published()
750
-    {
751
-        // first check if event id is present and not NULL,
752
-        // then check if this event is published (or any of the equivalent "published" statuses)
753
-        return
754
-            $this->ID() && $this->ID() !== null
755
-            && (
756
-                $this->status() === 'publish'
757
-                || $this->status() === EEM_Event::sold_out
758
-                || $this->status() === EEM_Event::postponed
759
-                || $this->status() === EEM_Event::cancelled
760
-            );
761
-    }
762
-
763
-
764
-    /**
765
-     * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
766
-     *
767
-     * @access public
768
-     * @return boolean true yes, false no
769
-     * @throws EE_Error
770
-     */
771
-    public function is_upcoming()
772
-    {
773
-        // check if event id is present and if this event is published
774
-        if ($this->is_inactive()) {
775
-            return false;
776
-        }
777
-        // set initial value
778
-        $upcoming = false;
779
-        // next let's get all datetimes and loop through them
780
-        $datetimes = $this->datetimes_in_chronological_order();
781
-        foreach ($datetimes as $datetime) {
782
-            if ($datetime instanceof EE_Datetime) {
783
-                // if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
784
-                if ($datetime->is_expired()) {
785
-                    continue;
786
-                }
787
-                // if this dtt is active then we return false.
788
-                if ($datetime->is_active()) {
789
-                    return false;
790
-                }
791
-                // otherwise let's check upcoming status
792
-                $upcoming = $datetime->is_upcoming();
793
-            }
794
-        }
795
-        return $upcoming;
796
-    }
797
-
798
-
799
-    /**
800
-     * @return bool
801
-     * @throws EE_Error
802
-     */
803
-    public function is_active()
804
-    {
805
-        // check if event id is present and if this event is published
806
-        if ($this->is_inactive()) {
807
-            return false;
808
-        }
809
-        // set initial value
810
-        $active = false;
811
-        // next let's get all datetimes and loop through them
812
-        $datetimes = $this->datetimes_in_chronological_order();
813
-        foreach ($datetimes as $datetime) {
814
-            if ($datetime instanceof EE_Datetime) {
815
-                // if this dtt is expired then we continue cause one of the other datetimes might be active.
816
-                if ($datetime->is_expired()) {
817
-                    continue;
818
-                }
819
-                // if this dtt is upcoming then we return false.
820
-                if ($datetime->is_upcoming()) {
821
-                    return false;
822
-                }
823
-                // otherwise let's check active status
824
-                $active = $datetime->is_active();
825
-            }
826
-        }
827
-        return $active;
828
-    }
829
-
830
-
831
-    /**
832
-     * @return bool
833
-     * @throws EE_Error
834
-     */
835
-    public function is_expired()
836
-    {
837
-        // check if event id is present and if this event is published
838
-        if ($this->is_inactive()) {
839
-            return false;
840
-        }
841
-        // set initial value
842
-        $expired = false;
843
-        // first let's get all datetimes and loop through them
844
-        $datetimes = $this->datetimes_in_chronological_order();
845
-        foreach ($datetimes as $datetime) {
846
-            if ($datetime instanceof EE_Datetime) {
847
-                // if this dtt is upcoming or active then we return false.
848
-                if ($datetime->is_upcoming() || $datetime->is_active()) {
849
-                    return false;
850
-                }
851
-                // otherwise let's check active status
852
-                $expired = $datetime->is_expired();
853
-            }
854
-        }
855
-        return $expired;
856
-    }
857
-
858
-
859
-    /**
860
-     * @return bool
861
-     * @throws EE_Error
862
-     */
863
-    public function is_inactive()
864
-    {
865
-        // check if event id is present and if this event is published
866
-        if ($this->_has_ID_and_is_published()) {
867
-            return false;
868
-        }
869
-        return true;
870
-    }
871
-
872
-
873
-    /**
874
-     * calculate spaces remaining based on "saleable" tickets
875
-     *
876
-     * @param array $tickets
877
-     * @param bool  $filtered
878
-     * @return int|float
879
-     * @throws EE_Error
880
-     * @throws DomainException
881
-     * @throws UnexpectedEntityException
882
-     */
883
-    public function spaces_remaining($tickets = array(), $filtered = true)
884
-    {
885
-        $this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
886
-        $spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
887
-        return $filtered
888
-            ? apply_filters(
889
-                'FHEE_EE_Event__spaces_remaining',
890
-                $spaces_remaining,
891
-                $this,
892
-                $tickets
893
-            )
894
-            : $spaces_remaining;
895
-    }
896
-
897
-
898
-    /**
899
-     *    perform_sold_out_status_check
900
-     *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
901
-     *    available... if NOT, then the event status will get toggled to 'sold_out'
902
-     *
903
-     * @return bool    return the ACTUAL sold out state.
904
-     * @throws EE_Error
905
-     * @throws DomainException
906
-     * @throws UnexpectedEntityException
907
-     */
908
-    public function perform_sold_out_status_check()
909
-    {
910
-        // get all tickets
911
-        $tickets = $this->tickets(
912
-            array(
913
-                'default_where_conditions' => 'none',
914
-                'order_by' => array('TKT_qty' => 'ASC'),
915
-            )
916
-        );
917
-        $all_expired = true;
918
-        foreach ($tickets as $ticket) {
919
-            if (! $ticket->is_expired()) {
920
-                $all_expired = false;
921
-                break;
922
-            }
923
-        }
924
-        // if all the tickets are just expired, then don't update the event status to sold out
925
-        if ($all_expired) {
926
-            return true;
927
-        }
928
-        $spaces_remaining = $this->spaces_remaining($tickets);
929
-        if ($spaces_remaining < 1) {
930
-            if ($this->status() !== EEM_Event::post_status_private) {
931
-                $this->set_status(EEM_Event::sold_out);
932
-                $this->save();
933
-            }
934
-            $sold_out = true;
935
-        } else {
936
-            $sold_out = false;
937
-            // was event previously marked as sold out ?
938
-            if ($this->status() === EEM_Event::sold_out) {
939
-                // revert status to previous value, if it was set
940
-                $previous_event_status = $this->get_post_meta('_previous_event_status', true);
941
-                if ($previous_event_status) {
942
-                    $this->set_status($previous_event_status);
943
-                    $this->save();
944
-                }
945
-            }
946
-        }
947
-        do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
948
-        return $sold_out;
949
-    }
950
-
951
-
952
-    /**
953
-     * This returns the total remaining spaces for sale on this event.
954
-     *
955
-     * @uses EE_Event::total_available_spaces()
956
-     * @return float|int
957
-     * @throws EE_Error
958
-     * @throws DomainException
959
-     * @throws UnexpectedEntityException
960
-     */
961
-    public function spaces_remaining_for_sale()
962
-    {
963
-        return $this->total_available_spaces(true);
964
-    }
965
-
966
-
967
-    /**
968
-     * This returns the total spaces available for an event
969
-     * while considering all the qtys on the tickets and the reg limits
970
-     * on the datetimes attached to this event.
971
-     *
972
-     * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
973
-     *                              If this is false, then we return the most tickets that could ever be sold
974
-     *                              for this event with the datetime and tickets setup on the event under optimal
975
-     *                              selling conditions.  Otherwise we return a live calculation of spaces available
976
-     *                              based on tickets sold.  Depending on setup and stage of sales, this
977
-     *                              may appear to equal remaining tickets.  However, the more tickets are
978
-     *                              sold out, the more accurate the "live" total is.
979
-     * @return float|int
980
-     * @throws EE_Error
981
-     * @throws DomainException
982
-     * @throws UnexpectedEntityException
983
-     */
984
-    public function total_available_spaces($consider_sold = false)
985
-    {
986
-        $spaces_available = $consider_sold
987
-            ? $this->getAvailableSpacesCalculator()->spacesRemaining()
988
-            : $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
989
-        return apply_filters(
990
-            'FHEE_EE_Event__total_available_spaces__spaces_available',
991
-            $spaces_available,
992
-            $this,
993
-            $this->getAvailableSpacesCalculator()->getDatetimes(),
994
-            $this->getAvailableSpacesCalculator()->getActiveTickets()
995
-        );
996
-    }
997
-
998
-
999
-    /**
1000
-     * Checks if the event is set to sold out
1001
-     *
1002
-     * @param  bool $actual whether or not to perform calculations to not only figure the
1003
-     *                      actual status but also to flip the status if necessary to sold
1004
-     *                      out If false, we just check the existing status of the event
1005
-     * @return boolean
1006
-     * @throws EE_Error
1007
-     */
1008
-    public function is_sold_out($actual = false)
1009
-    {
1010
-        if (! $actual) {
1011
-            return $this->status() === EEM_Event::sold_out;
1012
-        }
1013
-        return $this->perform_sold_out_status_check();
1014
-    }
1015
-
1016
-
1017
-    /**
1018
-     * Checks if the event is marked as postponed
1019
-     *
1020
-     * @return boolean
1021
-     */
1022
-    public function is_postponed()
1023
-    {
1024
-        return $this->status() === EEM_Event::postponed;
1025
-    }
1026
-
1027
-
1028
-    /**
1029
-     * Checks if the event is marked as cancelled
1030
-     *
1031
-     * @return boolean
1032
-     */
1033
-    public function is_cancelled()
1034
-    {
1035
-        return $this->status() === EEM_Event::cancelled;
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-     * Get the logical active status in a hierarchical order for all the datetimes.  Note
1041
-     * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1042
-     * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1043
-     * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1044
-     * the event is considered expired.
1045
-     * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1046
-     * status set on the EVENT when it is not published and thus is done
1047
-     *
1048
-     * @param bool $reset
1049
-     * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1050
-     * @throws EE_Error
1051
-     */
1052
-    public function get_active_status($reset = false)
1053
-    {
1054
-        // if the active status has already been set, then just use that value (unless we are resetting it)
1055
-        if (! empty($this->_active_status) && ! $reset) {
1056
-            return $this->_active_status;
1057
-        }
1058
-        // first check if event id is present on this object
1059
-        if (! $this->ID()) {
1060
-            return false;
1061
-        }
1062
-        $where_params_for_event = array(array('EVT_ID' => $this->ID()));
1063
-        // if event is published:
1064
-        if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1065
-            // active?
1066
-            if (
1067
-                EEM_Datetime::instance()->get_datetime_count_for_status(
1068
-                    EE_Datetime::active,
1069
-                    $where_params_for_event
1070
-                ) > 0
1071
-            ) {
1072
-                $this->_active_status = EE_Datetime::active;
1073
-            } else {
1074
-                // upcoming?
1075
-                if (
1076
-                    EEM_Datetime::instance()->get_datetime_count_for_status(
1077
-                        EE_Datetime::upcoming,
1078
-                        $where_params_for_event
1079
-                    ) > 0
1080
-                ) {
1081
-                    $this->_active_status = EE_Datetime::upcoming;
1082
-                } else {
1083
-                    // expired?
1084
-                    if (
1085
-                        EEM_Datetime::instance()->get_datetime_count_for_status(
1086
-                            EE_Datetime::expired,
1087
-                            $where_params_for_event
1088
-                        ) > 0
1089
-                    ) {
1090
-                        $this->_active_status = EE_Datetime::expired;
1091
-                    } else {
1092
-                        // it would be odd if things make it this far because it basically means there are no datetime's
1093
-                        // attached to the event.  So in this case it will just be considered inactive.
1094
-                        $this->_active_status = EE_Datetime::inactive;
1095
-                    }
1096
-                }
1097
-            }
1098
-        } else {
1099
-            // the event is not published, so let's just set it's active status according to its' post status
1100
-            switch ($this->status()) {
1101
-                case EEM_Event::sold_out:
1102
-                    $this->_active_status = EE_Datetime::sold_out;
1103
-                    break;
1104
-                case EEM_Event::cancelled:
1105
-                    $this->_active_status = EE_Datetime::cancelled;
1106
-                    break;
1107
-                case EEM_Event::postponed:
1108
-                    $this->_active_status = EE_Datetime::postponed;
1109
-                    break;
1110
-                default:
1111
-                    $this->_active_status = EE_Datetime::inactive;
1112
-            }
1113
-        }
1114
-        return $this->_active_status;
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     *    pretty_active_status
1120
-     *
1121
-     * @access public
1122
-     * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1123
-     * @return mixed void|string
1124
-     * @throws EE_Error
1125
-     */
1126
-    public function pretty_active_status($echo = true)
1127
-    {
1128
-        $active_status = $this->get_active_status();
1129
-        $status = '<span class="ee-status event-active-status-'
1130
-                  . $active_status
1131
-                  . '">'
1132
-                  . EEH_Template::pretty_status($active_status, false, 'sentence')
1133
-                  . '</span>';
1134
-        if ($echo) {
1135
-            echo $status;
1136
-            return '';
1137
-        }
1138
-        return $status;
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     * @return bool|int
1144
-     * @throws EE_Error
1145
-     */
1146
-    public function get_number_of_tickets_sold()
1147
-    {
1148
-        $tkt_sold = 0;
1149
-        if (! $this->ID()) {
1150
-            return 0;
1151
-        }
1152
-        $datetimes = $this->datetimes();
1153
-        foreach ($datetimes as $datetime) {
1154
-            if ($datetime instanceof EE_Datetime) {
1155
-                $tkt_sold += $datetime->sold();
1156
-            }
1157
-        }
1158
-        return $tkt_sold;
1159
-    }
1160
-
1161
-
1162
-    /**
1163
-     * This just returns a count of all the registrations for this event
1164
-     *
1165
-     * @access  public
1166
-     * @return int
1167
-     * @throws EE_Error
1168
-     */
1169
-    public function get_count_of_all_registrations()
1170
-    {
1171
-        return EEM_Event::instance()->count_related($this, 'Registration');
1172
-    }
1173
-
1174
-
1175
-    /**
1176
-     * This returns the ticket with the earliest start time that is
1177
-     * available for this event (across all datetimes attached to the event)
1178
-     *
1179
-     * @return EE_Base_Class|EE_Ticket|null
1180
-     * @throws EE_Error
1181
-     */
1182
-    public function get_ticket_with_earliest_start_time()
1183
-    {
1184
-        $where['Datetime.EVT_ID'] = $this->ID();
1185
-        $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1186
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1187
-    }
1188
-
1189
-
1190
-    /**
1191
-     * This returns the ticket with the latest end time that is available
1192
-     * for this event (across all datetimes attached to the event)
1193
-     *
1194
-     * @return EE_Base_Class|EE_Ticket|null
1195
-     * @throws EE_Error
1196
-     */
1197
-    public function get_ticket_with_latest_end_time()
1198
-    {
1199
-        $where['Datetime.EVT_ID'] = $this->ID();
1200
-        $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1201
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1202
-    }
1203
-
1204
-
1205
-    /**
1206
-     * This returns the number of different ticket types currently on sale for this event.
1207
-     *
1208
-     * @return int
1209
-     * @throws EE_Error
1210
-     */
1211
-    public function countTicketsOnSale()
1212
-    {
1213
-        $where = array(
1214
-            'Datetime.EVT_ID' => $this->ID(),
1215
-            'TKT_start_date'  => array('<', time()),
1216
-            'TKT_end_date'    => array('>', time()),
1217
-        );
1218
-        return EEM_Ticket::instance()->count(array($where));
1219
-    }
1220
-
1221
-
1222
-    /**
1223
-     * This returns whether there are any tickets on sale for this event.
1224
-     *
1225
-     * @return bool true = YES tickets on sale.
1226
-     * @throws EE_Error
1227
-     */
1228
-    public function tickets_on_sale()
1229
-    {
1230
-        return $this->countTicketsOnSale() > 0;
1231
-    }
1232
-
1233
-
1234
-    /**
1235
-     * Gets the URL for viewing this event on the front-end. Overrides parent
1236
-     * to check for an external URL first
1237
-     *
1238
-     * @return string
1239
-     * @throws EE_Error
1240
-     */
1241
-    public function get_permalink()
1242
-    {
1243
-        if ($this->external_url()) {
1244
-            return $this->external_url();
1245
-        }
1246
-        return parent::get_permalink();
1247
-    }
1248
-
1249
-
1250
-    /**
1251
-     * Gets the first term for 'espresso_event_categories' we can find
1252
-     *
1253
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1254
-     * @return EE_Base_Class|EE_Term|null
1255
-     * @throws EE_Error
1256
-     */
1257
-    public function first_event_category($query_params = array())
1258
-    {
1259
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1260
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1261
-        return EEM_Term::instance()->get_one($query_params);
1262
-    }
1263
-
1264
-
1265
-    /**
1266
-     * Gets all terms for 'espresso_event_categories' we can find
1267
-     *
1268
-     * @param array $query_params
1269
-     * @return EE_Base_Class[]|EE_Term[]
1270
-     * @throws EE_Error
1271
-     */
1272
-    public function get_all_event_categories($query_params = array())
1273
-    {
1274
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1275
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1276
-        return EEM_Term::instance()->get_all($query_params);
1277
-    }
1278
-
1279
-
1280
-    /**
1281
-     * Adds a question group to this event
1282
-     *
1283
-     * @param EE_Question_Group|int $question_group_id_or_obj
1284
-     * @param bool $for_primary if true, the question group will be added for the primary
1285
-     *                                           registrant, if false will be added for others. default: false
1286
-     * @return EE_Base_Class|EE_Question_Group
1287
-     * @throws EE_Error
1288
-     * @throws InvalidArgumentException
1289
-     * @throws InvalidDataTypeException
1290
-     * @throws InvalidInterfaceException
1291
-     * @throws ReflectionException
1292
-     */
1293
-    public function add_question_group($question_group_id_or_obj, $for_primary = false)
1294
-    {
1295
-        // If the row already exists, it will be updated. If it doesn't, it will be inserted.
1296
-        // That's in EE_HABTM_Relation::add_relation_to().
1297
-        return $this->_add_relation_to(
1298
-            $question_group_id_or_obj,
1299
-            'Question_Group',
1300
-            [
1301
-                EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true
1302
-            ]
1303
-        );
1304
-    }
1305
-
1306
-
1307
-    /**
1308
-     * Removes a question group from the event
1309
-     *
1310
-     * @param EE_Question_Group|int $question_group_id_or_obj
1311
-     * @param bool $for_primary if true, the question group will be removed from the primary
1312
-     *                                           registrant, if false will be removed from others. default: false
1313
-     * @return EE_Base_Class|EE_Question_Group
1314
-     * @throws EE_Error
1315
-     * @throws InvalidArgumentException
1316
-     * @throws ReflectionException
1317
-     * @throws InvalidDataTypeException
1318
-     * @throws InvalidInterfaceException
1319
-     */
1320
-    public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1321
-    {
1322
-        // If the question group is used for the other type (primary or additional)
1323
-        // then just update it. If not, delete it outright.
1324
-        $existing_relation = $this->get_first_related(
1325
-            'Event_Question_Group',
1326
-            [
1327
-                [
1328
-                    'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj)
1329
-                ]
1330
-            ]
1331
-        );
1332
-        $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1333
-        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1334
-        if ($existing_relation->get($other_field) === false) {
1335
-            // Delete it. It's now no longer for primary or additional question groups.
1336
-            return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
1337
-        }
1338
-        // Just update it. They'll still use this question group for the other category
1339
-        $existing_relation->save(
1340
-            [
1341
-                $field_to_update => false
1342
-            ]
1343
-        );
1344
-    }
1345
-
1346
-
1347
-    /**
1348
-     * Gets all the question groups, ordering them by QSG_order ascending
1349
-     *
1350
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1351
-     * @return EE_Base_Class[]|EE_Question_Group[]
1352
-     * @throws EE_Error
1353
-     */
1354
-    public function question_groups($query_params = array())
1355
-    {
1356
-        $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1357
-        return $this->get_many_related('Question_Group', $query_params);
1358
-    }
1359
-
1360
-
1361
-    /**
1362
-     * Implementation for EEI_Has_Icon interface method.
1363
-     *
1364
-     * @see EEI_Visual_Representation for comments
1365
-     * @return string
1366
-     */
1367
-    public function get_icon()
1368
-    {
1369
-        return '<span class="dashicons dashicons-flag"></span>';
1370
-    }
1371
-
1372
-
1373
-    /**
1374
-     * Implementation for EEI_Admin_Links interface method.
1375
-     *
1376
-     * @see EEI_Admin_Links for comments
1377
-     * @return string
1378
-     * @throws EE_Error
1379
-     */
1380
-    public function get_admin_details_link()
1381
-    {
1382
-        return $this->get_admin_edit_link();
1383
-    }
1384
-
1385
-
1386
-    /**
1387
-     * Implementation for EEI_Admin_Links interface method.
1388
-     *
1389
-     * @see EEI_Admin_Links for comments
1390
-     * @return string
1391
-     * @throws EE_Error
1392
-     */
1393
-    public function get_admin_edit_link()
1394
-    {
1395
-        return EEH_URL::add_query_args_and_nonce(
1396
-            array(
1397
-                'page'   => 'espresso_events',
1398
-                'action' => 'edit',
1399
-                'post'   => $this->ID(),
1400
-            ),
1401
-            admin_url('admin.php')
1402
-        );
1403
-    }
1404
-
1405
-
1406
-    /**
1407
-     * Implementation for EEI_Admin_Links interface method.
1408
-     *
1409
-     * @see EEI_Admin_Links for comments
1410
-     * @return string
1411
-     */
1412
-    public function get_admin_settings_link()
1413
-    {
1414
-        return EEH_URL::add_query_args_and_nonce(
1415
-            array(
1416
-                'page'   => 'espresso_events',
1417
-                'action' => 'default_event_settings',
1418
-            ),
1419
-            admin_url('admin.php')
1420
-        );
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * Implementation for EEI_Admin_Links interface method.
1426
-     *
1427
-     * @see EEI_Admin_Links for comments
1428
-     * @return string
1429
-     */
1430
-    public function get_admin_overview_link()
1431
-    {
1432
-        return EEH_URL::add_query_args_and_nonce(
1433
-            array(
1434
-                'page'   => 'espresso_events',
1435
-                'action' => 'default',
1436
-            ),
1437
-            admin_url('admin.php')
1438
-        );
1439
-    }
1440
-
1441
-
1442
-    /**
1443
-     * @return string|null
1444
-     * @throws EE_Error
1445
-     * @throws ReflectionException
1446
-     */
1447
-    public function registrationFormUuid(): ?string
1448
-    {
1449
-        return $this->get('FSC_UUID');
1450
-    }
1451
-
1452
-
1453
-    /**
1454
-     * Gets all the form sections for this event
1455
-     *
1456
-     * @return EE_Base_Class[]|EE_Form_Section[]
1457
-     * @throws EE_Error
1458
-     * @throws ReflectionException
1459
-     */
1460
-    public function registrationForm()
1461
-    {
1462
-        $FSC_UUID = $this->registrationFormUuid();
1463
-
1464
-        if (empty($FSC_UUID)) {
1465
-            return [];
1466
-        }
1467
-
1468
-        return EEM_Form_Section::instance()->get_all([
1469
-            [
1470
-                'OR' => [
1471
-                    'FSC_UUID'      => $FSC_UUID, // top level form
1472
-                    'FSC_belongsTo' => $FSC_UUID, // child form sections
1473
-                ]
1474
-                ],
1475
-            'order_by' => ['FSC_order' => 'ASC'],
1476
-        ]);
1477
-    }
1478
-
1479
-
1480
-    /**
1481
-     * @param string $UUID
1482
-     * @throws EE_Error
1483
-     */
1484
-    public function setRegistrationFormUuid(string $UUID): void
1485
-    {
1486
-        if (! Cuid::isCuid($UUID)) {
1487
-            throw new InvalidArgumentException(
1488
-                sprintf(
1489
-                /* translators: 1: UUID value, 2: UUID generator function. */
1490
-                    esc_html__(
1491
-                        'The supplied UUID "%1$s" is invalid or missing. Please use %2$s to generate a valid one.',
1492
-                        'event_espresso'
1493
-                    ),
1494
-                    $UUID,
1495
-                    '`Cuid::cuid()`'
1496
-                )
1497
-            );
1498
-        }
1499
-        $this->set('FSC_UUID', $UUID);
1500
-    }
19
+	/**
20
+	 * cached value for the the logical active status for the event
21
+	 *
22
+	 * @see get_active_status()
23
+	 * @var string
24
+	 */
25
+	protected $_active_status = '';
26
+
27
+	/**
28
+	 * This is just used for caching the Primary Datetime for the Event on initial retrieval
29
+	 *
30
+	 * @var EE_Datetime
31
+	 */
32
+	protected $_Primary_Datetime;
33
+
34
+	/**
35
+	 * @var EventSpacesCalculator $available_spaces_calculator
36
+	 */
37
+	protected $available_spaces_calculator;
38
+
39
+
40
+	/**
41
+	 * @param array  $props_n_values          incoming values
42
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
43
+	 *                                        used.)
44
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
45
+	 *                                        date_format and the second value is the time format
46
+	 * @return EE_Event
47
+	 * @throws EE_Error
48
+	 */
49
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
50
+	{
51
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
52
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
53
+	}
54
+
55
+
56
+	/**
57
+	 * @param array  $props_n_values  incoming values from the database
58
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
59
+	 *                                the website will be used.
60
+	 * @return EE_Event
61
+	 * @throws EE_Error
62
+	 */
63
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
64
+	{
65
+		return new self($props_n_values, true, $timezone);
66
+	}
67
+
68
+
69
+	/**
70
+	 * @return EventSpacesCalculator
71
+	 * @throws \EE_Error
72
+	 */
73
+	public function getAvailableSpacesCalculator()
74
+	{
75
+		if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
76
+			$this->available_spaces_calculator = new EventSpacesCalculator($this);
77
+		}
78
+		return $this->available_spaces_calculator;
79
+	}
80
+
81
+
82
+	/**
83
+	 * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
84
+	 *
85
+	 * @param string $field_name
86
+	 * @param mixed  $field_value
87
+	 * @param bool   $use_default
88
+	 * @throws EE_Error
89
+	 */
90
+	public function set($field_name, $field_value, $use_default = false)
91
+	{
92
+		switch ($field_name) {
93
+			case 'status':
94
+				$this->set_status($field_value, $use_default);
95
+				break;
96
+			default:
97
+				parent::set($field_name, $field_value, $use_default);
98
+		}
99
+	}
100
+
101
+
102
+	/**
103
+	 *    set_status
104
+	 * Checks if event status is being changed to SOLD OUT
105
+	 * and updates event meta data with previous event status
106
+	 * so that we can revert things if/when the event is no longer sold out
107
+	 *
108
+	 * @access public
109
+	 * @param string $new_status
110
+	 * @param bool   $use_default
111
+	 * @return void
112
+	 * @throws EE_Error
113
+	 */
114
+	public function set_status($new_status = null, $use_default = false)
115
+	{
116
+		// if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
117
+		if (empty($new_status) && ! $use_default) {
118
+			return;
119
+		}
120
+		// get current Event status
121
+		$old_status = $this->status();
122
+		// if status has changed
123
+		if ($old_status !== $new_status) {
124
+			// TO sold_out
125
+			if ($new_status === EEM_Event::sold_out) {
126
+				// save the previous event status so that we can revert if the event is no longer sold out
127
+				$this->add_post_meta('_previous_event_status', $old_status);
128
+				do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
129
+			// OR FROM  sold_out
130
+			} elseif ($old_status === EEM_Event::sold_out) {
131
+				$this->delete_post_meta('_previous_event_status');
132
+				do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
133
+			}
134
+			// clear out the active status so that it gets reset the next time it is requested
135
+			$this->_active_status = null;
136
+			// update status
137
+			parent::set('status', $new_status, $use_default);
138
+			do_action('AHEE__EE_Event__set_status__after_update', $this);
139
+			return;
140
+		}
141
+		// even though the old value matches the new value, it's still good to
142
+		// allow the parent set method to have a say
143
+		parent::set('status', $new_status, $use_default);
144
+	}
145
+
146
+
147
+	/**
148
+	 * Gets all the datetimes for this event
149
+	 *
150
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
151
+	 * @return EE_Base_Class[]|EE_Datetime[]
152
+	 * @throws EE_Error
153
+	 */
154
+	public function datetimes($query_params = array())
155
+	{
156
+		return $this->get_many_related('Datetime', $query_params);
157
+	}
158
+
159
+
160
+	/**
161
+	 * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
162
+	 *
163
+	 * @return EE_Base_Class[]|EE_Datetime[]
164
+	 * @throws EE_Error
165
+	 */
166
+	public function datetimes_in_chronological_order()
167
+	{
168
+		return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
169
+	}
170
+
171
+
172
+	/**
173
+	 * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
174
+	 * @darren, we should probably UNSET timezone on the EEM_Datetime model
175
+	 * after running our query, so that this timezone isn't set for EVERY query
176
+	 * on EEM_Datetime for the rest of the request, no?
177
+	 *
178
+	 * @param boolean $show_expired whether or not to include expired events
179
+	 * @param boolean $show_deleted whether or not to include deleted events
180
+	 * @param null    $limit
181
+	 * @return EE_Datetime[]
182
+	 * @throws EE_Error
183
+	 */
184
+	public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
185
+	{
186
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
187
+			$this->ID(),
188
+			$show_expired,
189
+			$show_deleted,
190
+			$limit
191
+		);
192
+	}
193
+
194
+
195
+	/**
196
+	 * Returns one related datetime. Mostly only used by some legacy code.
197
+	 *
198
+	 * @return EE_Base_Class|EE_Datetime
199
+	 * @throws EE_Error
200
+	 */
201
+	public function first_datetime()
202
+	{
203
+		return $this->get_first_related('Datetime');
204
+	}
205
+
206
+
207
+	/**
208
+	 * Returns the 'primary' datetime for the event
209
+	 *
210
+	 * @param bool $try_to_exclude_expired
211
+	 * @param bool $try_to_exclude_deleted
212
+	 * @return EE_Datetime
213
+	 * @throws EE_Error
214
+	 */
215
+	public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
216
+	{
217
+		if (! empty($this->_Primary_Datetime)) {
218
+			return $this->_Primary_Datetime;
219
+		}
220
+		$this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
221
+			$this->ID(),
222
+			$try_to_exclude_expired,
223
+			$try_to_exclude_deleted
224
+		);
225
+		return $this->_Primary_Datetime;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Gets all the tickets available for purchase of this event
231
+	 *
232
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
233
+	 * @return EE_Base_Class[]|EE_Ticket[]
234
+	 * @throws EE_Error
235
+	 */
236
+	public function tickets($query_params = array())
237
+	{
238
+		// first get all datetimes
239
+		$datetimes = $this->datetimes_ordered();
240
+		if (! $datetimes) {
241
+			return array();
242
+		}
243
+		$datetime_ids = array();
244
+		foreach ($datetimes as $datetime) {
245
+			$datetime_ids[] = $datetime->ID();
246
+		}
247
+		$where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
248
+		// if incoming $query_params has where conditions let's merge but not override existing.
249
+		if (is_array($query_params) && isset($query_params[0])) {
250
+			$where_params = array_merge($query_params[0], $where_params);
251
+			unset($query_params[0]);
252
+		}
253
+		// now add $where_params to $query_params
254
+		$query_params[0] = $where_params;
255
+		return EEM_Ticket::instance()->get_all($query_params);
256
+	}
257
+
258
+
259
+	/**
260
+	 * get all unexpired untrashed tickets
261
+	 *
262
+	 * @return EE_Ticket[]
263
+	 * @throws EE_Error
264
+	 */
265
+	public function active_tickets()
266
+	{
267
+		return $this->tickets(
268
+			array(
269
+				array(
270
+					'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
271
+					'TKT_deleted'  => false,
272
+				),
273
+			)
274
+		);
275
+	}
276
+
277
+
278
+	/**
279
+	 * @return bool
280
+	 * @throws EE_Error
281
+	 */
282
+	public function additional_limit()
283
+	{
284
+		return $this->get('EVT_additional_limit');
285
+	}
286
+
287
+
288
+	/**
289
+	 * @return bool
290
+	 * @throws EE_Error
291
+	 */
292
+	public function allow_overflow()
293
+	{
294
+		return $this->get('EVT_allow_overflow');
295
+	}
296
+
297
+
298
+	/**
299
+	 * @return bool
300
+	 * @throws EE_Error
301
+	 */
302
+	public function created()
303
+	{
304
+		return $this->get('EVT_created');
305
+	}
306
+
307
+
308
+	/**
309
+	 * @return bool
310
+	 * @throws EE_Error
311
+	 */
312
+	public function description()
313
+	{
314
+		return $this->get('EVT_desc');
315
+	}
316
+
317
+
318
+	/**
319
+	 * Runs do_shortcode and wpautop on the description
320
+	 *
321
+	 * @return string of html
322
+	 * @throws EE_Error
323
+	 */
324
+	public function description_filtered()
325
+	{
326
+		return $this->get_pretty('EVT_desc');
327
+	}
328
+
329
+
330
+	/**
331
+	 * @return bool
332
+	 * @throws EE_Error
333
+	 */
334
+	public function display_description()
335
+	{
336
+		return $this->get('EVT_display_desc');
337
+	}
338
+
339
+
340
+	/**
341
+	 * @return bool
342
+	 * @throws EE_Error
343
+	 */
344
+	public function display_ticket_selector()
345
+	{
346
+		return (bool) $this->get('EVT_display_ticket_selector');
347
+	}
348
+
349
+
350
+	/**
351
+	 * @return bool
352
+	 * @throws EE_Error
353
+	 */
354
+	public function external_url()
355
+	{
356
+		return $this->get('EVT_external_URL');
357
+	}
358
+
359
+
360
+	/**
361
+	 * @return bool
362
+	 * @throws EE_Error
363
+	 */
364
+	public function member_only()
365
+	{
366
+		return $this->get('EVT_member_only');
367
+	}
368
+
369
+
370
+	/**
371
+	 * @return bool
372
+	 * @throws EE_Error
373
+	 */
374
+	public function phone()
375
+	{
376
+		return $this->get('EVT_phone');
377
+	}
378
+
379
+
380
+	/**
381
+	 * @return bool
382
+	 * @throws EE_Error
383
+	 */
384
+	public function modified()
385
+	{
386
+		return $this->get('EVT_modified');
387
+	}
388
+
389
+
390
+	/**
391
+	 * @return bool
392
+	 * @throws EE_Error
393
+	 */
394
+	public function name()
395
+	{
396
+		return $this->get('EVT_name');
397
+	}
398
+
399
+
400
+	/**
401
+	 * @return bool
402
+	 * @throws EE_Error
403
+	 */
404
+	public function order()
405
+	{
406
+		return $this->get('EVT_order');
407
+	}
408
+
409
+
410
+	/**
411
+	 * @return bool|string
412
+	 * @throws EE_Error
413
+	 */
414
+	public function default_registration_status()
415
+	{
416
+		$event_default_registration_status = $this->get('EVT_default_registration_status');
417
+		return ! empty($event_default_registration_status)
418
+			? $event_default_registration_status
419
+			: EE_Registry::instance()->CFG->registration->default_STS_ID;
420
+	}
421
+
422
+
423
+	/**
424
+	 * @param int  $num_words
425
+	 * @param null $more
426
+	 * @param bool $not_full_desc
427
+	 * @return bool|string
428
+	 * @throws EE_Error
429
+	 */
430
+	public function short_description($num_words = 55, $more = null, $not_full_desc = false)
431
+	{
432
+		$short_desc = $this->get('EVT_short_desc');
433
+		if (! empty($short_desc) || $not_full_desc) {
434
+			return $short_desc;
435
+		}
436
+		$full_desc = $this->get('EVT_desc');
437
+		return wp_trim_words($full_desc, $num_words, $more);
438
+	}
439
+
440
+
441
+	/**
442
+	 * @return bool
443
+	 * @throws EE_Error
444
+	 */
445
+	public function slug()
446
+	{
447
+		return $this->get('EVT_slug');
448
+	}
449
+
450
+
451
+	/**
452
+	 * @return bool
453
+	 * @throws EE_Error
454
+	 */
455
+	public function timezone_string()
456
+	{
457
+		return $this->get('EVT_timezone_string');
458
+	}
459
+
460
+
461
+	/**
462
+	 * @return bool
463
+	 * @throws EE_Error
464
+	 */
465
+	public function visible_on()
466
+	{
467
+		return $this->get('EVT_visible_on');
468
+	}
469
+
470
+
471
+	/**
472
+	 * @return int
473
+	 * @throws EE_Error
474
+	 */
475
+	public function wp_user()
476
+	{
477
+		return $this->get('EVT_wp_user');
478
+	}
479
+
480
+
481
+	/**
482
+	 * @return bool
483
+	 * @throws EE_Error
484
+	 */
485
+	public function donations()
486
+	{
487
+		return $this->get('EVT_donations');
488
+	}
489
+
490
+
491
+	/**
492
+	 * @param $limit
493
+	 * @throws EE_Error
494
+	 */
495
+	public function set_additional_limit($limit)
496
+	{
497
+		$this->set('EVT_additional_limit', $limit);
498
+	}
499
+
500
+
501
+	/**
502
+	 * @param $created
503
+	 * @throws EE_Error
504
+	 */
505
+	public function set_created($created)
506
+	{
507
+		$this->set('EVT_created', $created);
508
+	}
509
+
510
+
511
+	/**
512
+	 * @param $desc
513
+	 * @throws EE_Error
514
+	 */
515
+	public function set_description($desc)
516
+	{
517
+		$this->set('EVT_desc', $desc);
518
+	}
519
+
520
+
521
+	/**
522
+	 * @param $display_desc
523
+	 * @throws EE_Error
524
+	 */
525
+	public function set_display_description($display_desc)
526
+	{
527
+		$this->set('EVT_display_desc', $display_desc);
528
+	}
529
+
530
+
531
+	/**
532
+	 * @param $display_ticket_selector
533
+	 * @throws EE_Error
534
+	 */
535
+	public function set_display_ticket_selector($display_ticket_selector)
536
+	{
537
+		$this->set('EVT_display_ticket_selector', $display_ticket_selector);
538
+	}
539
+
540
+
541
+	/**
542
+	 * @param $external_url
543
+	 * @throws EE_Error
544
+	 */
545
+	public function set_external_url($external_url)
546
+	{
547
+		$this->set('EVT_external_URL', $external_url);
548
+	}
549
+
550
+
551
+	/**
552
+	 * @param $member_only
553
+	 * @throws EE_Error
554
+	 */
555
+	public function set_member_only($member_only)
556
+	{
557
+		$this->set('EVT_member_only', $member_only);
558
+	}
559
+
560
+
561
+	/**
562
+	 * @param $event_phone
563
+	 * @throws EE_Error
564
+	 */
565
+	public function set_event_phone($event_phone)
566
+	{
567
+		$this->set('EVT_phone', $event_phone);
568
+	}
569
+
570
+
571
+	/**
572
+	 * @param $modified
573
+	 * @throws EE_Error
574
+	 */
575
+	public function set_modified($modified)
576
+	{
577
+		$this->set('EVT_modified', $modified);
578
+	}
579
+
580
+
581
+	/**
582
+	 * @param $name
583
+	 * @throws EE_Error
584
+	 */
585
+	public function set_name($name)
586
+	{
587
+		$this->set('EVT_name', $name);
588
+	}
589
+
590
+
591
+	/**
592
+	 * @param $order
593
+	 * @throws EE_Error
594
+	 */
595
+	public function set_order($order)
596
+	{
597
+		$this->set('EVT_order', $order);
598
+	}
599
+
600
+
601
+	/**
602
+	 * @param $short_desc
603
+	 * @throws EE_Error
604
+	 */
605
+	public function set_short_description($short_desc)
606
+	{
607
+		$this->set('EVT_short_desc', $short_desc);
608
+	}
609
+
610
+
611
+	/**
612
+	 * @param $slug
613
+	 * @throws EE_Error
614
+	 */
615
+	public function set_slug($slug)
616
+	{
617
+		$this->set('EVT_slug', $slug);
618
+	}
619
+
620
+
621
+	/**
622
+	 * @param $timezone_string
623
+	 * @throws EE_Error
624
+	 */
625
+	public function set_timezone_string($timezone_string)
626
+	{
627
+		$this->set('EVT_timezone_string', $timezone_string);
628
+	}
629
+
630
+
631
+	/**
632
+	 * @param $visible_on
633
+	 * @throws EE_Error
634
+	 */
635
+	public function set_visible_on($visible_on)
636
+	{
637
+		$this->set('EVT_visible_on', $visible_on);
638
+	}
639
+
640
+
641
+	/**
642
+	 * @param $wp_user
643
+	 * @throws EE_Error
644
+	 */
645
+	public function set_wp_user($wp_user)
646
+	{
647
+		$this->set('EVT_wp_user', $wp_user);
648
+	}
649
+
650
+
651
+	/**
652
+	 * @param $default_registration_status
653
+	 * @throws EE_Error
654
+	 */
655
+	public function set_default_registration_status($default_registration_status)
656
+	{
657
+		$this->set('EVT_default_registration_status', $default_registration_status);
658
+	}
659
+
660
+
661
+	/**
662
+	 * @param $donations
663
+	 * @throws EE_Error
664
+	 */
665
+	public function set_donations($donations)
666
+	{
667
+		$this->set('EVT_donations', $donations);
668
+	}
669
+
670
+
671
+	/**
672
+	 * Adds a venue to this event
673
+	 *
674
+	 * @param int|EE_Venue /int $venue_id_or_obj
675
+	 * @return EE_Base_Class|EE_Venue
676
+	 * @throws EE_Error
677
+	 * @throws ReflectionException
678
+	 */
679
+	public function add_venue($venue_id_or_obj): EE_Venue
680
+	{
681
+		return $this->_add_relation_to($venue_id_or_obj, 'Venue');
682
+	}
683
+
684
+
685
+	/**
686
+	 * Removes a venue from the event
687
+	 *
688
+	 * @param EE_Venue /int $venue_id_or_obj
689
+	 * @return EE_Base_Class|EE_Venue
690
+	 * @throws EE_Error
691
+	 * @throws ReflectionException
692
+	 */
693
+	public function remove_venue($venue_id_or_obj): EE_Venue
694
+	{
695
+		$venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue();
696
+		return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
697
+	}
698
+
699
+
700
+	/**
701
+	 * Gets the venue related to the event. May provide additional $query_params if desired
702
+	 *
703
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
704
+	 * @return int
705
+	 * @throws EE_Error
706
+	 * @throws ReflectionException
707
+	 */
708
+	public function venue_ID(array $query_params = array()): int
709
+	{
710
+		$venue = $this->get_first_related('Venue', $query_params);
711
+		return $venue instanceof EE_Venue ? $venue->ID() : 0;
712
+	}
713
+
714
+
715
+	/**
716
+	 * Gets the venue related to the event. May provide additional $query_params if desired
717
+	 *
718
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
719
+	 * @return EE_Base_Class|EE_Venue
720
+	 * @throws EE_Error
721
+	 * @throws ReflectionException
722
+	 */
723
+	public function venue(array $query_params = array())
724
+	{
725
+		return $this->get_first_related('Venue', $query_params);
726
+	}
727
+
728
+
729
+	/**
730
+	 * @param array $query_params
731
+	 * @return EE_Base_Class[]|EE_Venue[]
732
+	 * @throws EE_Error
733
+	 * @throws ReflectionException
734
+	 * @deprecated $VID:$
735
+	 */
736
+	public function venues(array $query_params = array()): array
737
+	{
738
+		return (array) $this->venue($query_params);
739
+	}
740
+
741
+
742
+	/**
743
+	 * check if event id is present and if event is published
744
+	 *
745
+	 * @access public
746
+	 * @return boolean true yes, false no
747
+	 * @throws EE_Error
748
+	 */
749
+	private function _has_ID_and_is_published()
750
+	{
751
+		// first check if event id is present and not NULL,
752
+		// then check if this event is published (or any of the equivalent "published" statuses)
753
+		return
754
+			$this->ID() && $this->ID() !== null
755
+			&& (
756
+				$this->status() === 'publish'
757
+				|| $this->status() === EEM_Event::sold_out
758
+				|| $this->status() === EEM_Event::postponed
759
+				|| $this->status() === EEM_Event::cancelled
760
+			);
761
+	}
762
+
763
+
764
+	/**
765
+	 * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
766
+	 *
767
+	 * @access public
768
+	 * @return boolean true yes, false no
769
+	 * @throws EE_Error
770
+	 */
771
+	public function is_upcoming()
772
+	{
773
+		// check if event id is present and if this event is published
774
+		if ($this->is_inactive()) {
775
+			return false;
776
+		}
777
+		// set initial value
778
+		$upcoming = false;
779
+		// next let's get all datetimes and loop through them
780
+		$datetimes = $this->datetimes_in_chronological_order();
781
+		foreach ($datetimes as $datetime) {
782
+			if ($datetime instanceof EE_Datetime) {
783
+				// if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
784
+				if ($datetime->is_expired()) {
785
+					continue;
786
+				}
787
+				// if this dtt is active then we return false.
788
+				if ($datetime->is_active()) {
789
+					return false;
790
+				}
791
+				// otherwise let's check upcoming status
792
+				$upcoming = $datetime->is_upcoming();
793
+			}
794
+		}
795
+		return $upcoming;
796
+	}
797
+
798
+
799
+	/**
800
+	 * @return bool
801
+	 * @throws EE_Error
802
+	 */
803
+	public function is_active()
804
+	{
805
+		// check if event id is present and if this event is published
806
+		if ($this->is_inactive()) {
807
+			return false;
808
+		}
809
+		// set initial value
810
+		$active = false;
811
+		// next let's get all datetimes and loop through them
812
+		$datetimes = $this->datetimes_in_chronological_order();
813
+		foreach ($datetimes as $datetime) {
814
+			if ($datetime instanceof EE_Datetime) {
815
+				// if this dtt is expired then we continue cause one of the other datetimes might be active.
816
+				if ($datetime->is_expired()) {
817
+					continue;
818
+				}
819
+				// if this dtt is upcoming then we return false.
820
+				if ($datetime->is_upcoming()) {
821
+					return false;
822
+				}
823
+				// otherwise let's check active status
824
+				$active = $datetime->is_active();
825
+			}
826
+		}
827
+		return $active;
828
+	}
829
+
830
+
831
+	/**
832
+	 * @return bool
833
+	 * @throws EE_Error
834
+	 */
835
+	public function is_expired()
836
+	{
837
+		// check if event id is present and if this event is published
838
+		if ($this->is_inactive()) {
839
+			return false;
840
+		}
841
+		// set initial value
842
+		$expired = false;
843
+		// first let's get all datetimes and loop through them
844
+		$datetimes = $this->datetimes_in_chronological_order();
845
+		foreach ($datetimes as $datetime) {
846
+			if ($datetime instanceof EE_Datetime) {
847
+				// if this dtt is upcoming or active then we return false.
848
+				if ($datetime->is_upcoming() || $datetime->is_active()) {
849
+					return false;
850
+				}
851
+				// otherwise let's check active status
852
+				$expired = $datetime->is_expired();
853
+			}
854
+		}
855
+		return $expired;
856
+	}
857
+
858
+
859
+	/**
860
+	 * @return bool
861
+	 * @throws EE_Error
862
+	 */
863
+	public function is_inactive()
864
+	{
865
+		// check if event id is present and if this event is published
866
+		if ($this->_has_ID_and_is_published()) {
867
+			return false;
868
+		}
869
+		return true;
870
+	}
871
+
872
+
873
+	/**
874
+	 * calculate spaces remaining based on "saleable" tickets
875
+	 *
876
+	 * @param array $tickets
877
+	 * @param bool  $filtered
878
+	 * @return int|float
879
+	 * @throws EE_Error
880
+	 * @throws DomainException
881
+	 * @throws UnexpectedEntityException
882
+	 */
883
+	public function spaces_remaining($tickets = array(), $filtered = true)
884
+	{
885
+		$this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
886
+		$spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
887
+		return $filtered
888
+			? apply_filters(
889
+				'FHEE_EE_Event__spaces_remaining',
890
+				$spaces_remaining,
891
+				$this,
892
+				$tickets
893
+			)
894
+			: $spaces_remaining;
895
+	}
896
+
897
+
898
+	/**
899
+	 *    perform_sold_out_status_check
900
+	 *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
901
+	 *    available... if NOT, then the event status will get toggled to 'sold_out'
902
+	 *
903
+	 * @return bool    return the ACTUAL sold out state.
904
+	 * @throws EE_Error
905
+	 * @throws DomainException
906
+	 * @throws UnexpectedEntityException
907
+	 */
908
+	public function perform_sold_out_status_check()
909
+	{
910
+		// get all tickets
911
+		$tickets = $this->tickets(
912
+			array(
913
+				'default_where_conditions' => 'none',
914
+				'order_by' => array('TKT_qty' => 'ASC'),
915
+			)
916
+		);
917
+		$all_expired = true;
918
+		foreach ($tickets as $ticket) {
919
+			if (! $ticket->is_expired()) {
920
+				$all_expired = false;
921
+				break;
922
+			}
923
+		}
924
+		// if all the tickets are just expired, then don't update the event status to sold out
925
+		if ($all_expired) {
926
+			return true;
927
+		}
928
+		$spaces_remaining = $this->spaces_remaining($tickets);
929
+		if ($spaces_remaining < 1) {
930
+			if ($this->status() !== EEM_Event::post_status_private) {
931
+				$this->set_status(EEM_Event::sold_out);
932
+				$this->save();
933
+			}
934
+			$sold_out = true;
935
+		} else {
936
+			$sold_out = false;
937
+			// was event previously marked as sold out ?
938
+			if ($this->status() === EEM_Event::sold_out) {
939
+				// revert status to previous value, if it was set
940
+				$previous_event_status = $this->get_post_meta('_previous_event_status', true);
941
+				if ($previous_event_status) {
942
+					$this->set_status($previous_event_status);
943
+					$this->save();
944
+				}
945
+			}
946
+		}
947
+		do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
948
+		return $sold_out;
949
+	}
950
+
951
+
952
+	/**
953
+	 * This returns the total remaining spaces for sale on this event.
954
+	 *
955
+	 * @uses EE_Event::total_available_spaces()
956
+	 * @return float|int
957
+	 * @throws EE_Error
958
+	 * @throws DomainException
959
+	 * @throws UnexpectedEntityException
960
+	 */
961
+	public function spaces_remaining_for_sale()
962
+	{
963
+		return $this->total_available_spaces(true);
964
+	}
965
+
966
+
967
+	/**
968
+	 * This returns the total spaces available for an event
969
+	 * while considering all the qtys on the tickets and the reg limits
970
+	 * on the datetimes attached to this event.
971
+	 *
972
+	 * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
973
+	 *                              If this is false, then we return the most tickets that could ever be sold
974
+	 *                              for this event with the datetime and tickets setup on the event under optimal
975
+	 *                              selling conditions.  Otherwise we return a live calculation of spaces available
976
+	 *                              based on tickets sold.  Depending on setup and stage of sales, this
977
+	 *                              may appear to equal remaining tickets.  However, the more tickets are
978
+	 *                              sold out, the more accurate the "live" total is.
979
+	 * @return float|int
980
+	 * @throws EE_Error
981
+	 * @throws DomainException
982
+	 * @throws UnexpectedEntityException
983
+	 */
984
+	public function total_available_spaces($consider_sold = false)
985
+	{
986
+		$spaces_available = $consider_sold
987
+			? $this->getAvailableSpacesCalculator()->spacesRemaining()
988
+			: $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
989
+		return apply_filters(
990
+			'FHEE_EE_Event__total_available_spaces__spaces_available',
991
+			$spaces_available,
992
+			$this,
993
+			$this->getAvailableSpacesCalculator()->getDatetimes(),
994
+			$this->getAvailableSpacesCalculator()->getActiveTickets()
995
+		);
996
+	}
997
+
998
+
999
+	/**
1000
+	 * Checks if the event is set to sold out
1001
+	 *
1002
+	 * @param  bool $actual whether or not to perform calculations to not only figure the
1003
+	 *                      actual status but also to flip the status if necessary to sold
1004
+	 *                      out If false, we just check the existing status of the event
1005
+	 * @return boolean
1006
+	 * @throws EE_Error
1007
+	 */
1008
+	public function is_sold_out($actual = false)
1009
+	{
1010
+		if (! $actual) {
1011
+			return $this->status() === EEM_Event::sold_out;
1012
+		}
1013
+		return $this->perform_sold_out_status_check();
1014
+	}
1015
+
1016
+
1017
+	/**
1018
+	 * Checks if the event is marked as postponed
1019
+	 *
1020
+	 * @return boolean
1021
+	 */
1022
+	public function is_postponed()
1023
+	{
1024
+		return $this->status() === EEM_Event::postponed;
1025
+	}
1026
+
1027
+
1028
+	/**
1029
+	 * Checks if the event is marked as cancelled
1030
+	 *
1031
+	 * @return boolean
1032
+	 */
1033
+	public function is_cancelled()
1034
+	{
1035
+		return $this->status() === EEM_Event::cancelled;
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+	 * Get the logical active status in a hierarchical order for all the datetimes.  Note
1041
+	 * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1042
+	 * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1043
+	 * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1044
+	 * the event is considered expired.
1045
+	 * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1046
+	 * status set on the EVENT when it is not published and thus is done
1047
+	 *
1048
+	 * @param bool $reset
1049
+	 * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1050
+	 * @throws EE_Error
1051
+	 */
1052
+	public function get_active_status($reset = false)
1053
+	{
1054
+		// if the active status has already been set, then just use that value (unless we are resetting it)
1055
+		if (! empty($this->_active_status) && ! $reset) {
1056
+			return $this->_active_status;
1057
+		}
1058
+		// first check if event id is present on this object
1059
+		if (! $this->ID()) {
1060
+			return false;
1061
+		}
1062
+		$where_params_for_event = array(array('EVT_ID' => $this->ID()));
1063
+		// if event is published:
1064
+		if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1065
+			// active?
1066
+			if (
1067
+				EEM_Datetime::instance()->get_datetime_count_for_status(
1068
+					EE_Datetime::active,
1069
+					$where_params_for_event
1070
+				) > 0
1071
+			) {
1072
+				$this->_active_status = EE_Datetime::active;
1073
+			} else {
1074
+				// upcoming?
1075
+				if (
1076
+					EEM_Datetime::instance()->get_datetime_count_for_status(
1077
+						EE_Datetime::upcoming,
1078
+						$where_params_for_event
1079
+					) > 0
1080
+				) {
1081
+					$this->_active_status = EE_Datetime::upcoming;
1082
+				} else {
1083
+					// expired?
1084
+					if (
1085
+						EEM_Datetime::instance()->get_datetime_count_for_status(
1086
+							EE_Datetime::expired,
1087
+							$where_params_for_event
1088
+						) > 0
1089
+					) {
1090
+						$this->_active_status = EE_Datetime::expired;
1091
+					} else {
1092
+						// it would be odd if things make it this far because it basically means there are no datetime's
1093
+						// attached to the event.  So in this case it will just be considered inactive.
1094
+						$this->_active_status = EE_Datetime::inactive;
1095
+					}
1096
+				}
1097
+			}
1098
+		} else {
1099
+			// the event is not published, so let's just set it's active status according to its' post status
1100
+			switch ($this->status()) {
1101
+				case EEM_Event::sold_out:
1102
+					$this->_active_status = EE_Datetime::sold_out;
1103
+					break;
1104
+				case EEM_Event::cancelled:
1105
+					$this->_active_status = EE_Datetime::cancelled;
1106
+					break;
1107
+				case EEM_Event::postponed:
1108
+					$this->_active_status = EE_Datetime::postponed;
1109
+					break;
1110
+				default:
1111
+					$this->_active_status = EE_Datetime::inactive;
1112
+			}
1113
+		}
1114
+		return $this->_active_status;
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 *    pretty_active_status
1120
+	 *
1121
+	 * @access public
1122
+	 * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1123
+	 * @return mixed void|string
1124
+	 * @throws EE_Error
1125
+	 */
1126
+	public function pretty_active_status($echo = true)
1127
+	{
1128
+		$active_status = $this->get_active_status();
1129
+		$status = '<span class="ee-status event-active-status-'
1130
+				  . $active_status
1131
+				  . '">'
1132
+				  . EEH_Template::pretty_status($active_status, false, 'sentence')
1133
+				  . '</span>';
1134
+		if ($echo) {
1135
+			echo $status;
1136
+			return '';
1137
+		}
1138
+		return $status;
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 * @return bool|int
1144
+	 * @throws EE_Error
1145
+	 */
1146
+	public function get_number_of_tickets_sold()
1147
+	{
1148
+		$tkt_sold = 0;
1149
+		if (! $this->ID()) {
1150
+			return 0;
1151
+		}
1152
+		$datetimes = $this->datetimes();
1153
+		foreach ($datetimes as $datetime) {
1154
+			if ($datetime instanceof EE_Datetime) {
1155
+				$tkt_sold += $datetime->sold();
1156
+			}
1157
+		}
1158
+		return $tkt_sold;
1159
+	}
1160
+
1161
+
1162
+	/**
1163
+	 * This just returns a count of all the registrations for this event
1164
+	 *
1165
+	 * @access  public
1166
+	 * @return int
1167
+	 * @throws EE_Error
1168
+	 */
1169
+	public function get_count_of_all_registrations()
1170
+	{
1171
+		return EEM_Event::instance()->count_related($this, 'Registration');
1172
+	}
1173
+
1174
+
1175
+	/**
1176
+	 * This returns the ticket with the earliest start time that is
1177
+	 * available for this event (across all datetimes attached to the event)
1178
+	 *
1179
+	 * @return EE_Base_Class|EE_Ticket|null
1180
+	 * @throws EE_Error
1181
+	 */
1182
+	public function get_ticket_with_earliest_start_time()
1183
+	{
1184
+		$where['Datetime.EVT_ID'] = $this->ID();
1185
+		$query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1186
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1187
+	}
1188
+
1189
+
1190
+	/**
1191
+	 * This returns the ticket with the latest end time that is available
1192
+	 * for this event (across all datetimes attached to the event)
1193
+	 *
1194
+	 * @return EE_Base_Class|EE_Ticket|null
1195
+	 * @throws EE_Error
1196
+	 */
1197
+	public function get_ticket_with_latest_end_time()
1198
+	{
1199
+		$where['Datetime.EVT_ID'] = $this->ID();
1200
+		$query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1201
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1202
+	}
1203
+
1204
+
1205
+	/**
1206
+	 * This returns the number of different ticket types currently on sale for this event.
1207
+	 *
1208
+	 * @return int
1209
+	 * @throws EE_Error
1210
+	 */
1211
+	public function countTicketsOnSale()
1212
+	{
1213
+		$where = array(
1214
+			'Datetime.EVT_ID' => $this->ID(),
1215
+			'TKT_start_date'  => array('<', time()),
1216
+			'TKT_end_date'    => array('>', time()),
1217
+		);
1218
+		return EEM_Ticket::instance()->count(array($where));
1219
+	}
1220
+
1221
+
1222
+	/**
1223
+	 * This returns whether there are any tickets on sale for this event.
1224
+	 *
1225
+	 * @return bool true = YES tickets on sale.
1226
+	 * @throws EE_Error
1227
+	 */
1228
+	public function tickets_on_sale()
1229
+	{
1230
+		return $this->countTicketsOnSale() > 0;
1231
+	}
1232
+
1233
+
1234
+	/**
1235
+	 * Gets the URL for viewing this event on the front-end. Overrides parent
1236
+	 * to check for an external URL first
1237
+	 *
1238
+	 * @return string
1239
+	 * @throws EE_Error
1240
+	 */
1241
+	public function get_permalink()
1242
+	{
1243
+		if ($this->external_url()) {
1244
+			return $this->external_url();
1245
+		}
1246
+		return parent::get_permalink();
1247
+	}
1248
+
1249
+
1250
+	/**
1251
+	 * Gets the first term for 'espresso_event_categories' we can find
1252
+	 *
1253
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1254
+	 * @return EE_Base_Class|EE_Term|null
1255
+	 * @throws EE_Error
1256
+	 */
1257
+	public function first_event_category($query_params = array())
1258
+	{
1259
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1260
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1261
+		return EEM_Term::instance()->get_one($query_params);
1262
+	}
1263
+
1264
+
1265
+	/**
1266
+	 * Gets all terms for 'espresso_event_categories' we can find
1267
+	 *
1268
+	 * @param array $query_params
1269
+	 * @return EE_Base_Class[]|EE_Term[]
1270
+	 * @throws EE_Error
1271
+	 */
1272
+	public function get_all_event_categories($query_params = array())
1273
+	{
1274
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1275
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1276
+		return EEM_Term::instance()->get_all($query_params);
1277
+	}
1278
+
1279
+
1280
+	/**
1281
+	 * Adds a question group to this event
1282
+	 *
1283
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1284
+	 * @param bool $for_primary if true, the question group will be added for the primary
1285
+	 *                                           registrant, if false will be added for others. default: false
1286
+	 * @return EE_Base_Class|EE_Question_Group
1287
+	 * @throws EE_Error
1288
+	 * @throws InvalidArgumentException
1289
+	 * @throws InvalidDataTypeException
1290
+	 * @throws InvalidInterfaceException
1291
+	 * @throws ReflectionException
1292
+	 */
1293
+	public function add_question_group($question_group_id_or_obj, $for_primary = false)
1294
+	{
1295
+		// If the row already exists, it will be updated. If it doesn't, it will be inserted.
1296
+		// That's in EE_HABTM_Relation::add_relation_to().
1297
+		return $this->_add_relation_to(
1298
+			$question_group_id_or_obj,
1299
+			'Question_Group',
1300
+			[
1301
+				EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true
1302
+			]
1303
+		);
1304
+	}
1305
+
1306
+
1307
+	/**
1308
+	 * Removes a question group from the event
1309
+	 *
1310
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1311
+	 * @param bool $for_primary if true, the question group will be removed from the primary
1312
+	 *                                           registrant, if false will be removed from others. default: false
1313
+	 * @return EE_Base_Class|EE_Question_Group
1314
+	 * @throws EE_Error
1315
+	 * @throws InvalidArgumentException
1316
+	 * @throws ReflectionException
1317
+	 * @throws InvalidDataTypeException
1318
+	 * @throws InvalidInterfaceException
1319
+	 */
1320
+	public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1321
+	{
1322
+		// If the question group is used for the other type (primary or additional)
1323
+		// then just update it. If not, delete it outright.
1324
+		$existing_relation = $this->get_first_related(
1325
+			'Event_Question_Group',
1326
+			[
1327
+				[
1328
+					'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj)
1329
+				]
1330
+			]
1331
+		);
1332
+		$field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1333
+		$other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1334
+		if ($existing_relation->get($other_field) === false) {
1335
+			// Delete it. It's now no longer for primary or additional question groups.
1336
+			return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
1337
+		}
1338
+		// Just update it. They'll still use this question group for the other category
1339
+		$existing_relation->save(
1340
+			[
1341
+				$field_to_update => false
1342
+			]
1343
+		);
1344
+	}
1345
+
1346
+
1347
+	/**
1348
+	 * Gets all the question groups, ordering them by QSG_order ascending
1349
+	 *
1350
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1351
+	 * @return EE_Base_Class[]|EE_Question_Group[]
1352
+	 * @throws EE_Error
1353
+	 */
1354
+	public function question_groups($query_params = array())
1355
+	{
1356
+		$query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1357
+		return $this->get_many_related('Question_Group', $query_params);
1358
+	}
1359
+
1360
+
1361
+	/**
1362
+	 * Implementation for EEI_Has_Icon interface method.
1363
+	 *
1364
+	 * @see EEI_Visual_Representation for comments
1365
+	 * @return string
1366
+	 */
1367
+	public function get_icon()
1368
+	{
1369
+		return '<span class="dashicons dashicons-flag"></span>';
1370
+	}
1371
+
1372
+
1373
+	/**
1374
+	 * Implementation for EEI_Admin_Links interface method.
1375
+	 *
1376
+	 * @see EEI_Admin_Links for comments
1377
+	 * @return string
1378
+	 * @throws EE_Error
1379
+	 */
1380
+	public function get_admin_details_link()
1381
+	{
1382
+		return $this->get_admin_edit_link();
1383
+	}
1384
+
1385
+
1386
+	/**
1387
+	 * Implementation for EEI_Admin_Links interface method.
1388
+	 *
1389
+	 * @see EEI_Admin_Links for comments
1390
+	 * @return string
1391
+	 * @throws EE_Error
1392
+	 */
1393
+	public function get_admin_edit_link()
1394
+	{
1395
+		return EEH_URL::add_query_args_and_nonce(
1396
+			array(
1397
+				'page'   => 'espresso_events',
1398
+				'action' => 'edit',
1399
+				'post'   => $this->ID(),
1400
+			),
1401
+			admin_url('admin.php')
1402
+		);
1403
+	}
1404
+
1405
+
1406
+	/**
1407
+	 * Implementation for EEI_Admin_Links interface method.
1408
+	 *
1409
+	 * @see EEI_Admin_Links for comments
1410
+	 * @return string
1411
+	 */
1412
+	public function get_admin_settings_link()
1413
+	{
1414
+		return EEH_URL::add_query_args_and_nonce(
1415
+			array(
1416
+				'page'   => 'espresso_events',
1417
+				'action' => 'default_event_settings',
1418
+			),
1419
+			admin_url('admin.php')
1420
+		);
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * Implementation for EEI_Admin_Links interface method.
1426
+	 *
1427
+	 * @see EEI_Admin_Links for comments
1428
+	 * @return string
1429
+	 */
1430
+	public function get_admin_overview_link()
1431
+	{
1432
+		return EEH_URL::add_query_args_and_nonce(
1433
+			array(
1434
+				'page'   => 'espresso_events',
1435
+				'action' => 'default',
1436
+			),
1437
+			admin_url('admin.php')
1438
+		);
1439
+	}
1440
+
1441
+
1442
+	/**
1443
+	 * @return string|null
1444
+	 * @throws EE_Error
1445
+	 * @throws ReflectionException
1446
+	 */
1447
+	public function registrationFormUuid(): ?string
1448
+	{
1449
+		return $this->get('FSC_UUID');
1450
+	}
1451
+
1452
+
1453
+	/**
1454
+	 * Gets all the form sections for this event
1455
+	 *
1456
+	 * @return EE_Base_Class[]|EE_Form_Section[]
1457
+	 * @throws EE_Error
1458
+	 * @throws ReflectionException
1459
+	 */
1460
+	public function registrationForm()
1461
+	{
1462
+		$FSC_UUID = $this->registrationFormUuid();
1463
+
1464
+		if (empty($FSC_UUID)) {
1465
+			return [];
1466
+		}
1467
+
1468
+		return EEM_Form_Section::instance()->get_all([
1469
+			[
1470
+				'OR' => [
1471
+					'FSC_UUID'      => $FSC_UUID, // top level form
1472
+					'FSC_belongsTo' => $FSC_UUID, // child form sections
1473
+				]
1474
+				],
1475
+			'order_by' => ['FSC_order' => 'ASC'],
1476
+		]);
1477
+	}
1478
+
1479
+
1480
+	/**
1481
+	 * @param string $UUID
1482
+	 * @throws EE_Error
1483
+	 */
1484
+	public function setRegistrationFormUuid(string $UUID): void
1485
+	{
1486
+		if (! Cuid::isCuid($UUID)) {
1487
+			throw new InvalidArgumentException(
1488
+				sprintf(
1489
+				/* translators: 1: UUID value, 2: UUID generator function. */
1490
+					esc_html__(
1491
+						'The supplied UUID "%1$s" is invalid or missing. Please use %2$s to generate a valid one.',
1492
+						'event_espresso'
1493
+					),
1494
+					$UUID,
1495
+					'`Cuid::cuid()`'
1496
+				)
1497
+			);
1498
+		}
1499
+		$this->set('FSC_UUID', $UUID);
1500
+	}
1501 1501
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Form_Section.class.php 2 patches
Indentation   +490 added lines, -490 removed lines patch added patch discarded remove patch
@@ -26,494 +26,494 @@
 block discarded – undo
26 26
 class EE_Form_Section extends EE_Base_Class
27 27
 {
28 28
 
29
-    /**
30
-     * @var Attributes
31
-     */
32
-    private $attributes;
33
-
34
-    /**
35
-     * @var EE_Form_Element[]
36
-     */
37
-    private $form_elements = [];
38
-
39
-    /**
40
-     * @var FormLabel
41
-     */
42
-    private $label;
43
-
44
-
45
-
46
-    /**
47
-     * @param array $props_n_values
48
-     * @return EE_Form_Section
49
-     * @throws EE_Error
50
-     * @throws ReflectionException
51
-     */
52
-    public static function new_instance(array $props_n_values = []): EE_Form_Section
53
-    {
54
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
55
-        return $has_object ?: new self($props_n_values);
56
-    }
57
-
58
-
59
-    /**
60
-     * @param array $props_n_values
61
-     * @return EE_Form_Section
62
-     * @throws EE_Error
63
-     * @throws ReflectionException
64
-     */
65
-    public static function new_instance_from_db(array $props_n_values = []): EE_Form_Section
66
-    {
67
-        return new self($props_n_values, true);
68
-    }
69
-
70
-
71
-    /**
72
-     * Form Section UUID (universally unique identifier)
73
-     *
74
-     * @return string
75
-     * @throws EE_Error
76
-     * @throws ReflectionException
77
-     */
78
-    public function UUID(): string
79
-    {
80
-        return $this->get('FSC_UUID');
81
-    }
82
-
83
-
84
-    /**
85
-     * last 8 characters of the UUID
86
-     *
87
-     * @return string
88
-     * @throws EE_Error
89
-     * @throws ReflectionException
90
-     */
91
-    public function uuidSlug(): string
92
-    {
93
-        return substr($this->UUID(), -8);
94
-    }
95
-
96
-
97
-    /**
98
-     * @param string $UUID
99
-     * @throws EE_Error
100
-     * @throws ReflectionException
101
-     */
102
-    public function setUUID(string $UUID)
103
-    {
104
-        if (! Cuid::isCuid($UUID)) {
105
-            throw new InvalidArgumentException(
106
-                sprintf(
107
-                    /* translators: 1: UUID value, 2: UUID generator function. */
108
-                    esc_html__(
109
-                        'The supplied UUID "%1$s" is invalid or missing. Please use %2$s to generate a valid one.',
110
-                        'event_espresso'
111
-                    ),
112
-                    $UUID,
113
-                    "`Cuid::cuid()`"
114
-                )
115
-            );
116
-        }
117
-        $this->set('FSC_UUID', $UUID);
118
-    }
119
-
120
-
121
-    /**
122
-     * Form user types that this form section should be presented to.
123
-     * Values correspond to the EEM_Form_Section::APPLIES_TO_* constants.
124
-     *
125
-     * @return string
126
-     * @throws EE_Error
127
-     * @throws ReflectionException
128
-     */
129
-    public function appliesTo(): string
130
-    {
131
-        return $this->get('FSC_appliesTo');
132
-    }
133
-
134
-
135
-    /**
136
-     * Form user types that this form section should be presented to.
137
-     * Values correspond to the EEM_Form_Section::APPLIES_TO_* constants.
138
-     *
139
-     * @param EE_Registration|string $registrant
140
-     * @return bool
141
-     * @throws EE_Error
142
-     * @throws ReflectionException
143
-     */
144
-    public function appliesToRegistrant($registrant): bool
145
-    {
146
-        switch ($this->appliesTo()) {
147
-            case EEM_Form_Section::APPLIES_TO_PRIMARY:
148
-                return $registrant instanceof EE_Registration && $registrant->is_primary_registrant();
149
-            case EEM_Form_Section::APPLIES_TO_PURCHASER:
150
-                return $registrant === 'purchaser';
151
-            case EEM_Form_Section::APPLIES_TO_REGISTRANTS:
152
-                return $registrant instanceof EE_Registration && ! $registrant->is_primary_registrant();
153
-            case EEM_Form_Section::APPLIES_TO_ALL:
154
-            default:
155
-                return true;
156
-        }
157
-    }
158
-
159
-
160
-    /**
161
-     * @param string $user_type
162
-     * @throws EE_Error
163
-     * @throws ReflectionException
164
-     */
165
-    public function setAppliesTo(string $user_type)
166
-    {
167
-        $this->set('FSC_appliesTo', $user_type);
168
-    }
169
-
170
-
171
-    /**
172
-     * JSON string of HTML attributes, such as class, to be applied to this form section\'s container.
173
-     *
174
-     * @return Attributes
175
-     * @throws EE_Error
176
-     * @throws ReflectionException
177
-     */
178
-    public function attributes(): ?Attributes
179
-    {
180
-        if (! $this->attributes instanceof Attributes) {
181
-            $this->attributes = Attributes::fromJson($this->get('FSC_attributes'));
182
-        }
183
-        return $this->attributes;
184
-    }
185
-
186
-
187
-    /**
188
-     * @param Attributes $attributes
189
-     * @throws EE_Error
190
-     * @throws ReflectionException
191
-     */
192
-    public function setAttributes(Attributes $attributes)
193
-    {
194
-        // set local object
195
-        $this->attributes = $attributes;
196
-        // then pass to model as an array which will get converted to JSON by the model field
197
-        $this->set('FSC_attributes', $attributes->toArray());
198
-    }
199
-
200
-
201
-    /**
202
-     * UUID or ID of related entity this form section belongs to.
203
-     *
204
-     * @return string
205
-     * @throws EE_Error
206
-     * @throws ReflectionException
207
-     */
208
-    public function belongsTo(): ?string
209
-    {
210
-        return $this->get('FSC_belongsTo');
211
-    }
212
-
213
-
214
-    /**
215
-     * @param string $parent_UUID
216
-     * @throws EE_Error
217
-     * @throws ReflectionException
218
-     */
219
-    public function setBelongsTo(string $parent_UUID)
220
-    {
221
-        $this->set('FSC_belongsTo', $parent_UUID);
222
-    }
223
-
224
-
225
-    /**
226
-     * @return EE_Form_Element[]
227
-     * @throws EE_Error
228
-     * @throws ReflectionException
229
-     */
230
-    public function formElements(): array
231
-    {
232
-        return $this->form_elements ?: $this->getFormElements();
233
-    }
234
-
235
-
236
-    /**
237
-     * @return EE_Form_Element[]
238
-     * @throws EE_Error
239
-     * @throws ReflectionException
240
-     */
241
-    private function getFormElements(): array
242
-    {
243
-        $form_elements = $this->get_many_related('Form_Element', ['order_by' => ['FIN_order' => 'ASC']]);
244
-        foreach ($form_elements as $form_element) {
245
-            if ($form_element instanceof EE_Form_Element) {
246
-                $this->form_elements[ $form_element->UUID() ] = $form_element;
247
-            }
248
-        }
249
-        return $this->form_elements;
250
-    }
251
-
252
-
253
-    /**
254
-     * @param EE_Form_Element[] $form_elements
255
-     * @throws EE_Error
256
-     * @throws ReflectionException
257
-     */
258
-    public function setFormElements(array $form_elements): void
259
-    {
260
-        foreach ($form_elements as $form_element) {
261
-            if ($form_element instanceof EE_Form_Element) {
262
-                $this->_add_relation_to($form_element->UUID(), 'Form_Element');
263
-                $this->form_elements[ $form_element->UUID() ] = $form_element;
264
-            }
265
-        }
266
-    }
267
-
268
-
269
-    /**
270
-     * @param EE_Form_Element[] $all_form_elements
271
-     * @return EE_Form_Element[]
272
-     * @throws EE_Error
273
-     * @throws ReflectionException
274
-     */
275
-    public function filterFormElements(array $all_form_elements): array
276
-    {
277
-        return array_filter($all_form_elements, $this->formElementFilter());
278
-    }
279
-
280
-
281
-    /**
282
-     * returns a closure that can be used to filter form elements for this form section
283
-     * usage:
284
-     *  $filter = EEM_Form_Element::formElementFilter();
285
-     *  $filtered_form_elements = array_filter( $all_form_elements, $filter );
286
-     *
287
-     * @return Closure
288
-     * @throws EE_Error
289
-     * @throws ReflectionException
290
-     */
291
-    public function formElementFilter(): Closure
292
-    {
293
-        $FSC_UUID = strtolower($this->UUID());
294
-        return function ($form_element) use ($FSC_UUID) {
295
-            return $form_element instanceof EE_Form_Element && strtolower($form_element->belongsTo()) === $FSC_UUID;
296
-        };
297
-    }
298
-
299
-
300
-    /**
301
-     * returns a FormLabel object for managing form section labels, ie: the form section heading
302
-     *
303
-     * @return FormLabel
304
-     * @throws EE_Error
305
-     * @throws ReflectionException
306
-     */
307
-    public function label(): ?FormLabel
308
-    {
309
-        if (! $this->label instanceof FormLabel) {
310
-            $this->label = FormLabel::fromJson($this->get('FSC_label'));
311
-        }
312
-        return $this->label;
313
-    }
314
-
315
-
316
-    /**
317
-     * @param FormLabel $label
318
-     * @throws EE_Error
319
-     * @throws ReflectionException
320
-     */
321
-    public function setLabel(FormLabel $label)
322
-    {
323
-        // set local object
324
-        $this->label = $label;
325
-        // then pass to model as an array which will get converted to JSON by the model field
326
-        $this->set('FSC_label', $label->toJson());
327
-    }
328
-
329
-
330
-    /**
331
-     * Order in which form section appears in a form.
332
-     *
333
-     * @return int
334
-     * @throws EE_Error
335
-     * @throws ReflectionException
336
-     */
337
-    public function order(): int
338
-    {
339
-        return $this->get('FSC_order');
340
-    }
341
-
342
-
343
-    /**
344
-     * @param int $order
345
-     * @throws EE_Error
346
-     * @throws ReflectionException
347
-     */
348
-    public function setOrder(int $order)
349
-    {
350
-        $this->set('FSC_order', $order);
351
-    }
352
-
353
-
354
-    /**
355
-     * combination of public label and UUID slug for use in identifiers
356
-     *
357
-     * @return string
358
-     * @throws EE_Error
359
-     * @throws ReflectionException
360
-     */
361
-    public function slug(): ?string
362
-    {
363
-        $label = sanitize_title($this->label()->publicLabel());
364
-        return "{$label}-{$this->uuidSlug()}";
365
-    }
366
-
367
-
368
-    /**
369
-     * Whether form section is active, archived, trashed, or used as a default on new forms.
370
-     * Values correspond to the EEM_Form_Section::STATUS_* constants.
371
-     *
372
-     * @return string
373
-     * @throws EE_Error
374
-     * @throws ReflectionException
375
-     */
376
-    public function status(): ?string
377
-    {
378
-        return $this->get('FSC_status');
379
-    }
380
-
381
-
382
-    /**
383
-     * Whether form section is active, archived, trashed, or used as a default on new forms.
384
-     * Values correspond to the EEM_Form_Section::STATUS_* constants.
385
-     *
386
-     * @param string $status
387
-     * @throws EE_Error
388
-     * @throws ReflectionException
389
-     */
390
-    public function setStatus(string $status)
391
-    {
392
-        $this->set('FSC_status', $status);
393
-    }
394
-
395
-
396
-    /**
397
-     * returns the id the wordpress user who created this question
398
-     *
399
-     * @return int
400
-     * @throws EE_Error
401
-     * @throws ReflectionException
402
-     */
403
-    public function wp_user(): int
404
-    {
405
-        return $this->get('FSC_wpUser');
406
-    }
407
-
408
-
409
-    /**
410
-     * @param int $wp_user
411
-     * @throws EE_Error
412
-     * @throws ReflectionException
413
-     */
414
-    public function setWpUser(int $wp_user)
415
-    {
416
-        $this->set('FSC_wpUser', $wp_user);
417
-    }
418
-
419
-
420
-    /**
421
-     * @param array $set_cols_n_values
422
-     * @return bool|int|string
423
-     * @throws EE_Error
424
-     * @throws ReflectionException
425
-     */
426
-    public function save($set_cols_n_values = [])
427
-    {
428
-        // make sure internal versions for all composite objects are updated
429
-        $this->set('FSC_attributes', $this->attributes()->toArray());
430
-        $this->set('FSC_label', $this->label()->toArray());
431
-        return parent::save($set_cols_n_values);
432
-    }
433
-
434
-    /**
435
-     * Whether the section is active.
436
-     *
437
-     * @return boolean  TRUE if is active, FALSE if not.
438
-     * @throws ReflectionException
439
-     * @throws InvalidArgumentException
440
-     * @throws InvalidInterfaceException
441
-     * @throws InvalidDataTypeException
442
-     * @throws EE_Error
443
-     */
444
-    public function isActive(): bool
445
-    {
446
-        return $this->status() === FormStatus::ACTIVE;
447
-    }
448
-
449
-    /**
450
-     * Whether the section is archived.
451
-     *
452
-     * @return boolean  TRUE if is archived, FALSE if not.
453
-     * @throws ReflectionException
454
-     * @throws InvalidArgumentException
455
-     * @throws InvalidInterfaceException
456
-     * @throws InvalidDataTypeException
457
-     * @throws EE_Error
458
-     */
459
-    public function isArchived(): bool
460
-    {
461
-        return $this->status() === FormStatus::ARCHIVED;
462
-    }
463
-
464
-    /**
465
-     * Whether the section is a default one.
466
-     *
467
-     * @return boolean  TRUE if is default, FALSE if not.
468
-     * @throws ReflectionException
469
-     * @throws InvalidArgumentException
470
-     * @throws InvalidInterfaceException
471
-     * @throws InvalidDataTypeException
472
-     * @throws EE_Error
473
-     */
474
-    public function isDefault(): bool
475
-    {
476
-        return $this->status() === FormStatus::DEFAULT;
477
-    }
478
-
479
-    /**
480
-     * Whether the section is a shared one.
481
-     *
482
-     * @return boolean  TRUE if is shared, FALSE if not.
483
-     * @throws ReflectionException
484
-     * @throws InvalidArgumentException
485
-     * @throws InvalidInterfaceException
486
-     * @throws InvalidDataTypeException
487
-     * @throws EE_Error
488
-     */
489
-    public function isShared(): bool
490
-    {
491
-        return $this->status() === FormStatus::SHARED;
492
-    }
493
-
494
-    /**
495
-     * Whether the section is trashed.
496
-     *
497
-     * @return boolean  TRUE if is trashed, FALSE if not.
498
-     * @throws ReflectionException
499
-     * @throws InvalidArgumentException
500
-     * @throws InvalidInterfaceException
501
-     * @throws InvalidDataTypeException
502
-     * @throws EE_Error
503
-     */
504
-    public function isTrashed(): bool
505
-    {
506
-        return $this->status() === FormStatus::TRASHED;
507
-    }
508
-
509
-
510
-    /**
511
-     * @return bool
512
-     * @throws EE_Error
513
-     * @throws ReflectionException
514
-     */
515
-    public function isTopLevelFormSection(): bool
516
-    {
517
-        return empty($this->belongsTo());
518
-    }
29
+	/**
30
+	 * @var Attributes
31
+	 */
32
+	private $attributes;
33
+
34
+	/**
35
+	 * @var EE_Form_Element[]
36
+	 */
37
+	private $form_elements = [];
38
+
39
+	/**
40
+	 * @var FormLabel
41
+	 */
42
+	private $label;
43
+
44
+
45
+
46
+	/**
47
+	 * @param array $props_n_values
48
+	 * @return EE_Form_Section
49
+	 * @throws EE_Error
50
+	 * @throws ReflectionException
51
+	 */
52
+	public static function new_instance(array $props_n_values = []): EE_Form_Section
53
+	{
54
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
55
+		return $has_object ?: new self($props_n_values);
56
+	}
57
+
58
+
59
+	/**
60
+	 * @param array $props_n_values
61
+	 * @return EE_Form_Section
62
+	 * @throws EE_Error
63
+	 * @throws ReflectionException
64
+	 */
65
+	public static function new_instance_from_db(array $props_n_values = []): EE_Form_Section
66
+	{
67
+		return new self($props_n_values, true);
68
+	}
69
+
70
+
71
+	/**
72
+	 * Form Section UUID (universally unique identifier)
73
+	 *
74
+	 * @return string
75
+	 * @throws EE_Error
76
+	 * @throws ReflectionException
77
+	 */
78
+	public function UUID(): string
79
+	{
80
+		return $this->get('FSC_UUID');
81
+	}
82
+
83
+
84
+	/**
85
+	 * last 8 characters of the UUID
86
+	 *
87
+	 * @return string
88
+	 * @throws EE_Error
89
+	 * @throws ReflectionException
90
+	 */
91
+	public function uuidSlug(): string
92
+	{
93
+		return substr($this->UUID(), -8);
94
+	}
95
+
96
+
97
+	/**
98
+	 * @param string $UUID
99
+	 * @throws EE_Error
100
+	 * @throws ReflectionException
101
+	 */
102
+	public function setUUID(string $UUID)
103
+	{
104
+		if (! Cuid::isCuid($UUID)) {
105
+			throw new InvalidArgumentException(
106
+				sprintf(
107
+					/* translators: 1: UUID value, 2: UUID generator function. */
108
+					esc_html__(
109
+						'The supplied UUID "%1$s" is invalid or missing. Please use %2$s to generate a valid one.',
110
+						'event_espresso'
111
+					),
112
+					$UUID,
113
+					"`Cuid::cuid()`"
114
+				)
115
+			);
116
+		}
117
+		$this->set('FSC_UUID', $UUID);
118
+	}
119
+
120
+
121
+	/**
122
+	 * Form user types that this form section should be presented to.
123
+	 * Values correspond to the EEM_Form_Section::APPLIES_TO_* constants.
124
+	 *
125
+	 * @return string
126
+	 * @throws EE_Error
127
+	 * @throws ReflectionException
128
+	 */
129
+	public function appliesTo(): string
130
+	{
131
+		return $this->get('FSC_appliesTo');
132
+	}
133
+
134
+
135
+	/**
136
+	 * Form user types that this form section should be presented to.
137
+	 * Values correspond to the EEM_Form_Section::APPLIES_TO_* constants.
138
+	 *
139
+	 * @param EE_Registration|string $registrant
140
+	 * @return bool
141
+	 * @throws EE_Error
142
+	 * @throws ReflectionException
143
+	 */
144
+	public function appliesToRegistrant($registrant): bool
145
+	{
146
+		switch ($this->appliesTo()) {
147
+			case EEM_Form_Section::APPLIES_TO_PRIMARY:
148
+				return $registrant instanceof EE_Registration && $registrant->is_primary_registrant();
149
+			case EEM_Form_Section::APPLIES_TO_PURCHASER:
150
+				return $registrant === 'purchaser';
151
+			case EEM_Form_Section::APPLIES_TO_REGISTRANTS:
152
+				return $registrant instanceof EE_Registration && ! $registrant->is_primary_registrant();
153
+			case EEM_Form_Section::APPLIES_TO_ALL:
154
+			default:
155
+				return true;
156
+		}
157
+	}
158
+
159
+
160
+	/**
161
+	 * @param string $user_type
162
+	 * @throws EE_Error
163
+	 * @throws ReflectionException
164
+	 */
165
+	public function setAppliesTo(string $user_type)
166
+	{
167
+		$this->set('FSC_appliesTo', $user_type);
168
+	}
169
+
170
+
171
+	/**
172
+	 * JSON string of HTML attributes, such as class, to be applied to this form section\'s container.
173
+	 *
174
+	 * @return Attributes
175
+	 * @throws EE_Error
176
+	 * @throws ReflectionException
177
+	 */
178
+	public function attributes(): ?Attributes
179
+	{
180
+		if (! $this->attributes instanceof Attributes) {
181
+			$this->attributes = Attributes::fromJson($this->get('FSC_attributes'));
182
+		}
183
+		return $this->attributes;
184
+	}
185
+
186
+
187
+	/**
188
+	 * @param Attributes $attributes
189
+	 * @throws EE_Error
190
+	 * @throws ReflectionException
191
+	 */
192
+	public function setAttributes(Attributes $attributes)
193
+	{
194
+		// set local object
195
+		$this->attributes = $attributes;
196
+		// then pass to model as an array which will get converted to JSON by the model field
197
+		$this->set('FSC_attributes', $attributes->toArray());
198
+	}
199
+
200
+
201
+	/**
202
+	 * UUID or ID of related entity this form section belongs to.
203
+	 *
204
+	 * @return string
205
+	 * @throws EE_Error
206
+	 * @throws ReflectionException
207
+	 */
208
+	public function belongsTo(): ?string
209
+	{
210
+		return $this->get('FSC_belongsTo');
211
+	}
212
+
213
+
214
+	/**
215
+	 * @param string $parent_UUID
216
+	 * @throws EE_Error
217
+	 * @throws ReflectionException
218
+	 */
219
+	public function setBelongsTo(string $parent_UUID)
220
+	{
221
+		$this->set('FSC_belongsTo', $parent_UUID);
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return EE_Form_Element[]
227
+	 * @throws EE_Error
228
+	 * @throws ReflectionException
229
+	 */
230
+	public function formElements(): array
231
+	{
232
+		return $this->form_elements ?: $this->getFormElements();
233
+	}
234
+
235
+
236
+	/**
237
+	 * @return EE_Form_Element[]
238
+	 * @throws EE_Error
239
+	 * @throws ReflectionException
240
+	 */
241
+	private function getFormElements(): array
242
+	{
243
+		$form_elements = $this->get_many_related('Form_Element', ['order_by' => ['FIN_order' => 'ASC']]);
244
+		foreach ($form_elements as $form_element) {
245
+			if ($form_element instanceof EE_Form_Element) {
246
+				$this->form_elements[ $form_element->UUID() ] = $form_element;
247
+			}
248
+		}
249
+		return $this->form_elements;
250
+	}
251
+
252
+
253
+	/**
254
+	 * @param EE_Form_Element[] $form_elements
255
+	 * @throws EE_Error
256
+	 * @throws ReflectionException
257
+	 */
258
+	public function setFormElements(array $form_elements): void
259
+	{
260
+		foreach ($form_elements as $form_element) {
261
+			if ($form_element instanceof EE_Form_Element) {
262
+				$this->_add_relation_to($form_element->UUID(), 'Form_Element');
263
+				$this->form_elements[ $form_element->UUID() ] = $form_element;
264
+			}
265
+		}
266
+	}
267
+
268
+
269
+	/**
270
+	 * @param EE_Form_Element[] $all_form_elements
271
+	 * @return EE_Form_Element[]
272
+	 * @throws EE_Error
273
+	 * @throws ReflectionException
274
+	 */
275
+	public function filterFormElements(array $all_form_elements): array
276
+	{
277
+		return array_filter($all_form_elements, $this->formElementFilter());
278
+	}
279
+
280
+
281
+	/**
282
+	 * returns a closure that can be used to filter form elements for this form section
283
+	 * usage:
284
+	 *  $filter = EEM_Form_Element::formElementFilter();
285
+	 *  $filtered_form_elements = array_filter( $all_form_elements, $filter );
286
+	 *
287
+	 * @return Closure
288
+	 * @throws EE_Error
289
+	 * @throws ReflectionException
290
+	 */
291
+	public function formElementFilter(): Closure
292
+	{
293
+		$FSC_UUID = strtolower($this->UUID());
294
+		return function ($form_element) use ($FSC_UUID) {
295
+			return $form_element instanceof EE_Form_Element && strtolower($form_element->belongsTo()) === $FSC_UUID;
296
+		};
297
+	}
298
+
299
+
300
+	/**
301
+	 * returns a FormLabel object for managing form section labels, ie: the form section heading
302
+	 *
303
+	 * @return FormLabel
304
+	 * @throws EE_Error
305
+	 * @throws ReflectionException
306
+	 */
307
+	public function label(): ?FormLabel
308
+	{
309
+		if (! $this->label instanceof FormLabel) {
310
+			$this->label = FormLabel::fromJson($this->get('FSC_label'));
311
+		}
312
+		return $this->label;
313
+	}
314
+
315
+
316
+	/**
317
+	 * @param FormLabel $label
318
+	 * @throws EE_Error
319
+	 * @throws ReflectionException
320
+	 */
321
+	public function setLabel(FormLabel $label)
322
+	{
323
+		// set local object
324
+		$this->label = $label;
325
+		// then pass to model as an array which will get converted to JSON by the model field
326
+		$this->set('FSC_label', $label->toJson());
327
+	}
328
+
329
+
330
+	/**
331
+	 * Order in which form section appears in a form.
332
+	 *
333
+	 * @return int
334
+	 * @throws EE_Error
335
+	 * @throws ReflectionException
336
+	 */
337
+	public function order(): int
338
+	{
339
+		return $this->get('FSC_order');
340
+	}
341
+
342
+
343
+	/**
344
+	 * @param int $order
345
+	 * @throws EE_Error
346
+	 * @throws ReflectionException
347
+	 */
348
+	public function setOrder(int $order)
349
+	{
350
+		$this->set('FSC_order', $order);
351
+	}
352
+
353
+
354
+	/**
355
+	 * combination of public label and UUID slug for use in identifiers
356
+	 *
357
+	 * @return string
358
+	 * @throws EE_Error
359
+	 * @throws ReflectionException
360
+	 */
361
+	public function slug(): ?string
362
+	{
363
+		$label = sanitize_title($this->label()->publicLabel());
364
+		return "{$label}-{$this->uuidSlug()}";
365
+	}
366
+
367
+
368
+	/**
369
+	 * Whether form section is active, archived, trashed, or used as a default on new forms.
370
+	 * Values correspond to the EEM_Form_Section::STATUS_* constants.
371
+	 *
372
+	 * @return string
373
+	 * @throws EE_Error
374
+	 * @throws ReflectionException
375
+	 */
376
+	public function status(): ?string
377
+	{
378
+		return $this->get('FSC_status');
379
+	}
380
+
381
+
382
+	/**
383
+	 * Whether form section is active, archived, trashed, or used as a default on new forms.
384
+	 * Values correspond to the EEM_Form_Section::STATUS_* constants.
385
+	 *
386
+	 * @param string $status
387
+	 * @throws EE_Error
388
+	 * @throws ReflectionException
389
+	 */
390
+	public function setStatus(string $status)
391
+	{
392
+		$this->set('FSC_status', $status);
393
+	}
394
+
395
+
396
+	/**
397
+	 * returns the id the wordpress user who created this question
398
+	 *
399
+	 * @return int
400
+	 * @throws EE_Error
401
+	 * @throws ReflectionException
402
+	 */
403
+	public function wp_user(): int
404
+	{
405
+		return $this->get('FSC_wpUser');
406
+	}
407
+
408
+
409
+	/**
410
+	 * @param int $wp_user
411
+	 * @throws EE_Error
412
+	 * @throws ReflectionException
413
+	 */
414
+	public function setWpUser(int $wp_user)
415
+	{
416
+		$this->set('FSC_wpUser', $wp_user);
417
+	}
418
+
419
+
420
+	/**
421
+	 * @param array $set_cols_n_values
422
+	 * @return bool|int|string
423
+	 * @throws EE_Error
424
+	 * @throws ReflectionException
425
+	 */
426
+	public function save($set_cols_n_values = [])
427
+	{
428
+		// make sure internal versions for all composite objects are updated
429
+		$this->set('FSC_attributes', $this->attributes()->toArray());
430
+		$this->set('FSC_label', $this->label()->toArray());
431
+		return parent::save($set_cols_n_values);
432
+	}
433
+
434
+	/**
435
+	 * Whether the section is active.
436
+	 *
437
+	 * @return boolean  TRUE if is active, FALSE if not.
438
+	 * @throws ReflectionException
439
+	 * @throws InvalidArgumentException
440
+	 * @throws InvalidInterfaceException
441
+	 * @throws InvalidDataTypeException
442
+	 * @throws EE_Error
443
+	 */
444
+	public function isActive(): bool
445
+	{
446
+		return $this->status() === FormStatus::ACTIVE;
447
+	}
448
+
449
+	/**
450
+	 * Whether the section is archived.
451
+	 *
452
+	 * @return boolean  TRUE if is archived, FALSE if not.
453
+	 * @throws ReflectionException
454
+	 * @throws InvalidArgumentException
455
+	 * @throws InvalidInterfaceException
456
+	 * @throws InvalidDataTypeException
457
+	 * @throws EE_Error
458
+	 */
459
+	public function isArchived(): bool
460
+	{
461
+		return $this->status() === FormStatus::ARCHIVED;
462
+	}
463
+
464
+	/**
465
+	 * Whether the section is a default one.
466
+	 *
467
+	 * @return boolean  TRUE if is default, FALSE if not.
468
+	 * @throws ReflectionException
469
+	 * @throws InvalidArgumentException
470
+	 * @throws InvalidInterfaceException
471
+	 * @throws InvalidDataTypeException
472
+	 * @throws EE_Error
473
+	 */
474
+	public function isDefault(): bool
475
+	{
476
+		return $this->status() === FormStatus::DEFAULT;
477
+	}
478
+
479
+	/**
480
+	 * Whether the section is a shared one.
481
+	 *
482
+	 * @return boolean  TRUE if is shared, FALSE if not.
483
+	 * @throws ReflectionException
484
+	 * @throws InvalidArgumentException
485
+	 * @throws InvalidInterfaceException
486
+	 * @throws InvalidDataTypeException
487
+	 * @throws EE_Error
488
+	 */
489
+	public function isShared(): bool
490
+	{
491
+		return $this->status() === FormStatus::SHARED;
492
+	}
493
+
494
+	/**
495
+	 * Whether the section is trashed.
496
+	 *
497
+	 * @return boolean  TRUE if is trashed, FALSE if not.
498
+	 * @throws ReflectionException
499
+	 * @throws InvalidArgumentException
500
+	 * @throws InvalidInterfaceException
501
+	 * @throws InvalidDataTypeException
502
+	 * @throws EE_Error
503
+	 */
504
+	public function isTrashed(): bool
505
+	{
506
+		return $this->status() === FormStatus::TRASHED;
507
+	}
508
+
509
+
510
+	/**
511
+	 * @return bool
512
+	 * @throws EE_Error
513
+	 * @throws ReflectionException
514
+	 */
515
+	public function isTopLevelFormSection(): bool
516
+	{
517
+		return empty($this->belongsTo());
518
+	}
519 519
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
      */
102 102
     public function setUUID(string $UUID)
103 103
     {
104
-        if (! Cuid::isCuid($UUID)) {
104
+        if ( ! Cuid::isCuid($UUID)) {
105 105
             throw new InvalidArgumentException(
106 106
                 sprintf(
107 107
                     /* translators: 1: UUID value, 2: UUID generator function. */
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
      */
178 178
     public function attributes(): ?Attributes
179 179
     {
180
-        if (! $this->attributes instanceof Attributes) {
180
+        if ( ! $this->attributes instanceof Attributes) {
181 181
             $this->attributes = Attributes::fromJson($this->get('FSC_attributes'));
182 182
         }
183 183
         return $this->attributes;
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
         $form_elements = $this->get_many_related('Form_Element', ['order_by' => ['FIN_order' => 'ASC']]);
244 244
         foreach ($form_elements as $form_element) {
245 245
             if ($form_element instanceof EE_Form_Element) {
246
-                $this->form_elements[ $form_element->UUID() ] = $form_element;
246
+                $this->form_elements[$form_element->UUID()] = $form_element;
247 247
             }
248 248
         }
249 249
         return $this->form_elements;
@@ -260,7 +260,7 @@  discard block
 block discarded – undo
260 260
         foreach ($form_elements as $form_element) {
261 261
             if ($form_element instanceof EE_Form_Element) {
262 262
                 $this->_add_relation_to($form_element->UUID(), 'Form_Element');
263
-                $this->form_elements[ $form_element->UUID() ] = $form_element;
263
+                $this->form_elements[$form_element->UUID()] = $form_element;
264 264
             }
265 265
         }
266 266
     }
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
     public function formElementFilter(): Closure
292 292
     {
293 293
         $FSC_UUID = strtolower($this->UUID());
294
-        return function ($form_element) use ($FSC_UUID) {
294
+        return function($form_element) use ($FSC_UUID) {
295 295
             return $form_element instanceof EE_Form_Element && strtolower($form_element->belongsTo()) === $FSC_UUID;
296 296
         };
297 297
     }
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
      */
307 307
     public function label(): ?FormLabel
308 308
     {
309
-        if (! $this->label instanceof FormLabel) {
309
+        if ( ! $this->label instanceof FormLabel) {
310 310
             $this->label = FormLabel::fromJson($this->get('FSC_label'));
311 311
         }
312 312
         return $this->label;
Please login to merge, or discard this patch.
core/domain/services/admin/events/editor/NewEventDefaultEntities.php 2 patches
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -30,122 +30,122 @@
 block discarded – undo
30 30
 class NewEventDefaultEntities extends EventEditorData
31 31
 {
32 32
 
33
-    /**
34
-     * @var DefaultDatetimes
35
-     */
36
-    protected $default_datetimes;
33
+	/**
34
+	 * @var DefaultDatetimes
35
+	 */
36
+	protected $default_datetimes;
37 37
 
38
-    /**
39
-     * @var   DefaultFormSections
40
-     */
41
-    protected $default_form_sections;
38
+	/**
39
+	 * @var   DefaultFormSections
40
+	 */
41
+	protected $default_form_sections;
42 42
 
43 43
 
44
-    /**
45
-     * NewEventDefaultEntities constructor.
46
-     *
47
-     * @param DefaultDatetimes $default_datetimes
48
-     * @param DefaultFormSections $default_form_sections
49
-     * @param EEM_Datetime     $datetime_model
50
-     * @param EEM_Event        $event_model
51
-     * @param EEM_Price        $price_model
52
-     * @param EEM_Price_Type   $price_type_model
53
-     * @param EEM_Ticket       $ticket_model
54
-     * @param Utilities        $utilities
55
-     */
56
-    public function __construct(
57
-        DefaultDatetimes $default_datetimes,
58
-        DefaultFormSections $default_form_sections,
59
-        EEM_Datetime $datetime_model,
60
-        EEM_Event $event_model,
61
-        EEM_Price $price_model,
62
-        EEM_Price_Type $price_type_model,
63
-        EEM_Ticket $ticket_model,
64
-        Utilities $utilities
65
-    ) {
66
-        $this->default_datetimes = $default_datetimes;
67
-        $this->default_form_sections = $default_form_sections;
68
-        parent::__construct(
69
-            $datetime_model,
70
-            $event_model,
71
-            $price_model,
72
-            $price_type_model,
73
-            $ticket_model,
74
-            $utilities
75
-        );
76
-    }
44
+	/**
45
+	 * NewEventDefaultEntities constructor.
46
+	 *
47
+	 * @param DefaultDatetimes $default_datetimes
48
+	 * @param DefaultFormSections $default_form_sections
49
+	 * @param EEM_Datetime     $datetime_model
50
+	 * @param EEM_Event        $event_model
51
+	 * @param EEM_Price        $price_model
52
+	 * @param EEM_Price_Type   $price_type_model
53
+	 * @param EEM_Ticket       $ticket_model
54
+	 * @param Utilities        $utilities
55
+	 */
56
+	public function __construct(
57
+		DefaultDatetimes $default_datetimes,
58
+		DefaultFormSections $default_form_sections,
59
+		EEM_Datetime $datetime_model,
60
+		EEM_Event $event_model,
61
+		EEM_Price $price_model,
62
+		EEM_Price_Type $price_type_model,
63
+		EEM_Ticket $ticket_model,
64
+		Utilities $utilities
65
+	) {
66
+		$this->default_datetimes = $default_datetimes;
67
+		$this->default_form_sections = $default_form_sections;
68
+		parent::__construct(
69
+			$datetime_model,
70
+			$event_model,
71
+			$price_model,
72
+			$price_type_model,
73
+			$ticket_model,
74
+			$utilities
75
+		);
76
+	}
77 77
 
78 78
 
79
-    /**
80
-     * @param int $eventId
81
-     * @return EE_Datetime[]
82
-     * @throws EE_Error
83
-     * @throws InvalidArgumentException
84
-     * @throws InvalidEntityException
85
-     * @throws ReflectionException
86
-     * @since $VID:$
87
-     */
88
-    public function getData(int $eventId): array
89
-    {
90
-        $EVT_ID = absint($eventId);
91
-        if ($EVT_ID < 1) {
92
-            throw new InvalidArgumentException(
93
-                esc_html__(
94
-                    'A missing or invalid event ID was received.',
95
-                    'event_espresso'
96
-                )
97
-            );
98
-        }
99
-        $event = $this->event_model->get_one_by_ID($EVT_ID);
100
-        if (! $event instanceof EE_Event) {
101
-            throw new InvalidEntityException($event, 'EE_Event');
102
-        }
103
-        $new_event = isset($_REQUEST['action']) && $_REQUEST['action'] === 'create_new';
104
-        return [
105
-            'datetimes'     => $this->createDefaultDatetimes($event, $new_event),
106
-            'form_sections' => $this->createDefaultFormSections($event, $new_event)
107
-        ];
108
-    }
79
+	/**
80
+	 * @param int $eventId
81
+	 * @return EE_Datetime[]
82
+	 * @throws EE_Error
83
+	 * @throws InvalidArgumentException
84
+	 * @throws InvalidEntityException
85
+	 * @throws ReflectionException
86
+	 * @since $VID:$
87
+	 */
88
+	public function getData(int $eventId): array
89
+	{
90
+		$EVT_ID = absint($eventId);
91
+		if ($EVT_ID < 1) {
92
+			throw new InvalidArgumentException(
93
+				esc_html__(
94
+					'A missing or invalid event ID was received.',
95
+					'event_espresso'
96
+				)
97
+			);
98
+		}
99
+		$event = $this->event_model->get_one_by_ID($EVT_ID);
100
+		if (! $event instanceof EE_Event) {
101
+			throw new InvalidEntityException($event, 'EE_Event');
102
+		}
103
+		$new_event = isset($_REQUEST['action']) && $_REQUEST['action'] === 'create_new';
104
+		return [
105
+			'datetimes'     => $this->createDefaultDatetimes($event, $new_event),
106
+			'form_sections' => $this->createDefaultFormSections($event, $new_event)
107
+		];
108
+	}
109 109
 
110 110
 
111
-    /**
112
-     * @param EE_Event $event
113
-     * @param bool     $new_event
114
-     * @return EE_Datetime[]
115
-     * @throws EE_Error
116
-     * @throws ReflectionException
117
-     */
118
-    private function createDefaultDatetimes(EE_Event $event, bool $new_event): array
119
-    {
120
-        $datetime_count = $this->datetime_model->count(
121
-            [
122
-                [
123
-                    'EVT_ID'      => $event->ID(),
124
-                    'DTT_deleted' => ['IN', [true, false]],
125
-                ],
126
-                'default_where_conditions' => EEM_Base::default_where_conditions_none,
127
-            ],
128
-            'EVT_ID'
129
-        );
130
-        return $new_event || $datetime_count === 0
131
-            ? $this->default_datetimes->create($event)
132
-            : [];
133
-    }
111
+	/**
112
+	 * @param EE_Event $event
113
+	 * @param bool     $new_event
114
+	 * @return EE_Datetime[]
115
+	 * @throws EE_Error
116
+	 * @throws ReflectionException
117
+	 */
118
+	private function createDefaultDatetimes(EE_Event $event, bool $new_event): array
119
+	{
120
+		$datetime_count = $this->datetime_model->count(
121
+			[
122
+				[
123
+					'EVT_ID'      => $event->ID(),
124
+					'DTT_deleted' => ['IN', [true, false]],
125
+				],
126
+				'default_where_conditions' => EEM_Base::default_where_conditions_none,
127
+			],
128
+			'EVT_ID'
129
+		);
130
+		return $new_event || $datetime_count === 0
131
+			? $this->default_datetimes->create($event)
132
+			: [];
133
+	}
134 134
 
135 135
 
136
-    /**
137
-     * @param EE_Event $event
138
-     * @param bool     $new_event
139
-     * @return EE_Form_Section[]
140
-     * @throws EE_Error
141
-     * @throws ReflectionException
142
-     */
143
-    private function createDefaultFormSections(EE_Event $event, bool $new_event): array
144
-    {
145
-        $reg_form_UUID = $event->registrationFormUuid();
146
-        // if it's a new event and defaults have not been created yet, OR if there is no reg form at all...
147
-        return ($new_event && ! $reg_form_UUID) ||  ! $reg_form_UUID
148
-            ? $this->default_form_sections->create($event)
149
-            : [];
150
-    }
136
+	/**
137
+	 * @param EE_Event $event
138
+	 * @param bool     $new_event
139
+	 * @return EE_Form_Section[]
140
+	 * @throws EE_Error
141
+	 * @throws ReflectionException
142
+	 */
143
+	private function createDefaultFormSections(EE_Event $event, bool $new_event): array
144
+	{
145
+		$reg_form_UUID = $event->registrationFormUuid();
146
+		// if it's a new event and defaults have not been created yet, OR if there is no reg form at all...
147
+		return ($new_event && ! $reg_form_UUID) ||  ! $reg_form_UUID
148
+			? $this->default_form_sections->create($event)
149
+			: [];
150
+	}
151 151
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -97,7 +97,7 @@  discard block
 block discarded – undo
97 97
             );
98 98
         }
99 99
         $event = $this->event_model->get_one_by_ID($EVT_ID);
100
-        if (! $event instanceof EE_Event) {
100
+        if ( ! $event instanceof EE_Event) {
101 101
             throw new InvalidEntityException($event, 'EE_Event');
102 102
         }
103 103
         $new_event = isset($_REQUEST['action']) && $_REQUEST['action'] === 'create_new';
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
     {
145 145
         $reg_form_UUID = $event->registrationFormUuid();
146 146
         // if it's a new event and defaults have not been created yet, OR if there is no reg form at all...
147
-        return ($new_event && ! $reg_form_UUID) ||  ! $reg_form_UUID
147
+        return ($new_event && ! $reg_form_UUID) || ! $reg_form_UUID
148 148
             ? $this->default_form_sections->create($event)
149 149
             : [];
150 150
     }
Please login to merge, or discard this patch.
core/domain/services/admin/entities/DefaultDatetimes.php 2 patches
Indentation   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -21,56 +21,56 @@
 block discarded – undo
21 21
 class DefaultDatetimes implements DefaultEntityGeneratorInterface
22 22
 {
23 23
 
24
-    /**
25
-     * @var DefaultTickets $default_tickets
26
-     */
27
-    protected $default_tickets;
24
+	/**
25
+	 * @var DefaultTickets $default_tickets
26
+	 */
27
+	protected $default_tickets;
28 28
 
29
-    /**
30
-     * @var EEM_Datetime $datetime_model
31
-     */
32
-    protected $datetime_model;
29
+	/**
30
+	 * @var EEM_Datetime $datetime_model
31
+	 */
32
+	protected $datetime_model;
33 33
 
34
-    /**
35
-     * @param DefaultTickets $default_tickets
36
-     * @param EEM_Datetime $datetime_model
37
-     */
38
-    public function __construct(DefaultTickets $default_tickets, EEM_Datetime $datetime_model)
39
-    {
40
-        $this->default_tickets = $default_tickets;
41
-        $this->datetime_model = $datetime_model;
42
-    }
34
+	/**
35
+	 * @param DefaultTickets $default_tickets
36
+	 * @param EEM_Datetime $datetime_model
37
+	 */
38
+	public function __construct(DefaultTickets $default_tickets, EEM_Datetime $datetime_model)
39
+	{
40
+		$this->default_tickets = $default_tickets;
41
+		$this->datetime_model = $datetime_model;
42
+	}
43 43
 
44 44
 
45
-    /**
46
-     * @param EE_Event|EE_Base_Class $entity
47
-     * @return EE_Datetime[]
48
-     * @throws EE_Error
49
-     * @throws InvalidEntityException
50
-     * @throws ReflectionException
51
-     * @since $VID:$
52
-     */
53
-    public function create(EE_Base_Class $entity): array
54
-    {
55
-        if (! $entity instanceof EE_Event) {
56
-            throw new InvalidEntityException($entity, 'EE_Event');
57
-        }
58
-        $default_dates = [];
59
-        $blank_dates = $this->datetime_model->create_new_blank_datetime();
60
-        if (is_array($blank_dates)) {
61
-            foreach ($blank_dates as $blank_date) {
62
-                if (! $blank_date instanceof EE_Datetime) {
63
-                    throw new InvalidEntityException($blank_date, 'EE_Datetime');
64
-                }
65
-                // clone date, strip out ID, then save to get a new ID
66
-                $default_date = clone $blank_date;
67
-                $default_date->set('DTT_ID', null);
68
-                $default_date->save();
69
-                $default_date->_add_relation_to($entity->ID(), 'Event');
70
-                $this->default_tickets->create($default_date);
71
-                $default_dates[ $default_date->ID() ] = $default_date;
72
-            }
73
-        }
74
-        return $default_dates;
75
-    }
45
+	/**
46
+	 * @param EE_Event|EE_Base_Class $entity
47
+	 * @return EE_Datetime[]
48
+	 * @throws EE_Error
49
+	 * @throws InvalidEntityException
50
+	 * @throws ReflectionException
51
+	 * @since $VID:$
52
+	 */
53
+	public function create(EE_Base_Class $entity): array
54
+	{
55
+		if (! $entity instanceof EE_Event) {
56
+			throw new InvalidEntityException($entity, 'EE_Event');
57
+		}
58
+		$default_dates = [];
59
+		$blank_dates = $this->datetime_model->create_new_blank_datetime();
60
+		if (is_array($blank_dates)) {
61
+			foreach ($blank_dates as $blank_date) {
62
+				if (! $blank_date instanceof EE_Datetime) {
63
+					throw new InvalidEntityException($blank_date, 'EE_Datetime');
64
+				}
65
+				// clone date, strip out ID, then save to get a new ID
66
+				$default_date = clone $blank_date;
67
+				$default_date->set('DTT_ID', null);
68
+				$default_date->save();
69
+				$default_date->_add_relation_to($entity->ID(), 'Event');
70
+				$this->default_tickets->create($default_date);
71
+				$default_dates[ $default_date->ID() ] = $default_date;
72
+			}
73
+		}
74
+		return $default_dates;
75
+	}
76 76
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -52,14 +52,14 @@  discard block
 block discarded – undo
52 52
      */
53 53
     public function create(EE_Base_Class $entity): array
54 54
     {
55
-        if (! $entity instanceof EE_Event) {
55
+        if ( ! $entity instanceof EE_Event) {
56 56
             throw new InvalidEntityException($entity, 'EE_Event');
57 57
         }
58 58
         $default_dates = [];
59 59
         $blank_dates = $this->datetime_model->create_new_blank_datetime();
60 60
         if (is_array($blank_dates)) {
61 61
             foreach ($blank_dates as $blank_date) {
62
-                if (! $blank_date instanceof EE_Datetime) {
62
+                if ( ! $blank_date instanceof EE_Datetime) {
63 63
                     throw new InvalidEntityException($blank_date, 'EE_Datetime');
64 64
                 }
65 65
                 // clone date, strip out ID, then save to get a new ID
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
                 $default_date->save();
69 69
                 $default_date->_add_relation_to($entity->ID(), 'Event');
70 70
                 $this->default_tickets->create($default_date);
71
-                $default_dates[ $default_date->ID() ] = $default_date;
71
+                $default_dates[$default_date->ID()] = $default_date;
72 72
             }
73 73
         }
74 74
         return $default_dates;
Please login to merge, or discard this patch.
core/domain/services/admin/entities/DefaultFormSections.php 2 patches
Indentation   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -25,97 +25,97 @@
 block discarded – undo
25 25
 class DefaultFormSections implements DefaultEntityGeneratorInterface
26 26
 {
27 27
 
28
-    /**
29
-     * @var EEM_Form_Element $form_element_model
30
-     */
31
-    protected $form_element_model;
28
+	/**
29
+	 * @var EEM_Form_Element $form_element_model
30
+	 */
31
+	protected $form_element_model;
32 32
 
33
-    /**
34
-     * @var EEM_Form_Section $form_section_model
35
-     */
36
-    protected $form_section_model;
33
+	/**
34
+	 * @var EEM_Form_Section $form_section_model
35
+	 */
36
+	protected $form_section_model;
37 37
 
38
-    /**
39
-     * @param EEM_Form_Element $form_element_model
40
-     * @param EEM_Form_Section $form_section_model
41
-     */
42
-    public function __construct(EEM_Form_Element $form_element_model, EEM_Form_Section $form_section_model)
43
-    {
44
-        $this->form_element_model = $form_element_model;
45
-        $this->form_section_model = $form_section_model;
46
-    }
38
+	/**
39
+	 * @param EEM_Form_Element $form_element_model
40
+	 * @param EEM_Form_Section $form_section_model
41
+	 */
42
+	public function __construct(EEM_Form_Element $form_element_model, EEM_Form_Section $form_section_model)
43
+	{
44
+		$this->form_element_model = $form_element_model;
45
+		$this->form_section_model = $form_section_model;
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * @param EE_Event|EE_Base_Class $entity
51
-     * @return EE_Form_Section[]
52
-     * @throws EE_Error
53
-     * @throws InvalidEntityException
54
-     * @throws ReflectionException
55
-     */
56
-    public function create(EE_Base_Class $entity): array
57
-    {
58
-        if (! $entity instanceof EE_Event) {
59
-            throw new InvalidEntityException($entity, 'EE_Event');
60
-        }
61
-        /** @var EE_Form_Section[] $new_form_sections */
62
-        $new_form_sections     = [];
63
-        $default_form_sections = $this->form_section_model->getDefaultFormSections();
64
-        if (is_array($default_form_sections)) {
65
-            foreach ($default_form_sections as $default_form_section) {
66
-                if (! $default_form_section instanceof EE_Form_Section) {
67
-                    throw new InvalidEntityException($default_form_section, 'EE_Form_Section');
68
-                }
69
-                // we're calling this inside the loop, because this might get set the first time around
70
-                // and it would always be blank for a new event if we were to call it before the loop,
71
-                // and then we couldn't set the "BelongsTo" for any child form sections
72
-                $top_level_form_section = $entity->registrationFormUuid();
73
-                $default_form_elements = $default_form_section->formElements();
74
-                // clone form_section, generate a new UUID, reset the status, then save it
75
-                $new_form_section = clone $default_form_section;
76
-                $UUID = Cuid::cuid();
77
-                $new_form_section->setUUID($UUID);
78
-                $new_form_section->setStatus(FormStatus::ACTIVE);
79
-                if ($top_level_form_section) {
80
-                    $new_form_section->setBelongsTo($top_level_form_section);
81
-                }
82
-                $new_form_section->save();
83
-                $new_form_sections[ $UUID ] = $new_form_section;
84
-                // now retrieve, clone, and save all of the form elements
85
-                $this->createDefaultFormElements($new_form_section, $default_form_elements);
86
-                // save form section UUID on event if it is the top-level form section
87
-                if ($new_form_section->isTopLevelFormSection()) {
88
-                    $entity->setRegistrationFormUuid($UUID);
89
-                    $entity->save();
90
-                }
91
-            }
92
-        }
93
-        return $new_form_sections;
94
-    }
49
+	/**
50
+	 * @param EE_Event|EE_Base_Class $entity
51
+	 * @return EE_Form_Section[]
52
+	 * @throws EE_Error
53
+	 * @throws InvalidEntityException
54
+	 * @throws ReflectionException
55
+	 */
56
+	public function create(EE_Base_Class $entity): array
57
+	{
58
+		if (! $entity instanceof EE_Event) {
59
+			throw new InvalidEntityException($entity, 'EE_Event');
60
+		}
61
+		/** @var EE_Form_Section[] $new_form_sections */
62
+		$new_form_sections     = [];
63
+		$default_form_sections = $this->form_section_model->getDefaultFormSections();
64
+		if (is_array($default_form_sections)) {
65
+			foreach ($default_form_sections as $default_form_section) {
66
+				if (! $default_form_section instanceof EE_Form_Section) {
67
+					throw new InvalidEntityException($default_form_section, 'EE_Form_Section');
68
+				}
69
+				// we're calling this inside the loop, because this might get set the first time around
70
+				// and it would always be blank for a new event if we were to call it before the loop,
71
+				// and then we couldn't set the "BelongsTo" for any child form sections
72
+				$top_level_form_section = $entity->registrationFormUuid();
73
+				$default_form_elements = $default_form_section->formElements();
74
+				// clone form_section, generate a new UUID, reset the status, then save it
75
+				$new_form_section = clone $default_form_section;
76
+				$UUID = Cuid::cuid();
77
+				$new_form_section->setUUID($UUID);
78
+				$new_form_section->setStatus(FormStatus::ACTIVE);
79
+				if ($top_level_form_section) {
80
+					$new_form_section->setBelongsTo($top_level_form_section);
81
+				}
82
+				$new_form_section->save();
83
+				$new_form_sections[ $UUID ] = $new_form_section;
84
+				// now retrieve, clone, and save all of the form elements
85
+				$this->createDefaultFormElements($new_form_section, $default_form_elements);
86
+				// save form section UUID on event if it is the top-level form section
87
+				if ($new_form_section->isTopLevelFormSection()) {
88
+					$entity->setRegistrationFormUuid($UUID);
89
+					$entity->save();
90
+				}
91
+			}
92
+		}
93
+		return $new_form_sections;
94
+	}
95 95
 
96 96
 
97
-    /**
98
-     * @throws EE_Error
99
-     * @throws ReflectionException
100
-     */
101
-    private function createDefaultFormElements(EE_Form_Section $new_form_section, array $default_form_elements)
102
-    {
103
-        /** @var EE_Form_Element[] $new_form_sections */
104
-        $new_form_elements = [];
105
-        foreach ($default_form_elements as $default_form_element) {
106
-            if (! $default_form_element instanceof EE_Form_Element) {
107
-                throw new InvalidEntityException($default_form_element, 'EE_Form_Element');
108
-            }
109
-            // clone form_element, generate a new UUID, reset the status, then save it
110
-            $new_form_element = clone $default_form_element;
111
-            // generate a new UUID for this form section then save it
112
-            $UUID = Cuid::cuid();
113
-            $new_form_element->setUUID($UUID);
114
-            $new_form_element->setBelongsTo($new_form_section->UUID());
115
-            $new_form_element->setStatus(FormStatus::ACTIVE);
116
-            $new_form_element->save();
117
-            $new_form_elements[ $UUID ] = $new_form_element;
118
-        }
119
-        $new_form_section->setFormElements($new_form_elements);
120
-    }
97
+	/**
98
+	 * @throws EE_Error
99
+	 * @throws ReflectionException
100
+	 */
101
+	private function createDefaultFormElements(EE_Form_Section $new_form_section, array $default_form_elements)
102
+	{
103
+		/** @var EE_Form_Element[] $new_form_sections */
104
+		$new_form_elements = [];
105
+		foreach ($default_form_elements as $default_form_element) {
106
+			if (! $default_form_element instanceof EE_Form_Element) {
107
+				throw new InvalidEntityException($default_form_element, 'EE_Form_Element');
108
+			}
109
+			// clone form_element, generate a new UUID, reset the status, then save it
110
+			$new_form_element = clone $default_form_element;
111
+			// generate a new UUID for this form section then save it
112
+			$UUID = Cuid::cuid();
113
+			$new_form_element->setUUID($UUID);
114
+			$new_form_element->setBelongsTo($new_form_section->UUID());
115
+			$new_form_element->setStatus(FormStatus::ACTIVE);
116
+			$new_form_element->save();
117
+			$new_form_elements[ $UUID ] = $new_form_element;
118
+		}
119
+		$new_form_section->setFormElements($new_form_elements);
120
+	}
121 121
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
      */
56 56
     public function create(EE_Base_Class $entity): array
57 57
     {
58
-        if (! $entity instanceof EE_Event) {
58
+        if ( ! $entity instanceof EE_Event) {
59 59
             throw new InvalidEntityException($entity, 'EE_Event');
60 60
         }
61 61
         /** @var EE_Form_Section[] $new_form_sections */
@@ -63,7 +63,7 @@  discard block
 block discarded – undo
63 63
         $default_form_sections = $this->form_section_model->getDefaultFormSections();
64 64
         if (is_array($default_form_sections)) {
65 65
             foreach ($default_form_sections as $default_form_section) {
66
-                if (! $default_form_section instanceof EE_Form_Section) {
66
+                if ( ! $default_form_section instanceof EE_Form_Section) {
67 67
                     throw new InvalidEntityException($default_form_section, 'EE_Form_Section');
68 68
                 }
69 69
                 // we're calling this inside the loop, because this might get set the first time around
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
                     $new_form_section->setBelongsTo($top_level_form_section);
81 81
                 }
82 82
                 $new_form_section->save();
83
-                $new_form_sections[ $UUID ] = $new_form_section;
83
+                $new_form_sections[$UUID] = $new_form_section;
84 84
                 // now retrieve, clone, and save all of the form elements
85 85
                 $this->createDefaultFormElements($new_form_section, $default_form_elements);
86 86
                 // save form section UUID on event if it is the top-level form section
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
         /** @var EE_Form_Element[] $new_form_sections */
104 104
         $new_form_elements = [];
105 105
         foreach ($default_form_elements as $default_form_element) {
106
-            if (! $default_form_element instanceof EE_Form_Element) {
106
+            if ( ! $default_form_element instanceof EE_Form_Element) {
107 107
                 throw new InvalidEntityException($default_form_element, 'EE_Form_Element');
108 108
             }
109 109
             // clone form_element, generate a new UUID, reset the status, then save it
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
             $new_form_element->setBelongsTo($new_form_section->UUID());
115 115
             $new_form_element->setStatus(FormStatus::ACTIVE);
116 116
             $new_form_element->save();
117
-            $new_form_elements[ $UUID ] = $new_form_element;
117
+            $new_form_elements[$UUID] = $new_form_element;
118 118
         }
119 119
         $new_form_section->setFormElements($new_form_elements);
120 120
     }
Please login to merge, or discard this patch.