Completed
Branch master (59af22)
by
unknown
07:35 queued 03:06
created
core/services/collections/Collection.php 1 patch
Indentation   +510 added lines, -510 removed lines patch added patch discarded remove patch
@@ -18,514 +18,514 @@
 block discarded – undo
18 18
  */
19 19
 class Collection extends SplObjectStorage implements CollectionInterface
20 20
 {
21
-    /**
22
-     * a unique string for identifying this collection
23
-     *
24
-     * @type string $collection_identifier
25
-     */
26
-    protected $collection_identifier;
27
-
28
-
29
-    /**
30
-     * an interface (or class) name to be used for restricting the type of objects added to the storage
31
-     * this should be set from within the child class constructor
32
-     *
33
-     * @type string $interface
34
-     */
35
-    protected $collection_interface;
36
-
37
-    /**
38
-     * a short dash separated string describing the contents of this collection
39
-     * used as the base for the $collection_identifier
40
-     * defaults to the class short name if not set
41
-     *
42
-     * @type string $collection_identifier
43
-     */
44
-    protected $collection_name;
45
-
46
-
47
-    /**
48
-     * Collection constructor
49
-     *
50
-     * @param string $collection_interface
51
-     * @param string $collection_name
52
-     * @throws InvalidInterfaceException
53
-     */
54
-    public function __construct($collection_interface, $collection_name = '')
55
-    {
56
-        $this->setCollectionInterface($collection_interface);
57
-        $this->setCollectionName($collection_name);
58
-        $this->setCollectionIdentifier();
59
-    }
60
-
61
-
62
-    /**
63
-     * @return string
64
-     * @since 4.10.33.p
65
-     */
66
-    public function collectionInterface(): string
67
-    {
68
-        return $this->collection_interface;
69
-    }
70
-
71
-
72
-    /**
73
-     * setCollectionInterface
74
-     *
75
-     * @param  string $collection_interface
76
-     * @throws InvalidInterfaceException
77
-     */
78
-    protected function setCollectionInterface($collection_interface)
79
-    {
80
-        if (! (interface_exists($collection_interface) || class_exists($collection_interface))) {
81
-            throw new InvalidInterfaceException($collection_interface);
82
-        }
83
-        $this->collection_interface = $collection_interface;
84
-    }
85
-
86
-
87
-    /**
88
-     * @return string
89
-     */
90
-    public function collectionName()
91
-    {
92
-        return $this->collection_name;
93
-    }
94
-
95
-
96
-    /**
97
-     * @param string $collection_name
98
-     */
99
-    protected function setCollectionName($collection_name)
100
-    {
101
-        $this->collection_name = ! empty($collection_name)
102
-            ? sanitize_key($collection_name)
103
-            : basename(str_replace('\\', '/', get_class($this)));
104
-    }
105
-
106
-
107
-    /**
108
-     * @return string
109
-     */
110
-    public function collectionIdentifier()
111
-    {
112
-        return $this->collection_identifier;
113
-    }
114
-
115
-
116
-    /**
117
-     * creates a very readable unique 9 character identifier like:  CF2-532-DAC
118
-     * and appends it to the non-qualified class name, ex: ThingCollection-CF2-532-DAC
119
-     *
120
-     * @return void
121
-     */
122
-    protected function setCollectionIdentifier()
123
-    {
124
-        // hash a few collection details
125
-        $identifier = md5(spl_object_hash($this) . $this->collection_interface . time());
126
-        // grab a few characters from the start, middle, and end of the hash
127
-        $id = array();
128
-        for ($x = 0; $x < 19; $x += 9) {
129
-            $id[] = substr($identifier, $x, 3);
130
-        }
131
-        $this->collection_identifier = $this->collection_name . '-' . strtoupper(implode('-', $id));
132
-    }
133
-
134
-
135
-    /**
136
-     * add
137
-     * attaches an object to the Collection
138
-     * and sets any supplied data associated with the current iterator entry
139
-     * by calling EE_Object_Collection::set_identifier()
140
-     *
141
-     * @param        $object
142
-     * @param  mixed $identifier
143
-     * @return bool
144
-     * @throws InvalidEntityException
145
-     * @throws DuplicateCollectionIdentifierException
146
-     */
147
-    public function add($object, $identifier = null)
148
-    {
149
-        if (! $object instanceof $this->collection_interface) {
150
-            throw new InvalidEntityException($object, $this->collection_interface);
151
-        }
152
-        if ($this->contains($object)) {
153
-            throw new DuplicateCollectionIdentifierException($identifier);
154
-        }
155
-        $this->attach($object);
156
-        $this->setIdentifier($object, $identifier);
157
-        return $this->contains($object);
158
-    }
159
-
160
-
161
-    /**
162
-     * getIdentifier
163
-     * if no $identifier is supplied, then the spl_object_hash() is used
164
-     *
165
-     * @param        $object
166
-     * @param  mixed $identifier
167
-     * @return string
168
-     */
169
-    public function getIdentifier($object, $identifier = null)
170
-    {
171
-        return ! empty($identifier)
172
-            ? $identifier
173
-            : spl_object_hash($object);
174
-    }
175
-
176
-
177
-    /**
178
-     * setIdentifier
179
-     * Sets the data associated with an object in the Collection
180
-     * if no $identifier is supplied, then the spl_object_hash() is used
181
-     *
182
-     * @param        $object
183
-     * @param  mixed $identifier
184
-     * @return bool
185
-     */
186
-    public function setIdentifier($object, $identifier = null)
187
-    {
188
-        $identifier = $this->getIdentifier($object, $identifier);
189
-        $this->rewind();
190
-        while ($this->valid()) {
191
-            if ($object === $this->current()) {
192
-                $this->setInfo($identifier);
193
-                $this->rewind();
194
-                return true;
195
-            }
196
-            $this->next();
197
-        }
198
-        return false;
199
-    }
200
-
201
-
202
-    /**
203
-     * get
204
-     * finds and returns an object in the Collection based on the identifier that was set using addObject()
205
-     * PLZ NOTE: the pointer is reset to the beginning of the collection before returning
206
-     *
207
-     * @param mixed $identifier
208
-     * @return mixed
209
-     */
210
-    public function get($identifier)
211
-    {
212
-        $this->rewind();
213
-        while ($this->valid()) {
214
-            if ($identifier === $this->getInfo()) {
215
-                $object = $this->current();
216
-                $this->rewind();
217
-                return $object;
218
-            }
219
-            $this->next();
220
-        }
221
-        return null;
222
-    }
223
-
224
-
225
-    /**
226
-     * has
227
-     * returns TRUE or FALSE
228
-     * depending on whether the object is within the Collection
229
-     * based on the supplied $identifier
230
-     *
231
-     * @param  mixed $identifier
232
-     * @return bool
233
-     */
234
-    public function has($identifier)
235
-    {
236
-        $this->rewind();
237
-        while ($this->valid()) {
238
-            if ($identifier === $this->getInfo()) {
239
-                $this->rewind();
240
-                return true;
241
-            }
242
-            $this->next();
243
-        }
244
-        return false;
245
-    }
246
-
247
-
248
-    /**
249
-     * hasObject
250
-     * returns TRUE or FALSE depending on whether the supplied object is within the Collection
251
-     *
252
-     * @param $object
253
-     * @return bool
254
-     */
255
-    public function hasObject($object)
256
-    {
257
-        return $this->contains($object);
258
-    }
259
-
260
-
261
-    /**
262
-     * hasObjects
263
-     * returns true if there are objects within the Collection, and false if it is empty
264
-     *
265
-     * @return bool
266
-     */
267
-    public function hasObjects()
268
-    {
269
-        return $this->count() !== 0;
270
-    }
271
-
272
-
273
-    /**
274
-     * isEmpty
275
-     * returns true if there are no objects within the Collection, and false if there are
276
-     *
277
-     * @return bool
278
-     */
279
-    public function isEmpty()
280
-    {
281
-        return $this->count() === 0;
282
-    }
283
-
284
-
285
-    /**
286
-     * remove
287
-     * detaches an object from the Collection
288
-     *
289
-     * @param $object
290
-     * @return bool
291
-     */
292
-    public function remove($object)
293
-    {
294
-        $this->detach($object);
295
-        return true;
296
-    }
297
-
298
-
299
-    /**
300
-     * setCurrent
301
-     * advances pointer to the object whose identifier matches that which was provided
302
-     *
303
-     * @param mixed $identifier
304
-     * @return boolean
305
-     */
306
-    public function setCurrent($identifier)
307
-    {
308
-        $this->rewind();
309
-        while ($this->valid()) {
310
-            if ($identifier === $this->getInfo()) {
311
-                return true;
312
-            }
313
-            $this->next();
314
-        }
315
-        return false;
316
-    }
317
-
318
-
319
-    /**
320
-     * setCurrentUsingObject
321
-     * advances pointer to the provided object
322
-     *
323
-     * @param $object
324
-     * @return boolean
325
-     */
326
-    public function setCurrentUsingObject($object)
327
-    {
328
-        $this->rewind();
329
-        while ($this->valid()) {
330
-            if ($this->current() === $object) {
331
-                return true;
332
-            }
333
-            $this->next();
334
-        }
335
-        return false;
336
-    }
337
-
338
-
339
-    /**
340
-     * Returns the object occupying the index before the current object,
341
-     * unless this is already the first object, in which case it just returns the first object
342
-     *
343
-     * @return mixed
344
-     */
345
-    public function previous()
346
-    {
347
-        $index = $this->indexOf($this->current());
348
-        if ($index === 0) {
349
-            return $this->current();
350
-        }
351
-        $index--;
352
-        return $this->objectAtIndex($index);
353
-    }
354
-
355
-
356
-    /**
357
-     * Returns the index of a given object, or false if not found
358
-     *
359
-     * @see https://stackoverflow.com/a/8736013
360
-     * @param $object
361
-     * @return boolean|int|string
362
-     */
363
-    public function indexOf($object)
364
-    {
365
-        if (! $this->contains($object)) {
366
-            return false;
367
-        }
368
-        foreach ($this as $index => $obj) {
369
-            if ($obj === $object) {
370
-                return $index;
371
-            }
372
-        }
373
-        return false;
374
-    }
375
-
376
-
377
-    /**
378
-     * Returns the object at the given index
379
-     *
380
-     * @see https://stackoverflow.com/a/8736013
381
-     * @param int $index
382
-     * @return mixed
383
-     */
384
-    public function objectAtIndex($index)
385
-    {
386
-        $iterator = new LimitIterator($this, $index, 1);
387
-        $iterator->rewind();
388
-        return $iterator->current();
389
-    }
390
-
391
-
392
-    /**
393
-     * Returns the sequence of objects as specified by the offset and length
394
-     *
395
-     * @see https://stackoverflow.com/a/8736013
396
-     * @param int $offset
397
-     * @param int $length
398
-     * @return array
399
-     */
400
-    public function slice($offset, $length)
401
-    {
402
-        $slice = array();
403
-        $iterator = new LimitIterator($this, $offset, $length);
404
-        foreach ($iterator as $object) {
405
-            $slice[] = $object;
406
-        }
407
-        return $slice;
408
-    }
409
-
410
-
411
-    /**
412
-     * Inserts an object at a certain point
413
-     *
414
-     * @see https://stackoverflow.com/a/8736013
415
-     * @param mixed $object A single object
416
-     * @param int   $index
417
-     * @param mixed $identifier
418
-     * @return bool
419
-     * @throws DuplicateCollectionIdentifierException
420
-     * @throws InvalidEntityException
421
-     */
422
-    public function insertObjectAt($object, $index, $identifier = null)
423
-    {
424
-        // check to ensure that objects don't already exist in the collection
425
-        if ($this->has($identifier)) {
426
-            throw new DuplicateCollectionIdentifierException($identifier);
427
-        }
428
-        // detach any objects at or past this index
429
-        $remaining_objects = array();
430
-        if ($index < $this->count()) {
431
-            $remaining_objects = $this->slice($index, $this->count() - $index);
432
-            foreach ($remaining_objects as $key => $remaining_object) {
433
-                // we need to grab the identifiers for each object and use them as keys
434
-                $remaining_objects[ $remaining_object->getInfo() ] = $remaining_object;
435
-                // and then remove the object from the current tracking array
436
-                unset($remaining_objects[ $key ]);
437
-                // and then remove it from the Collection
438
-                $this->detach($remaining_object);
439
-            }
440
-        }
441
-        // add the new object we're splicing in
442
-        $this->add($object, $identifier);
443
-        // attach the objects we previously detached
444
-        foreach ($remaining_objects as $key => $remaining_object) {
445
-            $this->add($remaining_object, $key);
446
-        }
447
-        return $this->contains($object);
448
-    }
449
-
450
-
451
-    /**
452
-     * Inserts an object (or an array of objects) at a certain point
453
-     *
454
-     * @see https://stackoverflow.com/a/8736013
455
-     * @param mixed $objects A single object or an array of objects
456
-     * @param int   $index
457
-     */
458
-    public function insertAt($objects, $index)
459
-    {
460
-        if (! is_array($objects)) {
461
-            $objects = array($objects);
462
-        }
463
-        // check to ensure that objects don't already exist in the collection
464
-        foreach ($objects as $key => $object) {
465
-            if ($this->contains($object)) {
466
-                unset($objects[ $key ]);
467
-            }
468
-        }
469
-        // do we have any objects left?
470
-        if (! $objects) {
471
-            return;
472
-        }
473
-        // detach any objects at or past this index
474
-        $remaining = array();
475
-        if ($index < $this->count()) {
476
-            $remaining = $this->slice($index, $this->count() - $index);
477
-            foreach ($remaining as $object) {
478
-                $this->detach($object);
479
-            }
480
-        }
481
-        // add the new objects we're splicing in
482
-        foreach ($objects as $object) {
483
-            $this->attach($object);
484
-        }
485
-        // attach the objects we previously detached
486
-        foreach ($remaining as $object) {
487
-            $this->attach($object);
488
-        }
489
-    }
490
-
491
-
492
-    /**
493
-     * Removes the object at the given index
494
-     *
495
-     * @see https://stackoverflow.com/a/8736013
496
-     * @param int $index
497
-     */
498
-    public function removeAt($index)
499
-    {
500
-        $this->detach($this->objectAtIndex($index));
501
-    }
502
-
503
-
504
-    /**
505
-     * detaches ALL objects from the Collection
506
-     */
507
-    public function detachAll()
508
-    {
509
-        $this->rewind();
510
-        while ($this->valid()) {
511
-            $object = $this->current();
512
-            $this->next();
513
-            $this->detach($object);
514
-        }
515
-    }
516
-
517
-
518
-    /**
519
-     * unsets and detaches ALL objects from the Collection
520
-     */
521
-    public function trashAndDetachAll()
522
-    {
523
-        $this->rewind();
524
-        while ($this->valid()) {
525
-            $object = $this->current();
526
-            $this->next();
527
-            $this->detach($object);
528
-            unset($object);
529
-        }
530
-    }
21
+	/**
22
+	 * a unique string for identifying this collection
23
+	 *
24
+	 * @type string $collection_identifier
25
+	 */
26
+	protected $collection_identifier;
27
+
28
+
29
+	/**
30
+	 * an interface (or class) name to be used for restricting the type of objects added to the storage
31
+	 * this should be set from within the child class constructor
32
+	 *
33
+	 * @type string $interface
34
+	 */
35
+	protected $collection_interface;
36
+
37
+	/**
38
+	 * a short dash separated string describing the contents of this collection
39
+	 * used as the base for the $collection_identifier
40
+	 * defaults to the class short name if not set
41
+	 *
42
+	 * @type string $collection_identifier
43
+	 */
44
+	protected $collection_name;
45
+
46
+
47
+	/**
48
+	 * Collection constructor
49
+	 *
50
+	 * @param string $collection_interface
51
+	 * @param string $collection_name
52
+	 * @throws InvalidInterfaceException
53
+	 */
54
+	public function __construct($collection_interface, $collection_name = '')
55
+	{
56
+		$this->setCollectionInterface($collection_interface);
57
+		$this->setCollectionName($collection_name);
58
+		$this->setCollectionIdentifier();
59
+	}
60
+
61
+
62
+	/**
63
+	 * @return string
64
+	 * @since 4.10.33.p
65
+	 */
66
+	public function collectionInterface(): string
67
+	{
68
+		return $this->collection_interface;
69
+	}
70
+
71
+
72
+	/**
73
+	 * setCollectionInterface
74
+	 *
75
+	 * @param  string $collection_interface
76
+	 * @throws InvalidInterfaceException
77
+	 */
78
+	protected function setCollectionInterface($collection_interface)
79
+	{
80
+		if (! (interface_exists($collection_interface) || class_exists($collection_interface))) {
81
+			throw new InvalidInterfaceException($collection_interface);
82
+		}
83
+		$this->collection_interface = $collection_interface;
84
+	}
85
+
86
+
87
+	/**
88
+	 * @return string
89
+	 */
90
+	public function collectionName()
91
+	{
92
+		return $this->collection_name;
93
+	}
94
+
95
+
96
+	/**
97
+	 * @param string $collection_name
98
+	 */
99
+	protected function setCollectionName($collection_name)
100
+	{
101
+		$this->collection_name = ! empty($collection_name)
102
+			? sanitize_key($collection_name)
103
+			: basename(str_replace('\\', '/', get_class($this)));
104
+	}
105
+
106
+
107
+	/**
108
+	 * @return string
109
+	 */
110
+	public function collectionIdentifier()
111
+	{
112
+		return $this->collection_identifier;
113
+	}
114
+
115
+
116
+	/**
117
+	 * creates a very readable unique 9 character identifier like:  CF2-532-DAC
118
+	 * and appends it to the non-qualified class name, ex: ThingCollection-CF2-532-DAC
119
+	 *
120
+	 * @return void
121
+	 */
122
+	protected function setCollectionIdentifier()
123
+	{
124
+		// hash a few collection details
125
+		$identifier = md5(spl_object_hash($this) . $this->collection_interface . time());
126
+		// grab a few characters from the start, middle, and end of the hash
127
+		$id = array();
128
+		for ($x = 0; $x < 19; $x += 9) {
129
+			$id[] = substr($identifier, $x, 3);
130
+		}
131
+		$this->collection_identifier = $this->collection_name . '-' . strtoupper(implode('-', $id));
132
+	}
133
+
134
+
135
+	/**
136
+	 * add
137
+	 * attaches an object to the Collection
138
+	 * and sets any supplied data associated with the current iterator entry
139
+	 * by calling EE_Object_Collection::set_identifier()
140
+	 *
141
+	 * @param        $object
142
+	 * @param  mixed $identifier
143
+	 * @return bool
144
+	 * @throws InvalidEntityException
145
+	 * @throws DuplicateCollectionIdentifierException
146
+	 */
147
+	public function add($object, $identifier = null)
148
+	{
149
+		if (! $object instanceof $this->collection_interface) {
150
+			throw new InvalidEntityException($object, $this->collection_interface);
151
+		}
152
+		if ($this->contains($object)) {
153
+			throw new DuplicateCollectionIdentifierException($identifier);
154
+		}
155
+		$this->attach($object);
156
+		$this->setIdentifier($object, $identifier);
157
+		return $this->contains($object);
158
+	}
159
+
160
+
161
+	/**
162
+	 * getIdentifier
163
+	 * if no $identifier is supplied, then the spl_object_hash() is used
164
+	 *
165
+	 * @param        $object
166
+	 * @param  mixed $identifier
167
+	 * @return string
168
+	 */
169
+	public function getIdentifier($object, $identifier = null)
170
+	{
171
+		return ! empty($identifier)
172
+			? $identifier
173
+			: spl_object_hash($object);
174
+	}
175
+
176
+
177
+	/**
178
+	 * setIdentifier
179
+	 * Sets the data associated with an object in the Collection
180
+	 * if no $identifier is supplied, then the spl_object_hash() is used
181
+	 *
182
+	 * @param        $object
183
+	 * @param  mixed $identifier
184
+	 * @return bool
185
+	 */
186
+	public function setIdentifier($object, $identifier = null)
187
+	{
188
+		$identifier = $this->getIdentifier($object, $identifier);
189
+		$this->rewind();
190
+		while ($this->valid()) {
191
+			if ($object === $this->current()) {
192
+				$this->setInfo($identifier);
193
+				$this->rewind();
194
+				return true;
195
+			}
196
+			$this->next();
197
+		}
198
+		return false;
199
+	}
200
+
201
+
202
+	/**
203
+	 * get
204
+	 * finds and returns an object in the Collection based on the identifier that was set using addObject()
205
+	 * PLZ NOTE: the pointer is reset to the beginning of the collection before returning
206
+	 *
207
+	 * @param mixed $identifier
208
+	 * @return mixed
209
+	 */
210
+	public function get($identifier)
211
+	{
212
+		$this->rewind();
213
+		while ($this->valid()) {
214
+			if ($identifier === $this->getInfo()) {
215
+				$object = $this->current();
216
+				$this->rewind();
217
+				return $object;
218
+			}
219
+			$this->next();
220
+		}
221
+		return null;
222
+	}
223
+
224
+
225
+	/**
226
+	 * has
227
+	 * returns TRUE or FALSE
228
+	 * depending on whether the object is within the Collection
229
+	 * based on the supplied $identifier
230
+	 *
231
+	 * @param  mixed $identifier
232
+	 * @return bool
233
+	 */
234
+	public function has($identifier)
235
+	{
236
+		$this->rewind();
237
+		while ($this->valid()) {
238
+			if ($identifier === $this->getInfo()) {
239
+				$this->rewind();
240
+				return true;
241
+			}
242
+			$this->next();
243
+		}
244
+		return false;
245
+	}
246
+
247
+
248
+	/**
249
+	 * hasObject
250
+	 * returns TRUE or FALSE depending on whether the supplied object is within the Collection
251
+	 *
252
+	 * @param $object
253
+	 * @return bool
254
+	 */
255
+	public function hasObject($object)
256
+	{
257
+		return $this->contains($object);
258
+	}
259
+
260
+
261
+	/**
262
+	 * hasObjects
263
+	 * returns true if there are objects within the Collection, and false if it is empty
264
+	 *
265
+	 * @return bool
266
+	 */
267
+	public function hasObjects()
268
+	{
269
+		return $this->count() !== 0;
270
+	}
271
+
272
+
273
+	/**
274
+	 * isEmpty
275
+	 * returns true if there are no objects within the Collection, and false if there are
276
+	 *
277
+	 * @return bool
278
+	 */
279
+	public function isEmpty()
280
+	{
281
+		return $this->count() === 0;
282
+	}
283
+
284
+
285
+	/**
286
+	 * remove
287
+	 * detaches an object from the Collection
288
+	 *
289
+	 * @param $object
290
+	 * @return bool
291
+	 */
292
+	public function remove($object)
293
+	{
294
+		$this->detach($object);
295
+		return true;
296
+	}
297
+
298
+
299
+	/**
300
+	 * setCurrent
301
+	 * advances pointer to the object whose identifier matches that which was provided
302
+	 *
303
+	 * @param mixed $identifier
304
+	 * @return boolean
305
+	 */
306
+	public function setCurrent($identifier)
307
+	{
308
+		$this->rewind();
309
+		while ($this->valid()) {
310
+			if ($identifier === $this->getInfo()) {
311
+				return true;
312
+			}
313
+			$this->next();
314
+		}
315
+		return false;
316
+	}
317
+
318
+
319
+	/**
320
+	 * setCurrentUsingObject
321
+	 * advances pointer to the provided object
322
+	 *
323
+	 * @param $object
324
+	 * @return boolean
325
+	 */
326
+	public function setCurrentUsingObject($object)
327
+	{
328
+		$this->rewind();
329
+		while ($this->valid()) {
330
+			if ($this->current() === $object) {
331
+				return true;
332
+			}
333
+			$this->next();
334
+		}
335
+		return false;
336
+	}
337
+
338
+
339
+	/**
340
+	 * Returns the object occupying the index before the current object,
341
+	 * unless this is already the first object, in which case it just returns the first object
342
+	 *
343
+	 * @return mixed
344
+	 */
345
+	public function previous()
346
+	{
347
+		$index = $this->indexOf($this->current());
348
+		if ($index === 0) {
349
+			return $this->current();
350
+		}
351
+		$index--;
352
+		return $this->objectAtIndex($index);
353
+	}
354
+
355
+
356
+	/**
357
+	 * Returns the index of a given object, or false if not found
358
+	 *
359
+	 * @see https://stackoverflow.com/a/8736013
360
+	 * @param $object
361
+	 * @return boolean|int|string
362
+	 */
363
+	public function indexOf($object)
364
+	{
365
+		if (! $this->contains($object)) {
366
+			return false;
367
+		}
368
+		foreach ($this as $index => $obj) {
369
+			if ($obj === $object) {
370
+				return $index;
371
+			}
372
+		}
373
+		return false;
374
+	}
375
+
376
+
377
+	/**
378
+	 * Returns the object at the given index
379
+	 *
380
+	 * @see https://stackoverflow.com/a/8736013
381
+	 * @param int $index
382
+	 * @return mixed
383
+	 */
384
+	public function objectAtIndex($index)
385
+	{
386
+		$iterator = new LimitIterator($this, $index, 1);
387
+		$iterator->rewind();
388
+		return $iterator->current();
389
+	}
390
+
391
+
392
+	/**
393
+	 * Returns the sequence of objects as specified by the offset and length
394
+	 *
395
+	 * @see https://stackoverflow.com/a/8736013
396
+	 * @param int $offset
397
+	 * @param int $length
398
+	 * @return array
399
+	 */
400
+	public function slice($offset, $length)
401
+	{
402
+		$slice = array();
403
+		$iterator = new LimitIterator($this, $offset, $length);
404
+		foreach ($iterator as $object) {
405
+			$slice[] = $object;
406
+		}
407
+		return $slice;
408
+	}
409
+
410
+
411
+	/**
412
+	 * Inserts an object at a certain point
413
+	 *
414
+	 * @see https://stackoverflow.com/a/8736013
415
+	 * @param mixed $object A single object
416
+	 * @param int   $index
417
+	 * @param mixed $identifier
418
+	 * @return bool
419
+	 * @throws DuplicateCollectionIdentifierException
420
+	 * @throws InvalidEntityException
421
+	 */
422
+	public function insertObjectAt($object, $index, $identifier = null)
423
+	{
424
+		// check to ensure that objects don't already exist in the collection
425
+		if ($this->has($identifier)) {
426
+			throw new DuplicateCollectionIdentifierException($identifier);
427
+		}
428
+		// detach any objects at or past this index
429
+		$remaining_objects = array();
430
+		if ($index < $this->count()) {
431
+			$remaining_objects = $this->slice($index, $this->count() - $index);
432
+			foreach ($remaining_objects as $key => $remaining_object) {
433
+				// we need to grab the identifiers for each object and use them as keys
434
+				$remaining_objects[ $remaining_object->getInfo() ] = $remaining_object;
435
+				// and then remove the object from the current tracking array
436
+				unset($remaining_objects[ $key ]);
437
+				// and then remove it from the Collection
438
+				$this->detach($remaining_object);
439
+			}
440
+		}
441
+		// add the new object we're splicing in
442
+		$this->add($object, $identifier);
443
+		// attach the objects we previously detached
444
+		foreach ($remaining_objects as $key => $remaining_object) {
445
+			$this->add($remaining_object, $key);
446
+		}
447
+		return $this->contains($object);
448
+	}
449
+
450
+
451
+	/**
452
+	 * Inserts an object (or an array of objects) at a certain point
453
+	 *
454
+	 * @see https://stackoverflow.com/a/8736013
455
+	 * @param mixed $objects A single object or an array of objects
456
+	 * @param int   $index
457
+	 */
458
+	public function insertAt($objects, $index)
459
+	{
460
+		if (! is_array($objects)) {
461
+			$objects = array($objects);
462
+		}
463
+		// check to ensure that objects don't already exist in the collection
464
+		foreach ($objects as $key => $object) {
465
+			if ($this->contains($object)) {
466
+				unset($objects[ $key ]);
467
+			}
468
+		}
469
+		// do we have any objects left?
470
+		if (! $objects) {
471
+			return;
472
+		}
473
+		// detach any objects at or past this index
474
+		$remaining = array();
475
+		if ($index < $this->count()) {
476
+			$remaining = $this->slice($index, $this->count() - $index);
477
+			foreach ($remaining as $object) {
478
+				$this->detach($object);
479
+			}
480
+		}
481
+		// add the new objects we're splicing in
482
+		foreach ($objects as $object) {
483
+			$this->attach($object);
484
+		}
485
+		// attach the objects we previously detached
486
+		foreach ($remaining as $object) {
487
+			$this->attach($object);
488
+		}
489
+	}
490
+
491
+
492
+	/**
493
+	 * Removes the object at the given index
494
+	 *
495
+	 * @see https://stackoverflow.com/a/8736013
496
+	 * @param int $index
497
+	 */
498
+	public function removeAt($index)
499
+	{
500
+		$this->detach($this->objectAtIndex($index));
501
+	}
502
+
503
+
504
+	/**
505
+	 * detaches ALL objects from the Collection
506
+	 */
507
+	public function detachAll()
508
+	{
509
+		$this->rewind();
510
+		while ($this->valid()) {
511
+			$object = $this->current();
512
+			$this->next();
513
+			$this->detach($object);
514
+		}
515
+	}
516
+
517
+
518
+	/**
519
+	 * unsets and detaches ALL objects from the Collection
520
+	 */
521
+	public function trashAndDetachAll()
522
+	{
523
+		$this->rewind();
524
+		while ($this->valid()) {
525
+			$object = $this->current();
526
+			$this->next();
527
+			$this->detach($object);
528
+			unset($object);
529
+		}
530
+	}
531 531
 }
Please login to merge, or discard this patch.
caffeinated/admin/new/pricing/Pricing_Admin_Page.core.php 2 patches
Indentation   +1292 added lines, -1292 removed lines patch added patch discarded remove patch
@@ -12,1187 +12,1187 @@  discard block
 block discarded – undo
12 12
  */
13 13
 class Pricing_Admin_Page extends EE_Admin_Page
14 14
 {
15
-    protected function _init_page_props()
16
-    {
17
-        $this->page_slug        = PRICING_PG_SLUG;
18
-        $this->page_label       = PRICING_LABEL;
19
-        $this->_admin_base_url  = PRICING_ADMIN_URL;
20
-        $this->_admin_base_path = PRICING_ADMIN;
21
-    }
22
-
23
-
24
-    protected function _ajax_hooks()
25
-    {
26
-        if (! $this->capabilities->current_user_can('ee_edit_default_prices', 'update-price-order')) {
27
-            return;
28
-        }
29
-        add_action('wp_ajax_espresso_update_prices_order', [$this, 'update_price_order']);
30
-    }
31
-
32
-
33
-    protected function _define_page_props()
34
-    {
35
-        $this->_admin_page_title = PRICING_LABEL;
36
-        $this->_labels           = [
37
-            'buttons' => [
38
-                'add'         => esc_html__('Add New Default Price', 'event_espresso'),
39
-                'edit'        => esc_html__('Edit Default Price', 'event_espresso'),
40
-                'delete'      => esc_html__('Delete Default Price', 'event_espresso'),
41
-                'add_type'    => esc_html__('Add New Default Price Type', 'event_espresso'),
42
-                'edit_type'   => esc_html__('Edit Price Type', 'event_espresso'),
43
-                'delete_type' => esc_html__('Delete Price Type', 'event_espresso'),
44
-            ],
45
-            'publishbox' => [
46
-                'add_new_price'      => esc_html__('Add New Default Price', 'event_espresso'),
47
-                'edit_price'         => esc_html__('Edit Default Price', 'event_espresso'),
48
-                'add_new_price_type' => esc_html__('Add New Default Price Type', 'event_espresso'),
49
-                'edit_price_type'    => esc_html__('Edit Price Type', 'event_espresso'),
50
-            ],
51
-        ];
52
-    }
53
-
54
-
55
-    /**
56
-     * an array for storing request actions and their corresponding methods
57
-     *
58
-     * @return void
59
-     */
60
-    protected function _set_page_routes()
61
-    {
62
-        $PRC_ID             = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
63
-        $PRT_ID             = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
64
-        $this->_page_routes = [
65
-            'default'                     => [
66
-                'func'       => [$this, '_price_overview_list_table'],
67
-                'capability' => 'ee_read_default_prices',
68
-            ],
69
-            'add_new_price'               => [
70
-                'func'       => [$this, '_edit_price_details'],
71
-                'capability' => 'ee_edit_default_prices',
72
-            ],
73
-            'edit_price'                  => [
74
-                'func'       => [$this, '_edit_price_details'],
75
-                'capability' => 'ee_edit_default_price',
76
-                'obj_id'     => $PRC_ID,
77
-            ],
78
-            'insert_price'                => [
79
-                'func'       => [$this, '_insert_or_update_price'],
80
-                'args'       => ['insert' => true],
81
-                'noheader'   => true,
82
-                'capability' => 'ee_edit_default_prices',
83
-            ],
84
-            'update_price'                => [
85
-                'func'       => [$this, '_insert_or_update_price'],
86
-                'args'       => ['insert' => false],
87
-                'noheader'   => true,
88
-                'capability' => 'ee_edit_default_price',
89
-                'obj_id'     => $PRC_ID,
90
-            ],
91
-            'trash_price'                 => [
92
-                'func'       => [$this, '_trash_or_restore_price'],
93
-                'args'       => ['trash' => true],
94
-                'noheader'   => true,
95
-                'capability' => 'ee_delete_default_price',
96
-                'obj_id'     => $PRC_ID,
97
-            ],
98
-            'restore_price'               => [
99
-                'func'       => [$this, '_trash_or_restore_price'],
100
-                'args'       => ['trash' => false],
101
-                'noheader'   => true,
102
-                'capability' => 'ee_delete_default_price',
103
-                'obj_id'     => $PRC_ID,
104
-            ],
105
-            'delete_price'                => [
106
-                'func'       => [$this, '_delete_price'],
107
-                'noheader'   => true,
108
-                'capability' => 'ee_delete_default_price',
109
-                'obj_id'     => $PRC_ID,
110
-            ],
111
-            'espresso_update_price_order' => [
112
-                'func'       => [$this, 'update_price_order'],
113
-                'noheader'   => true,
114
-                'capability' => 'ee_edit_default_prices',
115
-            ],
116
-            // price types
117
-            'price_types'                 => [
118
-                'func'       => [$this, '_price_types_overview_list_table'],
119
-                'capability' => 'ee_read_default_price_types',
120
-            ],
121
-            'add_new_price_type'          => [
122
-                'func'       => [$this, '_edit_price_type_details'],
123
-                'capability' => 'ee_edit_default_price_types',
124
-            ],
125
-            'edit_price_type'             => [
126
-                'func'       => [$this, '_edit_price_type_details'],
127
-                'capability' => 'ee_edit_default_price_type',
128
-                'obj_id'     => $PRT_ID,
129
-            ],
130
-            'insert_price_type'           => [
131
-                'func'       => [$this, '_insert_or_update_price_type'],
132
-                'args'       => ['new_price_type' => true],
133
-                'noheader'   => true,
134
-                'capability' => 'ee_edit_default_price_types',
135
-            ],
136
-            'update_price_type'           => [
137
-                'func'       => [$this, '_insert_or_update_price_type'],
138
-                'args'       => ['new_price_type' => false],
139
-                'noheader'   => true,
140
-                'capability' => 'ee_edit_default_price_type',
141
-                'obj_id'     => $PRT_ID,
142
-            ],
143
-            'trash_price_type'            => [
144
-                'func'       => [$this, '_trash_or_restore_price_type'],
145
-                'args'       => ['trash' => true],
146
-                'noheader'   => true,
147
-                'capability' => 'ee_delete_default_price_type',
148
-                'obj_id'     => $PRT_ID,
149
-            ],
150
-            'restore_price_type'          => [
151
-                'func'       => [$this, '_trash_or_restore_price_type'],
152
-                'args'       => ['trash' => false],
153
-                'noheader'   => true,
154
-                'capability' => 'ee_delete_default_price_type',
155
-                'obj_id'     => $PRT_ID,
156
-            ],
157
-            'delete_price_type'           => [
158
-                'func'       => [$this, '_delete_price_type'],
159
-                'noheader'   => true,
160
-                'capability' => 'ee_delete_default_price_type',
161
-                'obj_id'     => $PRT_ID,
162
-            ],
163
-            'tax_settings'                => [
164
-                'func'       => [$this, '_tax_settings'],
165
-                'capability' => 'manage_options',
166
-            ],
167
-            'update_tax_settings'         => [
168
-                'func'       => [$this, '_update_tax_settings'],
169
-                'capability' => 'manage_options',
170
-                'noheader'   => true,
171
-            ],
172
-        ];
173
-    }
174
-
175
-
176
-    protected function _set_page_config()
177
-    {
178
-        $PRC_ID             = $this->request->getRequestParam('id', 0, DataType::INTEGER);
179
-        $this->_page_config = [
180
-            'default'            => [
181
-                'nav'           => [
182
-                    'label' => esc_html__('Default Pricing', 'event_espresso'),
183
-                    'icon' => 'dashicons-money-alt',
184
-                    'order' => 10,
185
-                ],
186
-                'list_table'    => 'Prices_List_Table',
187
-                'metaboxes'     => $this->_default_espresso_metaboxes,
188
-                'help_tabs'     => [
189
-                    'pricing_default_pricing_help_tab'                           => [
190
-                        'title'    => esc_html__('Default Pricing', 'event_espresso'),
191
-                        'filename' => 'pricing_default_pricing',
192
-                    ],
193
-                    'pricing_default_pricing_table_column_headings_help_tab'     => [
194
-                        'title'    => esc_html__('Default Pricing Table Column Headings', 'event_espresso'),
195
-                        'filename' => 'pricing_default_pricing_table_column_headings',
196
-                    ],
197
-                    'pricing_default_pricing_views_bulk_actions_search_help_tab' => [
198
-                        'title'    => esc_html__('Default Pricing Views & Bulk Actions & Search', 'event_espresso'),
199
-                        'filename' => 'pricing_default_pricing_views_bulk_actions_search',
200
-                    ],
201
-                ],
202
-                'require_nonce' => false,
203
-            ],
204
-            'add_new_price'      => [
205
-                'nav'           => [
206
-                    'label'      => esc_html__('Add New Default Price', 'event_espresso'),
207
-                    'icon' => 'dashicons-plus-alt',
208
-                    'order'      => 20,
209
-                    'persistent' => false,
210
-                ],
211
-                'help_tabs'     => [
212
-                    'add_new_default_price_help_tab' => [
213
-                        'title'    => esc_html__('Add New Default Price', 'event_espresso'),
214
-                        'filename' => 'pricing_add_new_default_price',
215
-                    ],
216
-                ],
217
-                'metaboxes'     => array_merge(
218
-                    ['_publish_post_box'],
219
-                    $this->_default_espresso_metaboxes
220
-                ),
221
-                'require_nonce' => false,
222
-            ],
223
-            'edit_price'         => [
224
-                'nav'           => [
225
-                    'label'      => esc_html__('Edit Default Price', 'event_espresso'),
226
-                    'icon' => 'dashicons-edit-large',
227
-                    'order'      => 20,
228
-                    'url'        => $PRC_ID
229
-                        ? add_query_arg(['id' => $PRC_ID], $this->_current_page_view_url)
230
-                        : $this->_admin_base_url,
231
-                    'persistent' => false,
232
-                ],
233
-                'metaboxes'     => array_merge(
234
-                    ['_publish_post_box'],
235
-                    $this->_default_espresso_metaboxes
236
-                ),
237
-                'help_tabs'     => [
238
-                    'edit_default_price_help_tab' => [
239
-                        'title'    => esc_html__('Edit Default Price', 'event_espresso'),
240
-                        'filename' => 'pricing_edit_default_price',
241
-                    ],
242
-                ],
243
-                'require_nonce' => false,
244
-            ],
245
-            'price_types'        => [
246
-                'nav'           => [
247
-                    'label' => esc_html__('Price Types', 'event_espresso'),
248
-                    'icon' => 'dashicons-networking',
249
-                    'order' => 30,
250
-                ],
251
-                'list_table'    => 'Price_Types_List_Table',
252
-                'help_tabs'     => [
253
-                    'pricing_price_types_help_tab'                           => [
254
-                        'title'    => esc_html__('Price Types', 'event_espresso'),
255
-                        'filename' => 'pricing_price_types',
256
-                    ],
257
-                    'pricing_price_types_table_column_headings_help_tab'     => [
258
-                        'title'    => esc_html__('Price Types Table Column Headings', 'event_espresso'),
259
-                        'filename' => 'pricing_price_types_table_column_headings',
260
-                    ],
261
-                    'pricing_price_types_views_bulk_actions_search_help_tab' => [
262
-                        'title'    => esc_html__('Price Types Views & Bulk Actions & Search', 'event_espresso'),
263
-                        'filename' => 'pricing_price_types_views_bulk_actions_search',
264
-                    ],
265
-                ],
266
-                'metaboxes'     => $this->_default_espresso_metaboxes,
267
-                'require_nonce' => false,
268
-            ],
269
-            'add_new_price_type' => [
270
-                'nav'           => [
271
-                    'label'      => esc_html__('Add New Price Type', 'event_espresso'),
272
-                    'icon' => 'dashicons-plus-alt',
273
-                    'order'      => 40,
274
-                    'persistent' => false,
275
-                ],
276
-                'help_tabs'     => [
277
-                    'add_new_price_type_help_tab' => [
278
-                        'title'    => esc_html__('Add New Price Type', 'event_espresso'),
279
-                        'filename' => 'pricing_add_new_price_type',
280
-                    ],
281
-                ],
282
-                'metaboxes'     => array_merge(
283
-                    ['_publish_post_box'],
284
-                    $this->_default_espresso_metaboxes
285
-                ),
286
-                'require_nonce' => false,
287
-            ],
288
-            'edit_price_type'    => [
289
-                'nav'           => [
290
-                    'label'      => esc_html__('Edit Price Type', 'event_espresso'),
291
-                    'icon' => 'dashicons-edit-large',
292
-                    'order'      => 40,
293
-                    'persistent' => false,
294
-                ],
295
-                'help_tabs'     => [
296
-                    'edit_price_type_help_tab' => [
297
-                        'title'    => esc_html__('Edit Price Type', 'event_espresso'),
298
-                        'filename' => 'pricing_edit_price_type',
299
-                    ],
300
-                ],
301
-                'metaboxes'     => array_merge(
302
-                    ['_publish_post_box'],
303
-                    $this->_default_espresso_metaboxes
304
-                ),
305
-                'require_nonce' => false,
306
-            ],
307
-            'tax_settings'       => [
308
-                'nav' => [
309
-                    'label' => esc_html__('Tax Settings', 'event_espresso'),
310
-                    'icon' => 'dashicons-sticky',
311
-                    'order' => 50,
312
-                ],
313
-                'labels'        => [
314
-                    'publishbox' => esc_html__('Update Tax Settings', 'event_espresso'),
315
-                ],
316
-                'metaboxes'     => array_merge(
317
-                    ['_publish_post_box'],
318
-                    $this->_default_espresso_metaboxes
319
-                ),
320
-                'require_nonce' => true,
321
-            ],
322
-        ];
323
-    }
324
-
325
-
326
-    protected function _add_screen_options()
327
-    {
328
-        // todo
329
-    }
330
-
331
-
332
-    protected function _add_screen_options_default()
333
-    {
334
-        $this->_per_page_screen_option();
335
-    }
336
-
337
-
338
-    protected function _add_screen_options_price_types()
339
-    {
340
-        $page_title              = $this->_admin_page_title;
341
-        $this->_admin_page_title = esc_html__('Price Types', 'event_espresso');
342
-        $this->_per_page_screen_option();
343
-        $this->_admin_page_title = $page_title;
344
-    }
345
-
346
-
347
-    protected function _add_feature_pointers()
348
-    {
349
-    }
350
-
351
-
352
-    public function load_scripts_styles()
353
-    {
354
-        // styles
355
-        wp_enqueue_style('espresso-ui-theme');
356
-        wp_register_style(
357
-            'espresso_pricing_css',
358
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.css',
359
-            [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
360
-            EVENT_ESPRESSO_VERSION
361
-        );
362
-        wp_enqueue_style('espresso_pricing_css');
363
-
364
-        // scripts
365
-        wp_enqueue_script('ee_admin_js');
366
-        wp_enqueue_script('jquery-ui-position');
367
-        wp_enqueue_script('jquery-ui-widget');
368
-        wp_register_script(
369
-            'espresso_pricing_js',
370
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.js',
371
-            ['jquery'],
372
-            EVENT_ESPRESSO_VERSION,
373
-            true
374
-        );
375
-        wp_enqueue_script('espresso_pricing_js');
376
-    }
377
-
378
-
379
-    public function load_scripts_styles_default()
380
-    {
381
-        wp_enqueue_script('espresso_ajax_table_sorting');
382
-    }
383
-
384
-
385
-    public function admin_footer_scripts()
386
-    {
387
-    }
388
-
389
-
390
-    public function admin_init()
391
-    {
392
-    }
393
-
394
-
395
-    public function admin_notices()
396
-    {
397
-    }
398
-
399
-
400
-    protected function _set_list_table_views_default()
401
-    {
402
-        $this->_views = [
403
-            'all' => [
404
-                'slug'        => 'all',
405
-                'label'       => esc_html__('View All Default Pricing', 'event_espresso'),
406
-                'count'       => 0,
407
-                'bulk_action' => [
408
-                    'trash_price' => esc_html__('Move to Trash', 'event_espresso'),
409
-                ],
410
-            ],
411
-        ];
412
-
413
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_default_prices', 'pricing_trash_price')) {
414
-            $this->_views['trashed'] = [
415
-                'slug'        => 'trashed',
416
-                'label'       => esc_html__('Trash', 'event_espresso'),
417
-                'count'       => 0,
418
-                'bulk_action' => [
419
-                    'restore_price' => esc_html__('Restore from Trash', 'event_espresso'),
420
-                    'delete_price'  => esc_html__('Delete Permanently', 'event_espresso'),
421
-                ],
422
-            ];
423
-        }
424
-    }
425
-
426
-
427
-    protected function _set_list_table_views_price_types()
428
-    {
429
-        $this->_views = [
430
-            'all' => [
431
-                'slug'        => 'all',
432
-                'label'       => esc_html__('All', 'event_espresso'),
433
-                'count'       => 0,
434
-                'bulk_action' => [
435
-                    'trash_price_type' => esc_html__('Move to Trash', 'event_espresso'),
436
-                ],
437
-            ],
438
-        ];
439
-
440
-        if (
441
-            EE_Registry::instance()->CAP->current_user_can(
442
-                'ee_delete_default_price_types',
443
-                'pricing_trash_price_type'
444
-            )
445
-        ) {
446
-            $this->_views['trashed'] = [
447
-                'slug'        => 'trashed',
448
-                'label'       => esc_html__('Trash', 'event_espresso'),
449
-                'count'       => 0,
450
-                'bulk_action' => [
451
-                    'restore_price_type' => esc_html__('Restore from Trash', 'event_espresso'),
452
-                    'delete_price_type'  => esc_html__('Delete Permanently', 'event_espresso'),
453
-                ],
454
-            ];
455
-        }
456
-    }
457
-
458
-
459
-    /**
460
-     * generates HTML for main Prices Admin page
461
-     *
462
-     * @return void
463
-     * @throws EE_Error
464
-     */
465
-    protected function _price_overview_list_table()
466
-    {
467
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
468
-            'add_new_price',
469
-            'add',
470
-            [],
471
-            'add-new-h2'
472
-        );
473
-        $this->_admin_page_title .= $this->_learn_more_about_pricing_link();
474
-        $this->_search_btn_label = esc_html__('Default Prices', 'event_espresso');
475
-        $this->display_admin_list_table_page_with_sidebar();
476
-    }
477
-
478
-
479
-    /**
480
-     * retrieve data for Prices List table
481
-     *
482
-     * @param int  $per_page how many prices displayed per page
483
-     * @param bool $count    return the count or objects
484
-     * @param bool $trashed  whether the current view is of the trash can - eww yuck!
485
-     * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
486
-     * @throws EE_Error
487
-     * @throws ReflectionException
488
-     */
489
-    public function get_prices_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
490
-    {
491
-        // start with an empty array
492
-        $event_pricing = [];
493
-
494
-        require_once(PRICING_ADMIN . 'Prices_List_Table.class.php');
495
-
496
-        $orderby = $this->request->getRequestParam('orderby', '');
497
-        $order   = $this->request->getRequestParam('order', 'ASC');
498
-
499
-        switch ($orderby) {
500
-            case 'name':
501
-                $orderby = ['PRC_name' => $order];
502
-                break;
503
-            case 'type':
504
-                $orderby = ['Price_Type.PRT_name' => $order];
505
-                break;
506
-            case 'amount':
507
-                $orderby = ['PRC_amount' => $order];
508
-                break;
509
-            default:
510
-                $orderby = ['PRC_order' => $order, 'Price_Type.PRT_order' => $order, 'PRC_ID' => $order];
511
-        }
512
-
513
-        $current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
514
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
515
-
516
-        $where = [
517
-            'PRC_is_default' => 1,
518
-            'PRC_deleted'    => $trashed,
519
-        ];
520
-
521
-        $offset = ($current_page - 1) * $per_page;
522
-        $limit  = [$offset, $per_page];
523
-
524
-        $search_term = $this->request->getRequestParam('s');
525
-        if ($search_term) {
526
-            $search_term = "%{$search_term}%";
527
-            $where['OR'] = [
528
-                'PRC_name'            => ['LIKE', $search_term],
529
-                'PRC_desc'            => ['LIKE', $search_term],
530
-                'PRC_amount'          => ['LIKE', $search_term],
531
-                'Price_Type.PRT_name' => ['LIKE', $search_term],
532
-            ];
533
-        }
534
-
535
-        $query_params = [
536
-            $where,
537
-            'order_by' => $orderby,
538
-            'limit'    => $limit,
539
-            'group_by' => 'PRC_ID',
540
-        ];
541
-
542
-        if ($count) {
543
-            return $trashed
544
-                ? EEM_Price::instance()->count([$where])
545
-                : EEM_Price::instance()->count_deleted_and_undeleted([$where]);
546
-        }
547
-        return EEM_Price::instance()->get_all_deleted_and_undeleted($query_params);
548
-    }
549
-
550
-
551
-    /**
552
-     * @return void
553
-     * @throws EE_Error
554
-     * @throws ReflectionException
555
-     */
556
-    protected function _edit_price_details()
557
-    {
558
-        // grab price ID
559
-        $PRC_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
560
-        // change page title based on request action
561
-        switch ($this->_req_action) {
562
-            case 'add_new_price':
563
-                $this->_admin_page_title = esc_html__('Add New Price', 'event_espresso');
564
-                break;
565
-            case 'edit_price':
566
-                $this->_admin_page_title = esc_html__('Edit Price', 'event_espresso');
567
-                break;
568
-            default:
569
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
570
-        }
571
-        // add PRC_ID to title if editing
572
-        $this->_admin_page_title = $PRC_ID ? $this->_admin_page_title . ' # ' . $PRC_ID : $this->_admin_page_title;
573
-
574
-        if ($PRC_ID) {
575
-            $price                    = EEM_Price::instance()->get_one_by_ID($PRC_ID);
576
-            $additional_hidden_fields = [
577
-                'PRC_ID' => ['type' => 'hidden', 'value' => $PRC_ID],
578
-            ];
579
-            $this->_set_add_edit_form_tags('update_price', $additional_hidden_fields);
580
-        } else {
581
-            $price = EEM_Price::instance()->get_new_price();
582
-            $this->_set_add_edit_form_tags('insert_price');
583
-        }
584
-
585
-        if (! $price instanceof EE_Price) {
586
-            throw new RuntimeException(
587
-                sprintf(
588
-                    esc_html__(
589
-                        'A valid Price could not be retrieved from the database with ID: %1$s',
590
-                        'event_espresso'
591
-                    ),
592
-                    $PRC_ID
593
-                )
594
-            );
595
-        }
596
-
597
-        $this->_template_args['PRC_ID'] = $PRC_ID;
598
-        $this->_template_args['price']  = $price;
599
-
600
-        $default_base_price = $price->type_obj() && $price->type_obj()->base_type() === 1;
601
-
602
-        $this->_template_args['default_base_price'] = $default_base_price;
603
-
604
-        // get price types
605
-        $price_types = EEM_Price_Type::instance()->get_all([['PBT_ID' => ['!=', 1]]]);
606
-        if (empty($price_types)) {
607
-            $msg = esc_html__(
608
-                'You have no price types defined. Please add a price type before adding a price.',
609
-                'event_espresso'
610
-            );
611
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
612
-            $this->display_admin_page_with_sidebar();
613
-        }
614
-        $attributes       = [];
615
-        $price_type_names = [];
616
-        $attributes[]     = 'id="PRT_ID"';
617
-        if ($default_base_price) {
618
-            $attributes[]       = 'disabled="disabled"';
619
-            $price_type_names[] = ['id' => 1, 'text' => esc_html__('Base Price', 'event_espresso')];
620
-        }
621
-        foreach ($price_types as $type) {
622
-            $price_type_names[] = ['id' => $type->ID(), 'text' => $type->name()];
623
-        }
624
-        $this->_template_args['attributes']  = implode(' ', $attributes);
625
-        $this->_template_args['price_types'] = $price_type_names;
626
-
627
-        $this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
628
-        $this->_template_args['admin_page_content']            = $this->_edit_price_details_meta_box();
629
-
630
-        $this->_set_publish_post_box_vars('id', $PRC_ID, '', '', true);
631
-        // the details template wrapper
632
-        $this->display_admin_page_with_sidebar();
633
-    }
634
-
635
-
636
-    /**
637
-     *
638
-     * @return string
639
-     */
640
-    public function _edit_price_details_meta_box(): string
641
-    {
642
-        return EEH_Template::display_template(
643
-            PRICING_TEMPLATE_PATH . 'pricing_details_main_meta_box.template.php',
644
-            $this->_template_args,
645
-            true
646
-        );
647
-    }
648
-
649
-
650
-    /**
651
-     * @return array
652
-     * @throws EE_Error
653
-     * @throws ReflectionException
654
-     */
655
-    protected function set_price_column_values(): array
656
-    {
657
-        $PRC_order = 0;
658
-        $PRT_ID    = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
659
-        if ($PRT_ID) {
660
-            /** @var EE_Price_Type $price_type */
661
-            $price_type = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
662
-            if ($price_type instanceof EE_Price_Type) {
663
-                $PRC_order = $price_type->order();
664
-            }
665
-        }
666
-        return [
667
-            'PRT_ID'         => $PRT_ID,
668
-            'PRC_amount'     => $this->request->getRequestParam('PRC_amount', 0, DataType::FLOAT),
669
-            'PRC_name'       => $this->request->getRequestParam('PRC_name'),
670
-            'PRC_desc'       => $this->request->getRequestParam('PRC_desc'),
671
-            'PRC_is_default' => 1,
672
-            'PRC_overrides'  => null,
673
-            'PRC_order'      => $PRC_order,
674
-            'PRC_deleted'    => 0,
675
-            'PRC_parent'     => 0,
676
-        ];
677
-    }
678
-
679
-
680
-    /**
681
-     * @param bool $insert - whether to insert or update
682
-     * @return void
683
-     * @throws EE_Error
684
-     * @throws ReflectionException
685
-     */
686
-    protected function _insert_or_update_price(bool $insert = false)
687
-    {
688
-        // why be so pessimistic ???  : (
689
-        $updated = 0;
690
-
691
-        $set_column_values = $this->set_price_column_values();
692
-        // is this a new Price ?
693
-        if ($insert) {
694
-            // run the insert
695
-            $PRC_ID = EEM_Price::instance()->insert($set_column_values);
696
-            if ($PRC_ID) {
697
-                // make sure this new price modifier is attached to the ticket but ONLY if it is not a tax type
698
-                $price = EEM_price::instance()->get_one_by_ID($PRC_ID);
699
-                if (
700
-                    $price instanceof EE_Price
701
-                    && $price->type_obj() instanceof EE_Price_type
702
-                    && $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax
703
-                ) {
704
-                    $ticket = EEM_Ticket::instance()->get_one_by_ID(1);
705
-                    // TODO: create new default ticket if it doesn't exist
706
-                    if ($ticket instanceof EE_Ticket) {
707
-                        $ticket->_add_relation_to($price, 'Price');
708
-                        $ticket->save();
709
-                    }
710
-                }
711
-                $updated = 1;
712
-            }
713
-            $action_desc = 'created';
714
-        } else {
715
-            $PRC_ID = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
716
-            // run the update
717
-            $where_cols_n_values = ['PRC_ID' => $PRC_ID];
718
-            $updated             = EEM_Price::instance()->update($set_column_values, [$where_cols_n_values]);
719
-
720
-            $price = EEM_Price::instance()->get_one_by_ID($PRC_ID);
721
-            if ($price instanceof EE_Price && $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax) {
722
-                // if this is $PRC_ID == 1,
723
-                // then we need to update the default ticket attached to this price so the TKT_price value is updated.
724
-                if ($PRC_ID === 1) {
725
-                    $ticket = $price->get_first_related('Ticket');
726
-                    if ($ticket) {
727
-                        $ticket->set('TKT_price', $price->get('PRC_amount'));
728
-                        $ticket->set('TKT_name', $price->get('PRC_name'));
729
-                        $ticket->set('TKT_description', $price->get('PRC_desc'));
730
-                        $ticket->save();
731
-                    }
732
-                } else {
733
-                    // we make sure this price is attached to base ticket. but ONLY if it's not a tax ticket type.
734
-                    $ticket = EEM_Ticket::instance()->get_one_by_ID(1);
735
-                    if ($ticket instanceof EE_Ticket) {
736
-                        $ticket->_add_relation_to($PRC_ID, 'Price');
737
-                        $ticket->save();
738
-                    }
739
-                }
740
-            }
741
-
742
-            $action_desc = 'updated';
743
-        }
744
-
745
-        $query_args = ['action' => 'edit_price', 'id' => $PRC_ID];
746
-
747
-        $this->_redirect_after_action($updated, 'Prices', $action_desc, $query_args);
748
-    }
749
-
750
-
751
-    /**
752
-     * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
753
-     * @return void
754
-     * @throws EE_Error
755
-     */
756
-    protected function _trash_or_restore_price($trash = true)
757
-    {
758
-        $entity_model = EEM_Price::instance();
759
-        $action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
760
-        $result       = $this->trashRestoreDeleteEntities(
761
-            $entity_model,
762
-            'id',
763
-            $action,
764
-            'PRC_deleted',
765
-            [$this, 'adjustTicketRelations']
766
-        );
767
-
768
-        if ($result) {
769
-            $msg = $trash
770
-                ? esc_html(
771
-                    _n(
772
-                        'The Price has been trashed',
773
-                        'The Prices have been trashed',
774
-                        $result,
775
-                        'event_espresso'
776
-                    )
777
-                )
778
-                : esc_html(
779
-                    _n(
780
-                        'The Price has been restored',
781
-                        'The Prices have been restored',
782
-                        $result,
783
-                        'event_espresso'
784
-                    )
785
-                );
786
-            EE_Error::add_success($msg);
787
-        }
788
-
789
-        $this->_redirect_after_action(
790
-            $result,
791
-            _n('Price', 'Prices', $result, 'event_espresso'),
792
-            $trash ? 'trashed' : 'restored',
793
-            ['action' => 'default'],
794
-            true
795
-        );
796
-    }
797
-
798
-
799
-    /**
800
-     * @param EEM_Base   $entity_model
801
-     * @param int|string $entity_ID
802
-     * @param string     $action
803
-     * @param int        $result
804
-     * @throws EE_Error
805
-     * @throws ReflectionException
806
-     * @since 4.10.30.p
807
-     */
808
-    public function adjustTicketRelations(
809
-        EEM_Base $entity_model,
810
-        $entity_ID,
811
-        string $action,
812
-        int $result
813
-    ) {
814
-        if (! $entity_ID || (float) $result < 1) {
815
-            return;
816
-        }
817
-
818
-        $entity = $entity_model->get_one_by_ID($entity_ID);
819
-        if (! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
820
-            return;
821
-        }
822
-
823
-        // get default tickets for updating
824
-        $default_tickets = EEM_Ticket::instance()->get_all_default_tickets();
825
-        foreach ($default_tickets as $default_ticket) {
826
-            if (! $default_ticket instanceof EE_Ticket) {
827
-                continue;
828
-            }
829
-            switch ($action) {
830
-                case EE_Admin_List_Table::ACTION_DELETE:
831
-                case EE_Admin_List_Table::ACTION_TRASH:
832
-                    // if trashing then remove relations to base default ticket.
833
-                    $default_ticket->_remove_relation_to($entity_ID, 'Price');
834
-                    break;
835
-                case EE_Admin_List_Table::ACTION_RESTORE:
836
-                    // if restoring then add back to base default ticket
837
-                    $default_ticket->_add_relation_to($entity_ID, 'Price');
838
-                    break;
839
-            }
840
-            $default_ticket->save();
841
-        }
842
-    }
843
-
844
-
845
-    /**
846
-     * @return void
847
-     * @throws EE_Error
848
-     * @throws ReflectionException
849
-     */
850
-    protected function _delete_price()
851
-    {
852
-        $entity_model = EEM_Price::instance();
853
-        $deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
854
-        $entity       = $entity_model->item_name($deleted);
855
-        $this->_redirect_after_action(
856
-            $deleted,
857
-            $entity,
858
-            'deleted',
859
-            ['action' => 'default']
860
-        );
861
-    }
862
-
863
-
864
-    /**
865
-     * @throws EE_Error
866
-     * @throws ReflectionException
867
-     */
868
-    public function update_price_order()
869
-    {
870
-        if (! $this->capabilities->current_user_can('ee_edit_default_prices', __FUNCTION__)) {
871
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
872
-        }
873
-        // grab our row IDs
874
-        $row_ids = $this->request->getRequestParam('row_ids', '');
875
-        $row_ids = explode(',', rtrim($row_ids, ','));
876
-
877
-        $all_updated = true;
878
-        foreach ($row_ids as $i => $row_id) {
879
-            // Update the prices when re-ordering
880
-            $fields_n_values = ['PRC_order' => $i + 1];
881
-            $query_params    = [['PRC_ID' => absint($row_id)]];
882
-            // any failure will toggle $all_updated to false
883
-            $all_updated = $row_id && EEM_Price::instance()->update($fields_n_values, $query_params) !== false
884
-                ? $all_updated
885
-                : false;
886
-        }
887
-        $success = $all_updated
888
-            ? esc_html__('Price order was updated successfully.', 'event_espresso')
889
-            : false;
890
-        $errors  = ! $all_updated
891
-            ? esc_html__('An error occurred. The price order was not updated.', 'event_espresso')
892
-            : false;
893
-
894
-        echo wp_json_encode(['return_data' => false, 'success' => $success, 'errors' => $errors]);
895
-        die();
896
-    }
897
-
898
-
899
-    /******************************************************************************************************************
15
+	protected function _init_page_props()
16
+	{
17
+		$this->page_slug        = PRICING_PG_SLUG;
18
+		$this->page_label       = PRICING_LABEL;
19
+		$this->_admin_base_url  = PRICING_ADMIN_URL;
20
+		$this->_admin_base_path = PRICING_ADMIN;
21
+	}
22
+
23
+
24
+	protected function _ajax_hooks()
25
+	{
26
+		if (! $this->capabilities->current_user_can('ee_edit_default_prices', 'update-price-order')) {
27
+			return;
28
+		}
29
+		add_action('wp_ajax_espresso_update_prices_order', [$this, 'update_price_order']);
30
+	}
31
+
32
+
33
+	protected function _define_page_props()
34
+	{
35
+		$this->_admin_page_title = PRICING_LABEL;
36
+		$this->_labels           = [
37
+			'buttons' => [
38
+				'add'         => esc_html__('Add New Default Price', 'event_espresso'),
39
+				'edit'        => esc_html__('Edit Default Price', 'event_espresso'),
40
+				'delete'      => esc_html__('Delete Default Price', 'event_espresso'),
41
+				'add_type'    => esc_html__('Add New Default Price Type', 'event_espresso'),
42
+				'edit_type'   => esc_html__('Edit Price Type', 'event_espresso'),
43
+				'delete_type' => esc_html__('Delete Price Type', 'event_espresso'),
44
+			],
45
+			'publishbox' => [
46
+				'add_new_price'      => esc_html__('Add New Default Price', 'event_espresso'),
47
+				'edit_price'         => esc_html__('Edit Default Price', 'event_espresso'),
48
+				'add_new_price_type' => esc_html__('Add New Default Price Type', 'event_espresso'),
49
+				'edit_price_type'    => esc_html__('Edit Price Type', 'event_espresso'),
50
+			],
51
+		];
52
+	}
53
+
54
+
55
+	/**
56
+	 * an array for storing request actions and their corresponding methods
57
+	 *
58
+	 * @return void
59
+	 */
60
+	protected function _set_page_routes()
61
+	{
62
+		$PRC_ID             = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
63
+		$PRT_ID             = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
64
+		$this->_page_routes = [
65
+			'default'                     => [
66
+				'func'       => [$this, '_price_overview_list_table'],
67
+				'capability' => 'ee_read_default_prices',
68
+			],
69
+			'add_new_price'               => [
70
+				'func'       => [$this, '_edit_price_details'],
71
+				'capability' => 'ee_edit_default_prices',
72
+			],
73
+			'edit_price'                  => [
74
+				'func'       => [$this, '_edit_price_details'],
75
+				'capability' => 'ee_edit_default_price',
76
+				'obj_id'     => $PRC_ID,
77
+			],
78
+			'insert_price'                => [
79
+				'func'       => [$this, '_insert_or_update_price'],
80
+				'args'       => ['insert' => true],
81
+				'noheader'   => true,
82
+				'capability' => 'ee_edit_default_prices',
83
+			],
84
+			'update_price'                => [
85
+				'func'       => [$this, '_insert_or_update_price'],
86
+				'args'       => ['insert' => false],
87
+				'noheader'   => true,
88
+				'capability' => 'ee_edit_default_price',
89
+				'obj_id'     => $PRC_ID,
90
+			],
91
+			'trash_price'                 => [
92
+				'func'       => [$this, '_trash_or_restore_price'],
93
+				'args'       => ['trash' => true],
94
+				'noheader'   => true,
95
+				'capability' => 'ee_delete_default_price',
96
+				'obj_id'     => $PRC_ID,
97
+			],
98
+			'restore_price'               => [
99
+				'func'       => [$this, '_trash_or_restore_price'],
100
+				'args'       => ['trash' => false],
101
+				'noheader'   => true,
102
+				'capability' => 'ee_delete_default_price',
103
+				'obj_id'     => $PRC_ID,
104
+			],
105
+			'delete_price'                => [
106
+				'func'       => [$this, '_delete_price'],
107
+				'noheader'   => true,
108
+				'capability' => 'ee_delete_default_price',
109
+				'obj_id'     => $PRC_ID,
110
+			],
111
+			'espresso_update_price_order' => [
112
+				'func'       => [$this, 'update_price_order'],
113
+				'noheader'   => true,
114
+				'capability' => 'ee_edit_default_prices',
115
+			],
116
+			// price types
117
+			'price_types'                 => [
118
+				'func'       => [$this, '_price_types_overview_list_table'],
119
+				'capability' => 'ee_read_default_price_types',
120
+			],
121
+			'add_new_price_type'          => [
122
+				'func'       => [$this, '_edit_price_type_details'],
123
+				'capability' => 'ee_edit_default_price_types',
124
+			],
125
+			'edit_price_type'             => [
126
+				'func'       => [$this, '_edit_price_type_details'],
127
+				'capability' => 'ee_edit_default_price_type',
128
+				'obj_id'     => $PRT_ID,
129
+			],
130
+			'insert_price_type'           => [
131
+				'func'       => [$this, '_insert_or_update_price_type'],
132
+				'args'       => ['new_price_type' => true],
133
+				'noheader'   => true,
134
+				'capability' => 'ee_edit_default_price_types',
135
+			],
136
+			'update_price_type'           => [
137
+				'func'       => [$this, '_insert_or_update_price_type'],
138
+				'args'       => ['new_price_type' => false],
139
+				'noheader'   => true,
140
+				'capability' => 'ee_edit_default_price_type',
141
+				'obj_id'     => $PRT_ID,
142
+			],
143
+			'trash_price_type'            => [
144
+				'func'       => [$this, '_trash_or_restore_price_type'],
145
+				'args'       => ['trash' => true],
146
+				'noheader'   => true,
147
+				'capability' => 'ee_delete_default_price_type',
148
+				'obj_id'     => $PRT_ID,
149
+			],
150
+			'restore_price_type'          => [
151
+				'func'       => [$this, '_trash_or_restore_price_type'],
152
+				'args'       => ['trash' => false],
153
+				'noheader'   => true,
154
+				'capability' => 'ee_delete_default_price_type',
155
+				'obj_id'     => $PRT_ID,
156
+			],
157
+			'delete_price_type'           => [
158
+				'func'       => [$this, '_delete_price_type'],
159
+				'noheader'   => true,
160
+				'capability' => 'ee_delete_default_price_type',
161
+				'obj_id'     => $PRT_ID,
162
+			],
163
+			'tax_settings'                => [
164
+				'func'       => [$this, '_tax_settings'],
165
+				'capability' => 'manage_options',
166
+			],
167
+			'update_tax_settings'         => [
168
+				'func'       => [$this, '_update_tax_settings'],
169
+				'capability' => 'manage_options',
170
+				'noheader'   => true,
171
+			],
172
+		];
173
+	}
174
+
175
+
176
+	protected function _set_page_config()
177
+	{
178
+		$PRC_ID             = $this->request->getRequestParam('id', 0, DataType::INTEGER);
179
+		$this->_page_config = [
180
+			'default'            => [
181
+				'nav'           => [
182
+					'label' => esc_html__('Default Pricing', 'event_espresso'),
183
+					'icon' => 'dashicons-money-alt',
184
+					'order' => 10,
185
+				],
186
+				'list_table'    => 'Prices_List_Table',
187
+				'metaboxes'     => $this->_default_espresso_metaboxes,
188
+				'help_tabs'     => [
189
+					'pricing_default_pricing_help_tab'                           => [
190
+						'title'    => esc_html__('Default Pricing', 'event_espresso'),
191
+						'filename' => 'pricing_default_pricing',
192
+					],
193
+					'pricing_default_pricing_table_column_headings_help_tab'     => [
194
+						'title'    => esc_html__('Default Pricing Table Column Headings', 'event_espresso'),
195
+						'filename' => 'pricing_default_pricing_table_column_headings',
196
+					],
197
+					'pricing_default_pricing_views_bulk_actions_search_help_tab' => [
198
+						'title'    => esc_html__('Default Pricing Views & Bulk Actions & Search', 'event_espresso'),
199
+						'filename' => 'pricing_default_pricing_views_bulk_actions_search',
200
+					],
201
+				],
202
+				'require_nonce' => false,
203
+			],
204
+			'add_new_price'      => [
205
+				'nav'           => [
206
+					'label'      => esc_html__('Add New Default Price', 'event_espresso'),
207
+					'icon' => 'dashicons-plus-alt',
208
+					'order'      => 20,
209
+					'persistent' => false,
210
+				],
211
+				'help_tabs'     => [
212
+					'add_new_default_price_help_tab' => [
213
+						'title'    => esc_html__('Add New Default Price', 'event_espresso'),
214
+						'filename' => 'pricing_add_new_default_price',
215
+					],
216
+				],
217
+				'metaboxes'     => array_merge(
218
+					['_publish_post_box'],
219
+					$this->_default_espresso_metaboxes
220
+				),
221
+				'require_nonce' => false,
222
+			],
223
+			'edit_price'         => [
224
+				'nav'           => [
225
+					'label'      => esc_html__('Edit Default Price', 'event_espresso'),
226
+					'icon' => 'dashicons-edit-large',
227
+					'order'      => 20,
228
+					'url'        => $PRC_ID
229
+						? add_query_arg(['id' => $PRC_ID], $this->_current_page_view_url)
230
+						: $this->_admin_base_url,
231
+					'persistent' => false,
232
+				],
233
+				'metaboxes'     => array_merge(
234
+					['_publish_post_box'],
235
+					$this->_default_espresso_metaboxes
236
+				),
237
+				'help_tabs'     => [
238
+					'edit_default_price_help_tab' => [
239
+						'title'    => esc_html__('Edit Default Price', 'event_espresso'),
240
+						'filename' => 'pricing_edit_default_price',
241
+					],
242
+				],
243
+				'require_nonce' => false,
244
+			],
245
+			'price_types'        => [
246
+				'nav'           => [
247
+					'label' => esc_html__('Price Types', 'event_espresso'),
248
+					'icon' => 'dashicons-networking',
249
+					'order' => 30,
250
+				],
251
+				'list_table'    => 'Price_Types_List_Table',
252
+				'help_tabs'     => [
253
+					'pricing_price_types_help_tab'                           => [
254
+						'title'    => esc_html__('Price Types', 'event_espresso'),
255
+						'filename' => 'pricing_price_types',
256
+					],
257
+					'pricing_price_types_table_column_headings_help_tab'     => [
258
+						'title'    => esc_html__('Price Types Table Column Headings', 'event_espresso'),
259
+						'filename' => 'pricing_price_types_table_column_headings',
260
+					],
261
+					'pricing_price_types_views_bulk_actions_search_help_tab' => [
262
+						'title'    => esc_html__('Price Types Views & Bulk Actions & Search', 'event_espresso'),
263
+						'filename' => 'pricing_price_types_views_bulk_actions_search',
264
+					],
265
+				],
266
+				'metaboxes'     => $this->_default_espresso_metaboxes,
267
+				'require_nonce' => false,
268
+			],
269
+			'add_new_price_type' => [
270
+				'nav'           => [
271
+					'label'      => esc_html__('Add New Price Type', 'event_espresso'),
272
+					'icon' => 'dashicons-plus-alt',
273
+					'order'      => 40,
274
+					'persistent' => false,
275
+				],
276
+				'help_tabs'     => [
277
+					'add_new_price_type_help_tab' => [
278
+						'title'    => esc_html__('Add New Price Type', 'event_espresso'),
279
+						'filename' => 'pricing_add_new_price_type',
280
+					],
281
+				],
282
+				'metaboxes'     => array_merge(
283
+					['_publish_post_box'],
284
+					$this->_default_espresso_metaboxes
285
+				),
286
+				'require_nonce' => false,
287
+			],
288
+			'edit_price_type'    => [
289
+				'nav'           => [
290
+					'label'      => esc_html__('Edit Price Type', 'event_espresso'),
291
+					'icon' => 'dashicons-edit-large',
292
+					'order'      => 40,
293
+					'persistent' => false,
294
+				],
295
+				'help_tabs'     => [
296
+					'edit_price_type_help_tab' => [
297
+						'title'    => esc_html__('Edit Price Type', 'event_espresso'),
298
+						'filename' => 'pricing_edit_price_type',
299
+					],
300
+				],
301
+				'metaboxes'     => array_merge(
302
+					['_publish_post_box'],
303
+					$this->_default_espresso_metaboxes
304
+				),
305
+				'require_nonce' => false,
306
+			],
307
+			'tax_settings'       => [
308
+				'nav' => [
309
+					'label' => esc_html__('Tax Settings', 'event_espresso'),
310
+					'icon' => 'dashicons-sticky',
311
+					'order' => 50,
312
+				],
313
+				'labels'        => [
314
+					'publishbox' => esc_html__('Update Tax Settings', 'event_espresso'),
315
+				],
316
+				'metaboxes'     => array_merge(
317
+					['_publish_post_box'],
318
+					$this->_default_espresso_metaboxes
319
+				),
320
+				'require_nonce' => true,
321
+			],
322
+		];
323
+	}
324
+
325
+
326
+	protected function _add_screen_options()
327
+	{
328
+		// todo
329
+	}
330
+
331
+
332
+	protected function _add_screen_options_default()
333
+	{
334
+		$this->_per_page_screen_option();
335
+	}
336
+
337
+
338
+	protected function _add_screen_options_price_types()
339
+	{
340
+		$page_title              = $this->_admin_page_title;
341
+		$this->_admin_page_title = esc_html__('Price Types', 'event_espresso');
342
+		$this->_per_page_screen_option();
343
+		$this->_admin_page_title = $page_title;
344
+	}
345
+
346
+
347
+	protected function _add_feature_pointers()
348
+	{
349
+	}
350
+
351
+
352
+	public function load_scripts_styles()
353
+	{
354
+		// styles
355
+		wp_enqueue_style('espresso-ui-theme');
356
+		wp_register_style(
357
+			'espresso_pricing_css',
358
+			PRICING_ASSETS_URL . 'espresso_pricing_admin.css',
359
+			[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
360
+			EVENT_ESPRESSO_VERSION
361
+		);
362
+		wp_enqueue_style('espresso_pricing_css');
363
+
364
+		// scripts
365
+		wp_enqueue_script('ee_admin_js');
366
+		wp_enqueue_script('jquery-ui-position');
367
+		wp_enqueue_script('jquery-ui-widget');
368
+		wp_register_script(
369
+			'espresso_pricing_js',
370
+			PRICING_ASSETS_URL . 'espresso_pricing_admin.js',
371
+			['jquery'],
372
+			EVENT_ESPRESSO_VERSION,
373
+			true
374
+		);
375
+		wp_enqueue_script('espresso_pricing_js');
376
+	}
377
+
378
+
379
+	public function load_scripts_styles_default()
380
+	{
381
+		wp_enqueue_script('espresso_ajax_table_sorting');
382
+	}
383
+
384
+
385
+	public function admin_footer_scripts()
386
+	{
387
+	}
388
+
389
+
390
+	public function admin_init()
391
+	{
392
+	}
393
+
394
+
395
+	public function admin_notices()
396
+	{
397
+	}
398
+
399
+
400
+	protected function _set_list_table_views_default()
401
+	{
402
+		$this->_views = [
403
+			'all' => [
404
+				'slug'        => 'all',
405
+				'label'       => esc_html__('View All Default Pricing', 'event_espresso'),
406
+				'count'       => 0,
407
+				'bulk_action' => [
408
+					'trash_price' => esc_html__('Move to Trash', 'event_espresso'),
409
+				],
410
+			],
411
+		];
412
+
413
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_default_prices', 'pricing_trash_price')) {
414
+			$this->_views['trashed'] = [
415
+				'slug'        => 'trashed',
416
+				'label'       => esc_html__('Trash', 'event_espresso'),
417
+				'count'       => 0,
418
+				'bulk_action' => [
419
+					'restore_price' => esc_html__('Restore from Trash', 'event_espresso'),
420
+					'delete_price'  => esc_html__('Delete Permanently', 'event_espresso'),
421
+				],
422
+			];
423
+		}
424
+	}
425
+
426
+
427
+	protected function _set_list_table_views_price_types()
428
+	{
429
+		$this->_views = [
430
+			'all' => [
431
+				'slug'        => 'all',
432
+				'label'       => esc_html__('All', 'event_espresso'),
433
+				'count'       => 0,
434
+				'bulk_action' => [
435
+					'trash_price_type' => esc_html__('Move to Trash', 'event_espresso'),
436
+				],
437
+			],
438
+		];
439
+
440
+		if (
441
+			EE_Registry::instance()->CAP->current_user_can(
442
+				'ee_delete_default_price_types',
443
+				'pricing_trash_price_type'
444
+			)
445
+		) {
446
+			$this->_views['trashed'] = [
447
+				'slug'        => 'trashed',
448
+				'label'       => esc_html__('Trash', 'event_espresso'),
449
+				'count'       => 0,
450
+				'bulk_action' => [
451
+					'restore_price_type' => esc_html__('Restore from Trash', 'event_espresso'),
452
+					'delete_price_type'  => esc_html__('Delete Permanently', 'event_espresso'),
453
+				],
454
+			];
455
+		}
456
+	}
457
+
458
+
459
+	/**
460
+	 * generates HTML for main Prices Admin page
461
+	 *
462
+	 * @return void
463
+	 * @throws EE_Error
464
+	 */
465
+	protected function _price_overview_list_table()
466
+	{
467
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
468
+			'add_new_price',
469
+			'add',
470
+			[],
471
+			'add-new-h2'
472
+		);
473
+		$this->_admin_page_title .= $this->_learn_more_about_pricing_link();
474
+		$this->_search_btn_label = esc_html__('Default Prices', 'event_espresso');
475
+		$this->display_admin_list_table_page_with_sidebar();
476
+	}
477
+
478
+
479
+	/**
480
+	 * retrieve data for Prices List table
481
+	 *
482
+	 * @param int  $per_page how many prices displayed per page
483
+	 * @param bool $count    return the count or objects
484
+	 * @param bool $trashed  whether the current view is of the trash can - eww yuck!
485
+	 * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
486
+	 * @throws EE_Error
487
+	 * @throws ReflectionException
488
+	 */
489
+	public function get_prices_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
490
+	{
491
+		// start with an empty array
492
+		$event_pricing = [];
493
+
494
+		require_once(PRICING_ADMIN . 'Prices_List_Table.class.php');
495
+
496
+		$orderby = $this->request->getRequestParam('orderby', '');
497
+		$order   = $this->request->getRequestParam('order', 'ASC');
498
+
499
+		switch ($orderby) {
500
+			case 'name':
501
+				$orderby = ['PRC_name' => $order];
502
+				break;
503
+			case 'type':
504
+				$orderby = ['Price_Type.PRT_name' => $order];
505
+				break;
506
+			case 'amount':
507
+				$orderby = ['PRC_amount' => $order];
508
+				break;
509
+			default:
510
+				$orderby = ['PRC_order' => $order, 'Price_Type.PRT_order' => $order, 'PRC_ID' => $order];
511
+		}
512
+
513
+		$current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
514
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
515
+
516
+		$where = [
517
+			'PRC_is_default' => 1,
518
+			'PRC_deleted'    => $trashed,
519
+		];
520
+
521
+		$offset = ($current_page - 1) * $per_page;
522
+		$limit  = [$offset, $per_page];
523
+
524
+		$search_term = $this->request->getRequestParam('s');
525
+		if ($search_term) {
526
+			$search_term = "%{$search_term}%";
527
+			$where['OR'] = [
528
+				'PRC_name'            => ['LIKE', $search_term],
529
+				'PRC_desc'            => ['LIKE', $search_term],
530
+				'PRC_amount'          => ['LIKE', $search_term],
531
+				'Price_Type.PRT_name' => ['LIKE', $search_term],
532
+			];
533
+		}
534
+
535
+		$query_params = [
536
+			$where,
537
+			'order_by' => $orderby,
538
+			'limit'    => $limit,
539
+			'group_by' => 'PRC_ID',
540
+		];
541
+
542
+		if ($count) {
543
+			return $trashed
544
+				? EEM_Price::instance()->count([$where])
545
+				: EEM_Price::instance()->count_deleted_and_undeleted([$where]);
546
+		}
547
+		return EEM_Price::instance()->get_all_deleted_and_undeleted($query_params);
548
+	}
549
+
550
+
551
+	/**
552
+	 * @return void
553
+	 * @throws EE_Error
554
+	 * @throws ReflectionException
555
+	 */
556
+	protected function _edit_price_details()
557
+	{
558
+		// grab price ID
559
+		$PRC_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
560
+		// change page title based on request action
561
+		switch ($this->_req_action) {
562
+			case 'add_new_price':
563
+				$this->_admin_page_title = esc_html__('Add New Price', 'event_espresso');
564
+				break;
565
+			case 'edit_price':
566
+				$this->_admin_page_title = esc_html__('Edit Price', 'event_espresso');
567
+				break;
568
+			default:
569
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
570
+		}
571
+		// add PRC_ID to title if editing
572
+		$this->_admin_page_title = $PRC_ID ? $this->_admin_page_title . ' # ' . $PRC_ID : $this->_admin_page_title;
573
+
574
+		if ($PRC_ID) {
575
+			$price                    = EEM_Price::instance()->get_one_by_ID($PRC_ID);
576
+			$additional_hidden_fields = [
577
+				'PRC_ID' => ['type' => 'hidden', 'value' => $PRC_ID],
578
+			];
579
+			$this->_set_add_edit_form_tags('update_price', $additional_hidden_fields);
580
+		} else {
581
+			$price = EEM_Price::instance()->get_new_price();
582
+			$this->_set_add_edit_form_tags('insert_price');
583
+		}
584
+
585
+		if (! $price instanceof EE_Price) {
586
+			throw new RuntimeException(
587
+				sprintf(
588
+					esc_html__(
589
+						'A valid Price could not be retrieved from the database with ID: %1$s',
590
+						'event_espresso'
591
+					),
592
+					$PRC_ID
593
+				)
594
+			);
595
+		}
596
+
597
+		$this->_template_args['PRC_ID'] = $PRC_ID;
598
+		$this->_template_args['price']  = $price;
599
+
600
+		$default_base_price = $price->type_obj() && $price->type_obj()->base_type() === 1;
601
+
602
+		$this->_template_args['default_base_price'] = $default_base_price;
603
+
604
+		// get price types
605
+		$price_types = EEM_Price_Type::instance()->get_all([['PBT_ID' => ['!=', 1]]]);
606
+		if (empty($price_types)) {
607
+			$msg = esc_html__(
608
+				'You have no price types defined. Please add a price type before adding a price.',
609
+				'event_espresso'
610
+			);
611
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
612
+			$this->display_admin_page_with_sidebar();
613
+		}
614
+		$attributes       = [];
615
+		$price_type_names = [];
616
+		$attributes[]     = 'id="PRT_ID"';
617
+		if ($default_base_price) {
618
+			$attributes[]       = 'disabled="disabled"';
619
+			$price_type_names[] = ['id' => 1, 'text' => esc_html__('Base Price', 'event_espresso')];
620
+		}
621
+		foreach ($price_types as $type) {
622
+			$price_type_names[] = ['id' => $type->ID(), 'text' => $type->name()];
623
+		}
624
+		$this->_template_args['attributes']  = implode(' ', $attributes);
625
+		$this->_template_args['price_types'] = $price_type_names;
626
+
627
+		$this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
628
+		$this->_template_args['admin_page_content']            = $this->_edit_price_details_meta_box();
629
+
630
+		$this->_set_publish_post_box_vars('id', $PRC_ID, '', '', true);
631
+		// the details template wrapper
632
+		$this->display_admin_page_with_sidebar();
633
+	}
634
+
635
+
636
+	/**
637
+	 *
638
+	 * @return string
639
+	 */
640
+	public function _edit_price_details_meta_box(): string
641
+	{
642
+		return EEH_Template::display_template(
643
+			PRICING_TEMPLATE_PATH . 'pricing_details_main_meta_box.template.php',
644
+			$this->_template_args,
645
+			true
646
+		);
647
+	}
648
+
649
+
650
+	/**
651
+	 * @return array
652
+	 * @throws EE_Error
653
+	 * @throws ReflectionException
654
+	 */
655
+	protected function set_price_column_values(): array
656
+	{
657
+		$PRC_order = 0;
658
+		$PRT_ID    = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
659
+		if ($PRT_ID) {
660
+			/** @var EE_Price_Type $price_type */
661
+			$price_type = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
662
+			if ($price_type instanceof EE_Price_Type) {
663
+				$PRC_order = $price_type->order();
664
+			}
665
+		}
666
+		return [
667
+			'PRT_ID'         => $PRT_ID,
668
+			'PRC_amount'     => $this->request->getRequestParam('PRC_amount', 0, DataType::FLOAT),
669
+			'PRC_name'       => $this->request->getRequestParam('PRC_name'),
670
+			'PRC_desc'       => $this->request->getRequestParam('PRC_desc'),
671
+			'PRC_is_default' => 1,
672
+			'PRC_overrides'  => null,
673
+			'PRC_order'      => $PRC_order,
674
+			'PRC_deleted'    => 0,
675
+			'PRC_parent'     => 0,
676
+		];
677
+	}
678
+
679
+
680
+	/**
681
+	 * @param bool $insert - whether to insert or update
682
+	 * @return void
683
+	 * @throws EE_Error
684
+	 * @throws ReflectionException
685
+	 */
686
+	protected function _insert_or_update_price(bool $insert = false)
687
+	{
688
+		// why be so pessimistic ???  : (
689
+		$updated = 0;
690
+
691
+		$set_column_values = $this->set_price_column_values();
692
+		// is this a new Price ?
693
+		if ($insert) {
694
+			// run the insert
695
+			$PRC_ID = EEM_Price::instance()->insert($set_column_values);
696
+			if ($PRC_ID) {
697
+				// make sure this new price modifier is attached to the ticket but ONLY if it is not a tax type
698
+				$price = EEM_price::instance()->get_one_by_ID($PRC_ID);
699
+				if (
700
+					$price instanceof EE_Price
701
+					&& $price->type_obj() instanceof EE_Price_type
702
+					&& $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax
703
+				) {
704
+					$ticket = EEM_Ticket::instance()->get_one_by_ID(1);
705
+					// TODO: create new default ticket if it doesn't exist
706
+					if ($ticket instanceof EE_Ticket) {
707
+						$ticket->_add_relation_to($price, 'Price');
708
+						$ticket->save();
709
+					}
710
+				}
711
+				$updated = 1;
712
+			}
713
+			$action_desc = 'created';
714
+		} else {
715
+			$PRC_ID = $this->request->getRequestParam('PRC_ID', 0, DataType::INTEGER);
716
+			// run the update
717
+			$where_cols_n_values = ['PRC_ID' => $PRC_ID];
718
+			$updated             = EEM_Price::instance()->update($set_column_values, [$where_cols_n_values]);
719
+
720
+			$price = EEM_Price::instance()->get_one_by_ID($PRC_ID);
721
+			if ($price instanceof EE_Price && $price->type_obj()->base_type() !== EEM_Price_Type::base_type_tax) {
722
+				// if this is $PRC_ID == 1,
723
+				// then we need to update the default ticket attached to this price so the TKT_price value is updated.
724
+				if ($PRC_ID === 1) {
725
+					$ticket = $price->get_first_related('Ticket');
726
+					if ($ticket) {
727
+						$ticket->set('TKT_price', $price->get('PRC_amount'));
728
+						$ticket->set('TKT_name', $price->get('PRC_name'));
729
+						$ticket->set('TKT_description', $price->get('PRC_desc'));
730
+						$ticket->save();
731
+					}
732
+				} else {
733
+					// we make sure this price is attached to base ticket. but ONLY if it's not a tax ticket type.
734
+					$ticket = EEM_Ticket::instance()->get_one_by_ID(1);
735
+					if ($ticket instanceof EE_Ticket) {
736
+						$ticket->_add_relation_to($PRC_ID, 'Price');
737
+						$ticket->save();
738
+					}
739
+				}
740
+			}
741
+
742
+			$action_desc = 'updated';
743
+		}
744
+
745
+		$query_args = ['action' => 'edit_price', 'id' => $PRC_ID];
746
+
747
+		$this->_redirect_after_action($updated, 'Prices', $action_desc, $query_args);
748
+	}
749
+
750
+
751
+	/**
752
+	 * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
753
+	 * @return void
754
+	 * @throws EE_Error
755
+	 */
756
+	protected function _trash_or_restore_price($trash = true)
757
+	{
758
+		$entity_model = EEM_Price::instance();
759
+		$action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
760
+		$result       = $this->trashRestoreDeleteEntities(
761
+			$entity_model,
762
+			'id',
763
+			$action,
764
+			'PRC_deleted',
765
+			[$this, 'adjustTicketRelations']
766
+		);
767
+
768
+		if ($result) {
769
+			$msg = $trash
770
+				? esc_html(
771
+					_n(
772
+						'The Price has been trashed',
773
+						'The Prices have been trashed',
774
+						$result,
775
+						'event_espresso'
776
+					)
777
+				)
778
+				: esc_html(
779
+					_n(
780
+						'The Price has been restored',
781
+						'The Prices have been restored',
782
+						$result,
783
+						'event_espresso'
784
+					)
785
+				);
786
+			EE_Error::add_success($msg);
787
+		}
788
+
789
+		$this->_redirect_after_action(
790
+			$result,
791
+			_n('Price', 'Prices', $result, 'event_espresso'),
792
+			$trash ? 'trashed' : 'restored',
793
+			['action' => 'default'],
794
+			true
795
+		);
796
+	}
797
+
798
+
799
+	/**
800
+	 * @param EEM_Base   $entity_model
801
+	 * @param int|string $entity_ID
802
+	 * @param string     $action
803
+	 * @param int        $result
804
+	 * @throws EE_Error
805
+	 * @throws ReflectionException
806
+	 * @since 4.10.30.p
807
+	 */
808
+	public function adjustTicketRelations(
809
+		EEM_Base $entity_model,
810
+		$entity_ID,
811
+		string $action,
812
+		int $result
813
+	) {
814
+		if (! $entity_ID || (float) $result < 1) {
815
+			return;
816
+		}
817
+
818
+		$entity = $entity_model->get_one_by_ID($entity_ID);
819
+		if (! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
820
+			return;
821
+		}
822
+
823
+		// get default tickets for updating
824
+		$default_tickets = EEM_Ticket::instance()->get_all_default_tickets();
825
+		foreach ($default_tickets as $default_ticket) {
826
+			if (! $default_ticket instanceof EE_Ticket) {
827
+				continue;
828
+			}
829
+			switch ($action) {
830
+				case EE_Admin_List_Table::ACTION_DELETE:
831
+				case EE_Admin_List_Table::ACTION_TRASH:
832
+					// if trashing then remove relations to base default ticket.
833
+					$default_ticket->_remove_relation_to($entity_ID, 'Price');
834
+					break;
835
+				case EE_Admin_List_Table::ACTION_RESTORE:
836
+					// if restoring then add back to base default ticket
837
+					$default_ticket->_add_relation_to($entity_ID, 'Price');
838
+					break;
839
+			}
840
+			$default_ticket->save();
841
+		}
842
+	}
843
+
844
+
845
+	/**
846
+	 * @return void
847
+	 * @throws EE_Error
848
+	 * @throws ReflectionException
849
+	 */
850
+	protected function _delete_price()
851
+	{
852
+		$entity_model = EEM_Price::instance();
853
+		$deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
854
+		$entity       = $entity_model->item_name($deleted);
855
+		$this->_redirect_after_action(
856
+			$deleted,
857
+			$entity,
858
+			'deleted',
859
+			['action' => 'default']
860
+		);
861
+	}
862
+
863
+
864
+	/**
865
+	 * @throws EE_Error
866
+	 * @throws ReflectionException
867
+	 */
868
+	public function update_price_order()
869
+	{
870
+		if (! $this->capabilities->current_user_can('ee_edit_default_prices', __FUNCTION__)) {
871
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
872
+		}
873
+		// grab our row IDs
874
+		$row_ids = $this->request->getRequestParam('row_ids', '');
875
+		$row_ids = explode(',', rtrim($row_ids, ','));
876
+
877
+		$all_updated = true;
878
+		foreach ($row_ids as $i => $row_id) {
879
+			// Update the prices when re-ordering
880
+			$fields_n_values = ['PRC_order' => $i + 1];
881
+			$query_params    = [['PRC_ID' => absint($row_id)]];
882
+			// any failure will toggle $all_updated to false
883
+			$all_updated = $row_id && EEM_Price::instance()->update($fields_n_values, $query_params) !== false
884
+				? $all_updated
885
+				: false;
886
+		}
887
+		$success = $all_updated
888
+			? esc_html__('Price order was updated successfully.', 'event_espresso')
889
+			: false;
890
+		$errors  = ! $all_updated
891
+			? esc_html__('An error occurred. The price order was not updated.', 'event_espresso')
892
+			: false;
893
+
894
+		echo wp_json_encode(['return_data' => false, 'success' => $success, 'errors' => $errors]);
895
+		die();
896
+	}
897
+
898
+
899
+	/******************************************************************************************************************
900 900
      ***********************************************  TICKET PRICE TYPES  *********************************************
901 901
      ******************************************************************************************************************/
902 902
 
903 903
 
904
-    /**
905
-     * generates HTML for main Prices Admin page
906
-     *
907
-     * @return void
908
-     * @throws EE_Error
909
-     */
910
-    protected function _price_types_overview_list_table()
911
-    {
912
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
913
-            'add_new_price_type',
914
-            'add_type',
915
-            [],
916
-            'add-new-h2'
917
-        );
918
-        $this->_admin_page_title .= $this->_learn_more_about_pricing_link();
919
-        $this->_search_btn_label = esc_html__('Price Types', 'event_espresso');
920
-        $this->display_admin_list_table_page_with_sidebar();
921
-    }
922
-
923
-
924
-    /**
925
-     * retrieve data for Price Types List table
926
-     *
927
-     * @param int  $per_page how many prices displayed per page
928
-     * @param bool $count    return the count or objects
929
-     * @param bool $trashed  whether the current view is of the trash can - eww yuck!
930
-     * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
931
-     * @throws EE_Error
932
-     * @throws ReflectionException
933
-     */
934
-    public function get_price_types_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
935
-    {
936
-        // start with an empty array
937
-        require_once(PRICING_ADMIN . 'Price_Types_List_Table.class.php');
938
-
939
-        $orderby = $this->request->getRequestParam('orderby', '');
940
-        $order   = $this->request->getRequestParam('order', 'ASC');
941
-
942
-        switch ($orderby) {
943
-            case 'name':
944
-                $orderby = ['PRT_name' => $order];
945
-                break;
946
-            default:
947
-                $orderby = ['PRT_order' => $order];
948
-        }
949
-
950
-        $current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
951
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
952
-
953
-        $offset = ($current_page - 1) * $per_page;
954
-        $limit  = [$offset, $per_page];
955
-
956
-        $where = ['PRT_deleted' => $trashed, 'PBT_ID' => ['!=', 1]];
957
-
958
-        $search_term = $this->request->getRequestParam('s');
959
-        if ($search_term) {
960
-            $where['OR'] = [
961
-                'PRT_name' => ['LIKE', "%{$search_term}%"],
962
-            ];
963
-        }
964
-        $query_params = [
965
-            $where,
966
-            'order_by' => $orderby,
967
-            'limit'    => $limit,
968
-        ];
969
-        return $count
970
-            ? EEM_Price_Type::instance()->count_deleted_and_undeleted($query_params)
971
-            : EEM_Price_Type::instance()->get_all_deleted_and_undeleted($query_params);
972
-    }
973
-
974
-
975
-    /**
976
-     * _edit_price_type_details
977
-     *
978
-     * @return void
979
-     * @throws EE_Error
980
-     * @throws ReflectionException
981
-     */
982
-    protected function _edit_price_type_details()
983
-    {
984
-        // grab price type ID
985
-        $PRT_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
986
-        // change page title based on request action
987
-        switch ($this->_req_action) {
988
-            case 'add_new_price_type':
989
-                $this->_admin_page_title = esc_html__('Add New Price Type', 'event_espresso');
990
-                break;
991
-            case 'edit_price_type':
992
-                $this->_admin_page_title = esc_html__('Edit Price Type', 'event_espresso');
993
-                break;
994
-            default:
995
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
996
-        }
997
-        // add PRT_ID to title if editing
998
-        $this->_admin_page_title = $PRT_ID ? $this->_admin_page_title . ' # ' . $PRT_ID : $this->_admin_page_title;
999
-
1000
-        if ($PRT_ID) {
1001
-            $price_type               = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
1002
-            $additional_hidden_fields = ['PRT_ID' => ['type' => 'hidden', 'value' => $PRT_ID]];
1003
-            $this->_set_add_edit_form_tags('update_price_type', $additional_hidden_fields);
1004
-        } else {
1005
-            $price_type = EEM_Price_Type::instance()->get_new_price_type();
1006
-            $this->_set_add_edit_form_tags('insert_price_type');
1007
-        }
1008
-
1009
-        if (! $price_type instanceof EE_Price_Type) {
1010
-            throw new RuntimeException(
1011
-                sprintf(
1012
-                    esc_html__(
1013
-                        'A valid Price Type could not be retrieved from the database with ID: %1$s',
1014
-                        'event_espresso'
1015
-                    ),
1016
-                    $PRT_ID
1017
-                )
1018
-            );
1019
-        }
1020
-
1021
-        $this->_template_args['PRT_ID']     = $PRT_ID;
1022
-        $this->_template_args['price_type'] = $price_type;
1023
-
1024
-        $base_types    = EEM_Price_Type::instance()->get_base_types();
1025
-        $select_values = [];
1026
-        foreach ($base_types as $ref => $text) {
1027
-            if ($ref == EEM_Price_Type::base_type_base_price) {
1028
-                // do not allow creation of base_type_base_prices because that's a system only base type.
1029
-                continue;
1030
-            }
1031
-            $select_values[] = ['id' => $ref, 'text' => $text];
1032
-        }
1033
-
1034
-        $this->_template_args['base_type_select'] = EEH_Form_Fields::select_input(
1035
-            'base_type',
1036
-            $select_values,
1037
-            $price_type->base_type(),
1038
-            'id="price-type-base-type-slct"'
1039
-        );
1040
-
1041
-        $this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
1042
-        $this->_template_args['admin_page_content']            = $this->_edit_price_type_details_meta_box();
1043
-
1044
-        $redirect_URL = add_query_arg(['action' => 'price_types'], $this->_admin_base_url);
1045
-        $this->_set_publish_post_box_vars('id', $PRT_ID, false, $redirect_URL, true);
1046
-        // the details template wrapper
1047
-        $this->display_admin_page_with_sidebar();
1048
-    }
1049
-
1050
-
1051
-    /**
1052
-     * _edit_price_type_details_meta_box
1053
-     *
1054
-     * @return string
1055
-     */
1056
-    public function _edit_price_type_details_meta_box(): string
1057
-    {
1058
-        return EEH_Template::display_template(
1059
-            PRICING_TEMPLATE_PATH . 'pricing_type_details_main_meta_box.template.php',
1060
-            $this->_template_args,
1061
-            true
1062
-        );
1063
-    }
1064
-
1065
-
1066
-    /**
1067
-     * @return array
1068
-     */
1069
-    protected function set_price_type_column_values(): array
1070
-    {
1071
-        $base_type  = $this->request->getRequestParam(
1072
-            'base_type',
1073
-            EEM_Price_Type::base_type_base_price,
1074
-            DataType::INTEGER
1075
-        );
1076
-        $is_percent = $this->request->getRequestParam('PRT_is_percent', 0, DataType::INTEGER);
1077
-        $order      = $this->request->getRequestParam('PRT_order', 0, DataType::INTEGER);
1078
-        switch ($base_type) {
1079
-            case EEM_Price_Type::base_type_base_price:
1080
-                $is_percent = 0;
1081
-                $order      = 0;
1082
-                break;
1083
-
1084
-            case EEM_Price_Type::base_type_discount:
1085
-            case EEM_Price_Type::base_type_surcharge:
1086
-                break;
1087
-
1088
-            case EEM_Price_Type::base_type_tax:
1089
-                $is_percent = 1;
1090
-                break;
1091
-        }
1092
-
1093
-        return [
1094
-            'PBT_ID'         => $base_type,
1095
-            'PRT_name'       => $this->request->getRequestParam('PRT_name', ''),
1096
-            'PRT_is_percent' => $is_percent,
1097
-            'PRT_order'      => $order,
1098
-            'PRT_deleted'    => 0,
1099
-        ];
1100
-    }
1101
-
1102
-
1103
-    /**
1104
-     * @param bool $new_price_type - whether to insert or update
1105
-     * @return void
1106
-     * @throws EE_Error
1107
-     * @throws ReflectionException
1108
-     */
1109
-    protected function _insert_or_update_price_type(bool $new_price_type = false)
1110
-    {
1111
-        // why be so pessimistic ???  : (
1112
-        $success = 0;
1113
-
1114
-        $set_column_values = $this->set_price_type_column_values();
1115
-        // is this a new Price ?
1116
-        if ($new_price_type) {
1117
-            // run the insert
1118
-            if ($PRT_ID = EEM_Price_Type::instance()->insert($set_column_values)) {
1119
-                $success = 1;
1120
-            }
1121
-            $action_desc = 'created';
1122
-        } else {
1123
-            $PRT_ID = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
1124
-            // run the update
1125
-            $where_cols_n_values = ['PRT_ID' => $PRT_ID];
1126
-            if (EEM_Price_Type::instance()->update($set_column_values, [$where_cols_n_values])) {
1127
-                $success = 1;
1128
-            }
1129
-            $action_desc = 'updated';
1130
-        }
1131
-
1132
-        $query_args = ['action' => 'edit_price_type', 'id' => $PRT_ID];
1133
-        $this->_redirect_after_action($success, 'Price Type', $action_desc, $query_args);
1134
-    }
1135
-
1136
-
1137
-    /**
1138
-     * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
1139
-     * @return void
1140
-     * @throws EE_Error
1141
-     * @throws ReflectionException
1142
-     */
1143
-    protected function _trash_or_restore_price_type(bool $trash = true)
1144
-    {
1145
-        $entity_model = EEM_Price_Type::instance();
1146
-        $action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
1147
-        $success      = $this->trashRestoreDeleteEntities($entity_model, 'id', $action, 'PRT_deleted');
1148
-        if ($success) {
1149
-            $msg = $trash
1150
-                ? esc_html(
1151
-                    _n(
1152
-                        'The Price Type has been trashed',
1153
-                        'The Price Types have been trashed',
1154
-                        $success,
1155
-                        'event_espresso'
1156
-                    )
1157
-                )
1158
-                : esc_html(
1159
-                    _n(
1160
-                        'The Price Type has been restored',
1161
-                        'The Price Types have been restored',
1162
-                        $success,
1163
-                        'event_espresso'
1164
-                    )
1165
-                );
1166
-            EE_Error::add_success($msg);
1167
-        }
1168
-        $this->_redirect_after_action('', '', '', ['action' => 'price_types'], true);
1169
-    }
1170
-
1171
-
1172
-    /**
1173
-     * @return void
1174
-     * @throws EE_Error
1175
-     * @throws ReflectionException
1176
-     */
1177
-    protected function _delete_price_type()
1178
-    {
1179
-        $entity_model = EEM_Price_Type::instance();
1180
-        $deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
1181
-        $this->_redirect_after_action(
1182
-            $deleted,
1183
-            $entity_model->item_name($deleted),
1184
-            'deleted',
1185
-            ['action' => 'price_types']
1186
-        );
1187
-    }
1188
-
1189
-
1190
-    /**
1191
-     * @return string
1192
-     */
1193
-    protected function _learn_more_about_pricing_link(): string
1194
-    {
1195
-        return '
904
+	/**
905
+	 * generates HTML for main Prices Admin page
906
+	 *
907
+	 * @return void
908
+	 * @throws EE_Error
909
+	 */
910
+	protected function _price_types_overview_list_table()
911
+	{
912
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
913
+			'add_new_price_type',
914
+			'add_type',
915
+			[],
916
+			'add-new-h2'
917
+		);
918
+		$this->_admin_page_title .= $this->_learn_more_about_pricing_link();
919
+		$this->_search_btn_label = esc_html__('Price Types', 'event_espresso');
920
+		$this->display_admin_list_table_page_with_sidebar();
921
+	}
922
+
923
+
924
+	/**
925
+	 * retrieve data for Price Types List table
926
+	 *
927
+	 * @param int  $per_page how many prices displayed per page
928
+	 * @param bool $count    return the count or objects
929
+	 * @param bool $trashed  whether the current view is of the trash can - eww yuck!
930
+	 * @return EE_Soft_Delete_Base_Class[]|int int = count || array of price objects
931
+	 * @throws EE_Error
932
+	 * @throws ReflectionException
933
+	 */
934
+	public function get_price_types_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
935
+	{
936
+		// start with an empty array
937
+		require_once(PRICING_ADMIN . 'Price_Types_List_Table.class.php');
938
+
939
+		$orderby = $this->request->getRequestParam('orderby', '');
940
+		$order   = $this->request->getRequestParam('order', 'ASC');
941
+
942
+		switch ($orderby) {
943
+			case 'name':
944
+				$orderby = ['PRT_name' => $order];
945
+				break;
946
+			default:
947
+				$orderby = ['PRT_order' => $order];
948
+		}
949
+
950
+		$current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
951
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
952
+
953
+		$offset = ($current_page - 1) * $per_page;
954
+		$limit  = [$offset, $per_page];
955
+
956
+		$where = ['PRT_deleted' => $trashed, 'PBT_ID' => ['!=', 1]];
957
+
958
+		$search_term = $this->request->getRequestParam('s');
959
+		if ($search_term) {
960
+			$where['OR'] = [
961
+				'PRT_name' => ['LIKE', "%{$search_term}%"],
962
+			];
963
+		}
964
+		$query_params = [
965
+			$where,
966
+			'order_by' => $orderby,
967
+			'limit'    => $limit,
968
+		];
969
+		return $count
970
+			? EEM_Price_Type::instance()->count_deleted_and_undeleted($query_params)
971
+			: EEM_Price_Type::instance()->get_all_deleted_and_undeleted($query_params);
972
+	}
973
+
974
+
975
+	/**
976
+	 * _edit_price_type_details
977
+	 *
978
+	 * @return void
979
+	 * @throws EE_Error
980
+	 * @throws ReflectionException
981
+	 */
982
+	protected function _edit_price_type_details()
983
+	{
984
+		// grab price type ID
985
+		$PRT_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
986
+		// change page title based on request action
987
+		switch ($this->_req_action) {
988
+			case 'add_new_price_type':
989
+				$this->_admin_page_title = esc_html__('Add New Price Type', 'event_espresso');
990
+				break;
991
+			case 'edit_price_type':
992
+				$this->_admin_page_title = esc_html__('Edit Price Type', 'event_espresso');
993
+				break;
994
+			default:
995
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
996
+		}
997
+		// add PRT_ID to title if editing
998
+		$this->_admin_page_title = $PRT_ID ? $this->_admin_page_title . ' # ' . $PRT_ID : $this->_admin_page_title;
999
+
1000
+		if ($PRT_ID) {
1001
+			$price_type               = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
1002
+			$additional_hidden_fields = ['PRT_ID' => ['type' => 'hidden', 'value' => $PRT_ID]];
1003
+			$this->_set_add_edit_form_tags('update_price_type', $additional_hidden_fields);
1004
+		} else {
1005
+			$price_type = EEM_Price_Type::instance()->get_new_price_type();
1006
+			$this->_set_add_edit_form_tags('insert_price_type');
1007
+		}
1008
+
1009
+		if (! $price_type instanceof EE_Price_Type) {
1010
+			throw new RuntimeException(
1011
+				sprintf(
1012
+					esc_html__(
1013
+						'A valid Price Type could not be retrieved from the database with ID: %1$s',
1014
+						'event_espresso'
1015
+					),
1016
+					$PRT_ID
1017
+				)
1018
+			);
1019
+		}
1020
+
1021
+		$this->_template_args['PRT_ID']     = $PRT_ID;
1022
+		$this->_template_args['price_type'] = $price_type;
1023
+
1024
+		$base_types    = EEM_Price_Type::instance()->get_base_types();
1025
+		$select_values = [];
1026
+		foreach ($base_types as $ref => $text) {
1027
+			if ($ref == EEM_Price_Type::base_type_base_price) {
1028
+				// do not allow creation of base_type_base_prices because that's a system only base type.
1029
+				continue;
1030
+			}
1031
+			$select_values[] = ['id' => $ref, 'text' => $text];
1032
+		}
1033
+
1034
+		$this->_template_args['base_type_select'] = EEH_Form_Fields::select_input(
1035
+			'base_type',
1036
+			$select_values,
1037
+			$price_type->base_type(),
1038
+			'id="price-type-base-type-slct"'
1039
+		);
1040
+
1041
+		$this->_template_args['learn_more_about_pricing_link'] = $this->_learn_more_about_pricing_link();
1042
+		$this->_template_args['admin_page_content']            = $this->_edit_price_type_details_meta_box();
1043
+
1044
+		$redirect_URL = add_query_arg(['action' => 'price_types'], $this->_admin_base_url);
1045
+		$this->_set_publish_post_box_vars('id', $PRT_ID, false, $redirect_URL, true);
1046
+		// the details template wrapper
1047
+		$this->display_admin_page_with_sidebar();
1048
+	}
1049
+
1050
+
1051
+	/**
1052
+	 * _edit_price_type_details_meta_box
1053
+	 *
1054
+	 * @return string
1055
+	 */
1056
+	public function _edit_price_type_details_meta_box(): string
1057
+	{
1058
+		return EEH_Template::display_template(
1059
+			PRICING_TEMPLATE_PATH . 'pricing_type_details_main_meta_box.template.php',
1060
+			$this->_template_args,
1061
+			true
1062
+		);
1063
+	}
1064
+
1065
+
1066
+	/**
1067
+	 * @return array
1068
+	 */
1069
+	protected function set_price_type_column_values(): array
1070
+	{
1071
+		$base_type  = $this->request->getRequestParam(
1072
+			'base_type',
1073
+			EEM_Price_Type::base_type_base_price,
1074
+			DataType::INTEGER
1075
+		);
1076
+		$is_percent = $this->request->getRequestParam('PRT_is_percent', 0, DataType::INTEGER);
1077
+		$order      = $this->request->getRequestParam('PRT_order', 0, DataType::INTEGER);
1078
+		switch ($base_type) {
1079
+			case EEM_Price_Type::base_type_base_price:
1080
+				$is_percent = 0;
1081
+				$order      = 0;
1082
+				break;
1083
+
1084
+			case EEM_Price_Type::base_type_discount:
1085
+			case EEM_Price_Type::base_type_surcharge:
1086
+				break;
1087
+
1088
+			case EEM_Price_Type::base_type_tax:
1089
+				$is_percent = 1;
1090
+				break;
1091
+		}
1092
+
1093
+		return [
1094
+			'PBT_ID'         => $base_type,
1095
+			'PRT_name'       => $this->request->getRequestParam('PRT_name', ''),
1096
+			'PRT_is_percent' => $is_percent,
1097
+			'PRT_order'      => $order,
1098
+			'PRT_deleted'    => 0,
1099
+		];
1100
+	}
1101
+
1102
+
1103
+	/**
1104
+	 * @param bool $new_price_type - whether to insert or update
1105
+	 * @return void
1106
+	 * @throws EE_Error
1107
+	 * @throws ReflectionException
1108
+	 */
1109
+	protected function _insert_or_update_price_type(bool $new_price_type = false)
1110
+	{
1111
+		// why be so pessimistic ???  : (
1112
+		$success = 0;
1113
+
1114
+		$set_column_values = $this->set_price_type_column_values();
1115
+		// is this a new Price ?
1116
+		if ($new_price_type) {
1117
+			// run the insert
1118
+			if ($PRT_ID = EEM_Price_Type::instance()->insert($set_column_values)) {
1119
+				$success = 1;
1120
+			}
1121
+			$action_desc = 'created';
1122
+		} else {
1123
+			$PRT_ID = $this->request->getRequestParam('PRT_ID', 0, DataType::INTEGER);
1124
+			// run the update
1125
+			$where_cols_n_values = ['PRT_ID' => $PRT_ID];
1126
+			if (EEM_Price_Type::instance()->update($set_column_values, [$where_cols_n_values])) {
1127
+				$success = 1;
1128
+			}
1129
+			$action_desc = 'updated';
1130
+		}
1131
+
1132
+		$query_args = ['action' => 'edit_price_type', 'id' => $PRT_ID];
1133
+		$this->_redirect_after_action($success, 'Price Type', $action_desc, $query_args);
1134
+	}
1135
+
1136
+
1137
+	/**
1138
+	 * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
1139
+	 * @return void
1140
+	 * @throws EE_Error
1141
+	 * @throws ReflectionException
1142
+	 */
1143
+	protected function _trash_or_restore_price_type(bool $trash = true)
1144
+	{
1145
+		$entity_model = EEM_Price_Type::instance();
1146
+		$action       = $trash ? EE_Admin_List_Table::ACTION_TRASH : EE_Admin_List_Table::ACTION_RESTORE;
1147
+		$success      = $this->trashRestoreDeleteEntities($entity_model, 'id', $action, 'PRT_deleted');
1148
+		if ($success) {
1149
+			$msg = $trash
1150
+				? esc_html(
1151
+					_n(
1152
+						'The Price Type has been trashed',
1153
+						'The Price Types have been trashed',
1154
+						$success,
1155
+						'event_espresso'
1156
+					)
1157
+				)
1158
+				: esc_html(
1159
+					_n(
1160
+						'The Price Type has been restored',
1161
+						'The Price Types have been restored',
1162
+						$success,
1163
+						'event_espresso'
1164
+					)
1165
+				);
1166
+			EE_Error::add_success($msg);
1167
+		}
1168
+		$this->_redirect_after_action('', '', '', ['action' => 'price_types'], true);
1169
+	}
1170
+
1171
+
1172
+	/**
1173
+	 * @return void
1174
+	 * @throws EE_Error
1175
+	 * @throws ReflectionException
1176
+	 */
1177
+	protected function _delete_price_type()
1178
+	{
1179
+		$entity_model = EEM_Price_Type::instance();
1180
+		$deleted      = $this->trashRestoreDeleteEntities($entity_model, 'id');
1181
+		$this->_redirect_after_action(
1182
+			$deleted,
1183
+			$entity_model->item_name($deleted),
1184
+			'deleted',
1185
+			['action' => 'price_types']
1186
+		);
1187
+	}
1188
+
1189
+
1190
+	/**
1191
+	 * @return string
1192
+	 */
1193
+	protected function _learn_more_about_pricing_link(): string
1194
+	{
1195
+		return '
1196 1196
             <a
1197 1197
                 href="https://eventespresso.com/2019/08/how-to-leverage-pricing-and-packaging-to-sell-out-your-next-event/"
1198 1198
                 target="_blank"
@@ -1200,119 +1200,119 @@  discard block
 block discarded – undo
1200 1200
             >
1201 1201
                 ' . esc_html__('learn more about how pricing works', 'event_espresso') . '
1202 1202
             </a>';
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * @throws EE_Error
1208
-     */
1209
-    protected function _tax_settings()
1210
-    {
1211
-        $this->_set_add_edit_form_tags('update_tax_settings');
1212
-        $this->_set_publish_post_box_vars();
1213
-        $this->_template_args['admin_page_content'] = $this->tax_settings_form()->get_html();
1214
-        $this->display_admin_page_with_sidebar();
1215
-    }
1216
-
1217
-
1218
-    /**
1219
-     * @return EE_Form_Section_Proper
1220
-     * @throws EE_Error
1221
-     */
1222
-    protected function tax_settings_form(): EE_Form_Section_Proper
1223
-    {
1224
-        $tax_settings = EE_Config::instance()->tax_settings;
1225
-        return new EE_Form_Section_Proper(
1226
-            [
1227
-                'name'            => 'tax_settings_form',
1228
-                'html_id'         => 'tax_settings_form',
1229
-                'html_class'      => 'padding',
1230
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1231
-                'subsections'     => apply_filters(
1232
-                    'FHEE__Pricing_Admin_Page__tax_settings_form__form_subsections',
1233
-                    [
1234
-                        'tax_settings' => new EE_Form_Section_Proper(
1235
-                            [
1236
-                                'name'            => 'tax_settings_tbl',
1237
-                                'html_id'         => 'tax_settings_tbl',
1238
-                                'html_class'      => 'form-table',
1239
-                                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1240
-                                'subsections'     => [
1241
-                                    'prices_displayed_including_taxes' => new EE_Yes_No_Input(
1242
-                                        [
1243
-                                            'html_label_text'         => esc_html__(
1244
-                                                'Show Prices With Taxes Included?',
1245
-                                                'event_espresso'
1246
-                                            ),
1247
-                                            'html_help_text'          => esc_html__(
1248
-                                                'Indicates whether or not to display prices with the taxes included',
1249
-                                                'event_espresso'
1250
-                                            ),
1251
-                                            'default'                 => $tax_settings->prices_displayed_including_taxes
1252
-                                                                         ?? true,
1253
-                                            'display_html_label_text' => false,
1254
-                                        ]
1255
-                                    ),
1256
-                                ],
1257
-                            ]
1258
-                        ),
1259
-                    ]
1260
-                ),
1261
-            ]
1262
-        );
1263
-    }
1264
-
1265
-
1266
-    /**
1267
-     * _update_tax_settings
1268
-     *
1269
-     * @return void
1270
-     * @throws EE_Error
1271
-     * @throws ReflectionException
1272
-     * @since 4.9.13
1273
-     */
1274
-    public function _update_tax_settings()
1275
-    {
1276
-        $tax_settings = EE_Config::instance()->tax_settings;
1277
-        if (! $tax_settings instanceof EE_Tax_Config) {
1278
-            $tax_settings = new EE_Tax_Config();
1279
-        }
1280
-        try {
1281
-            $tax_form = $this->tax_settings_form();
1282
-            // check for form submission
1283
-            if ($tax_form->was_submitted()) {
1284
-                // capture form data
1285
-                $tax_form->receive_form_submission();
1286
-                // validate form data
1287
-                if ($tax_form->is_valid()) {
1288
-                    // grab validated data from form
1289
-                    $valid_data = $tax_form->valid_data();
1290
-                    // set data on config
1291
-                    $tax_settings->prices_displayed_including_taxes =
1292
-                        $valid_data['tax_settings']['prices_displayed_including_taxes'];
1293
-                } else {
1294
-                    if ($tax_form->submission_error_message() !== '') {
1295
-                        EE_Error::add_error(
1296
-                            $tax_form->submission_error_message(),
1297
-                            __FILE__,
1298
-                            __FUNCTION__,
1299
-                            __LINE__
1300
-                        );
1301
-                    }
1302
-                }
1303
-            }
1304
-        } catch (EE_Error $e) {
1305
-            EE_Error::add_error($e->get_error(), __FILE__, __FUNCTION__, __LINE__);
1306
-        }
1307
-
1308
-        $what    = 'Tax Settings';
1309
-        $success = $this->_update_espresso_configuration(
1310
-            $what,
1311
-            $tax_settings,
1312
-            __FILE__,
1313
-            __FUNCTION__,
1314
-            __LINE__
1315
-        );
1316
-        $this->_redirect_after_action($success, $what, 'updated', ['action' => 'tax_settings']);
1317
-    }
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * @throws EE_Error
1208
+	 */
1209
+	protected function _tax_settings()
1210
+	{
1211
+		$this->_set_add_edit_form_tags('update_tax_settings');
1212
+		$this->_set_publish_post_box_vars();
1213
+		$this->_template_args['admin_page_content'] = $this->tax_settings_form()->get_html();
1214
+		$this->display_admin_page_with_sidebar();
1215
+	}
1216
+
1217
+
1218
+	/**
1219
+	 * @return EE_Form_Section_Proper
1220
+	 * @throws EE_Error
1221
+	 */
1222
+	protected function tax_settings_form(): EE_Form_Section_Proper
1223
+	{
1224
+		$tax_settings = EE_Config::instance()->tax_settings;
1225
+		return new EE_Form_Section_Proper(
1226
+			[
1227
+				'name'            => 'tax_settings_form',
1228
+				'html_id'         => 'tax_settings_form',
1229
+				'html_class'      => 'padding',
1230
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1231
+				'subsections'     => apply_filters(
1232
+					'FHEE__Pricing_Admin_Page__tax_settings_form__form_subsections',
1233
+					[
1234
+						'tax_settings' => new EE_Form_Section_Proper(
1235
+							[
1236
+								'name'            => 'tax_settings_tbl',
1237
+								'html_id'         => 'tax_settings_tbl',
1238
+								'html_class'      => 'form-table',
1239
+								'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1240
+								'subsections'     => [
1241
+									'prices_displayed_including_taxes' => new EE_Yes_No_Input(
1242
+										[
1243
+											'html_label_text'         => esc_html__(
1244
+												'Show Prices With Taxes Included?',
1245
+												'event_espresso'
1246
+											),
1247
+											'html_help_text'          => esc_html__(
1248
+												'Indicates whether or not to display prices with the taxes included',
1249
+												'event_espresso'
1250
+											),
1251
+											'default'                 => $tax_settings->prices_displayed_including_taxes
1252
+																		 ?? true,
1253
+											'display_html_label_text' => false,
1254
+										]
1255
+									),
1256
+								],
1257
+							]
1258
+						),
1259
+					]
1260
+				),
1261
+			]
1262
+		);
1263
+	}
1264
+
1265
+
1266
+	/**
1267
+	 * _update_tax_settings
1268
+	 *
1269
+	 * @return void
1270
+	 * @throws EE_Error
1271
+	 * @throws ReflectionException
1272
+	 * @since 4.9.13
1273
+	 */
1274
+	public function _update_tax_settings()
1275
+	{
1276
+		$tax_settings = EE_Config::instance()->tax_settings;
1277
+		if (! $tax_settings instanceof EE_Tax_Config) {
1278
+			$tax_settings = new EE_Tax_Config();
1279
+		}
1280
+		try {
1281
+			$tax_form = $this->tax_settings_form();
1282
+			// check for form submission
1283
+			if ($tax_form->was_submitted()) {
1284
+				// capture form data
1285
+				$tax_form->receive_form_submission();
1286
+				// validate form data
1287
+				if ($tax_form->is_valid()) {
1288
+					// grab validated data from form
1289
+					$valid_data = $tax_form->valid_data();
1290
+					// set data on config
1291
+					$tax_settings->prices_displayed_including_taxes =
1292
+						$valid_data['tax_settings']['prices_displayed_including_taxes'];
1293
+				} else {
1294
+					if ($tax_form->submission_error_message() !== '') {
1295
+						EE_Error::add_error(
1296
+							$tax_form->submission_error_message(),
1297
+							__FILE__,
1298
+							__FUNCTION__,
1299
+							__LINE__
1300
+						);
1301
+					}
1302
+				}
1303
+			}
1304
+		} catch (EE_Error $e) {
1305
+			EE_Error::add_error($e->get_error(), __FILE__, __FUNCTION__, __LINE__);
1306
+		}
1307
+
1308
+		$what    = 'Tax Settings';
1309
+		$success = $this->_update_espresso_configuration(
1310
+			$what,
1311
+			$tax_settings,
1312
+			__FILE__,
1313
+			__FUNCTION__,
1314
+			__LINE__
1315
+		);
1316
+		$this->_redirect_after_action($success, $what, 'updated', ['action' => 'tax_settings']);
1317
+	}
1318 1318
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -23,7 +23,7 @@  discard block
 block discarded – undo
23 23
 
24 24
     protected function _ajax_hooks()
25 25
     {
26
-        if (! $this->capabilities->current_user_can('ee_edit_default_prices', 'update-price-order')) {
26
+        if ( ! $this->capabilities->current_user_can('ee_edit_default_prices', 'update-price-order')) {
27 27
             return;
28 28
         }
29 29
         add_action('wp_ajax_espresso_update_prices_order', [$this, 'update_price_order']);
@@ -355,7 +355,7 @@  discard block
 block discarded – undo
355 355
         wp_enqueue_style('espresso-ui-theme');
356 356
         wp_register_style(
357 357
             'espresso_pricing_css',
358
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.css',
358
+            PRICING_ASSETS_URL.'espresso_pricing_admin.css',
359 359
             [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
360 360
             EVENT_ESPRESSO_VERSION
361 361
         );
@@ -367,7 +367,7 @@  discard block
 block discarded – undo
367 367
         wp_enqueue_script('jquery-ui-widget');
368 368
         wp_register_script(
369 369
             'espresso_pricing_js',
370
-            PRICING_ASSETS_URL . 'espresso_pricing_admin.js',
370
+            PRICING_ASSETS_URL.'espresso_pricing_admin.js',
371 371
             ['jquery'],
372 372
             EVENT_ESPRESSO_VERSION,
373 373
             true
@@ -464,7 +464,7 @@  discard block
 block discarded – undo
464 464
      */
465 465
     protected function _price_overview_list_table()
466 466
     {
467
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
467
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
468 468
             'add_new_price',
469 469
             'add',
470 470
             [],
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
         // start with an empty array
492 492
         $event_pricing = [];
493 493
 
494
-        require_once(PRICING_ADMIN . 'Prices_List_Table.class.php');
494
+        require_once(PRICING_ADMIN.'Prices_List_Table.class.php');
495 495
 
496 496
         $orderby = $this->request->getRequestParam('orderby', '');
497 497
         $order   = $this->request->getRequestParam('order', 'ASC');
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
                 $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
570 570
         }
571 571
         // add PRC_ID to title if editing
572
-        $this->_admin_page_title = $PRC_ID ? $this->_admin_page_title . ' # ' . $PRC_ID : $this->_admin_page_title;
572
+        $this->_admin_page_title = $PRC_ID ? $this->_admin_page_title.' # '.$PRC_ID : $this->_admin_page_title;
573 573
 
574 574
         if ($PRC_ID) {
575 575
             $price                    = EEM_Price::instance()->get_one_by_ID($PRC_ID);
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
             $this->_set_add_edit_form_tags('insert_price');
583 583
         }
584 584
 
585
-        if (! $price instanceof EE_Price) {
585
+        if ( ! $price instanceof EE_Price) {
586 586
             throw new RuntimeException(
587 587
                 sprintf(
588 588
                     esc_html__(
@@ -640,7 +640,7 @@  discard block
 block discarded – undo
640 640
     public function _edit_price_details_meta_box(): string
641 641
     {
642 642
         return EEH_Template::display_template(
643
-            PRICING_TEMPLATE_PATH . 'pricing_details_main_meta_box.template.php',
643
+            PRICING_TEMPLATE_PATH.'pricing_details_main_meta_box.template.php',
644 644
             $this->_template_args,
645 645
             true
646 646
         );
@@ -811,19 +811,19 @@  discard block
 block discarded – undo
811 811
         string $action,
812 812
         int $result
813 813
     ) {
814
-        if (! $entity_ID || (float) $result < 1) {
814
+        if ( ! $entity_ID || (float) $result < 1) {
815 815
             return;
816 816
         }
817 817
 
818 818
         $entity = $entity_model->get_one_by_ID($entity_ID);
819
-        if (! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
819
+        if ( ! $entity instanceof EE_Price || $entity->type_obj()->base_type() === EEM_Price_Type::base_type_tax) {
820 820
             return;
821 821
         }
822 822
 
823 823
         // get default tickets for updating
824 824
         $default_tickets = EEM_Ticket::instance()->get_all_default_tickets();
825 825
         foreach ($default_tickets as $default_ticket) {
826
-            if (! $default_ticket instanceof EE_Ticket) {
826
+            if ( ! $default_ticket instanceof EE_Ticket) {
827 827
                 continue;
828 828
             }
829 829
             switch ($action) {
@@ -867,7 +867,7 @@  discard block
 block discarded – undo
867 867
      */
868 868
     public function update_price_order()
869 869
     {
870
-        if (! $this->capabilities->current_user_can('ee_edit_default_prices', __FUNCTION__)) {
870
+        if ( ! $this->capabilities->current_user_can('ee_edit_default_prices', __FUNCTION__)) {
871 871
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
872 872
         }
873 873
         // grab our row IDs
@@ -909,7 +909,7 @@  discard block
 block discarded – undo
909 909
      */
910 910
     protected function _price_types_overview_list_table()
911 911
     {
912
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
912
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
913 913
             'add_new_price_type',
914 914
             'add_type',
915 915
             [],
@@ -934,7 +934,7 @@  discard block
 block discarded – undo
934 934
     public function get_price_types_overview_data(int $per_page = 10, bool $count = false, bool $trashed = false)
935 935
     {
936 936
         // start with an empty array
937
-        require_once(PRICING_ADMIN . 'Price_Types_List_Table.class.php');
937
+        require_once(PRICING_ADMIN.'Price_Types_List_Table.class.php');
938 938
 
939 939
         $orderby = $this->request->getRequestParam('orderby', '');
940 940
         $order   = $this->request->getRequestParam('order', 'ASC');
@@ -995,7 +995,7 @@  discard block
 block discarded – undo
995 995
                 $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
996 996
         }
997 997
         // add PRT_ID to title if editing
998
-        $this->_admin_page_title = $PRT_ID ? $this->_admin_page_title . ' # ' . $PRT_ID : $this->_admin_page_title;
998
+        $this->_admin_page_title = $PRT_ID ? $this->_admin_page_title.' # '.$PRT_ID : $this->_admin_page_title;
999 999
 
1000 1000
         if ($PRT_ID) {
1001 1001
             $price_type               = EEM_Price_Type::instance()->get_one_by_ID($PRT_ID);
@@ -1006,7 +1006,7 @@  discard block
 block discarded – undo
1006 1006
             $this->_set_add_edit_form_tags('insert_price_type');
1007 1007
         }
1008 1008
 
1009
-        if (! $price_type instanceof EE_Price_Type) {
1009
+        if ( ! $price_type instanceof EE_Price_Type) {
1010 1010
             throw new RuntimeException(
1011 1011
                 sprintf(
1012 1012
                     esc_html__(
@@ -1056,7 +1056,7 @@  discard block
 block discarded – undo
1056 1056
     public function _edit_price_type_details_meta_box(): string
1057 1057
     {
1058 1058
         return EEH_Template::display_template(
1059
-            PRICING_TEMPLATE_PATH . 'pricing_type_details_main_meta_box.template.php',
1059
+            PRICING_TEMPLATE_PATH.'pricing_type_details_main_meta_box.template.php',
1060 1060
             $this->_template_args,
1061 1061
             true
1062 1062
         );
@@ -1068,7 +1068,7 @@  discard block
 block discarded – undo
1068 1068
      */
1069 1069
     protected function set_price_type_column_values(): array
1070 1070
     {
1071
-        $base_type  = $this->request->getRequestParam(
1071
+        $base_type = $this->request->getRequestParam(
1072 1072
             'base_type',
1073 1073
             EEM_Price_Type::base_type_base_price,
1074 1074
             DataType::INTEGER
@@ -1198,7 +1198,7 @@  discard block
 block discarded – undo
1198 1198
                 target="_blank"
1199 1199
                 class="ee-price-guide-link"
1200 1200
             >
1201
-                ' . esc_html__('learn more about how pricing works', 'event_espresso') . '
1201
+                ' . esc_html__('learn more about how pricing works', 'event_espresso').'
1202 1202
             </a>';
1203 1203
     }
1204 1204
 
@@ -1274,7 +1274,7 @@  discard block
 block discarded – undo
1274 1274
     public function _update_tax_settings()
1275 1275
     {
1276 1276
         $tax_settings = EE_Config::instance()->tax_settings;
1277
-        if (! $tax_settings instanceof EE_Tax_Config) {
1277
+        if ( ! $tax_settings instanceof EE_Tax_Config) {
1278 1278
             $tax_settings = new EE_Tax_Config();
1279 1279
         }
1280 1280
         try {
Please login to merge, or discard this patch.
caffeinated/admin/new/license_keys/License_Keys_Admin_Page.core.php 2 patches
Indentation   +264 added lines, -264 removed lines patch added patch discarded remove patch
@@ -16,269 +16,269 @@
 block discarded – undo
16 16
  */
17 17
 class License_Keys_Admin_Page extends EE_Admin_Page
18 18
 {
19
-    protected function _init_page_props()
20
-    {
21
-        $this->page_slug        = LICENSE_KEYS_PG_SLUG;
22
-        $this->page_label       = LICENSE_KEYS_LABEL;
23
-        $this->_admin_base_url  = LICENSE_KEYS_ADMIN_URL;
24
-        $this->_admin_base_path = LICENSE_KEYS_ADMIN;
25
-    }
26
-
27
-
28
-    protected function _ajax_hooks()
29
-    {
30
-        if (! $this->capabilities->current_user_can('manage_options', 'update-license-key')) {
31
-            return;
32
-        }
33
-        add_action('wp_ajax_espresso_update_license', [$this, 'updateLicenseKey']);
34
-    }
35
-
36
-
37
-    protected function _define_page_props()
38
-    {
39
-        $this->_admin_page_title = LICENSE_KEYS_LABEL;
40
-    }
41
-
42
-
43
-    protected function _set_page_routes()
44
-    {
45
-        $this->_page_routes = [
46
-            'default'            => [
47
-                'func'       => [$this, 'licenseKeysAdminPage'],
48
-                'capability' => 'manage_options',
49
-            ],
50
-            'update_license_key' => [
51
-                'func'       => [$this, 'updateLicenseKey'],
52
-                'capability' => 'manage_options',
53
-                'noheader'   => true,
54
-            ],
55
-        ];
56
-    }
57
-
58
-
59
-    protected function _set_page_config()
60
-    {
61
-        $this->_page_config = [
62
-            'default' => [
63
-                'nav'           => [
64
-                    'label' => LICENSE_KEYS_LABEL,
65
-                    'icon'  => 'dashicons-admin-network',
66
-                    'order' => 10,
67
-                ],
68
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes),
69
-                'require_nonce' => false,
70
-            ],
71
-        ];
72
-    }
73
-
74
-
75
-    protected function _add_screen_options()
76
-    {
77
-        // TODO: Implement _add_screen_options() method.
78
-    }
79
-
80
-
81
-    protected function _add_feature_pointers()
82
-    {
83
-        // TODO: Implement _add_feature_pointers() method.
84
-    }
85
-
86
-
87
-    public function load_scripts_styles()
88
-    {
89
-        wp_enqueue_style(
90
-            'license_keys_admin_style',
91
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.css',
92
-            [],
93
-            EVENT_ESPRESSO_VERSION
94
-        );
95
-
96
-        wp_enqueue_script(
97
-            'license_keys_admin_js',
98
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.js',
99
-            ['jquery'],
100
-            EVENT_ESPRESSO_VERSION,
101
-            true
102
-        );
103
-        wp_localize_script(
104
-            'license_keys_admin_js',
105
-            'eeLicenseData',
106
-            [
107
-                'domain'              => home_url(),
108
-                'statusMessages'      => LicenseStatus::statusMessages(),
109
-                'confirmDeactivation' => esc_html__(
110
-                    'Are you sure you want to deactivate this license?',
111
-                    'event_espresso'
112
-                ),
113
-                'resetDeactivation'   => esc_html__(
114
-                    'Are you sure you want to reset this license?',
115
-                    'event_espresso'
116
-                ),
117
-            ]
118
-        );
119
-    }
120
-
121
-
122
-    public function admin_init()
123
-    {
124
-        // TODO: Implement admin_init() method.
125
-    }
126
-
127
-
128
-    public function admin_notices()
129
-    {
130
-        // TODO: Implement admin_notices() method.
131
-    }
132
-
133
-
134
-    public function admin_footer_scripts()
135
-    {
136
-        // TODO: Implement admin_footer_scripts() method.
137
-    }
138
-
139
-
140
-    public function _before_page_setup()
141
-    {
142
-        EE_Dependency_Map::instance()->registerDependencies(
143
-            LicenseManager::class,
144
-            [
145
-                LicenseAPI::class              => EE_Dependency_Map::load_from_cache,
146
-                LicenseKeyData::class          => EE_Dependency_Map::load_from_cache,
147
-                PluginLicenseCollection::class => EE_Dependency_Map::load_from_cache,
148
-            ]
149
-        );
150
-        EE_Dependency_Map::instance()->registerDependencies(
151
-            LicenseKeysAdminForm::class,
152
-            ['EE_Registry' => EE_Dependency_Map::load_from_cache]
153
-        );
154
-        parent::_before_page_setup();
155
-    }
156
-
157
-
158
-    private function getLicenseManager(): LicenseManager
159
-    {
160
-        return $this->loader->getShared(LicenseManager::class);
161
-    }
162
-
163
-
164
-    private function getPluginLicenseCollection(): PluginLicenseCollection
165
-    {
166
-        return $this->loader->getShared(PluginLicenseCollection::class);
167
-    }
168
-
169
-
170
-    /**
171
-     * @throws EE_Error
172
-     */
173
-    public function licenseKeysAdminPage()
174
-    {
175
-        $this->_template_args['admin_page_content'] = '';
176
-        try {
177
-            $license_keys_admin_form                    = $this->loader->getShared(LicenseKeysAdminForm::class);
178
-            $this->_template_args['admin_page_content'] = EEH_HTML::div(
179
-                $license_keys_admin_form->display(),
180
-                '',
181
-                'padding'
182
-            );
183
-        } catch (Exception $e) {
184
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
185
-        }
186
-        $this->_set_add_edit_form_tags('update_license_keys');
187
-        $this->_set_publish_post_box_vars();
188
-        $this->display_admin_page_with_sidebar();
189
-    }
190
-
191
-
192
-    /**
193
-     * @throws EE_Error
194
-     */
195
-    public function updateLicenseKey()
196
-    {
197
-        if ($this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
198
-            $licence_manager  = $this->getLicenseManager();
199
-            $license_action   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ACTION);
200
-            $license_key      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_LICENSE_KEY);
201
-            $item_id          = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_ID, 0, DataType::INT);
202
-            $item_name        = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_NAME);
203
-            $plugin_slug      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_SLUG);
204
-            $plugin_version   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_VER);
205
-            $min_core_version = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_MIN_CORE_VER);
206
-
207
-            $license_data = [];
208
-            switch ($license_action) {
209
-                case LicenseAPI::ACTION_ACTIVATE:
210
-                    $license_data = $licence_manager->activateLicense(
211
-                        $license_key,
212
-                        $item_id,
213
-                        $item_name,
214
-                        $plugin_slug,
215
-                        $plugin_version,
216
-                        $min_core_version
217
-                    );
218
-                    break;
219
-
220
-                case LicenseAPI::ACTION_DEACTIVATE:
221
-                    $license_data = $licence_manager->deactivateLicense(
222
-                        $license_key,
223
-                        $item_id,
224
-                        $item_name,
225
-                        $plugin_slug,
226
-                        $plugin_version,
227
-                        $min_core_version
228
-                    );
229
-                    break;
230
-
231
-                case LicenseAPI::ACTION_CHECK:
232
-                    $license_data = $licence_manager->checkLicense(
233
-                        $license_key,
234
-                        $item_id,
235
-                        $item_name,
236
-                        $plugin_slug,
237
-                        $plugin_version,
238
-                        $min_core_version
239
-                    );
240
-                    break;
241
-
242
-                case LicenseAPI::ACTION_GET_VERSION:
243
-                    $license_data = $licence_manager->getVersionInfo();
244
-                    break;
245
-
246
-                case LicenseAPI::ACTION_RESET:
247
-                    $license_data = $licence_manager->resetLicenseKey($plugin_slug);
248
-                    break;
249
-            }
250
-
251
-            $license_data = (object) $license_data;
252
-            $license_data->statusNotice = LicenseStatus::statusNotice($license_data->license);
253
-            $license_data->statusClass  = LicenseStatus::statusClass($license_data->license);
254
-            $notices = EE_Error::get_notices(false, false, false);
255
-        } else {
256
-            $license_data = new stdClass();
257
-            $notices = [
258
-                'success' => false,
259
-                'errors'  => [
260
-                    esc_html__('You do not have the required privileges to perform this action', 'event_espresso'),
261
-                ],
262
-            ];
263
-        }
264
-
265
-        if ($this->request->isAjax()) {
266
-            wp_send_json(
267
-                [
268
-                    'return_data' => $license_data,
269
-                    'success'     => $notices['success'],
270
-                    'errors'      => $notices['errors'],
271
-                ]
272
-            );
273
-        }
274
-
275
-        $this->_redirect_after_action(
276
-            empty($notices['errors']),
277
-            '',
278
-            '',
279
-            ['action' => 'default'],
280
-            true
281
-        );
282
-    }
19
+	protected function _init_page_props()
20
+	{
21
+		$this->page_slug        = LICENSE_KEYS_PG_SLUG;
22
+		$this->page_label       = LICENSE_KEYS_LABEL;
23
+		$this->_admin_base_url  = LICENSE_KEYS_ADMIN_URL;
24
+		$this->_admin_base_path = LICENSE_KEYS_ADMIN;
25
+	}
26
+
27
+
28
+	protected function _ajax_hooks()
29
+	{
30
+		if (! $this->capabilities->current_user_can('manage_options', 'update-license-key')) {
31
+			return;
32
+		}
33
+		add_action('wp_ajax_espresso_update_license', [$this, 'updateLicenseKey']);
34
+	}
35
+
36
+
37
+	protected function _define_page_props()
38
+	{
39
+		$this->_admin_page_title = LICENSE_KEYS_LABEL;
40
+	}
41
+
42
+
43
+	protected function _set_page_routes()
44
+	{
45
+		$this->_page_routes = [
46
+			'default'            => [
47
+				'func'       => [$this, 'licenseKeysAdminPage'],
48
+				'capability' => 'manage_options',
49
+			],
50
+			'update_license_key' => [
51
+				'func'       => [$this, 'updateLicenseKey'],
52
+				'capability' => 'manage_options',
53
+				'noheader'   => true,
54
+			],
55
+		];
56
+	}
57
+
58
+
59
+	protected function _set_page_config()
60
+	{
61
+		$this->_page_config = [
62
+			'default' => [
63
+				'nav'           => [
64
+					'label' => LICENSE_KEYS_LABEL,
65
+					'icon'  => 'dashicons-admin-network',
66
+					'order' => 10,
67
+				],
68
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes),
69
+				'require_nonce' => false,
70
+			],
71
+		];
72
+	}
73
+
74
+
75
+	protected function _add_screen_options()
76
+	{
77
+		// TODO: Implement _add_screen_options() method.
78
+	}
79
+
80
+
81
+	protected function _add_feature_pointers()
82
+	{
83
+		// TODO: Implement _add_feature_pointers() method.
84
+	}
85
+
86
+
87
+	public function load_scripts_styles()
88
+	{
89
+		wp_enqueue_style(
90
+			'license_keys_admin_style',
91
+			LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.css',
92
+			[],
93
+			EVENT_ESPRESSO_VERSION
94
+		);
95
+
96
+		wp_enqueue_script(
97
+			'license_keys_admin_js',
98
+			LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.js',
99
+			['jquery'],
100
+			EVENT_ESPRESSO_VERSION,
101
+			true
102
+		);
103
+		wp_localize_script(
104
+			'license_keys_admin_js',
105
+			'eeLicenseData',
106
+			[
107
+				'domain'              => home_url(),
108
+				'statusMessages'      => LicenseStatus::statusMessages(),
109
+				'confirmDeactivation' => esc_html__(
110
+					'Are you sure you want to deactivate this license?',
111
+					'event_espresso'
112
+				),
113
+				'resetDeactivation'   => esc_html__(
114
+					'Are you sure you want to reset this license?',
115
+					'event_espresso'
116
+				),
117
+			]
118
+		);
119
+	}
120
+
121
+
122
+	public function admin_init()
123
+	{
124
+		// TODO: Implement admin_init() method.
125
+	}
126
+
127
+
128
+	public function admin_notices()
129
+	{
130
+		// TODO: Implement admin_notices() method.
131
+	}
132
+
133
+
134
+	public function admin_footer_scripts()
135
+	{
136
+		// TODO: Implement admin_footer_scripts() method.
137
+	}
138
+
139
+
140
+	public function _before_page_setup()
141
+	{
142
+		EE_Dependency_Map::instance()->registerDependencies(
143
+			LicenseManager::class,
144
+			[
145
+				LicenseAPI::class              => EE_Dependency_Map::load_from_cache,
146
+				LicenseKeyData::class          => EE_Dependency_Map::load_from_cache,
147
+				PluginLicenseCollection::class => EE_Dependency_Map::load_from_cache,
148
+			]
149
+		);
150
+		EE_Dependency_Map::instance()->registerDependencies(
151
+			LicenseKeysAdminForm::class,
152
+			['EE_Registry' => EE_Dependency_Map::load_from_cache]
153
+		);
154
+		parent::_before_page_setup();
155
+	}
156
+
157
+
158
+	private function getLicenseManager(): LicenseManager
159
+	{
160
+		return $this->loader->getShared(LicenseManager::class);
161
+	}
162
+
163
+
164
+	private function getPluginLicenseCollection(): PluginLicenseCollection
165
+	{
166
+		return $this->loader->getShared(PluginLicenseCollection::class);
167
+	}
168
+
169
+
170
+	/**
171
+	 * @throws EE_Error
172
+	 */
173
+	public function licenseKeysAdminPage()
174
+	{
175
+		$this->_template_args['admin_page_content'] = '';
176
+		try {
177
+			$license_keys_admin_form                    = $this->loader->getShared(LicenseKeysAdminForm::class);
178
+			$this->_template_args['admin_page_content'] = EEH_HTML::div(
179
+				$license_keys_admin_form->display(),
180
+				'',
181
+				'padding'
182
+			);
183
+		} catch (Exception $e) {
184
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
185
+		}
186
+		$this->_set_add_edit_form_tags('update_license_keys');
187
+		$this->_set_publish_post_box_vars();
188
+		$this->display_admin_page_with_sidebar();
189
+	}
190
+
191
+
192
+	/**
193
+	 * @throws EE_Error
194
+	 */
195
+	public function updateLicenseKey()
196
+	{
197
+		if ($this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
198
+			$licence_manager  = $this->getLicenseManager();
199
+			$license_action   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ACTION);
200
+			$license_key      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_LICENSE_KEY);
201
+			$item_id          = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_ID, 0, DataType::INT);
202
+			$item_name        = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_ITEM_NAME);
203
+			$plugin_slug      = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_SLUG);
204
+			$plugin_version   = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_PLUGIN_VER);
205
+			$min_core_version = $this->request->getRequestParam(LicenseAPI::REQUEST_PARAM_MIN_CORE_VER);
206
+
207
+			$license_data = [];
208
+			switch ($license_action) {
209
+				case LicenseAPI::ACTION_ACTIVATE:
210
+					$license_data = $licence_manager->activateLicense(
211
+						$license_key,
212
+						$item_id,
213
+						$item_name,
214
+						$plugin_slug,
215
+						$plugin_version,
216
+						$min_core_version
217
+					);
218
+					break;
219
+
220
+				case LicenseAPI::ACTION_DEACTIVATE:
221
+					$license_data = $licence_manager->deactivateLicense(
222
+						$license_key,
223
+						$item_id,
224
+						$item_name,
225
+						$plugin_slug,
226
+						$plugin_version,
227
+						$min_core_version
228
+					);
229
+					break;
230
+
231
+				case LicenseAPI::ACTION_CHECK:
232
+					$license_data = $licence_manager->checkLicense(
233
+						$license_key,
234
+						$item_id,
235
+						$item_name,
236
+						$plugin_slug,
237
+						$plugin_version,
238
+						$min_core_version
239
+					);
240
+					break;
241
+
242
+				case LicenseAPI::ACTION_GET_VERSION:
243
+					$license_data = $licence_manager->getVersionInfo();
244
+					break;
245
+
246
+				case LicenseAPI::ACTION_RESET:
247
+					$license_data = $licence_manager->resetLicenseKey($plugin_slug);
248
+					break;
249
+			}
250
+
251
+			$license_data = (object) $license_data;
252
+			$license_data->statusNotice = LicenseStatus::statusNotice($license_data->license);
253
+			$license_data->statusClass  = LicenseStatus::statusClass($license_data->license);
254
+			$notices = EE_Error::get_notices(false, false, false);
255
+		} else {
256
+			$license_data = new stdClass();
257
+			$notices = [
258
+				'success' => false,
259
+				'errors'  => [
260
+					esc_html__('You do not have the required privileges to perform this action', 'event_espresso'),
261
+				],
262
+			];
263
+		}
264
+
265
+		if ($this->request->isAjax()) {
266
+			wp_send_json(
267
+				[
268
+					'return_data' => $license_data,
269
+					'success'     => $notices['success'],
270
+					'errors'      => $notices['errors'],
271
+				]
272
+			);
273
+		}
274
+
275
+		$this->_redirect_after_action(
276
+			empty($notices['errors']),
277
+			'',
278
+			'',
279
+			['action' => 'default'],
280
+			true
281
+		);
282
+	}
283 283
 }
284 284
 
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@  discard block
 block discarded – undo
27 27
 
28 28
     protected function _ajax_hooks()
29 29
     {
30
-        if (! $this->capabilities->current_user_can('manage_options', 'update-license-key')) {
30
+        if ( ! $this->capabilities->current_user_can('manage_options', 'update-license-key')) {
31 31
             return;
32 32
         }
33 33
         add_action('wp_ajax_espresso_update_license', [$this, 'updateLicenseKey']);
@@ -88,14 +88,14 @@  discard block
 block discarded – undo
88 88
     {
89 89
         wp_enqueue_style(
90 90
             'license_keys_admin_style',
91
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.css',
91
+            LICENSE_KEYS_ASSETS_URL.'license_keys_admin.css',
92 92
             [],
93 93
             EVENT_ESPRESSO_VERSION
94 94
         );
95 95
 
96 96
         wp_enqueue_script(
97 97
             'license_keys_admin_js',
98
-            LICENSE_KEYS_ASSETS_URL . 'license_keys_admin.js',
98
+            LICENSE_KEYS_ASSETS_URL.'license_keys_admin.js',
99 99
             ['jquery'],
100 100
             EVENT_ESPRESSO_VERSION,
101 101
             true
Please login to merge, or discard this patch.
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 2 patches
Indentation   +1491 added lines, -1491 removed lines patch added patch discarded remove patch
@@ -16,1495 +16,1495 @@
 block discarded – undo
16 16
  */
17 17
 class Extend_Registration_Form_Admin_Page extends Registration_Form_Admin_Page
18 18
 {
19
-    /**
20
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
21
-     * @throws EE_Error
22
-     * @throws ReflectionException
23
-     */
24
-    public function __construct($routing = true)
25
-    {
26
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
27
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
28
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
29
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
30
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
31
-        parent::__construct($routing);
32
-    }
33
-
34
-
35
-    protected function _define_page_props()
36
-    {
37
-        parent::_define_page_props();
38
-        $this->_labels['publishbox'] = [
39
-            'add_question'        => esc_html__('Add New Question', 'event_espresso'),
40
-            'edit_question'       => esc_html__('Edit Question', 'event_espresso'),
41
-            'add_question_group'  => esc_html__('Add New Question Group', 'event_espresso'),
42
-            'edit_question_group' => esc_html__('Edit Question Group', 'event_espresso'),
43
-        ];
44
-    }
45
-
46
-
47
-    protected function _set_page_config()
48
-    {
49
-        parent::_set_page_config();
50
-
51
-        $this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
52
-        $qst_id                 = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
53
-            ? $this->_req_data['QST_ID'] : 0;
54
-        $qsg_id                 = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
55
-            ? $this->_req_data['QSG_ID'] : 0;
56
-
57
-        $new_page_routes    = [
58
-            'question_groups'    => [
59
-                'func'       => '_question_groups_overview_list_table',
60
-                'capability' => 'ee_read_question_groups',
61
-            ],
62
-            'add_question'       => [
63
-                'func'       => '_edit_question',
64
-                'capability' => 'ee_edit_questions',
65
-            ],
66
-            'insert_question'    => [
67
-                'func'       => '_insert_or_update_question',
68
-                'args'       => ['new_question' => true],
69
-                'capability' => 'ee_edit_questions',
70
-                'noheader'   => true,
71
-            ],
72
-            'duplicate_question' => [
73
-                'func'       => '_duplicate_question',
74
-                'capability' => 'ee_edit_questions',
75
-                'noheader'   => true,
76
-            ],
77
-            'trash_question'     => [
78
-                'func'       => '_trash_question',
79
-                'capability' => 'ee_delete_question',
80
-                'obj_id'     => $qst_id,
81
-                'noheader'   => true,
82
-            ],
83
-
84
-            'restore_question' => [
85
-                'func'       => '_trash_or_restore_questions',
86
-                'capability' => 'ee_delete_question',
87
-                'obj_id'     => $qst_id,
88
-                'args'       => ['trash' => false],
89
-                'noheader'   => true,
90
-            ],
91
-
92
-            'delete_question' => [
93
-                'func'       => '_delete_question',
94
-                'capability' => 'ee_delete_question',
95
-                'obj_id'     => $qst_id,
96
-                'noheader'   => true,
97
-            ],
98
-
99
-            'trash_questions' => [
100
-                'func'       => '_trash_or_restore_questions',
101
-                'capability' => 'ee_delete_questions',
102
-                'args'       => ['trash' => true],
103
-                'noheader'   => true,
104
-            ],
105
-
106
-            'restore_questions' => [
107
-                'func'       => '_trash_or_restore_questions',
108
-                'capability' => 'ee_delete_questions',
109
-                'args'       => ['trash' => false],
110
-                'noheader'   => true,
111
-            ],
112
-
113
-            'delete_questions' => [
114
-                'func'       => '_delete_questions',
115
-                'args'       => [],
116
-                'capability' => 'ee_delete_questions',
117
-                'noheader'   => true,
118
-            ],
119
-
120
-            'add_question_group' => [
121
-                'func'       => '_edit_question_group',
122
-                'capability' => 'ee_edit_question_groups',
123
-            ],
124
-
125
-            'edit_question_group' => [
126
-                'func'       => '_edit_question_group',
127
-                'capability' => 'ee_edit_question_group',
128
-                'obj_id'     => $qsg_id,
129
-                'args'       => ['edit'],
130
-            ],
131
-
132
-            'delete_question_groups' => [
133
-                'func'       => '_delete_question_groups',
134
-                'capability' => 'ee_delete_question_groups',
135
-                'noheader'   => true,
136
-            ],
137
-
138
-            'delete_question_group' => [
139
-                'func'       => '_delete_question_groups',
140
-                'capability' => 'ee_delete_question_group',
141
-                'obj_id'     => $qsg_id,
142
-                'noheader'   => true,
143
-            ],
144
-
145
-            'trash_question_group' => [
146
-                'func'       => '_trash_or_restore_question_groups',
147
-                'args'       => ['trash' => true],
148
-                'capability' => 'ee_delete_question_group',
149
-                'obj_id'     => $qsg_id,
150
-                'noheader'   => true,
151
-            ],
152
-
153
-            'restore_question_group' => [
154
-                'func'       => '_trash_or_restore_question_groups',
155
-                'args'       => ['trash' => false],
156
-                'capability' => 'ee_delete_question_group',
157
-                'obj_id'     => $qsg_id,
158
-                'noheader'   => true,
159
-            ],
160
-
161
-            'insert_question_group' => [
162
-                'func'       => '_insert_or_update_question_group',
163
-                'args'       => ['new_question_group' => true],
164
-                'capability' => 'ee_edit_question_groups',
165
-                'noheader'   => true,
166
-            ],
167
-
168
-            'update_question_group' => [
169
-                'func'       => '_insert_or_update_question_group',
170
-                'args'       => ['new_question_group' => false],
171
-                'capability' => 'ee_edit_question_group',
172
-                'obj_id'     => $qsg_id,
173
-                'noheader'   => true,
174
-            ],
175
-
176
-            'trash_question_groups' => [
177
-                'func'       => '_trash_or_restore_question_groups',
178
-                'args'       => ['trash' => true],
179
-                'capability' => 'ee_delete_question_groups',
180
-                'noheader'   => ['trash' => false],
181
-            ],
182
-
183
-            'restore_question_groups' => [
184
-                'func'       => '_trash_or_restore_question_groups',
185
-                'args'       => ['trash' => false],
186
-                'capability' => 'ee_delete_question_groups',
187
-                'noheader'   => true,
188
-            ],
189
-
190
-
191
-            'espresso_update_question_group_order' => [
192
-                'func'       => 'update_question_group_order',
193
-                'capability' => 'ee_edit_question_groups',
194
-                'noheader'   => true,
195
-            ],
196
-
197
-            'view_reg_form_settings' => [
198
-                'func'       => '_reg_form_settings',
199
-                'capability' => 'manage_options',
200
-            ],
201
-
202
-            'update_reg_form_settings' => [
203
-                'func'       => '_update_reg_form_settings',
204
-                'capability' => 'manage_options',
205
-                'noheader'   => true,
206
-            ],
207
-        ];
208
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
209
-
210
-        $new_page_config    = [
211
-
212
-            'question_groups' => [
213
-                'nav'           => [
214
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
215
-                    'icon'  => 'dashicons-forms',
216
-                    'order' => 20,
217
-                ],
218
-                'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
219
-                'help_tabs'     => [
220
-                    'registration_form_question_groups_help_tab'                           => [
221
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
222
-                        'filename' => 'registration_form_question_groups',
223
-                    ],
224
-                    'registration_form_question_groups_table_column_headings_help_tab'     => [
225
-                        'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
226
-                        'filename' => 'registration_form_question_groups_table_column_headings',
227
-                    ],
228
-                    'registration_form_question_groups_views_bulk_actions_search_help_tab' => [
229
-                        'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
230
-                        'filename' => 'registration_form_question_groups_views_bulk_actions_search',
231
-                    ],
232
-                ],
233
-                'metaboxes'     => $this->_default_espresso_metaboxes,
234
-                'require_nonce' => false,
235
-            ],
236
-
237
-            'add_question' => [
238
-                'nav'           => [
239
-                    'label'      => esc_html__('Add Question', 'event_espresso'),
240
-                    'icon'       => 'dashicons-plus-alt',
241
-                    'order'      => 15,
242
-                    'persistent' => false,
243
-                ],
244
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
245
-                'help_tabs'     => [
246
-                    'registration_form_add_question_help_tab' => [
247
-                        'title'    => esc_html__('Add Question', 'event_espresso'),
248
-                        'filename' => 'registration_form_add_question',
249
-                    ],
250
-                ],
251
-                'require_nonce' => false,
252
-            ],
253
-
254
-            'add_question_group' => [
255
-                'nav'           => [
256
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
257
-                    'icon'       => 'dashicons-plus-alt',
258
-                    'order'      => 25,
259
-                    'persistent' => false,
260
-                ],
261
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
262
-                'help_tabs'     => [
263
-                    'registration_form_add_question_group_help_tab' => [
264
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
265
-                        'filename' => 'registration_form_add_question_group',
266
-                    ],
267
-                ],
268
-                'require_nonce' => false,
269
-            ],
270
-
271
-            'edit_question_group' => [
272
-                'nav'           => [
273
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
274
-                    'icon'       => 'dashicons-edit-large',
275
-                    'order'      => 25,
276
-                    'persistent' => false,
277
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
278
-                        ['question_group_id' => $this->_req_data['question_group_id']],
279
-                        $this->_current_page_view_url
280
-                    ) : $this->_admin_base_url,
281
-                ],
282
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
283
-                'help_tabs'     => [
284
-                    'registration_form_edit_question_group_help_tab' => [
285
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
286
-                        'filename' => 'registration_form_edit_question_group',
287
-                    ],
288
-                ],
289
-                'require_nonce' => false,
290
-            ],
291
-
292
-            'view_reg_form_settings' => [
293
-                'nav'           => [
294
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
295
-                    'icon'  => 'dashicons-admin-generic',
296
-                    'order' => 40,
297
-                ],
298
-                'labels'        => [
299
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
300
-                ],
301
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
302
-                'help_tabs'     => [
303
-                    'registration_form_reg_form_settings_help_tab' => [
304
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
305
-                        'filename' => 'registration_form_reg_form_settings',
306
-                    ],
307
-                ],
308
-                'require_nonce' => false,
309
-            ],
310
-
311
-        ];
312
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
313
-
314
-        // change the list table we're going to use so it's the NEW list table!
315
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
316
-
317
-
318
-        // additional labels
319
-        $new_labels               = [
320
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
321
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
322
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
323
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
324
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
325
-        ];
326
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
327
-    }
328
-
329
-
330
-    /**
331
-     * @return void
332
-     */
333
-    protected function _ajax_hooks()
334
-    {
335
-        if (! $this->capabilities->current_user_can('ee_edit_question_groups', 'edit-questions')) {
336
-            return;
337
-        }
338
-        add_action('wp_ajax_espresso_update_question_group_order', [$this, 'update_question_group_order']);
339
-    }
340
-
341
-
342
-    /**
343
-     * @return void
344
-     */
345
-    public function load_scripts_styles_question_groups()
346
-    {
347
-        wp_enqueue_script('espresso_ajax_table_sorting');
348
-    }
349
-
350
-
351
-    /**
352
-     * @return void
353
-     */
354
-    public function load_scripts_styles_add_question_group()
355
-    {
356
-        $this->load_scripts_styles_forms();
357
-        $this->load_sortable_question_script();
358
-    }
359
-
360
-
361
-    /**
362
-     * @return void
363
-     */
364
-    public function load_scripts_styles_edit_question_group()
365
-    {
366
-        $this->load_scripts_styles_forms();
367
-        $this->load_sortable_question_script();
368
-    }
369
-
370
-
371
-    /**
372
-     * registers and enqueues script for questions
373
-     *
374
-     * @return void
375
-     */
376
-    public function load_sortable_question_script()
377
-    {
378
-        wp_register_script(
379
-            'ee-question-sortable',
380
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
381
-            ['jquery-ui-sortable'],
382
-            EVENT_ESPRESSO_VERSION,
383
-            true
384
-        );
385
-        wp_enqueue_script('ee-question-sortable');
386
-    }
387
-
388
-
389
-    /**
390
-     * @return void
391
-     */
392
-    protected function _set_list_table_views_default()
393
-    {
394
-        $this->_views = [
395
-            'all' => [
396
-                'slug'        => 'all',
397
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
398
-                'count'       => 0,
399
-                'bulk_action' => [
400
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
401
-                ],
402
-            ],
403
-        ];
404
-
405
-        if (
406
-        EE_Registry::instance()->CAP->current_user_can(
407
-            'ee_delete_questions',
408
-            'espresso_registration_form_trash_questions'
409
-        )
410
-        ) {
411
-            $this->_views['trash'] = [
412
-                'slug'        => 'trash',
413
-                'label'       => esc_html__('Trash', 'event_espresso'),
414
-                'count'       => 0,
415
-                'bulk_action' => [
416
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
417
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
418
-                ],
419
-            ];
420
-        }
421
-    }
422
-
423
-
424
-    /**
425
-     * @return void
426
-     */
427
-    protected function _set_list_table_views_question_groups()
428
-    {
429
-        $this->_views = [
430
-            'all' => [
431
-                'slug'        => 'all',
432
-                'label'       => esc_html__('All', 'event_espresso'),
433
-                'count'       => 0,
434
-                'bulk_action' => [
435
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
436
-                ],
437
-            ],
438
-        ];
439
-
440
-        if (
441
-        EE_Registry::instance()->CAP->current_user_can(
442
-            'ee_delete_question_groups',
443
-            'espresso_registration_form_trash_question_groups'
444
-        )
445
-        ) {
446
-            $this->_views['trash'] = [
447
-                'slug'        => 'trash',
448
-                'label'       => esc_html__('Trash', 'event_espresso'),
449
-                'count'       => 0,
450
-                'bulk_action' => [
451
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
452
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
453
-                ],
454
-            ];
455
-        }
456
-    }
457
-
458
-
459
-    /**
460
-     * @return void
461
-     * @throws EE_Error
462
-     * @throws InvalidArgumentException
463
-     * @throws InvalidDataTypeException
464
-     * @throws InvalidInterfaceException
465
-     */
466
-    protected function _questions_overview_list_table()
467
-    {
468
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
469
-                'add_question',
470
-                'add_question',
471
-                [],
472
-                'add-new-h2'
473
-            );
474
-        parent::_questions_overview_list_table();
475
-    }
476
-
477
-
478
-    /**
479
-     * @return void
480
-     * @throws DomainException
481
-     * @throws EE_Error
482
-     * @throws InvalidArgumentException
483
-     * @throws InvalidDataTypeException
484
-     * @throws InvalidInterfaceException
485
-     */
486
-    protected function _question_groups_overview_list_table()
487
-    {
488
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
489
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
490
-                'add_question_group',
491
-                'add_question_group',
492
-                [],
493
-                'add-new-h2'
494
-            );
495
-        $this->display_admin_list_table_page_with_sidebar();
496
-    }
497
-
498
-
499
-    /**
500
-     * @return void
501
-     * @throws EE_Error
502
-     * @throws InvalidArgumentException
503
-     * @throws InvalidDataTypeException
504
-     * @throws InvalidInterfaceException
505
-     * @throws ReflectionException
506
-     */
507
-    protected function _delete_question()
508
-    {
509
-        $success = $this->_delete_items($this->_question_model);
510
-        $this->_redirect_after_action(
511
-            $success,
512
-            $this->_question_model->item_name($success),
513
-            'deleted',
514
-            ['action' => 'default', 'status' => 'all']
515
-        );
516
-    }
517
-
518
-
519
-    /**
520
-     * @return void
521
-     * @throws EE_Error
522
-     * @throws InvalidArgumentException
523
-     * @throws InvalidDataTypeException
524
-     * @throws InvalidInterfaceException
525
-     * @throws ReflectionException
526
-     */
527
-    protected function _delete_questions()
528
-    {
529
-        $success = $this->_delete_items($this->_question_model);
530
-        $this->_redirect_after_action(
531
-            $success,
532
-            $this->_question_model->item_name($success),
533
-            'deleted permanently',
534
-            ['action' => 'default', 'status' => 'trash']
535
-        );
536
-    }
537
-
538
-
539
-    /**
540
-     * Performs the deletion of a single or multiple questions or question groups.
541
-     *
542
-     * @param EEM_Soft_Delete_Base $model
543
-     * @return int number of items deleted permanently
544
-     * @throws EE_Error
545
-     * @throws InvalidArgumentException
546
-     * @throws InvalidDataTypeException
547
-     * @throws InvalidInterfaceException
548
-     * @throws ReflectionException
549
-     */
550
-    private function _delete_items(EEM_Soft_Delete_Base $model)
551
-    {
552
-        $success = 0;
553
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
554
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
555
-            // if array has more than one element than success message should be plural
556
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
557
-            // cycle thru bulk action checkboxes
558
-            $checkboxes = $this->_req_data['checkbox'];
559
-            foreach (array_keys($checkboxes) as $ID) {
560
-                if (! $this->_delete_item($ID, $model)) {
561
-                    $success = 0;
562
-                }
563
-            }
564
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
565
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
566
-        } elseif (! empty($this->_req_data['QST_ID'])) {
567
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
568
-        } else {
569
-            EE_Error::add_error(
570
-                sprintf(
571
-                    esc_html__(
572
-                        "No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
573
-                        "event_espresso"
574
-                    )
575
-                ),
576
-                __FILE__,
577
-                __FUNCTION__,
578
-                __LINE__
579
-            );
580
-        }
581
-        return $success;
582
-    }
583
-
584
-
585
-    /**
586
-     * Deletes the specified question (and its associated question options) or question group
587
-     *
588
-     * @param int                  $id
589
-     * @param EEM_Soft_Delete_Base $model
590
-     * @return boolean
591
-     * @throws EE_Error
592
-     * @throws InvalidArgumentException
593
-     * @throws InvalidDataTypeException
594
-     * @throws InvalidInterfaceException
595
-     * @throws ReflectionException
596
-     */
597
-    protected function _delete_item($id, $model)
598
-    {
599
-        if ($model instanceof EEM_Question) {
600
-            EEM_Question_Option::instance()->delete_permanently([['QST_ID' => absint($id)]]);
601
-        }
602
-        return $model->delete_permanently_by_ID(absint($id));
603
-    }
604
-
605
-
606
-    /******************************    QUESTION GROUPS    ******************************/
607
-
608
-
609
-    /**
610
-     * @param string $type
611
-     * @return void
612
-     * @throws DomainException
613
-     * @throws EE_Error
614
-     * @throws InvalidArgumentException
615
-     * @throws InvalidDataTypeException
616
-     * @throws InvalidInterfaceException
617
-     * @throws ReflectionException
618
-     */
619
-    protected function _edit_question_group($type = 'add')
620
-    {
621
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
622
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
623
-            ? absint($this->_req_data['QSG_ID'])
624
-            : false;
625
-
626
-        switch ($this->_req_action) {
627
-            case 'add_question_group':
628
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
629
-                break;
630
-            case 'edit_question_group':
631
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
632
-                break;
633
-            default:
634
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
635
-        }
636
-        // add ID to title if editing
637
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
638
-        if ($ID) {
639
-            /** @var EE_Question_Group $questionGroup */
640
-            $questionGroup            = $this->_question_group_model->get_one_by_ID($ID);
641
-            $additional_hidden_fields = ['QSG_ID' => ['type' => 'hidden', 'value' => $ID]];
642
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
643
-        } else {
644
-            /** @var EE_Question_Group $questionGroup */
645
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
646
-            $questionGroup->set_order_to_latest();
647
-            $this->_set_add_edit_form_tags('insert_question_group');
648
-        }
649
-        $this->_template_args['values']         = $this->_yes_no_values;
650
-        $this->_template_args['all_questions']  = $questionGroup->questions_in_and_not_in_group();
651
-        $this->_template_args['QSG_ID']         = $ID ? $ID : true;
652
-        $this->_template_args['question_group'] = $questionGroup;
653
-
654
-        $redirect_URL = add_query_arg(['action' => 'question_groups'], $this->_admin_base_url);
655
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL, true);
656
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
657
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
658
-            $this->_template_args,
659
-            true
660
-        );
661
-
662
-        // the details template wrapper
663
-        $this->display_admin_page_with_sidebar();
664
-    }
665
-
666
-
667
-    /**
668
-     * @return void
669
-     * @throws EE_Error
670
-     * @throws InvalidArgumentException
671
-     * @throws InvalidDataTypeException
672
-     * @throws InvalidInterfaceException
673
-     * @throws ReflectionException
674
-     */
675
-    protected function _delete_question_groups()
676
-    {
677
-        $success = $this->_delete_items($this->_question_group_model);
678
-        $this->_redirect_after_action(
679
-            $success,
680
-            $this->_question_group_model->item_name($success),
681
-            'deleted permanently',
682
-            ['action' => 'question_groups', 'status' => 'trash']
683
-        );
684
-    }
685
-
686
-
687
-    /**
688
-     * @param bool $new_question_group
689
-     * @throws EE_Error
690
-     * @throws InvalidArgumentException
691
-     * @throws InvalidDataTypeException
692
-     * @throws InvalidInterfaceException
693
-     * @throws ReflectionException
694
-     */
695
-    protected function _insert_or_update_question_group($new_question_group = true)
696
-    {
697
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
698
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
699
-
700
-        // make sure identifier is unique
701
-        $identifier_value = $set_column_values['QSG_identifier'] ?? '';
702
-        $where_values     = ['QSG_identifier' => $identifier_value];
703
-        if (! $new_question_group && isset($set_column_values['QSG_ID'])) {
704
-            $where_values['QSG_ID'] = ['!=', $set_column_values['QSG_ID']];
705
-        }
706
-        $identifier_exists = ! empty($identifier_value) && $this->_question_group_model->count([$where_values]) > 0;
707
-        if ($identifier_exists) {
708
-            $set_column_values['QSG_identifier'] .= uniqid('id', true);
709
-        }
710
-
711
-        if ($new_question_group) {
712
-            $QSG_ID  = $this->_question_group_model->insert($set_column_values);
713
-            $success = $QSG_ID ? 1 : 0;
714
-            if ($success === 0) {
715
-                EE_Error::add_error(
716
-                    esc_html__('Something went wrong saving the question group.', 'event_espresso'),
717
-                    __FILE__,
718
-                    __FUNCTION__,
719
-                    __LINE__
720
-                );
721
-                $this->_redirect_after_action(
722
-                    false,
723
-                    '',
724
-                    '',
725
-                    ['action' => 'edit_question_group', 'QSG_ID' => $QSG_ID],
726
-                    true
727
-                );
728
-            }
729
-        } else {
730
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
731
-            unset($set_column_values['QSG_ID']);
732
-            $success = $this->_question_group_model->update($set_column_values, [['QSG_ID' => $QSG_ID]]);
733
-        }
734
-
735
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
736
-            EEM_Attendee::system_question_phone
737
-        );
738
-        // update the existing related questions
739
-        // BUT FIRST...  delete the phone question from the Question_Group_Question
740
-        // if it is being added to this question group (therefore removed from the existing group)
741
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
742
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
743
-            EEM_Question_Group_Question::instance()->delete(
744
-                [
745
-                    [
746
-                        'QST_ID' => $phone_question_id,
747
-                        'QSG_ID' => ['!=', $QSG_ID],
748
-                    ],
749
-                ]
750
-            );
751
-        }
752
-        /** @type EE_Question_Group $question_group */
753
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
754
-        $questions      = $question_group->questions();
755
-        // make sure system phone question is added to list of questions for this group
756
-        if (! isset($questions[ $phone_question_id ])) {
757
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
758
-        }
759
-
760
-        foreach ($questions as $question_ID => $question) {
761
-            // first we always check for order.
762
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
763
-                // update question order
764
-                $question_group->update_question_order(
765
-                    $question_ID,
766
-                    $this->_req_data['question_orders'][ $question_ID ]
767
-                );
768
-            }
769
-
770
-            // then we always check if adding or removing.
771
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
772
-                $question_group->add_question($question_ID);
773
-            } else {
774
-                // not found, remove it (but only if not a system question for the personal group
775
-                // with the exception of lname system question - we allow removal of it)
776
-                if (
777
-                in_array(
778
-                    $question->system_ID(),
779
-                    EEM_Question::instance()->required_system_questions_in_system_question_group(
780
-                        $question_group->system_group()
781
-                    )
782
-                )
783
-                ) {
784
-                    continue;
785
-                } else {
786
-                    $question_group->remove_question($question_ID);
787
-                }
788
-            }
789
-        }
790
-        // save new related questions
791
-        if (isset($this->_req_data['questions'])) {
792
-            foreach ($this->_req_data['questions'] as $QST_ID) {
793
-                $question_group->add_question($QST_ID);
794
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
795
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
796
-                }
797
-            }
798
-        }
799
-
800
-        if ($success !== false) {
801
-            $msg = $new_question_group
802
-                ? sprintf(
803
-                    esc_html__('The %s has been created', 'event_espresso'),
804
-                    $this->_question_group_model->item_name()
805
-                )
806
-                : sprintf(
807
-                    esc_html__(
808
-                        'The %s has been updated',
809
-                        'event_espresso'
810
-                    ),
811
-                    $this->_question_group_model->item_name()
812
-                );
813
-            EE_Error::add_success($msg);
814
-        }
815
-        $this->_redirect_after_action(
816
-            false,
817
-            '',
818
-            '',
819
-            ['action' => 'edit_question_group', 'QSG_ID' => $QSG_ID],
820
-            true
821
-        );
822
-    }
823
-
824
-
825
-    /**
826
-     * duplicates a question and all its question options and redirects to the new question.
827
-     *
828
-     * @return void
829
-     * @throws EE_Error
830
-     * @throws InvalidArgumentException
831
-     * @throws ReflectionException
832
-     * @throws InvalidDataTypeException
833
-     * @throws InvalidInterfaceException
834
-     */
835
-    public function _duplicate_question()
836
-    {
837
-        $question_ID = (int) $this->_req_data['QST_ID'];
838
-        $question    = EEM_Question::instance()->get_one_by_ID($question_ID);
839
-        if ($question instanceof EE_Question) {
840
-            $new_question = $question->duplicate();
841
-            if ($new_question instanceof EE_Question) {
842
-                $this->_redirect_after_action(
843
-                    true,
844
-                    esc_html__('Question', 'event_espresso'),
845
-                    esc_html__('Duplicated', 'event_espresso'),
846
-                    ['action' => 'edit_question', 'QST_ID' => $new_question->ID()],
847
-                    true
848
-                );
849
-            } else {
850
-                global $wpdb;
851
-                EE_Error::add_error(
852
-                    sprintf(
853
-                        esc_html__(
854
-                            'Could not duplicate question with ID %1$d because: %2$s',
855
-                            'event_espresso'
856
-                        ),
857
-                        $question_ID,
858
-                        $wpdb->last_error
859
-                    ),
860
-                    __FILE__,
861
-                    __FUNCTION__,
862
-                    __LINE__
863
-                );
864
-                $this->_redirect_after_action(false, '', '', ['action' => 'default'], false);
865
-            }
866
-        } else {
867
-            EE_Error::add_error(
868
-                sprintf(
869
-                    esc_html__(
870
-                        'Could not duplicate question with ID %d because it didn\'t exist!',
871
-                        'event_espresso'
872
-                    ),
873
-                    $question_ID
874
-                ),
875
-                __FILE__,
876
-                __FUNCTION__,
877
-                __LINE__
878
-            );
879
-            $this->_redirect_after_action(false, '', '', ['action' => 'default'], false);
880
-        }
881
-    }
882
-
883
-
884
-    /**
885
-     * @param bool $trash
886
-     * @throws EE_Error
887
-     */
888
-    protected function _trash_or_restore_question_groups($trash = true)
889
-    {
890
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
891
-    }
892
-
893
-
894
-    /**
895
-     *_trash_question
896
-     *
897
-     * @return void
898
-     * @throws EE_Error
899
-     */
900
-    protected function _trash_question()
901
-    {
902
-        $success    = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
903
-        $query_args = ['action' => 'default', 'status' => 'all'];
904
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
905
-    }
906
-
907
-
908
-    /**
909
-     * @param bool $trash
910
-     * @throws EE_Error
911
-     */
912
-    protected function _trash_or_restore_questions($trash = true)
913
-    {
914
-        $this->_trash_or_restore_items($this->_question_model, $trash);
915
-    }
916
-
917
-
918
-    /**
919
-     * Internally used to delete or restore items, using the request data. Meant to be
920
-     * flexible between question or question groups
921
-     *
922
-     * @param EEM_Soft_Delete_Base $model
923
-     * @param boolean              $trash whether to trash or restore
924
-     * @throws EE_Error
925
-     */
926
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
927
-    {
928
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
929
-
930
-        $success = 1;
931
-        // Checkboxes
932
-        // echo "trash $trash";
933
-        // var_dump($this->_req_data['checkbox']);die;
934
-        if (isset($this->_req_data['checkbox'])) {
935
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
936
-                // if array has more than one element than success message should be plural
937
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
938
-                // cycle thru bulk action checkboxes
939
-                $checkboxes = $this->_req_data['checkbox'];
940
-                foreach (array_keys($checkboxes) as $ID) {
941
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
942
-                        $success = 0;
943
-                    }
944
-                }
945
-            } else {
946
-                // grab single id and delete
947
-                $ID = absint($this->_req_data['checkbox']);
948
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
949
-                    $success = 0;
950
-                }
951
-            }
952
-        } else {
953
-            // delete via trash link
954
-            // grab single id and delete
955
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
956
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
957
-                $success = 0;
958
-            }
959
-        }
960
-
961
-
962
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
963
-        // echo "action :$action";
964
-        // $action = 'questions' ? 'default' : $action;
965
-        if ($trash) {
966
-            $action_desc = 'trashed';
967
-            $status      = 'trash';
968
-        } else {
969
-            $action_desc = 'restored';
970
-            $status      = 'all';
971
-        }
972
-        $this->_redirect_after_action(
973
-            $success,
974
-            $model->item_name($success),
975
-            $action_desc,
976
-            ['action' => $action, 'status' => $status]
977
-        );
978
-    }
979
-
980
-
981
-    /**
982
-     * @param            $per_page
983
-     * @param int        $current_page
984
-     * @param bool|false $count
985
-     * @return EE_Soft_Delete_Base_Class[]|int
986
-     * @throws EE_Error
987
-     * @throws InvalidArgumentException
988
-     * @throws InvalidDataTypeException
989
-     * @throws InvalidInterfaceException
990
-     * @throws ReflectionException
991
-     */
992
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
993
-    {
994
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
995
-
996
-        if ($count) {
997
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
998
-            $where   = isset($query_params[0]) ? [$query_params[0]] : [];
999
-            $results = $this->_question_model->count_deleted($where);
1000
-        } else {
1001
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
1002
-            $results = $this->_question_model->get_all_deleted($query_params);
1003
-        }
1004
-        return $results;
1005
-    }
1006
-
1007
-
1008
-    /**
1009
-     * @param            $per_page
1010
-     * @param int        $current_page
1011
-     * @param bool|false $count
1012
-     * @return EE_Soft_Delete_Base_Class[]|int
1013
-     * @throws EE_Error
1014
-     * @throws InvalidArgumentException
1015
-     * @throws InvalidDataTypeException
1016
-     * @throws InvalidInterfaceException
1017
-     * @throws ReflectionException
1018
-     */
1019
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
1020
-    {
1021
-        $questionGroupModel = EEM_Question_Group::instance();
1022
-        $query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1023
-        if ($count) {
1024
-            $where   = isset($query_params[0]) ? [$query_params[0]] : [];
1025
-            $results = $questionGroupModel->count($where);
1026
-        } else {
1027
-            $results = $questionGroupModel->get_all($query_params);
1028
-        }
1029
-        return $results;
1030
-    }
1031
-
1032
-
1033
-    /**
1034
-     * @param      $per_page
1035
-     * @param int  $current_page
1036
-     * @param bool $count
1037
-     * @return EE_Soft_Delete_Base_Class[]|int
1038
-     * @throws EE_Error
1039
-     * @throws InvalidArgumentException
1040
-     * @throws InvalidDataTypeException
1041
-     * @throws InvalidInterfaceException
1042
-     * @throws ReflectionException
1043
-     */
1044
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1045
-    {
1046
-        $questionGroupModel = EEM_Question_Group::instance();
1047
-        $query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1048
-        if ($count) {
1049
-            $where                 = isset($query_params[0]) ? [$query_params[0]] : [];
1050
-            $query_params['limit'] = null;
1051
-            $results               = $questionGroupModel->count_deleted($where);
1052
-        } else {
1053
-            $results = $questionGroupModel->get_all_deleted($query_params);
1054
-        }
1055
-        return $results;
1056
-    }
1057
-
1058
-
1059
-    /**
1060
-     * method for performing updates to question order
1061
-     *
1062
-     * @return void results array
1063
-     * @throws EE_Error
1064
-     * @throws InvalidArgumentException
1065
-     * @throws InvalidDataTypeException
1066
-     * @throws InvalidInterfaceException
1067
-     * @throws ReflectionException
1068
-     */
1069
-    public function update_question_group_order()
1070
-    {
1071
-        if (! $this->capabilities->current_user_can('ee_edit_question_groups', __FUNCTION__)) {
1072
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
1073
-        }
1074
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1075
-
1076
-        // grab our row IDs
1077
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1078
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
1079
-            : [];
1080
-
1081
-        $perpage = ! empty($this->_req_data['perpage'])
1082
-            ? (int) $this->_req_data['perpage']
1083
-            : null;
1084
-        $curpage = ! empty($this->_req_data['curpage'])
1085
-            ? (int) $this->_req_data['curpage']
1086
-            : null;
1087
-
1088
-        if (! empty($row_ids)) {
1089
-            // figure out where we start the row_id count at for the current page.
1090
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1091
-
1092
-            $row_count = count($row_ids);
1093
-            for ($i = 0; $i < $row_count; $i++) {
1094
-                // Update the questions when re-ordering
1095
-                $updated = EEM_Question_Group::instance()->update(
1096
-                    ['QSG_order' => $qsgcount],
1097
-                    [['QSG_ID' => $row_ids[ $i ]]]
1098
-                );
1099
-                if ($updated === false) {
1100
-                    $success = false;
1101
-                }
1102
-                $qsgcount++;
1103
-            }
1104
-        } else {
1105
-            $success = false;
1106
-        }
1107
-
1108
-        $errors = ! $success
1109
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1110
-            : false;
1111
-
1112
-        echo wp_json_encode(['return_data' => false, 'success' => $success, 'errors' => $errors]);
1113
-        die();
1114
-    }
1115
-
1116
-
1117
-
1118
-    /***************************************       REGISTRATION SETTINGS       ***************************************/
1119
-
1120
-
1121
-    /**
1122
-     * @throws DomainException
1123
-     * @throws EE_Error
1124
-     * @throws InvalidArgumentException
1125
-     * @throws InvalidDataTypeException
1126
-     * @throws InvalidInterfaceException
1127
-     */
1128
-    protected function _reg_form_settings()
1129
-    {
1130
-        $this->_template_args['values'] = $this->_yes_no_values;
1131
-        add_action(
1132
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1133
-            [$this, 'email_validation_settings_form'],
1134
-            2
1135
-        );
1136
-        add_action(
1137
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1138
-            [$this, 'copy_attendee_info_settings_form'],
1139
-            4
1140
-        );
1141
-        add_action(
1142
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1143
-            [$this, 'setSessionLifespan'],
1144
-            5
1145
-        );
1146
-        $this->_template_args = (array) apply_filters(
1147
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1148
-            $this->_template_args
1149
-        );
1150
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
1151
-        $this->_set_publish_post_box_vars();
1152
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1153
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1154
-            $this->_template_args,
1155
-            true
1156
-        );
1157
-        $this->display_admin_page_with_sidebar();
1158
-    }
1159
-
1160
-
1161
-    /**
1162
-     * @return void
1163
-     * @throws EE_Error
1164
-     * @throws InvalidArgumentException
1165
-     * @throws ReflectionException
1166
-     * @throws InvalidDataTypeException
1167
-     * @throws InvalidInterfaceException
1168
-     */
1169
-    protected function _update_reg_form_settings()
1170
-    {
1171
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1172
-            EE_Registry::instance()->CFG->registration
1173
-        );
1174
-        EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1175
-            EE_Registry::instance()->CFG->registration
1176
-        );
1177
-        $this->updateSessionLifespan();
1178
-        EE_Registry::instance()->CFG->registration = apply_filters(
1179
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1180
-            EE_Registry::instance()->CFG->registration
1181
-        );
1182
-        $success                                   = $this->_update_espresso_configuration(
1183
-            esc_html__('Registration Form Options', 'event_espresso'),
1184
-            EE_Registry::instance()->CFG,
1185
-            __FILE__,
1186
-            __FUNCTION__,
1187
-            __LINE__
1188
-        );
1189
-        $this->_redirect_after_action(
1190
-            $success,
1191
-            esc_html__('Registration Form Options', 'event_espresso'),
1192
-            'updated',
1193
-            ['action' => 'view_reg_form_settings']
1194
-        );
1195
-    }
1196
-
1197
-
1198
-    /**
1199
-     * @return void
1200
-     * @throws EE_Error
1201
-     * @throws InvalidArgumentException
1202
-     * @throws InvalidDataTypeException
1203
-     * @throws InvalidInterfaceException
1204
-     */
1205
-    public function copy_attendee_info_settings_form()
1206
-    {
1207
-        echo wp_kses($this->_copy_attendee_info_settings_form()->get_html(), AllowedTags::getWithFormTags());
1208
-    }
1209
-
1210
-
1211
-    /**
1212
-     * _copy_attendee_info_settings_form
1213
-     *
1214
-     * @access protected
1215
-     * @return EE_Form_Section_Proper
1216
-     * @throws \EE_Error
1217
-     */
1218
-    protected function _copy_attendee_info_settings_form()
1219
-    {
1220
-        return new EE_Form_Section_Proper(
1221
-            [
1222
-                'name'            => 'copy_attendee_info_settings',
1223
-                'html_id'         => 'copy_attendee_info_settings',
1224
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1225
-                'subsections'     => apply_filters(
1226
-                    'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1227
-                    [
1228
-                        'copy_attendee_info_hdr' => new EE_Form_Section_HTML(
1229
-                            EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1230
-                        ),
1231
-                        'copy_attendee_info'     => new EE_Yes_No_Input(
1232
-                            [
1233
-                                'html_label_text'         => esc_html__(
1234
-                                    'Allow copy #1 attendee info to extra attendees?',
1235
-                                    'event_espresso'
1236
-                                ),
1237
-                                'html_help_text'          => esc_html__(
1238
-                                    'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1239
-                                    'event_espresso'
1240
-                                ),
1241
-                                'default'                 => EE_Registry::instance(
1242
-                                )->CFG->registration->copyAttendeeInfo(),
1243
-                                'required'                => false,
1244
-                                'display_html_label_text' => false,
1245
-                            ]
1246
-                        ),
1247
-                    ]
1248
-                ),
1249
-            ]
1250
-        );
1251
-    }
1252
-
1253
-
1254
-    /**
1255
-     * @param EE_Registration_Config $EE_Registration_Config
1256
-     * @return EE_Registration_Config
1257
-     * @throws EE_Error
1258
-     * @throws InvalidArgumentException
1259
-     * @throws ReflectionException
1260
-     * @throws InvalidDataTypeException
1261
-     * @throws InvalidInterfaceException
1262
-     */
1263
-    public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1264
-    {
1265
-        $prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1266
-        try {
1267
-            $copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1268
-            // if not displaying a form, then check for form submission
1269
-            if ($copy_attendee_info_settings_form->was_submitted()) {
1270
-                // capture form data
1271
-                $copy_attendee_info_settings_form->receive_form_submission();
1272
-                // validate form data
1273
-                if ($copy_attendee_info_settings_form->is_valid()) {
1274
-                    // grab validated data from form
1275
-                    $valid_data = $copy_attendee_info_settings_form->valid_data();
1276
-                    if (isset($valid_data['copy_attendee_info'])) {
1277
-                        $EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1278
-                    } else {
1279
-                        EE_Error::add_error(
1280
-                            esc_html__(
1281
-                                'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1282
-                                'event_espresso'
1283
-                            ),
1284
-                            __FILE__,
1285
-                            __FUNCTION__,
1286
-                            __LINE__
1287
-                        );
1288
-                    }
1289
-                } elseif ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1290
-                    EE_Error::add_error(
1291
-                        $copy_attendee_info_settings_form->submission_error_message(),
1292
-                        __FILE__,
1293
-                        __FUNCTION__,
1294
-                        __LINE__
1295
-                    );
1296
-                }
1297
-            }
1298
-        } catch (EE_Error $e) {
1299
-            $e->get_error();
1300
-        }
1301
-        return $EE_Registration_Config;
1302
-    }
1303
-
1304
-
1305
-    /**
1306
-     * @return void
1307
-     * @throws EE_Error
1308
-     * @throws InvalidArgumentException
1309
-     * @throws InvalidDataTypeException
1310
-     * @throws InvalidInterfaceException
1311
-     */
1312
-    public function email_validation_settings_form()
1313
-    {
1314
-        echo wp_kses($this->_email_validation_settings_form()->get_html(), AllowedTags::getWithFormTags());
1315
-    }
1316
-
1317
-
1318
-    /**
1319
-     * _email_validation_settings_form
1320
-     *
1321
-     * @access protected
1322
-     * @return EE_Form_Section_Proper
1323
-     * @throws \EE_Error
1324
-     */
1325
-    protected function _email_validation_settings_form()
1326
-    {
1327
-        return new EE_Form_Section_Proper(
1328
-            [
1329
-                'name'            => 'email_validation_settings',
1330
-                'html_id'         => 'email_validation_settings',
1331
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1332
-                'subsections'     => apply_filters(
1333
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1334
-                    [
1335
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
1336
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1337
-                        ),
1338
-                        'email_validation_level' => new EE_Select_Input(
1339
-                            [
1340
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
1341
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1342
-                                'i18n'       => esc_html__('International', 'event_espresso'),
1343
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1344
-                            ],
1345
-                            [
1346
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1347
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
1348
-                                'html_help_text'  => esc_html__(
1349
-                                    'These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
1350
-                                    'event_espresso'
1351
-                                ),
1352
-                                'default'         => isset(
1353
-                                    EE_Registry::instance()->CFG->registration->email_validation_level
1354
-                                )
1355
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
1356
-                                    : 'wp_default',
1357
-                                'required'        => false,
1358
-                            ]
1359
-                        ),
1360
-                    ]
1361
-                ),
1362
-            ]
1363
-        );
1364
-    }
1365
-
1366
-
1367
-    /**
1368
-     * @param EE_Registration_Config $EE_Registration_Config
1369
-     * @return EE_Registration_Config
1370
-     * @throws EE_Error
1371
-     * @throws InvalidArgumentException
1372
-     * @throws ReflectionException
1373
-     * @throws InvalidDataTypeException
1374
-     * @throws InvalidInterfaceException
1375
-     */
1376
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1377
-    {
1378
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1379
-        try {
1380
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1381
-            // if not displaying a form, then check for form submission
1382
-            if ($email_validation_settings_form->was_submitted()) {
1383
-                // capture form data
1384
-                $email_validation_settings_form->receive_form_submission();
1385
-                // validate form data
1386
-                if ($email_validation_settings_form->is_valid()) {
1387
-                    // grab validated data from form
1388
-                    $valid_data = $email_validation_settings_form->valid_data();
1389
-                    if (isset($valid_data['email_validation_level'])) {
1390
-                        $email_validation_level = $valid_data['email_validation_level'];
1391
-                        // now if they want to use international email addresses
1392
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1393
-                            // in case we need to reset their email validation level,
1394
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1395
-                            if (
1396
-                                $prev_email_validation_level === 'i18n'
1397
-                                || $prev_email_validation_level
1398
-                                   === 'i18n_dns'
1399
-                            ) {
1400
-                                // if so, then reset it back to "basic" since that is the only other option that,
1401
-                                // despite offering poor validation, supports i18n email addresses
1402
-                                $prev_email_validation_level = 'basic';
1403
-                            }
1404
-                            // confirm our i18n email validation will work on the server
1405
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1406
-                                // or reset email validation level to previous value
1407
-                                $email_validation_level = $prev_email_validation_level;
1408
-                            }
1409
-                        }
1410
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1411
-                    } else {
1412
-                        EE_Error::add_error(
1413
-                            esc_html__(
1414
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1415
-                                'event_espresso'
1416
-                            ),
1417
-                            __FILE__,
1418
-                            __FUNCTION__,
1419
-                            __LINE__
1420
-                        );
1421
-                    }
1422
-                } elseif ($email_validation_settings_form->submission_error_message() !== '') {
1423
-                    EE_Error::add_error(
1424
-                        $email_validation_settings_form->submission_error_message(),
1425
-                        __FILE__,
1426
-                        __FUNCTION__,
1427
-                        __LINE__
1428
-                    );
1429
-                }
1430
-            }
1431
-        } catch (EE_Error $e) {
1432
-            $e->get_error();
1433
-        }
1434
-        return $EE_Registration_Config;
1435
-    }
1436
-
1437
-
1438
-    /**
1439
-     * confirms that the server's PHP version has the PCRE module enabled,
1440
-     * and that the PCRE version works with our i18n email validation
1441
-     *
1442
-     * @param EE_Registration_Config $EE_Registration_Config
1443
-     * @param string                 $email_validation_level
1444
-     * @return bool
1445
-     */
1446
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1447
-    {
1448
-        // first check that PCRE is enabled
1449
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1450
-            EE_Error::add_error(
1451
-                sprintf(
1452
-                    esc_html__(
1453
-                        'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1454
-                        'event_espresso'
1455
-                    ),
1456
-                    '<br />'
1457
-                ),
1458
-                __FILE__,
1459
-                __FUNCTION__,
1460
-                __LINE__
1461
-            );
1462
-            return false;
1463
-        } else {
1464
-            // PCRE support is enabled, but let's still
1465
-            // perform a test to see if the server will support it.
1466
-            // but first, save the updated validation level to the config,
1467
-            // so that the validation strategy picks it up.
1468
-            // this will get bumped back down if it doesn't work
1469
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1470
-            try {
1471
-                $email_validator    = new EE_Email_Validation_Strategy();
1472
-                $i18n_email_address = apply_filters(
1473
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1474
-                    'jägerjü[email protected]'
1475
-                );
1476
-                $email_validator->validate($i18n_email_address);
1477
-            } catch (Exception $e) {
1478
-                EE_Error::add_error(
1479
-                    sprintf(
1480
-                        esc_html__(
1481
-                            'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1482
-                            'event_espresso'
1483
-                        ),
1484
-                        '<br />',
1485
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1486
-                    ),
1487
-                    __FILE__,
1488
-                    __FUNCTION__,
1489
-                    __LINE__
1490
-                );
1491
-                return false;
1492
-            }
1493
-        }
1494
-        return true;
1495
-    }
1496
-
1497
-
1498
-    public function setSessionLifespan()
1499
-    {
1500
-        $session_lifespan_form = $this->loader->getNew(SessionLifespanForm::class);
1501
-        echo wp_kses($session_lifespan_form->get_html(), AllowedTags::getWithFormTags());
1502
-    }
1503
-
1504
-
1505
-    public function updateSessionLifespan()
1506
-    {
1507
-        $handler = $this->loader->getNew(SessionLifespanFormHandler::class);
1508
-        $handler->process($this->loader->getNew(SessionLifespanForm::class));
1509
-    }
19
+	/**
20
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
21
+	 * @throws EE_Error
22
+	 * @throws ReflectionException
23
+	 */
24
+	public function __construct($routing = true)
25
+	{
26
+		define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
27
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
28
+		define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
29
+		define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
30
+		define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
31
+		parent::__construct($routing);
32
+	}
33
+
34
+
35
+	protected function _define_page_props()
36
+	{
37
+		parent::_define_page_props();
38
+		$this->_labels['publishbox'] = [
39
+			'add_question'        => esc_html__('Add New Question', 'event_espresso'),
40
+			'edit_question'       => esc_html__('Edit Question', 'event_espresso'),
41
+			'add_question_group'  => esc_html__('Add New Question Group', 'event_espresso'),
42
+			'edit_question_group' => esc_html__('Edit Question Group', 'event_espresso'),
43
+		];
44
+	}
45
+
46
+
47
+	protected function _set_page_config()
48
+	{
49
+		parent::_set_page_config();
50
+
51
+		$this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
52
+		$qst_id                 = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
53
+			? $this->_req_data['QST_ID'] : 0;
54
+		$qsg_id                 = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
55
+			? $this->_req_data['QSG_ID'] : 0;
56
+
57
+		$new_page_routes    = [
58
+			'question_groups'    => [
59
+				'func'       => '_question_groups_overview_list_table',
60
+				'capability' => 'ee_read_question_groups',
61
+			],
62
+			'add_question'       => [
63
+				'func'       => '_edit_question',
64
+				'capability' => 'ee_edit_questions',
65
+			],
66
+			'insert_question'    => [
67
+				'func'       => '_insert_or_update_question',
68
+				'args'       => ['new_question' => true],
69
+				'capability' => 'ee_edit_questions',
70
+				'noheader'   => true,
71
+			],
72
+			'duplicate_question' => [
73
+				'func'       => '_duplicate_question',
74
+				'capability' => 'ee_edit_questions',
75
+				'noheader'   => true,
76
+			],
77
+			'trash_question'     => [
78
+				'func'       => '_trash_question',
79
+				'capability' => 'ee_delete_question',
80
+				'obj_id'     => $qst_id,
81
+				'noheader'   => true,
82
+			],
83
+
84
+			'restore_question' => [
85
+				'func'       => '_trash_or_restore_questions',
86
+				'capability' => 'ee_delete_question',
87
+				'obj_id'     => $qst_id,
88
+				'args'       => ['trash' => false],
89
+				'noheader'   => true,
90
+			],
91
+
92
+			'delete_question' => [
93
+				'func'       => '_delete_question',
94
+				'capability' => 'ee_delete_question',
95
+				'obj_id'     => $qst_id,
96
+				'noheader'   => true,
97
+			],
98
+
99
+			'trash_questions' => [
100
+				'func'       => '_trash_or_restore_questions',
101
+				'capability' => 'ee_delete_questions',
102
+				'args'       => ['trash' => true],
103
+				'noheader'   => true,
104
+			],
105
+
106
+			'restore_questions' => [
107
+				'func'       => '_trash_or_restore_questions',
108
+				'capability' => 'ee_delete_questions',
109
+				'args'       => ['trash' => false],
110
+				'noheader'   => true,
111
+			],
112
+
113
+			'delete_questions' => [
114
+				'func'       => '_delete_questions',
115
+				'args'       => [],
116
+				'capability' => 'ee_delete_questions',
117
+				'noheader'   => true,
118
+			],
119
+
120
+			'add_question_group' => [
121
+				'func'       => '_edit_question_group',
122
+				'capability' => 'ee_edit_question_groups',
123
+			],
124
+
125
+			'edit_question_group' => [
126
+				'func'       => '_edit_question_group',
127
+				'capability' => 'ee_edit_question_group',
128
+				'obj_id'     => $qsg_id,
129
+				'args'       => ['edit'],
130
+			],
131
+
132
+			'delete_question_groups' => [
133
+				'func'       => '_delete_question_groups',
134
+				'capability' => 'ee_delete_question_groups',
135
+				'noheader'   => true,
136
+			],
137
+
138
+			'delete_question_group' => [
139
+				'func'       => '_delete_question_groups',
140
+				'capability' => 'ee_delete_question_group',
141
+				'obj_id'     => $qsg_id,
142
+				'noheader'   => true,
143
+			],
144
+
145
+			'trash_question_group' => [
146
+				'func'       => '_trash_or_restore_question_groups',
147
+				'args'       => ['trash' => true],
148
+				'capability' => 'ee_delete_question_group',
149
+				'obj_id'     => $qsg_id,
150
+				'noheader'   => true,
151
+			],
152
+
153
+			'restore_question_group' => [
154
+				'func'       => '_trash_or_restore_question_groups',
155
+				'args'       => ['trash' => false],
156
+				'capability' => 'ee_delete_question_group',
157
+				'obj_id'     => $qsg_id,
158
+				'noheader'   => true,
159
+			],
160
+
161
+			'insert_question_group' => [
162
+				'func'       => '_insert_or_update_question_group',
163
+				'args'       => ['new_question_group' => true],
164
+				'capability' => 'ee_edit_question_groups',
165
+				'noheader'   => true,
166
+			],
167
+
168
+			'update_question_group' => [
169
+				'func'       => '_insert_or_update_question_group',
170
+				'args'       => ['new_question_group' => false],
171
+				'capability' => 'ee_edit_question_group',
172
+				'obj_id'     => $qsg_id,
173
+				'noheader'   => true,
174
+			],
175
+
176
+			'trash_question_groups' => [
177
+				'func'       => '_trash_or_restore_question_groups',
178
+				'args'       => ['trash' => true],
179
+				'capability' => 'ee_delete_question_groups',
180
+				'noheader'   => ['trash' => false],
181
+			],
182
+
183
+			'restore_question_groups' => [
184
+				'func'       => '_trash_or_restore_question_groups',
185
+				'args'       => ['trash' => false],
186
+				'capability' => 'ee_delete_question_groups',
187
+				'noheader'   => true,
188
+			],
189
+
190
+
191
+			'espresso_update_question_group_order' => [
192
+				'func'       => 'update_question_group_order',
193
+				'capability' => 'ee_edit_question_groups',
194
+				'noheader'   => true,
195
+			],
196
+
197
+			'view_reg_form_settings' => [
198
+				'func'       => '_reg_form_settings',
199
+				'capability' => 'manage_options',
200
+			],
201
+
202
+			'update_reg_form_settings' => [
203
+				'func'       => '_update_reg_form_settings',
204
+				'capability' => 'manage_options',
205
+				'noheader'   => true,
206
+			],
207
+		];
208
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
209
+
210
+		$new_page_config    = [
211
+
212
+			'question_groups' => [
213
+				'nav'           => [
214
+					'label' => esc_html__('Question Groups', 'event_espresso'),
215
+					'icon'  => 'dashicons-forms',
216
+					'order' => 20,
217
+				],
218
+				'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
219
+				'help_tabs'     => [
220
+					'registration_form_question_groups_help_tab'                           => [
221
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
222
+						'filename' => 'registration_form_question_groups',
223
+					],
224
+					'registration_form_question_groups_table_column_headings_help_tab'     => [
225
+						'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
226
+						'filename' => 'registration_form_question_groups_table_column_headings',
227
+					],
228
+					'registration_form_question_groups_views_bulk_actions_search_help_tab' => [
229
+						'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
230
+						'filename' => 'registration_form_question_groups_views_bulk_actions_search',
231
+					],
232
+				],
233
+				'metaboxes'     => $this->_default_espresso_metaboxes,
234
+				'require_nonce' => false,
235
+			],
236
+
237
+			'add_question' => [
238
+				'nav'           => [
239
+					'label'      => esc_html__('Add Question', 'event_espresso'),
240
+					'icon'       => 'dashicons-plus-alt',
241
+					'order'      => 15,
242
+					'persistent' => false,
243
+				],
244
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
245
+				'help_tabs'     => [
246
+					'registration_form_add_question_help_tab' => [
247
+						'title'    => esc_html__('Add Question', 'event_espresso'),
248
+						'filename' => 'registration_form_add_question',
249
+					],
250
+				],
251
+				'require_nonce' => false,
252
+			],
253
+
254
+			'add_question_group' => [
255
+				'nav'           => [
256
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
257
+					'icon'       => 'dashicons-plus-alt',
258
+					'order'      => 25,
259
+					'persistent' => false,
260
+				],
261
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
262
+				'help_tabs'     => [
263
+					'registration_form_add_question_group_help_tab' => [
264
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
265
+						'filename' => 'registration_form_add_question_group',
266
+					],
267
+				],
268
+				'require_nonce' => false,
269
+			],
270
+
271
+			'edit_question_group' => [
272
+				'nav'           => [
273
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
274
+					'icon'       => 'dashicons-edit-large',
275
+					'order'      => 25,
276
+					'persistent' => false,
277
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
278
+						['question_group_id' => $this->_req_data['question_group_id']],
279
+						$this->_current_page_view_url
280
+					) : $this->_admin_base_url,
281
+				],
282
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
283
+				'help_tabs'     => [
284
+					'registration_form_edit_question_group_help_tab' => [
285
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
286
+						'filename' => 'registration_form_edit_question_group',
287
+					],
288
+				],
289
+				'require_nonce' => false,
290
+			],
291
+
292
+			'view_reg_form_settings' => [
293
+				'nav'           => [
294
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
295
+					'icon'  => 'dashicons-admin-generic',
296
+					'order' => 40,
297
+				],
298
+				'labels'        => [
299
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
300
+				],
301
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
302
+				'help_tabs'     => [
303
+					'registration_form_reg_form_settings_help_tab' => [
304
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
305
+						'filename' => 'registration_form_reg_form_settings',
306
+					],
307
+				],
308
+				'require_nonce' => false,
309
+			],
310
+
311
+		];
312
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
313
+
314
+		// change the list table we're going to use so it's the NEW list table!
315
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
316
+
317
+
318
+		// additional labels
319
+		$new_labels               = [
320
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
321
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
322
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
323
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
324
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
325
+		];
326
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
327
+	}
328
+
329
+
330
+	/**
331
+	 * @return void
332
+	 */
333
+	protected function _ajax_hooks()
334
+	{
335
+		if (! $this->capabilities->current_user_can('ee_edit_question_groups', 'edit-questions')) {
336
+			return;
337
+		}
338
+		add_action('wp_ajax_espresso_update_question_group_order', [$this, 'update_question_group_order']);
339
+	}
340
+
341
+
342
+	/**
343
+	 * @return void
344
+	 */
345
+	public function load_scripts_styles_question_groups()
346
+	{
347
+		wp_enqueue_script('espresso_ajax_table_sorting');
348
+	}
349
+
350
+
351
+	/**
352
+	 * @return void
353
+	 */
354
+	public function load_scripts_styles_add_question_group()
355
+	{
356
+		$this->load_scripts_styles_forms();
357
+		$this->load_sortable_question_script();
358
+	}
359
+
360
+
361
+	/**
362
+	 * @return void
363
+	 */
364
+	public function load_scripts_styles_edit_question_group()
365
+	{
366
+		$this->load_scripts_styles_forms();
367
+		$this->load_sortable_question_script();
368
+	}
369
+
370
+
371
+	/**
372
+	 * registers and enqueues script for questions
373
+	 *
374
+	 * @return void
375
+	 */
376
+	public function load_sortable_question_script()
377
+	{
378
+		wp_register_script(
379
+			'ee-question-sortable',
380
+			REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
381
+			['jquery-ui-sortable'],
382
+			EVENT_ESPRESSO_VERSION,
383
+			true
384
+		);
385
+		wp_enqueue_script('ee-question-sortable');
386
+	}
387
+
388
+
389
+	/**
390
+	 * @return void
391
+	 */
392
+	protected function _set_list_table_views_default()
393
+	{
394
+		$this->_views = [
395
+			'all' => [
396
+				'slug'        => 'all',
397
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
398
+				'count'       => 0,
399
+				'bulk_action' => [
400
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
401
+				],
402
+			],
403
+		];
404
+
405
+		if (
406
+		EE_Registry::instance()->CAP->current_user_can(
407
+			'ee_delete_questions',
408
+			'espresso_registration_form_trash_questions'
409
+		)
410
+		) {
411
+			$this->_views['trash'] = [
412
+				'slug'        => 'trash',
413
+				'label'       => esc_html__('Trash', 'event_espresso'),
414
+				'count'       => 0,
415
+				'bulk_action' => [
416
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
417
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
418
+				],
419
+			];
420
+		}
421
+	}
422
+
423
+
424
+	/**
425
+	 * @return void
426
+	 */
427
+	protected function _set_list_table_views_question_groups()
428
+	{
429
+		$this->_views = [
430
+			'all' => [
431
+				'slug'        => 'all',
432
+				'label'       => esc_html__('All', 'event_espresso'),
433
+				'count'       => 0,
434
+				'bulk_action' => [
435
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
436
+				],
437
+			],
438
+		];
439
+
440
+		if (
441
+		EE_Registry::instance()->CAP->current_user_can(
442
+			'ee_delete_question_groups',
443
+			'espresso_registration_form_trash_question_groups'
444
+		)
445
+		) {
446
+			$this->_views['trash'] = [
447
+				'slug'        => 'trash',
448
+				'label'       => esc_html__('Trash', 'event_espresso'),
449
+				'count'       => 0,
450
+				'bulk_action' => [
451
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
452
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
453
+				],
454
+			];
455
+		}
456
+	}
457
+
458
+
459
+	/**
460
+	 * @return void
461
+	 * @throws EE_Error
462
+	 * @throws InvalidArgumentException
463
+	 * @throws InvalidDataTypeException
464
+	 * @throws InvalidInterfaceException
465
+	 */
466
+	protected function _questions_overview_list_table()
467
+	{
468
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
469
+				'add_question',
470
+				'add_question',
471
+				[],
472
+				'add-new-h2'
473
+			);
474
+		parent::_questions_overview_list_table();
475
+	}
476
+
477
+
478
+	/**
479
+	 * @return void
480
+	 * @throws DomainException
481
+	 * @throws EE_Error
482
+	 * @throws InvalidArgumentException
483
+	 * @throws InvalidDataTypeException
484
+	 * @throws InvalidInterfaceException
485
+	 */
486
+	protected function _question_groups_overview_list_table()
487
+	{
488
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
489
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
490
+				'add_question_group',
491
+				'add_question_group',
492
+				[],
493
+				'add-new-h2'
494
+			);
495
+		$this->display_admin_list_table_page_with_sidebar();
496
+	}
497
+
498
+
499
+	/**
500
+	 * @return void
501
+	 * @throws EE_Error
502
+	 * @throws InvalidArgumentException
503
+	 * @throws InvalidDataTypeException
504
+	 * @throws InvalidInterfaceException
505
+	 * @throws ReflectionException
506
+	 */
507
+	protected function _delete_question()
508
+	{
509
+		$success = $this->_delete_items($this->_question_model);
510
+		$this->_redirect_after_action(
511
+			$success,
512
+			$this->_question_model->item_name($success),
513
+			'deleted',
514
+			['action' => 'default', 'status' => 'all']
515
+		);
516
+	}
517
+
518
+
519
+	/**
520
+	 * @return void
521
+	 * @throws EE_Error
522
+	 * @throws InvalidArgumentException
523
+	 * @throws InvalidDataTypeException
524
+	 * @throws InvalidInterfaceException
525
+	 * @throws ReflectionException
526
+	 */
527
+	protected function _delete_questions()
528
+	{
529
+		$success = $this->_delete_items($this->_question_model);
530
+		$this->_redirect_after_action(
531
+			$success,
532
+			$this->_question_model->item_name($success),
533
+			'deleted permanently',
534
+			['action' => 'default', 'status' => 'trash']
535
+		);
536
+	}
537
+
538
+
539
+	/**
540
+	 * Performs the deletion of a single or multiple questions or question groups.
541
+	 *
542
+	 * @param EEM_Soft_Delete_Base $model
543
+	 * @return int number of items deleted permanently
544
+	 * @throws EE_Error
545
+	 * @throws InvalidArgumentException
546
+	 * @throws InvalidDataTypeException
547
+	 * @throws InvalidInterfaceException
548
+	 * @throws ReflectionException
549
+	 */
550
+	private function _delete_items(EEM_Soft_Delete_Base $model)
551
+	{
552
+		$success = 0;
553
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
554
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
555
+			// if array has more than one element than success message should be plural
556
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
557
+			// cycle thru bulk action checkboxes
558
+			$checkboxes = $this->_req_data['checkbox'];
559
+			foreach (array_keys($checkboxes) as $ID) {
560
+				if (! $this->_delete_item($ID, $model)) {
561
+					$success = 0;
562
+				}
563
+			}
564
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
565
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
566
+		} elseif (! empty($this->_req_data['QST_ID'])) {
567
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
568
+		} else {
569
+			EE_Error::add_error(
570
+				sprintf(
571
+					esc_html__(
572
+						"No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
573
+						"event_espresso"
574
+					)
575
+				),
576
+				__FILE__,
577
+				__FUNCTION__,
578
+				__LINE__
579
+			);
580
+		}
581
+		return $success;
582
+	}
583
+
584
+
585
+	/**
586
+	 * Deletes the specified question (and its associated question options) or question group
587
+	 *
588
+	 * @param int                  $id
589
+	 * @param EEM_Soft_Delete_Base $model
590
+	 * @return boolean
591
+	 * @throws EE_Error
592
+	 * @throws InvalidArgumentException
593
+	 * @throws InvalidDataTypeException
594
+	 * @throws InvalidInterfaceException
595
+	 * @throws ReflectionException
596
+	 */
597
+	protected function _delete_item($id, $model)
598
+	{
599
+		if ($model instanceof EEM_Question) {
600
+			EEM_Question_Option::instance()->delete_permanently([['QST_ID' => absint($id)]]);
601
+		}
602
+		return $model->delete_permanently_by_ID(absint($id));
603
+	}
604
+
605
+
606
+	/******************************    QUESTION GROUPS    ******************************/
607
+
608
+
609
+	/**
610
+	 * @param string $type
611
+	 * @return void
612
+	 * @throws DomainException
613
+	 * @throws EE_Error
614
+	 * @throws InvalidArgumentException
615
+	 * @throws InvalidDataTypeException
616
+	 * @throws InvalidInterfaceException
617
+	 * @throws ReflectionException
618
+	 */
619
+	protected function _edit_question_group($type = 'add')
620
+	{
621
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
622
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
623
+			? absint($this->_req_data['QSG_ID'])
624
+			: false;
625
+
626
+		switch ($this->_req_action) {
627
+			case 'add_question_group':
628
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
629
+				break;
630
+			case 'edit_question_group':
631
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
632
+				break;
633
+			default:
634
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
635
+		}
636
+		// add ID to title if editing
637
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
638
+		if ($ID) {
639
+			/** @var EE_Question_Group $questionGroup */
640
+			$questionGroup            = $this->_question_group_model->get_one_by_ID($ID);
641
+			$additional_hidden_fields = ['QSG_ID' => ['type' => 'hidden', 'value' => $ID]];
642
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
643
+		} else {
644
+			/** @var EE_Question_Group $questionGroup */
645
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
646
+			$questionGroup->set_order_to_latest();
647
+			$this->_set_add_edit_form_tags('insert_question_group');
648
+		}
649
+		$this->_template_args['values']         = $this->_yes_no_values;
650
+		$this->_template_args['all_questions']  = $questionGroup->questions_in_and_not_in_group();
651
+		$this->_template_args['QSG_ID']         = $ID ? $ID : true;
652
+		$this->_template_args['question_group'] = $questionGroup;
653
+
654
+		$redirect_URL = add_query_arg(['action' => 'question_groups'], $this->_admin_base_url);
655
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL, true);
656
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
657
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
658
+			$this->_template_args,
659
+			true
660
+		);
661
+
662
+		// the details template wrapper
663
+		$this->display_admin_page_with_sidebar();
664
+	}
665
+
666
+
667
+	/**
668
+	 * @return void
669
+	 * @throws EE_Error
670
+	 * @throws InvalidArgumentException
671
+	 * @throws InvalidDataTypeException
672
+	 * @throws InvalidInterfaceException
673
+	 * @throws ReflectionException
674
+	 */
675
+	protected function _delete_question_groups()
676
+	{
677
+		$success = $this->_delete_items($this->_question_group_model);
678
+		$this->_redirect_after_action(
679
+			$success,
680
+			$this->_question_group_model->item_name($success),
681
+			'deleted permanently',
682
+			['action' => 'question_groups', 'status' => 'trash']
683
+		);
684
+	}
685
+
686
+
687
+	/**
688
+	 * @param bool $new_question_group
689
+	 * @throws EE_Error
690
+	 * @throws InvalidArgumentException
691
+	 * @throws InvalidDataTypeException
692
+	 * @throws InvalidInterfaceException
693
+	 * @throws ReflectionException
694
+	 */
695
+	protected function _insert_or_update_question_group($new_question_group = true)
696
+	{
697
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
698
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
699
+
700
+		// make sure identifier is unique
701
+		$identifier_value = $set_column_values['QSG_identifier'] ?? '';
702
+		$where_values     = ['QSG_identifier' => $identifier_value];
703
+		if (! $new_question_group && isset($set_column_values['QSG_ID'])) {
704
+			$where_values['QSG_ID'] = ['!=', $set_column_values['QSG_ID']];
705
+		}
706
+		$identifier_exists = ! empty($identifier_value) && $this->_question_group_model->count([$where_values]) > 0;
707
+		if ($identifier_exists) {
708
+			$set_column_values['QSG_identifier'] .= uniqid('id', true);
709
+		}
710
+
711
+		if ($new_question_group) {
712
+			$QSG_ID  = $this->_question_group_model->insert($set_column_values);
713
+			$success = $QSG_ID ? 1 : 0;
714
+			if ($success === 0) {
715
+				EE_Error::add_error(
716
+					esc_html__('Something went wrong saving the question group.', 'event_espresso'),
717
+					__FILE__,
718
+					__FUNCTION__,
719
+					__LINE__
720
+				);
721
+				$this->_redirect_after_action(
722
+					false,
723
+					'',
724
+					'',
725
+					['action' => 'edit_question_group', 'QSG_ID' => $QSG_ID],
726
+					true
727
+				);
728
+			}
729
+		} else {
730
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
731
+			unset($set_column_values['QSG_ID']);
732
+			$success = $this->_question_group_model->update($set_column_values, [['QSG_ID' => $QSG_ID]]);
733
+		}
734
+
735
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
736
+			EEM_Attendee::system_question_phone
737
+		);
738
+		// update the existing related questions
739
+		// BUT FIRST...  delete the phone question from the Question_Group_Question
740
+		// if it is being added to this question group (therefore removed from the existing group)
741
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
742
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
743
+			EEM_Question_Group_Question::instance()->delete(
744
+				[
745
+					[
746
+						'QST_ID' => $phone_question_id,
747
+						'QSG_ID' => ['!=', $QSG_ID],
748
+					],
749
+				]
750
+			);
751
+		}
752
+		/** @type EE_Question_Group $question_group */
753
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
754
+		$questions      = $question_group->questions();
755
+		// make sure system phone question is added to list of questions for this group
756
+		if (! isset($questions[ $phone_question_id ])) {
757
+			$questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
758
+		}
759
+
760
+		foreach ($questions as $question_ID => $question) {
761
+			// first we always check for order.
762
+			if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
763
+				// update question order
764
+				$question_group->update_question_order(
765
+					$question_ID,
766
+					$this->_req_data['question_orders'][ $question_ID ]
767
+				);
768
+			}
769
+
770
+			// then we always check if adding or removing.
771
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
772
+				$question_group->add_question($question_ID);
773
+			} else {
774
+				// not found, remove it (but only if not a system question for the personal group
775
+				// with the exception of lname system question - we allow removal of it)
776
+				if (
777
+				in_array(
778
+					$question->system_ID(),
779
+					EEM_Question::instance()->required_system_questions_in_system_question_group(
780
+						$question_group->system_group()
781
+					)
782
+				)
783
+				) {
784
+					continue;
785
+				} else {
786
+					$question_group->remove_question($question_ID);
787
+				}
788
+			}
789
+		}
790
+		// save new related questions
791
+		if (isset($this->_req_data['questions'])) {
792
+			foreach ($this->_req_data['questions'] as $QST_ID) {
793
+				$question_group->add_question($QST_ID);
794
+				if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
795
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
796
+				}
797
+			}
798
+		}
799
+
800
+		if ($success !== false) {
801
+			$msg = $new_question_group
802
+				? sprintf(
803
+					esc_html__('The %s has been created', 'event_espresso'),
804
+					$this->_question_group_model->item_name()
805
+				)
806
+				: sprintf(
807
+					esc_html__(
808
+						'The %s has been updated',
809
+						'event_espresso'
810
+					),
811
+					$this->_question_group_model->item_name()
812
+				);
813
+			EE_Error::add_success($msg);
814
+		}
815
+		$this->_redirect_after_action(
816
+			false,
817
+			'',
818
+			'',
819
+			['action' => 'edit_question_group', 'QSG_ID' => $QSG_ID],
820
+			true
821
+		);
822
+	}
823
+
824
+
825
+	/**
826
+	 * duplicates a question and all its question options and redirects to the new question.
827
+	 *
828
+	 * @return void
829
+	 * @throws EE_Error
830
+	 * @throws InvalidArgumentException
831
+	 * @throws ReflectionException
832
+	 * @throws InvalidDataTypeException
833
+	 * @throws InvalidInterfaceException
834
+	 */
835
+	public function _duplicate_question()
836
+	{
837
+		$question_ID = (int) $this->_req_data['QST_ID'];
838
+		$question    = EEM_Question::instance()->get_one_by_ID($question_ID);
839
+		if ($question instanceof EE_Question) {
840
+			$new_question = $question->duplicate();
841
+			if ($new_question instanceof EE_Question) {
842
+				$this->_redirect_after_action(
843
+					true,
844
+					esc_html__('Question', 'event_espresso'),
845
+					esc_html__('Duplicated', 'event_espresso'),
846
+					['action' => 'edit_question', 'QST_ID' => $new_question->ID()],
847
+					true
848
+				);
849
+			} else {
850
+				global $wpdb;
851
+				EE_Error::add_error(
852
+					sprintf(
853
+						esc_html__(
854
+							'Could not duplicate question with ID %1$d because: %2$s',
855
+							'event_espresso'
856
+						),
857
+						$question_ID,
858
+						$wpdb->last_error
859
+					),
860
+					__FILE__,
861
+					__FUNCTION__,
862
+					__LINE__
863
+				);
864
+				$this->_redirect_after_action(false, '', '', ['action' => 'default'], false);
865
+			}
866
+		} else {
867
+			EE_Error::add_error(
868
+				sprintf(
869
+					esc_html__(
870
+						'Could not duplicate question with ID %d because it didn\'t exist!',
871
+						'event_espresso'
872
+					),
873
+					$question_ID
874
+				),
875
+				__FILE__,
876
+				__FUNCTION__,
877
+				__LINE__
878
+			);
879
+			$this->_redirect_after_action(false, '', '', ['action' => 'default'], false);
880
+		}
881
+	}
882
+
883
+
884
+	/**
885
+	 * @param bool $trash
886
+	 * @throws EE_Error
887
+	 */
888
+	protected function _trash_or_restore_question_groups($trash = true)
889
+	{
890
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
891
+	}
892
+
893
+
894
+	/**
895
+	 *_trash_question
896
+	 *
897
+	 * @return void
898
+	 * @throws EE_Error
899
+	 */
900
+	protected function _trash_question()
901
+	{
902
+		$success    = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
903
+		$query_args = ['action' => 'default', 'status' => 'all'];
904
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
905
+	}
906
+
907
+
908
+	/**
909
+	 * @param bool $trash
910
+	 * @throws EE_Error
911
+	 */
912
+	protected function _trash_or_restore_questions($trash = true)
913
+	{
914
+		$this->_trash_or_restore_items($this->_question_model, $trash);
915
+	}
916
+
917
+
918
+	/**
919
+	 * Internally used to delete or restore items, using the request data. Meant to be
920
+	 * flexible between question or question groups
921
+	 *
922
+	 * @param EEM_Soft_Delete_Base $model
923
+	 * @param boolean              $trash whether to trash or restore
924
+	 * @throws EE_Error
925
+	 */
926
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
927
+	{
928
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
929
+
930
+		$success = 1;
931
+		// Checkboxes
932
+		// echo "trash $trash";
933
+		// var_dump($this->_req_data['checkbox']);die;
934
+		if (isset($this->_req_data['checkbox'])) {
935
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
936
+				// if array has more than one element than success message should be plural
937
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
938
+				// cycle thru bulk action checkboxes
939
+				$checkboxes = $this->_req_data['checkbox'];
940
+				foreach (array_keys($checkboxes) as $ID) {
941
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
942
+						$success = 0;
943
+					}
944
+				}
945
+			} else {
946
+				// grab single id and delete
947
+				$ID = absint($this->_req_data['checkbox']);
948
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
949
+					$success = 0;
950
+				}
951
+			}
952
+		} else {
953
+			// delete via trash link
954
+			// grab single id and delete
955
+			$ID = absint($this->_req_data[ $model->primary_key_name() ]);
956
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
957
+				$success = 0;
958
+			}
959
+		}
960
+
961
+
962
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
963
+		// echo "action :$action";
964
+		// $action = 'questions' ? 'default' : $action;
965
+		if ($trash) {
966
+			$action_desc = 'trashed';
967
+			$status      = 'trash';
968
+		} else {
969
+			$action_desc = 'restored';
970
+			$status      = 'all';
971
+		}
972
+		$this->_redirect_after_action(
973
+			$success,
974
+			$model->item_name($success),
975
+			$action_desc,
976
+			['action' => $action, 'status' => $status]
977
+		);
978
+	}
979
+
980
+
981
+	/**
982
+	 * @param            $per_page
983
+	 * @param int        $current_page
984
+	 * @param bool|false $count
985
+	 * @return EE_Soft_Delete_Base_Class[]|int
986
+	 * @throws EE_Error
987
+	 * @throws InvalidArgumentException
988
+	 * @throws InvalidDataTypeException
989
+	 * @throws InvalidInterfaceException
990
+	 * @throws ReflectionException
991
+	 */
992
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
993
+	{
994
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
995
+
996
+		if ($count) {
997
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
998
+			$where   = isset($query_params[0]) ? [$query_params[0]] : [];
999
+			$results = $this->_question_model->count_deleted($where);
1000
+		} else {
1001
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
1002
+			$results = $this->_question_model->get_all_deleted($query_params);
1003
+		}
1004
+		return $results;
1005
+	}
1006
+
1007
+
1008
+	/**
1009
+	 * @param            $per_page
1010
+	 * @param int        $current_page
1011
+	 * @param bool|false $count
1012
+	 * @return EE_Soft_Delete_Base_Class[]|int
1013
+	 * @throws EE_Error
1014
+	 * @throws InvalidArgumentException
1015
+	 * @throws InvalidDataTypeException
1016
+	 * @throws InvalidInterfaceException
1017
+	 * @throws ReflectionException
1018
+	 */
1019
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
1020
+	{
1021
+		$questionGroupModel = EEM_Question_Group::instance();
1022
+		$query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1023
+		if ($count) {
1024
+			$where   = isset($query_params[0]) ? [$query_params[0]] : [];
1025
+			$results = $questionGroupModel->count($where);
1026
+		} else {
1027
+			$results = $questionGroupModel->get_all($query_params);
1028
+		}
1029
+		return $results;
1030
+	}
1031
+
1032
+
1033
+	/**
1034
+	 * @param      $per_page
1035
+	 * @param int  $current_page
1036
+	 * @param bool $count
1037
+	 * @return EE_Soft_Delete_Base_Class[]|int
1038
+	 * @throws EE_Error
1039
+	 * @throws InvalidArgumentException
1040
+	 * @throws InvalidDataTypeException
1041
+	 * @throws InvalidInterfaceException
1042
+	 * @throws ReflectionException
1043
+	 */
1044
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1045
+	{
1046
+		$questionGroupModel = EEM_Question_Group::instance();
1047
+		$query_params       = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1048
+		if ($count) {
1049
+			$where                 = isset($query_params[0]) ? [$query_params[0]] : [];
1050
+			$query_params['limit'] = null;
1051
+			$results               = $questionGroupModel->count_deleted($where);
1052
+		} else {
1053
+			$results = $questionGroupModel->get_all_deleted($query_params);
1054
+		}
1055
+		return $results;
1056
+	}
1057
+
1058
+
1059
+	/**
1060
+	 * method for performing updates to question order
1061
+	 *
1062
+	 * @return void results array
1063
+	 * @throws EE_Error
1064
+	 * @throws InvalidArgumentException
1065
+	 * @throws InvalidDataTypeException
1066
+	 * @throws InvalidInterfaceException
1067
+	 * @throws ReflectionException
1068
+	 */
1069
+	public function update_question_group_order()
1070
+	{
1071
+		if (! $this->capabilities->current_user_can('ee_edit_question_groups', __FUNCTION__)) {
1072
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
1073
+		}
1074
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1075
+
1076
+		// grab our row IDs
1077
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1078
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
1079
+			: [];
1080
+
1081
+		$perpage = ! empty($this->_req_data['perpage'])
1082
+			? (int) $this->_req_data['perpage']
1083
+			: null;
1084
+		$curpage = ! empty($this->_req_data['curpage'])
1085
+			? (int) $this->_req_data['curpage']
1086
+			: null;
1087
+
1088
+		if (! empty($row_ids)) {
1089
+			// figure out where we start the row_id count at for the current page.
1090
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1091
+
1092
+			$row_count = count($row_ids);
1093
+			for ($i = 0; $i < $row_count; $i++) {
1094
+				// Update the questions when re-ordering
1095
+				$updated = EEM_Question_Group::instance()->update(
1096
+					['QSG_order' => $qsgcount],
1097
+					[['QSG_ID' => $row_ids[ $i ]]]
1098
+				);
1099
+				if ($updated === false) {
1100
+					$success = false;
1101
+				}
1102
+				$qsgcount++;
1103
+			}
1104
+		} else {
1105
+			$success = false;
1106
+		}
1107
+
1108
+		$errors = ! $success
1109
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1110
+			: false;
1111
+
1112
+		echo wp_json_encode(['return_data' => false, 'success' => $success, 'errors' => $errors]);
1113
+		die();
1114
+	}
1115
+
1116
+
1117
+
1118
+	/***************************************       REGISTRATION SETTINGS       ***************************************/
1119
+
1120
+
1121
+	/**
1122
+	 * @throws DomainException
1123
+	 * @throws EE_Error
1124
+	 * @throws InvalidArgumentException
1125
+	 * @throws InvalidDataTypeException
1126
+	 * @throws InvalidInterfaceException
1127
+	 */
1128
+	protected function _reg_form_settings()
1129
+	{
1130
+		$this->_template_args['values'] = $this->_yes_no_values;
1131
+		add_action(
1132
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1133
+			[$this, 'email_validation_settings_form'],
1134
+			2
1135
+		);
1136
+		add_action(
1137
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1138
+			[$this, 'copy_attendee_info_settings_form'],
1139
+			4
1140
+		);
1141
+		add_action(
1142
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1143
+			[$this, 'setSessionLifespan'],
1144
+			5
1145
+		);
1146
+		$this->_template_args = (array) apply_filters(
1147
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1148
+			$this->_template_args
1149
+		);
1150
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
1151
+		$this->_set_publish_post_box_vars();
1152
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1153
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1154
+			$this->_template_args,
1155
+			true
1156
+		);
1157
+		$this->display_admin_page_with_sidebar();
1158
+	}
1159
+
1160
+
1161
+	/**
1162
+	 * @return void
1163
+	 * @throws EE_Error
1164
+	 * @throws InvalidArgumentException
1165
+	 * @throws ReflectionException
1166
+	 * @throws InvalidDataTypeException
1167
+	 * @throws InvalidInterfaceException
1168
+	 */
1169
+	protected function _update_reg_form_settings()
1170
+	{
1171
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1172
+			EE_Registry::instance()->CFG->registration
1173
+		);
1174
+		EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1175
+			EE_Registry::instance()->CFG->registration
1176
+		);
1177
+		$this->updateSessionLifespan();
1178
+		EE_Registry::instance()->CFG->registration = apply_filters(
1179
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1180
+			EE_Registry::instance()->CFG->registration
1181
+		);
1182
+		$success                                   = $this->_update_espresso_configuration(
1183
+			esc_html__('Registration Form Options', 'event_espresso'),
1184
+			EE_Registry::instance()->CFG,
1185
+			__FILE__,
1186
+			__FUNCTION__,
1187
+			__LINE__
1188
+		);
1189
+		$this->_redirect_after_action(
1190
+			$success,
1191
+			esc_html__('Registration Form Options', 'event_espresso'),
1192
+			'updated',
1193
+			['action' => 'view_reg_form_settings']
1194
+		);
1195
+	}
1196
+
1197
+
1198
+	/**
1199
+	 * @return void
1200
+	 * @throws EE_Error
1201
+	 * @throws InvalidArgumentException
1202
+	 * @throws InvalidDataTypeException
1203
+	 * @throws InvalidInterfaceException
1204
+	 */
1205
+	public function copy_attendee_info_settings_form()
1206
+	{
1207
+		echo wp_kses($this->_copy_attendee_info_settings_form()->get_html(), AllowedTags::getWithFormTags());
1208
+	}
1209
+
1210
+
1211
+	/**
1212
+	 * _copy_attendee_info_settings_form
1213
+	 *
1214
+	 * @access protected
1215
+	 * @return EE_Form_Section_Proper
1216
+	 * @throws \EE_Error
1217
+	 */
1218
+	protected function _copy_attendee_info_settings_form()
1219
+	{
1220
+		return new EE_Form_Section_Proper(
1221
+			[
1222
+				'name'            => 'copy_attendee_info_settings',
1223
+				'html_id'         => 'copy_attendee_info_settings',
1224
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1225
+				'subsections'     => apply_filters(
1226
+					'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1227
+					[
1228
+						'copy_attendee_info_hdr' => new EE_Form_Section_HTML(
1229
+							EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1230
+						),
1231
+						'copy_attendee_info'     => new EE_Yes_No_Input(
1232
+							[
1233
+								'html_label_text'         => esc_html__(
1234
+									'Allow copy #1 attendee info to extra attendees?',
1235
+									'event_espresso'
1236
+								),
1237
+								'html_help_text'          => esc_html__(
1238
+									'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1239
+									'event_espresso'
1240
+								),
1241
+								'default'                 => EE_Registry::instance(
1242
+								)->CFG->registration->copyAttendeeInfo(),
1243
+								'required'                => false,
1244
+								'display_html_label_text' => false,
1245
+							]
1246
+						),
1247
+					]
1248
+				),
1249
+			]
1250
+		);
1251
+	}
1252
+
1253
+
1254
+	/**
1255
+	 * @param EE_Registration_Config $EE_Registration_Config
1256
+	 * @return EE_Registration_Config
1257
+	 * @throws EE_Error
1258
+	 * @throws InvalidArgumentException
1259
+	 * @throws ReflectionException
1260
+	 * @throws InvalidDataTypeException
1261
+	 * @throws InvalidInterfaceException
1262
+	 */
1263
+	public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1264
+	{
1265
+		$prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1266
+		try {
1267
+			$copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1268
+			// if not displaying a form, then check for form submission
1269
+			if ($copy_attendee_info_settings_form->was_submitted()) {
1270
+				// capture form data
1271
+				$copy_attendee_info_settings_form->receive_form_submission();
1272
+				// validate form data
1273
+				if ($copy_attendee_info_settings_form->is_valid()) {
1274
+					// grab validated data from form
1275
+					$valid_data = $copy_attendee_info_settings_form->valid_data();
1276
+					if (isset($valid_data['copy_attendee_info'])) {
1277
+						$EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1278
+					} else {
1279
+						EE_Error::add_error(
1280
+							esc_html__(
1281
+								'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1282
+								'event_espresso'
1283
+							),
1284
+							__FILE__,
1285
+							__FUNCTION__,
1286
+							__LINE__
1287
+						);
1288
+					}
1289
+				} elseif ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1290
+					EE_Error::add_error(
1291
+						$copy_attendee_info_settings_form->submission_error_message(),
1292
+						__FILE__,
1293
+						__FUNCTION__,
1294
+						__LINE__
1295
+					);
1296
+				}
1297
+			}
1298
+		} catch (EE_Error $e) {
1299
+			$e->get_error();
1300
+		}
1301
+		return $EE_Registration_Config;
1302
+	}
1303
+
1304
+
1305
+	/**
1306
+	 * @return void
1307
+	 * @throws EE_Error
1308
+	 * @throws InvalidArgumentException
1309
+	 * @throws InvalidDataTypeException
1310
+	 * @throws InvalidInterfaceException
1311
+	 */
1312
+	public function email_validation_settings_form()
1313
+	{
1314
+		echo wp_kses($this->_email_validation_settings_form()->get_html(), AllowedTags::getWithFormTags());
1315
+	}
1316
+
1317
+
1318
+	/**
1319
+	 * _email_validation_settings_form
1320
+	 *
1321
+	 * @access protected
1322
+	 * @return EE_Form_Section_Proper
1323
+	 * @throws \EE_Error
1324
+	 */
1325
+	protected function _email_validation_settings_form()
1326
+	{
1327
+		return new EE_Form_Section_Proper(
1328
+			[
1329
+				'name'            => 'email_validation_settings',
1330
+				'html_id'         => 'email_validation_settings',
1331
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1332
+				'subsections'     => apply_filters(
1333
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1334
+					[
1335
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
1336
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1337
+						),
1338
+						'email_validation_level' => new EE_Select_Input(
1339
+							[
1340
+								'basic'      => esc_html__('Basic', 'event_espresso'),
1341
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1342
+								'i18n'       => esc_html__('International', 'event_espresso'),
1343
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1344
+							],
1345
+							[
1346
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1347
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
1348
+								'html_help_text'  => esc_html__(
1349
+									'These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
1350
+									'event_espresso'
1351
+								),
1352
+								'default'         => isset(
1353
+									EE_Registry::instance()->CFG->registration->email_validation_level
1354
+								)
1355
+									? EE_Registry::instance()->CFG->registration->email_validation_level
1356
+									: 'wp_default',
1357
+								'required'        => false,
1358
+							]
1359
+						),
1360
+					]
1361
+				),
1362
+			]
1363
+		);
1364
+	}
1365
+
1366
+
1367
+	/**
1368
+	 * @param EE_Registration_Config $EE_Registration_Config
1369
+	 * @return EE_Registration_Config
1370
+	 * @throws EE_Error
1371
+	 * @throws InvalidArgumentException
1372
+	 * @throws ReflectionException
1373
+	 * @throws InvalidDataTypeException
1374
+	 * @throws InvalidInterfaceException
1375
+	 */
1376
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1377
+	{
1378
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1379
+		try {
1380
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1381
+			// if not displaying a form, then check for form submission
1382
+			if ($email_validation_settings_form->was_submitted()) {
1383
+				// capture form data
1384
+				$email_validation_settings_form->receive_form_submission();
1385
+				// validate form data
1386
+				if ($email_validation_settings_form->is_valid()) {
1387
+					// grab validated data from form
1388
+					$valid_data = $email_validation_settings_form->valid_data();
1389
+					if (isset($valid_data['email_validation_level'])) {
1390
+						$email_validation_level = $valid_data['email_validation_level'];
1391
+						// now if they want to use international email addresses
1392
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1393
+							// in case we need to reset their email validation level,
1394
+							// make sure that the previous value wasn't already set to one of the i18n options.
1395
+							if (
1396
+								$prev_email_validation_level === 'i18n'
1397
+								|| $prev_email_validation_level
1398
+								   === 'i18n_dns'
1399
+							) {
1400
+								// if so, then reset it back to "basic" since that is the only other option that,
1401
+								// despite offering poor validation, supports i18n email addresses
1402
+								$prev_email_validation_level = 'basic';
1403
+							}
1404
+							// confirm our i18n email validation will work on the server
1405
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1406
+								// or reset email validation level to previous value
1407
+								$email_validation_level = $prev_email_validation_level;
1408
+							}
1409
+						}
1410
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1411
+					} else {
1412
+						EE_Error::add_error(
1413
+							esc_html__(
1414
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1415
+								'event_espresso'
1416
+							),
1417
+							__FILE__,
1418
+							__FUNCTION__,
1419
+							__LINE__
1420
+						);
1421
+					}
1422
+				} elseif ($email_validation_settings_form->submission_error_message() !== '') {
1423
+					EE_Error::add_error(
1424
+						$email_validation_settings_form->submission_error_message(),
1425
+						__FILE__,
1426
+						__FUNCTION__,
1427
+						__LINE__
1428
+					);
1429
+				}
1430
+			}
1431
+		} catch (EE_Error $e) {
1432
+			$e->get_error();
1433
+		}
1434
+		return $EE_Registration_Config;
1435
+	}
1436
+
1437
+
1438
+	/**
1439
+	 * confirms that the server's PHP version has the PCRE module enabled,
1440
+	 * and that the PCRE version works with our i18n email validation
1441
+	 *
1442
+	 * @param EE_Registration_Config $EE_Registration_Config
1443
+	 * @param string                 $email_validation_level
1444
+	 * @return bool
1445
+	 */
1446
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1447
+	{
1448
+		// first check that PCRE is enabled
1449
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1450
+			EE_Error::add_error(
1451
+				sprintf(
1452
+					esc_html__(
1453
+						'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1454
+						'event_espresso'
1455
+					),
1456
+					'<br />'
1457
+				),
1458
+				__FILE__,
1459
+				__FUNCTION__,
1460
+				__LINE__
1461
+			);
1462
+			return false;
1463
+		} else {
1464
+			// PCRE support is enabled, but let's still
1465
+			// perform a test to see if the server will support it.
1466
+			// but first, save the updated validation level to the config,
1467
+			// so that the validation strategy picks it up.
1468
+			// this will get bumped back down if it doesn't work
1469
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1470
+			try {
1471
+				$email_validator    = new EE_Email_Validation_Strategy();
1472
+				$i18n_email_address = apply_filters(
1473
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1474
+					'jägerjü[email protected]'
1475
+				);
1476
+				$email_validator->validate($i18n_email_address);
1477
+			} catch (Exception $e) {
1478
+				EE_Error::add_error(
1479
+					sprintf(
1480
+						esc_html__(
1481
+							'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1482
+							'event_espresso'
1483
+						),
1484
+						'<br />',
1485
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1486
+					),
1487
+					__FILE__,
1488
+					__FUNCTION__,
1489
+					__LINE__
1490
+				);
1491
+				return false;
1492
+			}
1493
+		}
1494
+		return true;
1495
+	}
1496
+
1497
+
1498
+	public function setSessionLifespan()
1499
+	{
1500
+		$session_lifespan_form = $this->loader->getNew(SessionLifespanForm::class);
1501
+		echo wp_kses($session_lifespan_form->get_html(), AllowedTags::getWithFormTags());
1502
+	}
1503
+
1504
+
1505
+	public function updateSessionLifespan()
1506
+	{
1507
+		$handler = $this->loader->getNew(SessionLifespanFormHandler::class);
1508
+		$handler->process($this->loader->getNew(SessionLifespanForm::class));
1509
+	}
1510 1510
 }
Please login to merge, or discard this patch.
Spacing   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -23,11 +23,11 @@  discard block
 block discarded – undo
23 23
      */
24 24
     public function __construct($routing = true)
25 25
     {
26
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
27
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
28
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
29
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
30
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
26
+        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND.'registration_form/');
27
+        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN.'assets/');
28
+        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registration_form/assets/');
29
+        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN.'templates/');
30
+        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registration_form/templates/');
31 31
         parent::__construct($routing);
32 32
     }
33 33
 
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
         $qsg_id                 = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
55 55
             ? $this->_req_data['QSG_ID'] : 0;
56 56
 
57
-        $new_page_routes    = [
57
+        $new_page_routes = [
58 58
             'question_groups'    => [
59 59
                 'func'       => '_question_groups_overview_list_table',
60 60
                 'capability' => 'ee_read_question_groups',
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
 
317 317
 
318 318
         // additional labels
319
-        $new_labels               = [
319
+        $new_labels = [
320 320
             'add_question'          => esc_html__('Add New Question', 'event_espresso'),
321 321
             'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
322 322
             'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
      */
333 333
     protected function _ajax_hooks()
334 334
     {
335
-        if (! $this->capabilities->current_user_can('ee_edit_question_groups', 'edit-questions')) {
335
+        if ( ! $this->capabilities->current_user_can('ee_edit_question_groups', 'edit-questions')) {
336 336
             return;
337 337
         }
338 338
         add_action('wp_ajax_espresso_update_question_group_order', [$this, 'update_question_group_order']);
@@ -377,7 +377,7 @@  discard block
 block discarded – undo
377 377
     {
378 378
         wp_register_script(
379 379
             'ee-question-sortable',
380
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
380
+            REGISTRATION_FORM_CAF_ASSETS_URL.'ee_question_order.js',
381 381
             ['jquery-ui-sortable'],
382 382
             EVENT_ESPRESSO_VERSION,
383 383
             true
@@ -465,7 +465,7 @@  discard block
 block discarded – undo
465 465
      */
466 466
     protected function _questions_overview_list_table()
467 467
     {
468
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
468
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
469 469
                 'add_question',
470 470
                 'add_question',
471 471
                 [],
@@ -486,7 +486,7 @@  discard block
 block discarded – undo
486 486
     protected function _question_groups_overview_list_table()
487 487
     {
488 488
         $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
489
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
489
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
490 490
                 'add_question_group',
491 491
                 'add_question_group',
492 492
                 [],
@@ -551,19 +551,19 @@  discard block
 block discarded – undo
551 551
     {
552 552
         $success = 0;
553 553
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
554
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
554
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
555 555
             // if array has more than one element than success message should be plural
556 556
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
557 557
             // cycle thru bulk action checkboxes
558 558
             $checkboxes = $this->_req_data['checkbox'];
559 559
             foreach (array_keys($checkboxes) as $ID) {
560
-                if (! $this->_delete_item($ID, $model)) {
560
+                if ( ! $this->_delete_item($ID, $model)) {
561 561
                     $success = 0;
562 562
                 }
563 563
             }
564
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
564
+        } elseif ( ! empty($this->_req_data['QSG_ID'])) {
565 565
             $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
566
-        } elseif (! empty($this->_req_data['QST_ID'])) {
566
+        } elseif ( ! empty($this->_req_data['QST_ID'])) {
567 567
             $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
568 568
         } else {
569 569
             EE_Error::add_error(
@@ -634,7 +634,7 @@  discard block
 block discarded – undo
634 634
                 $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
635 635
         }
636 636
         // add ID to title if editing
637
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
637
+        $this->_admin_page_title = $ID ? $this->_admin_page_title.' # '.$ID : $this->_admin_page_title;
638 638
         if ($ID) {
639 639
             /** @var EE_Question_Group $questionGroup */
640 640
             $questionGroup            = $this->_question_group_model->get_one_by_ID($ID);
@@ -654,7 +654,7 @@  discard block
 block discarded – undo
654 654
         $redirect_URL = add_query_arg(['action' => 'question_groups'], $this->_admin_base_url);
655 655
         $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL, true);
656 656
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
657
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
657
+            REGISTRATION_FORM_CAF_TEMPLATE_PATH.'question_groups_main_meta_box.template.php',
658 658
             $this->_template_args,
659 659
             true
660 660
         );
@@ -700,7 +700,7 @@  discard block
 block discarded – undo
700 700
         // make sure identifier is unique
701 701
         $identifier_value = $set_column_values['QSG_identifier'] ?? '';
702 702
         $where_values     = ['QSG_identifier' => $identifier_value];
703
-        if (! $new_question_group && isset($set_column_values['QSG_ID'])) {
703
+        if ( ! $new_question_group && isset($set_column_values['QSG_ID'])) {
704 704
             $where_values['QSG_ID'] = ['!=', $set_column_values['QSG_ID']];
705 705
         }
706 706
         $identifier_exists = ! empty($identifier_value) && $this->_question_group_model->count([$where_values]) > 0;
@@ -738,7 +738,7 @@  discard block
 block discarded – undo
738 738
         // update the existing related questions
739 739
         // BUT FIRST...  delete the phone question from the Question_Group_Question
740 740
         // if it is being added to this question group (therefore removed from the existing group)
741
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
741
+        if (isset($this->_req_data['questions'], $this->_req_data['questions'][$phone_question_id])) {
742 742
             // delete where QST ID = system phone question ID and Question Group ID is NOT this group
743 743
             EEM_Question_Group_Question::instance()->delete(
744 744
                 [
@@ -753,22 +753,22 @@  discard block
 block discarded – undo
753 753
         $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
754 754
         $questions      = $question_group->questions();
755 755
         // make sure system phone question is added to list of questions for this group
756
-        if (! isset($questions[ $phone_question_id ])) {
757
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
756
+        if ( ! isset($questions[$phone_question_id])) {
757
+            $questions[$phone_question_id] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
758 758
         }
759 759
 
760 760
         foreach ($questions as $question_ID => $question) {
761 761
             // first we always check for order.
762
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
762
+            if ( ! empty($this->_req_data['question_orders'][$question_ID])) {
763 763
                 // update question order
764 764
                 $question_group->update_question_order(
765 765
                     $question_ID,
766
-                    $this->_req_data['question_orders'][ $question_ID ]
766
+                    $this->_req_data['question_orders'][$question_ID]
767 767
                 );
768 768
             }
769 769
 
770 770
             // then we always check if adding or removing.
771
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
771
+            if (isset($this->_req_data['questions'], $this->_req_data['questions'][$question_ID])) {
772 772
                 $question_group->add_question($question_ID);
773 773
             } else {
774 774
                 // not found, remove it (but only if not a system question for the personal group
@@ -791,8 +791,8 @@  discard block
 block discarded – undo
791 791
         if (isset($this->_req_data['questions'])) {
792 792
             foreach ($this->_req_data['questions'] as $QST_ID) {
793 793
                 $question_group->add_question($QST_ID);
794
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
795
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
794
+                if (isset($this->_req_data['question_orders'][$QST_ID])) {
795
+                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][$QST_ID]);
796 796
                 }
797 797
             }
798 798
         }
@@ -932,34 +932,34 @@  discard block
 block discarded – undo
932 932
         // echo "trash $trash";
933 933
         // var_dump($this->_req_data['checkbox']);die;
934 934
         if (isset($this->_req_data['checkbox'])) {
935
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
935
+            if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
936 936
                 // if array has more than one element than success message should be plural
937 937
                 $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
938 938
                 // cycle thru bulk action checkboxes
939 939
                 $checkboxes = $this->_req_data['checkbox'];
940 940
                 foreach (array_keys($checkboxes) as $ID) {
941
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
941
+                    if ( ! $model->delete_or_restore_by_ID($trash, absint($ID))) {
942 942
                         $success = 0;
943 943
                     }
944 944
                 }
945 945
             } else {
946 946
                 // grab single id and delete
947 947
                 $ID = absint($this->_req_data['checkbox']);
948
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
948
+                if ( ! $model->delete_or_restore_by_ID($trash, $ID)) {
949 949
                     $success = 0;
950 950
                 }
951 951
             }
952 952
         } else {
953 953
             // delete via trash link
954 954
             // grab single id and delete
955
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
956
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
955
+            $ID = absint($this->_req_data[$model->primary_key_name()]);
956
+            if ( ! $model->delete_or_restore_by_ID($trash, $ID)) {
957 957
                 $success = 0;
958 958
             }
959 959
         }
960 960
 
961 961
 
962
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
962
+        $action = $model instanceof EEM_Question ? 'default' : 'question_groups'; // strtolower( $model->item_name(2) );
963 963
         // echo "action :$action";
964 964
         // $action = 'questions' ? 'default' : $action;
965 965
         if ($trash) {
@@ -1068,7 +1068,7 @@  discard block
 block discarded – undo
1068 1068
      */
1069 1069
     public function update_question_group_order()
1070 1070
     {
1071
-        if (! $this->capabilities->current_user_can('ee_edit_question_groups', __FUNCTION__)) {
1071
+        if ( ! $this->capabilities->current_user_can('ee_edit_question_groups', __FUNCTION__)) {
1072 1072
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
1073 1073
         }
1074 1074
         $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
@@ -1085,7 +1085,7 @@  discard block
 block discarded – undo
1085 1085
             ? (int) $this->_req_data['curpage']
1086 1086
             : null;
1087 1087
 
1088
-        if (! empty($row_ids)) {
1088
+        if ( ! empty($row_ids)) {
1089 1089
             // figure out where we start the row_id count at for the current page.
1090 1090
             $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1091 1091
 
@@ -1094,7 +1094,7 @@  discard block
 block discarded – undo
1094 1094
                 // Update the questions when re-ordering
1095 1095
                 $updated = EEM_Question_Group::instance()->update(
1096 1096
                     ['QSG_order' => $qsgcount],
1097
-                    [['QSG_ID' => $row_ids[ $i ]]]
1097
+                    [['QSG_ID' => $row_ids[$i]]]
1098 1098
                 );
1099 1099
                 if ($updated === false) {
1100 1100
                     $success = false;
@@ -1150,7 +1150,7 @@  discard block
 block discarded – undo
1150 1150
         $this->_set_add_edit_form_tags('update_reg_form_settings');
1151 1151
         $this->_set_publish_post_box_vars();
1152 1152
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1153
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1153
+            REGISTRATION_FORM_CAF_TEMPLATE_PATH.'reg_form_settings.template.php',
1154 1154
             $this->_template_args,
1155 1155
             true
1156 1156
         );
@@ -1179,7 +1179,7 @@  discard block
 block discarded – undo
1179 1179
             'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1180 1180
             EE_Registry::instance()->CFG->registration
1181 1181
         );
1182
-        $success                                   = $this->_update_espresso_configuration(
1182
+        $success = $this->_update_espresso_configuration(
1183 1183
             esc_html__('Registration Form Options', 'event_espresso'),
1184 1184
             EE_Registry::instance()->CFG,
1185 1185
             __FILE__,
@@ -1402,7 +1402,7 @@  discard block
 block discarded – undo
1402 1402
                                 $prev_email_validation_level = 'basic';
1403 1403
                             }
1404 1404
                             // confirm our i18n email validation will work on the server
1405
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1405
+                            if ( ! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1406 1406
                                 // or reset email validation level to previous value
1407 1407
                                 $email_validation_level = $prev_email_validation_level;
1408 1408
                             }
@@ -1446,7 +1446,7 @@  discard block
 block discarded – undo
1446 1446
     private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1447 1447
     {
1448 1448
         // first check that PCRE is enabled
1449
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1449
+        if ( ! defined('PREG_BAD_UTF8_ERROR')) {
1450 1450
             EE_Error::add_error(
1451 1451
                 sprintf(
1452 1452
                     esc_html__(
Please login to merge, or discard this patch.
admin/extend/registrations/Extend_Registrations_Admin_Page.core.php 2 patches
Indentation   +1266 added lines, -1266 removed lines patch added patch discarded remove patch
@@ -16,1277 +16,1277 @@
 block discarded – undo
16 16
  */
17 17
 class Extend_Registrations_Admin_Page extends Registrations_Admin_Page
18 18
 {
19
-    /**
20
-     * This is used to hold the reports template data which is setup early in the request.
21
-     *
22
-     * @type array
23
-     */
24
-    protected array $_reports_template_data = [];
25
-
26
-
27
-    /**
28
-     * Extend_Registrations_Admin_Page constructor.
29
-     *
30
-     * @param bool $routing
31
-     * @throws ReflectionException
32
-     */
33
-    public function __construct($routing = true)
34
-    {
35
-        parent::__construct($routing);
36
-        if (! defined('REG_CAF_TEMPLATE_PATH')) {
37
-            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
38
-            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
39
-            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
40
-        }
41
-    }
42
-
43
-
44
-    protected function _set_page_config()
45
-    {
46
-        parent::_set_page_config();
47
-
48
-        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
49
-        $reg_id                                           =
50
-            ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
51
-                ? $this->_req_data['_REG_ID']
52
-                : 0;
53
-        $new_page_routes                                  = [
54
-            'reports'                      => [
55
-                'func'       => [$this, '_registration_reports'],
56
-                'capability' => 'ee_read_registrations',
57
-            ],
58
-            'registration_checkins'        => [
59
-                'func'       => [$this, '_registration_checkin_list_table'],
60
-                'capability' => 'ee_read_checkins',
61
-            ],
62
-            'newsletter_selected_send'     => [
63
-                'func'       => [$this, '_newsletter_selected_send'],
64
-                'noheader'   => true,
65
-                'capability' => 'ee_send_message',
66
-            ],
67
-            'delete_checkin_rows'          => [
68
-                'func'       => [$this, '_delete_checkin_rows'],
69
-                'noheader'   => true,
70
-                'capability' => 'ee_delete_checkins',
71
-            ],
72
-            'delete_checkin_row'           => [
73
-                'func'       => [$this, '_delete_checkin_row'],
74
-                'noheader'   => true,
75
-                'capability' => 'ee_delete_checkin',
76
-                'obj_id'     => $reg_id,
77
-            ],
78
-            'toggle_checkin_status'        => [
79
-                'func'       => [$this, '_toggle_checkin_status'],
80
-                'noheader'   => true,
81
-                'capability' => 'ee_edit_checkin',
82
-                'obj_id'     => $reg_id,
83
-            ],
84
-            'toggle_checkin_status_bulk'   => [
85
-                'func'       => [$this, '_toggle_checkin_status'],
86
-                'noheader'   => true,
87
-                'capability' => 'ee_edit_checkins',
88
-            ],
89
-            'event_registrations'          => [
90
-                'func'       => [$this, '_event_registrations_list_table'],
91
-                'capability' => 'ee_read_checkins',
92
-            ],
93
-            'registrations_checkin_report' => [
94
-                'func'       => [$this, '_registrations_checkin_report'],
95
-                'noheader'   => true,
96
-                'capability' => 'ee_read_registrations',
97
-            ],
98
-        ];
99
-        $this->_page_routes                               = array_merge($this->_page_routes, $new_page_routes);
100
-        $new_page_config                                  = [
101
-            'reports'               => [
102
-                'nav'           => [
103
-                    'label' => esc_html__('Reports', 'event_espresso'),
104
-                    'icon'  => 'dashicons-chart-bar',
105
-                    'order' => 30,
106
-                ],
107
-                'help_tabs'     => [
108
-                    'registrations_reports_help_tab' => [
109
-                        'title'    => esc_html__('Registration Reports', 'event_espresso'),
110
-                        'filename' => 'registrations_reports',
111
-                    ],
112
-                ],
113
-                'require_nonce' => false,
114
-            ],
115
-            'event_registrations'   => [
116
-                'nav'           => [
117
-                    'label'      => esc_html__('Event Check-In', 'event_espresso'),
118
-                    'icon'       => 'dashicons-yes-alt',
119
-                    'order'      => 10,
120
-                    'persistent' => true,
121
-                ],
122
-                'help_tabs'     => [
123
-                    'registrations_event_checkin_help_tab'                       => [
124
-                        'title'    => esc_html__('Registrations Event Check-In', 'event_espresso'),
125
-                        'filename' => 'registrations_event_checkin',
126
-                    ],
127
-                    'registrations_event_checkin_table_column_headings_help_tab' => [
128
-                        'title'    => esc_html__('Event Check-In Table Column Headings', 'event_espresso'),
129
-                        'filename' => 'registrations_event_checkin_table_column_headings',
130
-                    ],
131
-                    'registrations_event_checkin_filters_help_tab'               => [
132
-                        'title'    => esc_html__('Event Check-In Filters', 'event_espresso'),
133
-                        'filename' => 'registrations_event_checkin_filters',
134
-                    ],
135
-                    'registrations_event_checkin_views_help_tab'                 => [
136
-                        'title'    => esc_html__('Event Check-In Views', 'event_espresso'),
137
-                        'filename' => 'registrations_event_checkin_views',
138
-                    ],
139
-                    'registrations_event_checkin_other_help_tab'                 => [
140
-                        'title'    => esc_html__('Event Check-In Other', 'event_espresso'),
141
-                        'filename' => 'registrations_event_checkin_other',
142
-                    ],
143
-                ],
144
-                'list_table'    => 'EE_Event_Registrations_List_Table',
145
-                'metaboxes'     => [],
146
-                'require_nonce' => false,
147
-            ],
148
-            'registration_checkins' => [
149
-                'nav'           => [
150
-                    'label'      => esc_html__('Check-In Records', 'event_espresso'),
151
-                    'icon'       => 'dashicons-list-view',
152
-                    'order'      => 15,
153
-                    'persistent' => false,
154
-                    'url'        => '',
155
-                ],
156
-                'list_table'    => 'EE_Registration_CheckIn_List_Table',
157
-                'metaboxes'     => [],
158
-                'require_nonce' => false,
159
-            ],
160
-        ];
161
-        $this->_page_config                               = array_merge($this->_page_config, $new_page_config);
162
-        $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
163
-        $this->_page_config['default']['list_table']      = 'Extend_EE_Registrations_List_Table';
164
-    }
165
-
166
-
167
-    /**
168
-     * Ajax hooks for all routes in this page.
169
-     */
170
-    protected function _ajax_hooks()
171
-    {
172
-        parent::_ajax_hooks();
173
-        add_action('wp_ajax_get_newsletter_form_content', [$this, 'get_newsletter_form_content']);
174
-        add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
175
-    }
176
-
177
-
178
-    /**
179
-     * Global scripts for all routes in this page.
180
-     *
181
-     * @throws EE_Error
182
-     * *@throws ReflectionException
183
-     */
184
-    public function load_scripts_styles()
185
-    {
186
-        parent::load_scripts_styles();
187
-        // if newsletter message type is active then let's add filter and load js for it.
188
-        if (EEH_MSG_Template::is_mt_active('newsletter')) {
189
-            wp_enqueue_style(
190
-                'ee_message_shortcodes',
191
-                EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
192
-                [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
193
-                EVENT_ESPRESSO_VERSION
194
-            );
195
-            // enqueue newsletter js
196
-            wp_enqueue_script(
197
-                'ee-newsletter-trigger',
198
-                REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
199
-                ['ee-dialog'],
200
-                EVENT_ESPRESSO_VERSION,
201
-                true
202
-            );
203
-            // hook in buttons for newsletter message type trigger.
204
-            add_action(
205
-                'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons',
206
-                [$this, 'add_newsletter_action_buttons']
207
-            );
208
-        }
209
-    }
210
-
211
-
212
-    /**
213
-     * Scripts and styles for just the reports route.
214
-     *
215
-     * @throws EE_Error
216
-     * @throws ReflectionException
217
-     */
218
-    public function load_scripts_styles_reports()
219
-    {
220
-        wp_register_script(
221
-            'ee-reg-reports-js',
222
-            REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
223
-            ['google-charts'],
224
-            EVENT_ESPRESSO_VERSION,
225
-            true
226
-        );
227
-        wp_enqueue_script('ee-reg-reports-js');
228
-        $this->_registration_reports_js_setup();
229
-    }
230
-
231
-
232
-    /**
233
-     * Register screen options for event_registrations route.
234
-     */
235
-    protected function _add_screen_options_event_registrations()
236
-    {
237
-        $this->_per_page_screen_option();
238
-    }
239
-
240
-
241
-    /**
242
-     * Register screen options for registration_checkins route
243
-     */
244
-    protected function _add_screen_options_registration_checkins()
245
-    {
246
-        $page_title              = $this->_admin_page_title;
247
-        $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso');
248
-        $this->_per_page_screen_option();
249
-        $this->_admin_page_title = $page_title;
250
-    }
251
-
252
-
253
-    /**
254
-     * Set views property for event_registrations route.
255
-     */
256
-    protected function _set_list_table_views_event_registrations()
257
-    {
258
-        $this->_views = [
259
-            'all' => [
260
-                'slug'        => 'all',
261
-                'label'       => esc_html__('All', 'event_espresso'),
262
-                'count'       => 0,
263
-                'bulk_action' => ! isset($this->_req_data['event_id'])
264
-                    ? []
265
-                    : [
266
-                        'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'),
267
-                    ],
268
-            ],
269
-        ];
270
-    }
271
-
272
-
273
-    /**
274
-     * Set views property for registration_checkins route.
275
-     */
276
-    protected function _set_list_table_views_registration_checkins()
277
-    {
278
-        $this->_views = [
279
-            'all' => [
280
-                'slug'        => 'all',
281
-                'label'       => esc_html__('All', 'event_espresso'),
282
-                'count'       => 0,
283
-                'bulk_action' => ['delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')],
284
-            ],
285
-        ];
286
-    }
287
-
288
-
289
-    /**
290
-     * callback for ajax action.
291
-     *
292
-     * @return void (JSON)
293
-     * @throws EE_Error
294
-     * @throws ReflectionException
295
-     * @since 4.3.0
296
-     */
297
-    public function get_newsletter_form_content()
298
-    {
299
-        if (! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
300
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
301
-        }
302
-        // do a nonce check because we're not coming in from a normal route here.
303
-        $nonce     = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field(
304
-            $this->_req_data['get_newsletter_form_content_nonce']
305
-        ) : '';
306
-        $nonce_ref = 'get_newsletter_form_content_nonce';
307
-        $this->_verify_nonce($nonce, $nonce_ref);
308
-        // let's get the mtp for the incoming MTP_ ID
309
-        if (! isset($this->_req_data['GRP_ID'])) {
310
-            EE_Error::add_error(
311
-                esc_html__(
312
-                    'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
313
-                    'event_espresso'
314
-                ),
315
-                __FILE__,
316
-                __FUNCTION__,
317
-                __LINE__
318
-            );
319
-            $this->_template_args['success'] = false;
320
-            $this->_template_args['error']   = true;
321
-            $this->_return_json();
322
-        }
323
-        $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
324
-        if (! $MTPG instanceof EE_Message_Template_Group) {
325
-            EE_Error::add_error(
326
-                sprintf(
327
-                    esc_html__(
328
-                        'The GRP_ID given (%d) does not appear to have a corresponding row in the database.',
329
-                        'event_espresso'
330
-                    ),
331
-                    $this->_req_data['GRP_ID']
332
-                ),
333
-                __FILE__,
334
-                __FUNCTION__,
335
-                __LINE__
336
-            );
337
-            $this->_template_args['success'] = false;
338
-            $this->_template_args['error']   = true;
339
-            $this->_return_json();
340
-        }
341
-        $MTPs            = $MTPG->context_templates();
342
-        $MTPs            = $MTPs['attendee'];
343
-        $template_fields = [];
344
-        /** @var EE_Message_Template $MTP */
345
-        foreach ($MTPs as $MTP) {
346
-            $field = $MTP->get('MTP_template_field');
347
-            if ($field === 'content') {
348
-                $content = $MTP->get('MTP_content');
349
-                if (! empty($content['newsletter_content'])) {
350
-                    $template_fields['newsletter_content'] = $content['newsletter_content'];
351
-                }
352
-                continue;
353
-            }
354
-            $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
355
-        }
356
-        $this->_template_args['success'] = true;
357
-        $this->_template_args['error']   = false;
358
-        $this->_template_args['data']    = [
359
-            'batch_message_from'    => $template_fields['from'] ?? '',
360
-            'batch_message_subject' => $template_fields['subject'] ?? '',
361
-            'batch_message_content' => $template_fields['newsletter_content'] ?? '',
362
-        ];
363
-        $this->_return_json();
364
-    }
365
-
366
-
367
-    /**
368
-     * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
369
-     *
370
-     * @param EE_Admin_List_Table $list_table
371
-     * @return void
372
-     * @since 4.3.0
373
-     */
374
-    public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table)
375
-    {
376
-        if (
377
-            ! EE_Registry::instance()->CAP->current_user_can(
378
-                'ee_send_message',
379
-                'espresso_registrations_newsletter_selected_send'
380
-            )
381
-        ) {
382
-            return;
383
-        }
384
-        $routes_to_add_to = [
385
-            'contact_list',
386
-            'event_registrations',
387
-            'default',
388
-        ];
389
-        if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) {
390
-            if (
391
-                ($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id']))
392
-                || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash')
393
-            ) {
394
-                echo '';
395
-            } else {
396
-                $button_text = sprintf(
397
-                    esc_html__('Send Batch Message (%s selected)', 'event_espresso'),
398
-                    '<span class="send-selected-newsletter-count">0</span>'
399
-                );
400
-                echo '<button id="selected-batch-send-trigger" class="button button--secondary">'
401
-                    . '<span class="dashicons dashicons-email "></span>'
402
-                    . $button_text
403
-                    . '</button>';
404
-                add_action('admin_footer', [$this, 'newsletter_send_form_skeleton']);
405
-            }
406
-        }
407
-    }
408
-
409
-
410
-    /**
411
-     * @throws DomainException
412
-     * @throws EE_Error
413
-     * @throws ReflectionException
414
-     */
415
-    public function newsletter_send_form_skeleton()
416
-    {
417
-        $list_table = $this->_list_table_object;
418
-        $codes      = [];
419
-        // need to templates for the newsletter message type for the template selector.
420
-        $values[] = ['text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0];
421
-        $mtps     = EEM_Message_Template_Group::instance()->get_all(
422
-            [['MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email']]
423
-        );
424
-        foreach ($mtps as $mtp) {
425
-            $name     = $mtp->name();
426
-            $values[] = [
427
-                'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name,
428
-                'id'   => $mtp->ID(),
429
-            ];
430
-        }
431
-        // need to get a list of shortcodes that are available for the newsletter message type.
432
-        $shortcodes = EEH_MSG_Template::get_shortcodes(
433
-            'newsletter',
434
-            'email',
435
-            [],
436
-            'attendee'
437
-        );
438
-
439
-        foreach ($shortcodes as $field => $shortcode_array) {
440
-            $available_shortcodes = [];
441
-            foreach ($shortcode_array as $shortcode => $shortcode_details) {
442
-                $field_id               = $field === '[NEWSLETTER_CONTENT]'
443
-                    ? 'content'
444
-                    : strtolower($field);
445
-                $field_id               = "batch-message-$field_id";
446
-                $available_shortcodes[] = '
19
+	/**
20
+	 * This is used to hold the reports template data which is setup early in the request.
21
+	 *
22
+	 * @type array
23
+	 */
24
+	protected array $_reports_template_data = [];
25
+
26
+
27
+	/**
28
+	 * Extend_Registrations_Admin_Page constructor.
29
+	 *
30
+	 * @param bool $routing
31
+	 * @throws ReflectionException
32
+	 */
33
+	public function __construct($routing = true)
34
+	{
35
+		parent::__construct($routing);
36
+		if (! defined('REG_CAF_TEMPLATE_PATH')) {
37
+			define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
38
+			define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
39
+			define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
40
+		}
41
+	}
42
+
43
+
44
+	protected function _set_page_config()
45
+	{
46
+		parent::_set_page_config();
47
+
48
+		$this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
49
+		$reg_id                                           =
50
+			! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
51
+				? $this->_req_data['_REG_ID']
52
+				: 0;
53
+		$new_page_routes                                  = [
54
+			'reports'                      => [
55
+				'func'       => [$this, '_registration_reports'],
56
+				'capability' => 'ee_read_registrations',
57
+			],
58
+			'registration_checkins'        => [
59
+				'func'       => [$this, '_registration_checkin_list_table'],
60
+				'capability' => 'ee_read_checkins',
61
+			],
62
+			'newsletter_selected_send'     => [
63
+				'func'       => [$this, '_newsletter_selected_send'],
64
+				'noheader'   => true,
65
+				'capability' => 'ee_send_message',
66
+			],
67
+			'delete_checkin_rows'          => [
68
+				'func'       => [$this, '_delete_checkin_rows'],
69
+				'noheader'   => true,
70
+				'capability' => 'ee_delete_checkins',
71
+			],
72
+			'delete_checkin_row'           => [
73
+				'func'       => [$this, '_delete_checkin_row'],
74
+				'noheader'   => true,
75
+				'capability' => 'ee_delete_checkin',
76
+				'obj_id'     => $reg_id,
77
+			],
78
+			'toggle_checkin_status'        => [
79
+				'func'       => [$this, '_toggle_checkin_status'],
80
+				'noheader'   => true,
81
+				'capability' => 'ee_edit_checkin',
82
+				'obj_id'     => $reg_id,
83
+			],
84
+			'toggle_checkin_status_bulk'   => [
85
+				'func'       => [$this, '_toggle_checkin_status'],
86
+				'noheader'   => true,
87
+				'capability' => 'ee_edit_checkins',
88
+			],
89
+			'event_registrations'          => [
90
+				'func'       => [$this, '_event_registrations_list_table'],
91
+				'capability' => 'ee_read_checkins',
92
+			],
93
+			'registrations_checkin_report' => [
94
+				'func'       => [$this, '_registrations_checkin_report'],
95
+				'noheader'   => true,
96
+				'capability' => 'ee_read_registrations',
97
+			],
98
+		];
99
+		$this->_page_routes                               = array_merge($this->_page_routes, $new_page_routes);
100
+		$new_page_config                                  = [
101
+			'reports'               => [
102
+				'nav'           => [
103
+					'label' => esc_html__('Reports', 'event_espresso'),
104
+					'icon'  => 'dashicons-chart-bar',
105
+					'order' => 30,
106
+				],
107
+				'help_tabs'     => [
108
+					'registrations_reports_help_tab' => [
109
+						'title'    => esc_html__('Registration Reports', 'event_espresso'),
110
+						'filename' => 'registrations_reports',
111
+					],
112
+				],
113
+				'require_nonce' => false,
114
+			],
115
+			'event_registrations'   => [
116
+				'nav'           => [
117
+					'label'      => esc_html__('Event Check-In', 'event_espresso'),
118
+					'icon'       => 'dashicons-yes-alt',
119
+					'order'      => 10,
120
+					'persistent' => true,
121
+				],
122
+				'help_tabs'     => [
123
+					'registrations_event_checkin_help_tab'                       => [
124
+						'title'    => esc_html__('Registrations Event Check-In', 'event_espresso'),
125
+						'filename' => 'registrations_event_checkin',
126
+					],
127
+					'registrations_event_checkin_table_column_headings_help_tab' => [
128
+						'title'    => esc_html__('Event Check-In Table Column Headings', 'event_espresso'),
129
+						'filename' => 'registrations_event_checkin_table_column_headings',
130
+					],
131
+					'registrations_event_checkin_filters_help_tab'               => [
132
+						'title'    => esc_html__('Event Check-In Filters', 'event_espresso'),
133
+						'filename' => 'registrations_event_checkin_filters',
134
+					],
135
+					'registrations_event_checkin_views_help_tab'                 => [
136
+						'title'    => esc_html__('Event Check-In Views', 'event_espresso'),
137
+						'filename' => 'registrations_event_checkin_views',
138
+					],
139
+					'registrations_event_checkin_other_help_tab'                 => [
140
+						'title'    => esc_html__('Event Check-In Other', 'event_espresso'),
141
+						'filename' => 'registrations_event_checkin_other',
142
+					],
143
+				],
144
+				'list_table'    => 'EE_Event_Registrations_List_Table',
145
+				'metaboxes'     => [],
146
+				'require_nonce' => false,
147
+			],
148
+			'registration_checkins' => [
149
+				'nav'           => [
150
+					'label'      => esc_html__('Check-In Records', 'event_espresso'),
151
+					'icon'       => 'dashicons-list-view',
152
+					'order'      => 15,
153
+					'persistent' => false,
154
+					'url'        => '',
155
+				],
156
+				'list_table'    => 'EE_Registration_CheckIn_List_Table',
157
+				'metaboxes'     => [],
158
+				'require_nonce' => false,
159
+			],
160
+		];
161
+		$this->_page_config                               = array_merge($this->_page_config, $new_page_config);
162
+		$this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
163
+		$this->_page_config['default']['list_table']      = 'Extend_EE_Registrations_List_Table';
164
+	}
165
+
166
+
167
+	/**
168
+	 * Ajax hooks for all routes in this page.
169
+	 */
170
+	protected function _ajax_hooks()
171
+	{
172
+		parent::_ajax_hooks();
173
+		add_action('wp_ajax_get_newsletter_form_content', [$this, 'get_newsletter_form_content']);
174
+		add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
175
+	}
176
+
177
+
178
+	/**
179
+	 * Global scripts for all routes in this page.
180
+	 *
181
+	 * @throws EE_Error
182
+	 * *@throws ReflectionException
183
+	 */
184
+	public function load_scripts_styles()
185
+	{
186
+		parent::load_scripts_styles();
187
+		// if newsletter message type is active then let's add filter and load js for it.
188
+		if (EEH_MSG_Template::is_mt_active('newsletter')) {
189
+			wp_enqueue_style(
190
+				'ee_message_shortcodes',
191
+				EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
192
+				[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
193
+				EVENT_ESPRESSO_VERSION
194
+			);
195
+			// enqueue newsletter js
196
+			wp_enqueue_script(
197
+				'ee-newsletter-trigger',
198
+				REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
199
+				['ee-dialog'],
200
+				EVENT_ESPRESSO_VERSION,
201
+				true
202
+			);
203
+			// hook in buttons for newsletter message type trigger.
204
+			add_action(
205
+				'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons',
206
+				[$this, 'add_newsletter_action_buttons']
207
+			);
208
+		}
209
+	}
210
+
211
+
212
+	/**
213
+	 * Scripts and styles for just the reports route.
214
+	 *
215
+	 * @throws EE_Error
216
+	 * @throws ReflectionException
217
+	 */
218
+	public function load_scripts_styles_reports()
219
+	{
220
+		wp_register_script(
221
+			'ee-reg-reports-js',
222
+			REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
223
+			['google-charts'],
224
+			EVENT_ESPRESSO_VERSION,
225
+			true
226
+		);
227
+		wp_enqueue_script('ee-reg-reports-js');
228
+		$this->_registration_reports_js_setup();
229
+	}
230
+
231
+
232
+	/**
233
+	 * Register screen options for event_registrations route.
234
+	 */
235
+	protected function _add_screen_options_event_registrations()
236
+	{
237
+		$this->_per_page_screen_option();
238
+	}
239
+
240
+
241
+	/**
242
+	 * Register screen options for registration_checkins route
243
+	 */
244
+	protected function _add_screen_options_registration_checkins()
245
+	{
246
+		$page_title              = $this->_admin_page_title;
247
+		$this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso');
248
+		$this->_per_page_screen_option();
249
+		$this->_admin_page_title = $page_title;
250
+	}
251
+
252
+
253
+	/**
254
+	 * Set views property for event_registrations route.
255
+	 */
256
+	protected function _set_list_table_views_event_registrations()
257
+	{
258
+		$this->_views = [
259
+			'all' => [
260
+				'slug'        => 'all',
261
+				'label'       => esc_html__('All', 'event_espresso'),
262
+				'count'       => 0,
263
+				'bulk_action' => ! isset($this->_req_data['event_id'])
264
+					? []
265
+					: [
266
+						'toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso'),
267
+					],
268
+			],
269
+		];
270
+	}
271
+
272
+
273
+	/**
274
+	 * Set views property for registration_checkins route.
275
+	 */
276
+	protected function _set_list_table_views_registration_checkins()
277
+	{
278
+		$this->_views = [
279
+			'all' => [
280
+				'slug'        => 'all',
281
+				'label'       => esc_html__('All', 'event_espresso'),
282
+				'count'       => 0,
283
+				'bulk_action' => ['delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')],
284
+			],
285
+		];
286
+	}
287
+
288
+
289
+	/**
290
+	 * callback for ajax action.
291
+	 *
292
+	 * @return void (JSON)
293
+	 * @throws EE_Error
294
+	 * @throws ReflectionException
295
+	 * @since 4.3.0
296
+	 */
297
+	public function get_newsletter_form_content()
298
+	{
299
+		if (! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
300
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
301
+		}
302
+		// do a nonce check because we're not coming in from a normal route here.
303
+		$nonce     = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field(
304
+			$this->_req_data['get_newsletter_form_content_nonce']
305
+		) : '';
306
+		$nonce_ref = 'get_newsletter_form_content_nonce';
307
+		$this->_verify_nonce($nonce, $nonce_ref);
308
+		// let's get the mtp for the incoming MTP_ ID
309
+		if (! isset($this->_req_data['GRP_ID'])) {
310
+			EE_Error::add_error(
311
+				esc_html__(
312
+					'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
313
+					'event_espresso'
314
+				),
315
+				__FILE__,
316
+				__FUNCTION__,
317
+				__LINE__
318
+			);
319
+			$this->_template_args['success'] = false;
320
+			$this->_template_args['error']   = true;
321
+			$this->_return_json();
322
+		}
323
+		$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
324
+		if (! $MTPG instanceof EE_Message_Template_Group) {
325
+			EE_Error::add_error(
326
+				sprintf(
327
+					esc_html__(
328
+						'The GRP_ID given (%d) does not appear to have a corresponding row in the database.',
329
+						'event_espresso'
330
+					),
331
+					$this->_req_data['GRP_ID']
332
+				),
333
+				__FILE__,
334
+				__FUNCTION__,
335
+				__LINE__
336
+			);
337
+			$this->_template_args['success'] = false;
338
+			$this->_template_args['error']   = true;
339
+			$this->_return_json();
340
+		}
341
+		$MTPs            = $MTPG->context_templates();
342
+		$MTPs            = $MTPs['attendee'];
343
+		$template_fields = [];
344
+		/** @var EE_Message_Template $MTP */
345
+		foreach ($MTPs as $MTP) {
346
+			$field = $MTP->get('MTP_template_field');
347
+			if ($field === 'content') {
348
+				$content = $MTP->get('MTP_content');
349
+				if (! empty($content['newsletter_content'])) {
350
+					$template_fields['newsletter_content'] = $content['newsletter_content'];
351
+				}
352
+				continue;
353
+			}
354
+			$template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
355
+		}
356
+		$this->_template_args['success'] = true;
357
+		$this->_template_args['error']   = false;
358
+		$this->_template_args['data']    = [
359
+			'batch_message_from'    => $template_fields['from'] ?? '',
360
+			'batch_message_subject' => $template_fields['subject'] ?? '',
361
+			'batch_message_content' => $template_fields['newsletter_content'] ?? '',
362
+		];
363
+		$this->_return_json();
364
+	}
365
+
366
+
367
+	/**
368
+	 * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
369
+	 *
370
+	 * @param EE_Admin_List_Table $list_table
371
+	 * @return void
372
+	 * @since 4.3.0
373
+	 */
374
+	public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table)
375
+	{
376
+		if (
377
+			! EE_Registry::instance()->CAP->current_user_can(
378
+				'ee_send_message',
379
+				'espresso_registrations_newsletter_selected_send'
380
+			)
381
+		) {
382
+			return;
383
+		}
384
+		$routes_to_add_to = [
385
+			'contact_list',
386
+			'event_registrations',
387
+			'default',
388
+		];
389
+		if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) {
390
+			if (
391
+				($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id']))
392
+				|| (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash')
393
+			) {
394
+				echo '';
395
+			} else {
396
+				$button_text = sprintf(
397
+					esc_html__('Send Batch Message (%s selected)', 'event_espresso'),
398
+					'<span class="send-selected-newsletter-count">0</span>'
399
+				);
400
+				echo '<button id="selected-batch-send-trigger" class="button button--secondary">'
401
+					. '<span class="dashicons dashicons-email "></span>'
402
+					. $button_text
403
+					. '</button>';
404
+				add_action('admin_footer', [$this, 'newsletter_send_form_skeleton']);
405
+			}
406
+		}
407
+	}
408
+
409
+
410
+	/**
411
+	 * @throws DomainException
412
+	 * @throws EE_Error
413
+	 * @throws ReflectionException
414
+	 */
415
+	public function newsletter_send_form_skeleton()
416
+	{
417
+		$list_table = $this->_list_table_object;
418
+		$codes      = [];
419
+		// need to templates for the newsletter message type for the template selector.
420
+		$values[] = ['text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0];
421
+		$mtps     = EEM_Message_Template_Group::instance()->get_all(
422
+			[['MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email']]
423
+		);
424
+		foreach ($mtps as $mtp) {
425
+			$name     = $mtp->name();
426
+			$values[] = [
427
+				'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name,
428
+				'id'   => $mtp->ID(),
429
+			];
430
+		}
431
+		// need to get a list of shortcodes that are available for the newsletter message type.
432
+		$shortcodes = EEH_MSG_Template::get_shortcodes(
433
+			'newsletter',
434
+			'email',
435
+			[],
436
+			'attendee'
437
+		);
438
+
439
+		foreach ($shortcodes as $field => $shortcode_array) {
440
+			$available_shortcodes = [];
441
+			foreach ($shortcode_array as $shortcode => $shortcode_details) {
442
+				$field_id               = $field === '[NEWSLETTER_CONTENT]'
443
+					? 'content'
444
+					: strtolower($field);
445
+				$field_id               = "batch-message-$field_id";
446
+				$available_shortcodes[] = '
447 447
                 <span class="js-shortcode-selection"
448 448
                       data-value="' . $shortcode . '"
449 449
                       data-linked-input-id="' . $field_id . '"
450 450
                 >' . $shortcode . '</span>';
451
-            }
452
-            $codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
453
-        }
454
-
455
-        EEH_Template::display_template(
456
-            REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
457
-            [
458
-                'form_action'       => admin_url('admin.php?page=espresso_registrations'),
459
-                'form_route'        => 'newsletter_selected_send',
460
-                'form_nonce_name'   => 'newsletter_selected_send_nonce',
461
-                'form_nonce'        => wp_create_nonce('newsletter_selected_send_nonce'),
462
-                'redirect_back_to'  => $this->_req_action,
463
-                'ajax_nonce'        => wp_create_nonce('get_newsletter_form_content_nonce'),
464
-                'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values),
465
-                'shortcodes'        => $codes,
466
-                'id_type'           => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact'
467
-                    : 'registration',
468
-            ]
469
-        );
470
-    }
471
-
472
-
473
-    /**
474
-     * Handles sending selected registrations/contacts a newsletter.
475
-     *
476
-     * @return void
477
-     * @throws EE_Error
478
-     * @throws ReflectionException
479
-     * @since  4.3.0
480
-     */
481
-    protected function _newsletter_selected_send()
482
-    {
483
-        $success = true;
484
-        // first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
485
-        if (empty($this->_req_data['newsletter_mtp_selected'])) {
486
-            EE_Error::add_error(
487
-                esc_html__(
488
-                    'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.',
489
-                    'event_espresso'
490
-                ),
491
-                __FILE__,
492
-                __FUNCTION__,
493
-                __LINE__
494
-            );
495
-            $success = false;
496
-        }
497
-        if ($success) {
498
-            // update Message template in case there are any changes
499
-            $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID(
500
-                $this->_req_data['newsletter_mtp_selected']
501
-            );
502
-            $Message_Templates      = $Message_Template_Group instanceof EE_Message_Template_Group
503
-                ? $Message_Template_Group->context_templates()
504
-                : [];
505
-            if (empty($Message_Templates)) {
506
-                EE_Error::add_error(
507
-                    esc_html__(
508
-                        'Unable to retrieve message template fields from the db. Messages not sent.',
509
-                        'event_espresso'
510
-                    ),
511
-                    __FILE__,
512
-                    __FUNCTION__,
513
-                    __LINE__
514
-                );
515
-            }
516
-            // let's just update the specific fields
517
-            foreach ($Message_Templates['attendee'] as $Message_Template) {
518
-                if ($Message_Template instanceof EE_Message_Template) {
519
-                    $field   = $Message_Template->get('MTP_template_field');
520
-                    $content = $Message_Template->get('MTP_content');
521
-                    switch ($field) {
522
-                        case 'from':
523
-                            $new_content = ! empty($this->_req_data['batch_message']['from'])
524
-                                ? $this->_req_data['batch_message']['from']
525
-                                : $content;
526
-                            break;
527
-                        case 'subject':
528
-                            $new_content = ! empty($this->_req_data['batch_message']['subject'])
529
-                                ? $this->_req_data['batch_message']['subject']
530
-                                : $content;
531
-                            break;
532
-                        case 'content':
533
-                            $new_content                       = $content;
534
-                            $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content'])
535
-                                ? $this->_req_data['batch_message']['content']
536
-                                : $content['newsletter_content'];
537
-                            break;
538
-                        default:
539
-                            // continue the foreach loop, we don't want to set $new_content nor save.
540
-                            continue 2;
541
-                    }
542
-                    $Message_Template->set('MTP_content', $new_content);
543
-                    $Message_Template->save();
544
-                }
545
-            }
546
-            // great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
547
-            $id_type = ! empty($this->_req_data['batch_message']['id_type'])
548
-                ? $this->_req_data['batch_message']['id_type']
549
-                : 'registration';
550
-            // id_type will affect how we assemble the ids.
551
-            $ids                                 = ! empty($this->_req_data['batch_message']['ids'])
552
-                ? json_decode(stripslashes($this->_req_data['batch_message']['ids']))
553
-                : [];
554
-            $registrations_used_for_contact_data = [];
555
-            // using switch because eventually we'll have other contexts that will be used for generating messages.
556
-            switch ($id_type) {
557
-                case 'registration':
558
-                    $registrations_used_for_contact_data = EEM_Registration::instance()->get_all(
559
-                        [
560
-                            [
561
-                                'REG_ID' => ['IN', $ids],
562
-                            ],
563
-                        ]
564
-                    );
565
-                    break;
566
-                case 'contact':
567
-                    $registrations_used_for_contact_data = EEM_Registration::instance()
568
-                                                                           ->get_latest_registration_for_each_of_given_contacts(
569
-                                                                               $ids
570
-                                                                           );
571
-                    break;
572
-            }
573
-            do_action_ref_array(
574
-                'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
575
-                [
576
-                    $registrations_used_for_contact_data,
577
-                    $Message_Template_Group->ID(),
578
-                ]
579
-            );
580
-            // kept for backward compat, internally we no longer use this action.
581
-            // @deprecated 4.8.36.rc.002
582
-            $contacts = $id_type === 'registration'
583
-                ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids)
584
-                : EEM_Attendee::instance()->get_all([['ATT_ID' => ['in', $ids]]]);
585
-            do_action_ref_array(
586
-                'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send',
587
-                [
588
-                    $contacts,
589
-                    $Message_Template_Group->ID(),
590
-                ]
591
-            );
592
-        }
593
-        $query_args = [
594
-            'action' => ! empty($this->_req_data['redirect_back_to'])
595
-                ? $this->_req_data['redirect_back_to']
596
-                : 'default',
597
-        ];
598
-        $this->_redirect_after_action(false, '', '', $query_args, true);
599
-    }
600
-
601
-
602
-    /**
603
-     * This is called when javascript is being enqueued to setup the various data needed for the reports js.
604
-     * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method.
605
-     *
606
-     * @throws EE_Error
607
-     * @throws ReflectionException
608
-     */
609
-    protected function _registration_reports_js_setup()
610
-    {
611
-        $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report();
612
-        $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report();
613
-    }
614
-
615
-
616
-    /**
617
-     * generates Business Reports regarding Registrations
618
-     *
619
-     * @return void
620
-     * @throws DomainException
621
-     * @throws EE_Error
622
-     */
623
-    protected function _registration_reports()
624
-    {
625
-        $template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
626
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
627
-            $template_path,
628
-            $this->_reports_template_data,
629
-            true
630
-        );
631
-        // the final template wrapper
632
-        $this->display_admin_page_with_no_sidebar();
633
-    }
634
-
635
-
636
-    /**
637
-     * Generates Business Report showing total registrations per day.
638
-     *
639
-     * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
640
-     * @return string
641
-     * @throws EE_Error
642
-     * @throws ReflectionException
643
-     * @throws Exception
644
-     * @throws Exception
645
-     * @throws Exception
646
-     */
647
-    private function _registrations_per_day_report(string $period = '-1 month'): string
648
-    {
649
-        $report_ID = 'reg-admin-registrations-per-day-report-dv';
650
-        $results   = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period);
651
-        $regs      = [];
652
-        $subtitle  = '';
653
-        if ($results) {
654
-            $column_titles = [];
655
-            $tracker       = 0;
656
-            foreach ($results as $result) {
657
-                $report_column_values = [];
658
-                foreach ($result as $property_name => $property_value) {
659
-                    $property_value         = $property_name === 'Registration_REG_date' ? $property_value
660
-                        : (int) $property_value;
661
-                    $report_column_values[] = $property_value;
662
-                    if ($tracker === 0) {
663
-                        if ($property_name === 'Registration_REG_date') {
664
-                            $column_titles[] = esc_html__(
665
-                                'Date (only days with registrations are shown)',
666
-                                'event_espresso'
667
-                            );
668
-                        } else {
669
-                            $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
670
-                        }
671
-                    }
672
-                }
673
-                $tracker++;
674
-                $regs[] = $report_column_values;
675
-            }
676
-            // make sure the column_titles is pushed to the beginning of the array
677
-            array_unshift($regs, $column_titles);
678
-            // setup the date range.
679
-            $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
680
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
681
-            $ending_date    = new DateTime("now", $DateTimeZone);
682
-            $subtitle       = sprintf(
683
-                wp_strip_all_tags(
684
-                    _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
685
-                ),
686
-                $beginning_date->format('Y-m-d'),
687
-                $ending_date->format('Y-m-d')
688
-            );
689
-        }
690
-        $report_title  = wp_strip_all_tags(__('Total Registrations per Day', 'event_espresso'));
691
-        $report_params = [
692
-            'title'     => $report_title,
693
-            'subtitle'  => $subtitle,
694
-            'id'        => $report_ID,
695
-            'regs'      => $regs,
696
-            'noResults' => empty($regs),
697
-            'noRegsMsg' => sprintf(
698
-                wp_strip_all_tags(
699
-                    __(
700
-                        '%sThere are currently no registration records in the last month for this report.%s',
701
-                        'event_espresso'
702
-                    )
703
-                ),
704
-                '<h2>' . $report_title . '</h2><p>',
705
-                '</p>'
706
-            ),
707
-        ];
708
-        wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params);
709
-        return $report_ID;
710
-    }
711
-
712
-
713
-    /**
714
-     * Generates Business Report showing total registrations per event.
715
-     *
716
-     * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
717
-     * @return string
718
-     * @throws EE_Error
719
-     * @throws ReflectionException
720
-     * @throws Exception
721
-     * @throws Exception
722
-     * @throws Exception
723
-     */
724
-    private function _registrations_per_event_report(string $period = '-1 month'): string
725
-    {
726
-        $report_ID = 'reg-admin-registrations-per-event-report-dv';
727
-        $results   = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
728
-        $regs      = [];
729
-        $subtitle  = '';
730
-        if ($results) {
731
-            $column_titles = [];
732
-            $tracker       = 0;
733
-            foreach ($results as $result) {
734
-                $report_column_values = [];
735
-                foreach ($result as $property_name => $property_value) {
736
-                    $property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
737
-                        $property_value,
738
-                        4,
739
-                        '...'
740
-                    ) : (int) $property_value;
741
-                    $report_column_values[] = $property_value;
742
-                    if ($tracker === 0) {
743
-                        if ($property_name === 'Registration_Event') {
744
-                            $column_titles[] = esc_html__('Event', 'event_espresso');
745
-                        } else {
746
-                            $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
747
-                        }
748
-                    }
749
-                }
750
-                $tracker++;
751
-                $regs[] = $report_column_values;
752
-            }
753
-            // make sure the column_titles is pushed to the beginning of the array
754
-            array_unshift($regs, $column_titles);
755
-            // setup the date range.
756
-            $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
757
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
758
-            $ending_date    = new DateTime("now", $DateTimeZone);
759
-            $subtitle       = sprintf(
760
-                wp_strip_all_tags(
761
-                    _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
762
-                ),
763
-                $beginning_date->format('Y-m-d'),
764
-                $ending_date->format('Y-m-d')
765
-            );
766
-        }
767
-        $report_title  = wp_strip_all_tags(__('Total Registrations per Event', 'event_espresso'));
768
-        $report_params = [
769
-            'title'     => $report_title,
770
-            'subtitle'  => $subtitle,
771
-            'id'        => $report_ID,
772
-            'regs'      => $regs,
773
-            'noResults' => empty($regs),
774
-            'noRegsMsg' => sprintf(
775
-                wp_strip_all_tags(
776
-                    __(
777
-                        '%sThere are currently no registration records in the last month for this report.%s',
778
-                        'event_espresso'
779
-                    )
780
-                ),
781
-                '<h2>' . $report_title . '</h2><p>',
782
-                '</p>'
783
-            ),
784
-        ];
785
-        wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
786
-        return $report_ID;
787
-    }
788
-
789
-
790
-    /**
791
-     * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
792
-     *
793
-     * @return void
794
-     * @throws EE_Error
795
-     * @throws EntityNotFoundException
796
-     * @throws ReflectionException
797
-     */
798
-    protected function _registration_checkin_list_table()
799
-    {
800
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, DataType::INTEGER);
801
-        /** @var EE_Registration $registration */
802
-        $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
803
-        if (! $registration instanceof EE_Registration) {
804
-            throw new EE_Error(
805
-                sprintf(
806
-                    esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
807
-                    $REG_ID
808
-                )
809
-            );
810
-        }
811
-        $attendee                                 = $registration->attendee();
812
-        $this->_admin_page_title                  .= $this->get_action_link_or_button(
813
-            'new_registration',
814
-            'add-registrant',
815
-            ['event_id' => $registration->event_ID()],
816
-            'add-new-h2'
817
-        );
818
-        $checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
819
-        $checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
820
-        $legend_items                             = [
821
-            'checkin'  => [
822
-                'class' => $checked_in->cssClasses(),
823
-                'desc'  => $checked_in->legendLabel(),
824
-            ],
825
-            'checkout' => [
826
-                'class' => $checked_out->cssClasses(),
827
-                'desc'  => $checked_out->legendLabel(),
828
-            ],
829
-        ];
830
-        $this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
831
-
832
-        $DTT_ID         = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
833
-        $datetime       = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
834
-        $datetime_label = '';
835
-        if ($datetime instanceof EE_Datetime) {
836
-            $datetime_label = $datetime->get_dtt_display_name(true);
837
-            $datetime_label .= ! empty($datetime_label)
838
-                ? ' (' . $datetime->get_dtt_display_name() . ')'
839
-                : $datetime->get_dtt_display_name();
840
-        }
841
-        $datetime_link                                    = ! $DTT_ID
842
-            ? EE_Admin_Page::add_query_args_and_nonce(
843
-                [
844
-                    'action'   => 'event_registrations',
845
-                    'event_id' => $registration->event_ID(),
846
-                    'DTT_ID'   => $DTT_ID,
847
-                ],
848
-                $this->_admin_base_url
849
-            )
850
-            : '';
851
-        $datetime_link                                    = ! empty($datetime_link)
852
-            ? '<a href="' . $datetime_link . '">'
853
-            . '<span id="checkin-dtt">'
854
-            . $datetime_label
855
-            . '</span></a>'
856
-            : $datetime_label;
857
-        $attendee_name                                    = $attendee instanceof EE_Attendee
858
-            ? $attendee->full_name()
859
-            : '';
860
-        $attendee_link                                    = $attendee instanceof EE_Attendee
861
-            ? $attendee->get_admin_details_link()
862
-            : '';
863
-        $attendee_link                                    = ! empty($attendee_link)
864
-            ? '<a href="' . $attendee->get_admin_details_link() . '"'
865
-            . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
866
-            . '<span id="checkin-attendee-name">'
867
-            . $attendee_name
868
-            . '</span></a>'
869
-            : '';
870
-        $event_link                                       = $registration->event() instanceof EE_Event
871
-            ? $registration->event()->get_admin_details_link()
872
-            : '';
873
-        $event_link                                       = ! empty($event_link)
874
-            ? '<a href="' . $event_link . '"'
875
-            . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
876
-            . '<span id="checkin-event-name">'
877
-            . $registration->event_name()
878
-            . '</span>'
879
-            . '</a>'
880
-            : '';
881
-        $this->_template_args['before_list_table']        = $REG_ID && $DTT_ID
882
-            ? '<h2>' . sprintf(
883
-                esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
884
-                $attendee_link,
885
-                $datetime_link,
886
-                $event_link
887
-            ) . '</h2>'
888
-            : '';
889
-        $this->_template_args['list_table_hidden_fields'] = $REG_ID
890
-            ? '<input type="hidden" name="_REG_ID" value="' . $REG_ID . '">'
891
-            : '';
892
-        $this->_template_args['list_table_hidden_fields'] .= $DTT_ID
893
-            ? '<input type="hidden" name="DTT_ID" value="' . $DTT_ID . '">'
894
-            : '';
895
-        $this->display_admin_list_table_page_with_no_sidebar();
896
-    }
897
-
898
-
899
-    /**
900
-     * toggle the Check-in status for the given registration (coming from ajax)
901
-     *
902
-     * @return void (JSON)
903
-     * @throws EE_Error
904
-     * @throws ReflectionException
905
-     */
906
-    public function toggle_checkin_status()
907
-    {
908
-        if (! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
909
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
910
-        }
911
-        // first make sure we have the necessary data
912
-        if (! isset($this->_req_data['_regid'])) {
913
-            EE_Error::add_error(
914
-                esc_html__(
915
-                    'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
916
-                    'event_espresso'
917
-                ),
918
-                __FILE__,
919
-                __FUNCTION__,
920
-                __LINE__
921
-            );
922
-            $this->_template_args['success'] = false;
923
-            $this->_template_args['error']   = true;
924
-            $this->_return_json();
925
-        }
926
-        // do a nonce check because we're not coming in from a normal route here.
927
-        $nonce     = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce'])
928
-            : '';
929
-        $nonce_ref = 'checkin_nonce';
930
-        $this->_verify_nonce($nonce, $nonce_ref);
931
-        // beautiful! Made it this far so let's get the status.
932
-        $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
933
-        // setup new class to return via ajax
934
-        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
935
-        $this->_template_args['success']            = true;
936
-        $this->_return_json();
937
-    }
938
-
939
-
940
-    /**
941
-     * handles toggling the checkin status for the registration,
942
-     *
943
-     * @return int|void
944
-     * @throws EE_Error
945
-     * @throws ReflectionException
946
-     */
947
-    protected function _toggle_checkin_status()
948
-    {
949
-        // first let's get the query args out of the way for the redirect
950
-        $query_args = [
951
-            'action'   => 'event_registrations',
952
-            'event_id' => $this->_req_data['event_id'] ?? null,
953
-            'DTT_ID'   => $this->_req_data['DTT_ID'] ?? null,
954
-        ];
955
-        $new_status = false;
956
-        // bulk action check in toggle
957
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
958
-            // cycle thru checkboxes
959
-            $checkboxes = $this->_req_data['checkbox'];
960
-            foreach (array_keys($checkboxes) as $REG_ID) {
961
-                $DTT_ID     = $this->_req_data['DTT_ID'] ?? null;
962
-                $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
963
-            }
964
-        } elseif (isset($this->_req_data['_regid'])) {
965
-            // coming from ajax request
966
-            $DTT_ID               = $this->_req_data['dttid'] ?? null;
967
-            $query_args['DTT_ID'] = $DTT_ID;
968
-            $new_status           = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID);
969
-        } else {
970
-            EE_Error::add_error(
971
-                esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'),
972
-                __FILE__,
973
-                __FUNCTION__,
974
-                __LINE__
975
-            );
976
-        }
977
-        if (defined('DOING_AJAX')) {
978
-            return $new_status;
979
-        }
980
-        $this->_redirect_after_action(false, '', '', $query_args, true);
981
-    }
982
-
983
-
984
-    /**
985
-     * This is toggles a single Check-in for the given registration and datetime.
986
-     *
987
-     * @param int $REG_ID The registration we're toggling
988
-     * @param int $DTT_ID The datetime we're toggling
989
-     * @return int The new status toggled to.
990
-     * @throws EE_Error
991
-     * @throws ReflectionException
992
-     */
993
-    private function _toggle_checkin(int $REG_ID, int $DTT_ID)
994
-    {
995
-        /** @var EE_Registration $REG */
996
-        $REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
997
-        $new_status = $REG->toggle_checkin_status($DTT_ID);
998
-        if ($new_status !== false) {
999
-            EE_Error::add_success($REG->get_checkin_msg($DTT_ID));
1000
-        } else {
1001
-            EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__);
1002
-            $new_status = false;
1003
-        }
1004
-        return $new_status;
1005
-    }
1006
-
1007
-
1008
-    /**
1009
-     * Takes care of deleting multiple EE_Checkin table rows
1010
-     *
1011
-     * @return void
1012
-     * @throws EE_Error
1013
-     * @throws ReflectionException
1014
-     */
1015
-    protected function _delete_checkin_rows()
1016
-    {
1017
-        $query_args = [
1018
-            'action'  => 'registration_checkins',
1019
-            'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1020
-            '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1021
-        ];
1022
-        $errors     = 0;
1023
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1024
-            $checkboxes = $this->_req_data['checkbox'];
1025
-            foreach (array_keys($checkboxes) as $CHK_ID) {
1026
-                if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1027
-                    $errors++;
1028
-                }
1029
-            }
1030
-        } else {
1031
-            EE_Error::add_error(
1032
-                esc_html__(
1033
-                    'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!',
1034
-                    'event_espresso'
1035
-                ),
1036
-                __FILE__,
1037
-                __FUNCTION__,
1038
-                __LINE__
1039
-            );
1040
-            $this->_redirect_after_action(false, '', '', $query_args, true);
1041
-        }
1042
-        if ($errors > 0) {
1043
-            EE_Error::add_error(
1044
-                sprintf(
1045
-                    esc_html__('There were %d records that did not delete successfully', 'event_espresso'),
1046
-                    $errors
1047
-                ),
1048
-                __FILE__,
1049
-                __FUNCTION__,
1050
-                __LINE__
1051
-            );
1052
-        } else {
1053
-            EE_Error::add_success(esc_html__('Records were successfully deleted', 'event_espresso'));
1054
-        }
1055
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1056
-    }
1057
-
1058
-
1059
-    /**
1060
-     * Deletes a single EE_Checkin row
1061
-     *
1062
-     * @return void
1063
-     * @throws EE_Error
1064
-     * @throws ReflectionException
1065
-     */
1066
-    protected function _delete_checkin_row()
1067
-    {
1068
-        $query_args = [
1069
-            'action'  => 'registration_checkins',
1070
-            'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1071
-            '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1072
-        ];
1073
-        if (! empty($this->_req_data['CHK_ID'])) {
1074
-            if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1075
-                EE_Error::add_error(
1076
-                    esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1077
-                    __FILE__,
1078
-                    __FUNCTION__,
1079
-                    __LINE__
1080
-                );
1081
-            } else {
1082
-                EE_Error::add_success(esc_html__('Check-In record successfully deleted', 'event_espresso'));
1083
-            }
1084
-        } else {
1085
-            EE_Error::add_error(
1086
-                esc_html__(
1087
-                    'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code',
1088
-                    'event_espresso'
1089
-                ),
1090
-                __FILE__,
1091
-                __FUNCTION__,
1092
-                __LINE__
1093
-            );
1094
-        }
1095
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1096
-    }
1097
-
1098
-
1099
-    /**
1100
-     * @return void
1101
-     * @throws EE_Error
1102
-     */
1103
-    protected function _event_registrations_list_table()
1104
-    {
1105
-        $EVT_ID                  = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1106
-        $this->_admin_page_title .= $EVT_ID
1107
-            ? $this->get_action_link_or_button(
1108
-                'new_registration',
1109
-                'add-registrant',
1110
-                ['event_id' => $EVT_ID],
1111
-                'add-new-h2'
1112
-            )
1113
-            : '';
1114
-
1115
-        $this->_template_args['before_list_table'] = $this->generateListTableHeaderText();
1116
-        $this->_template_args['after_list_table']  = $this->generateListTableLegend();
1117
-
1118
-        $this->display_admin_list_table_page_with_no_sidebar();
1119
-    }
1120
-
1121
-
1122
-    /**
1123
-     * @return string
1124
-     * @since 5.0.24.p
1125
-     */
1126
-    private function generateListTableHeaderText(): string
1127
-    {
1128
-        $header_text                  = '';
1129
-        $admin_page_header_decorators = [
1130
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1131
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1132
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1133
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1134
-        ];
1135
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1136
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1137
-            $header_text             = $filter_header_decorator->getHeaderText($header_text);
1138
-        }
1139
-        $header_text .= '
451
+			}
452
+			$codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
453
+		}
454
+
455
+		EEH_Template::display_template(
456
+			REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
457
+			[
458
+				'form_action'       => admin_url('admin.php?page=espresso_registrations'),
459
+				'form_route'        => 'newsletter_selected_send',
460
+				'form_nonce_name'   => 'newsletter_selected_send_nonce',
461
+				'form_nonce'        => wp_create_nonce('newsletter_selected_send_nonce'),
462
+				'redirect_back_to'  => $this->_req_action,
463
+				'ajax_nonce'        => wp_create_nonce('get_newsletter_form_content_nonce'),
464
+				'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values),
465
+				'shortcodes'        => $codes,
466
+				'id_type'           => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact'
467
+					: 'registration',
468
+			]
469
+		);
470
+	}
471
+
472
+
473
+	/**
474
+	 * Handles sending selected registrations/contacts a newsletter.
475
+	 *
476
+	 * @return void
477
+	 * @throws EE_Error
478
+	 * @throws ReflectionException
479
+	 * @since  4.3.0
480
+	 */
481
+	protected function _newsletter_selected_send()
482
+	{
483
+		$success = true;
484
+		// first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
485
+		if (empty($this->_req_data['newsletter_mtp_selected'])) {
486
+			EE_Error::add_error(
487
+				esc_html__(
488
+					'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.',
489
+					'event_espresso'
490
+				),
491
+				__FILE__,
492
+				__FUNCTION__,
493
+				__LINE__
494
+			);
495
+			$success = false;
496
+		}
497
+		if ($success) {
498
+			// update Message template in case there are any changes
499
+			$Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID(
500
+				$this->_req_data['newsletter_mtp_selected']
501
+			);
502
+			$Message_Templates      = $Message_Template_Group instanceof EE_Message_Template_Group
503
+				? $Message_Template_Group->context_templates()
504
+				: [];
505
+			if (empty($Message_Templates)) {
506
+				EE_Error::add_error(
507
+					esc_html__(
508
+						'Unable to retrieve message template fields from the db. Messages not sent.',
509
+						'event_espresso'
510
+					),
511
+					__FILE__,
512
+					__FUNCTION__,
513
+					__LINE__
514
+				);
515
+			}
516
+			// let's just update the specific fields
517
+			foreach ($Message_Templates['attendee'] as $Message_Template) {
518
+				if ($Message_Template instanceof EE_Message_Template) {
519
+					$field   = $Message_Template->get('MTP_template_field');
520
+					$content = $Message_Template->get('MTP_content');
521
+					switch ($field) {
522
+						case 'from':
523
+							$new_content = ! empty($this->_req_data['batch_message']['from'])
524
+								? $this->_req_data['batch_message']['from']
525
+								: $content;
526
+							break;
527
+						case 'subject':
528
+							$new_content = ! empty($this->_req_data['batch_message']['subject'])
529
+								? $this->_req_data['batch_message']['subject']
530
+								: $content;
531
+							break;
532
+						case 'content':
533
+							$new_content                       = $content;
534
+							$new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content'])
535
+								? $this->_req_data['batch_message']['content']
536
+								: $content['newsletter_content'];
537
+							break;
538
+						default:
539
+							// continue the foreach loop, we don't want to set $new_content nor save.
540
+							continue 2;
541
+					}
542
+					$Message_Template->set('MTP_content', $new_content);
543
+					$Message_Template->save();
544
+				}
545
+			}
546
+			// great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
547
+			$id_type = ! empty($this->_req_data['batch_message']['id_type'])
548
+				? $this->_req_data['batch_message']['id_type']
549
+				: 'registration';
550
+			// id_type will affect how we assemble the ids.
551
+			$ids                                 = ! empty($this->_req_data['batch_message']['ids'])
552
+				? json_decode(stripslashes($this->_req_data['batch_message']['ids']))
553
+				: [];
554
+			$registrations_used_for_contact_data = [];
555
+			// using switch because eventually we'll have other contexts that will be used for generating messages.
556
+			switch ($id_type) {
557
+				case 'registration':
558
+					$registrations_used_for_contact_data = EEM_Registration::instance()->get_all(
559
+						[
560
+							[
561
+								'REG_ID' => ['IN', $ids],
562
+							],
563
+						]
564
+					);
565
+					break;
566
+				case 'contact':
567
+					$registrations_used_for_contact_data = EEM_Registration::instance()
568
+																		   ->get_latest_registration_for_each_of_given_contacts(
569
+																			   $ids
570
+																		   );
571
+					break;
572
+			}
573
+			do_action_ref_array(
574
+				'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
575
+				[
576
+					$registrations_used_for_contact_data,
577
+					$Message_Template_Group->ID(),
578
+				]
579
+			);
580
+			// kept for backward compat, internally we no longer use this action.
581
+			// @deprecated 4.8.36.rc.002
582
+			$contacts = $id_type === 'registration'
583
+				? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids)
584
+				: EEM_Attendee::instance()->get_all([['ATT_ID' => ['in', $ids]]]);
585
+			do_action_ref_array(
586
+				'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send',
587
+				[
588
+					$contacts,
589
+					$Message_Template_Group->ID(),
590
+				]
591
+			);
592
+		}
593
+		$query_args = [
594
+			'action' => ! empty($this->_req_data['redirect_back_to'])
595
+				? $this->_req_data['redirect_back_to']
596
+				: 'default',
597
+		];
598
+		$this->_redirect_after_action(false, '', '', $query_args, true);
599
+	}
600
+
601
+
602
+	/**
603
+	 * This is called when javascript is being enqueued to setup the various data needed for the reports js.
604
+	 * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method.
605
+	 *
606
+	 * @throws EE_Error
607
+	 * @throws ReflectionException
608
+	 */
609
+	protected function _registration_reports_js_setup()
610
+	{
611
+		$this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report();
612
+		$this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report();
613
+	}
614
+
615
+
616
+	/**
617
+	 * generates Business Reports regarding Registrations
618
+	 *
619
+	 * @return void
620
+	 * @throws DomainException
621
+	 * @throws EE_Error
622
+	 */
623
+	protected function _registration_reports()
624
+	{
625
+		$template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
626
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
627
+			$template_path,
628
+			$this->_reports_template_data,
629
+			true
630
+		);
631
+		// the final template wrapper
632
+		$this->display_admin_page_with_no_sidebar();
633
+	}
634
+
635
+
636
+	/**
637
+	 * Generates Business Report showing total registrations per day.
638
+	 *
639
+	 * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
640
+	 * @return string
641
+	 * @throws EE_Error
642
+	 * @throws ReflectionException
643
+	 * @throws Exception
644
+	 * @throws Exception
645
+	 * @throws Exception
646
+	 */
647
+	private function _registrations_per_day_report(string $period = '-1 month'): string
648
+	{
649
+		$report_ID = 'reg-admin-registrations-per-day-report-dv';
650
+		$results   = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period);
651
+		$regs      = [];
652
+		$subtitle  = '';
653
+		if ($results) {
654
+			$column_titles = [];
655
+			$tracker       = 0;
656
+			foreach ($results as $result) {
657
+				$report_column_values = [];
658
+				foreach ($result as $property_name => $property_value) {
659
+					$property_value         = $property_name === 'Registration_REG_date' ? $property_value
660
+						: (int) $property_value;
661
+					$report_column_values[] = $property_value;
662
+					if ($tracker === 0) {
663
+						if ($property_name === 'Registration_REG_date') {
664
+							$column_titles[] = esc_html__(
665
+								'Date (only days with registrations are shown)',
666
+								'event_espresso'
667
+							);
668
+						} else {
669
+							$column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
670
+						}
671
+					}
672
+				}
673
+				$tracker++;
674
+				$regs[] = $report_column_values;
675
+			}
676
+			// make sure the column_titles is pushed to the beginning of the array
677
+			array_unshift($regs, $column_titles);
678
+			// setup the date range.
679
+			$DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
680
+			$beginning_date = new DateTime("now " . $period, $DateTimeZone);
681
+			$ending_date    = new DateTime("now", $DateTimeZone);
682
+			$subtitle       = sprintf(
683
+				wp_strip_all_tags(
684
+					_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
685
+				),
686
+				$beginning_date->format('Y-m-d'),
687
+				$ending_date->format('Y-m-d')
688
+			);
689
+		}
690
+		$report_title  = wp_strip_all_tags(__('Total Registrations per Day', 'event_espresso'));
691
+		$report_params = [
692
+			'title'     => $report_title,
693
+			'subtitle'  => $subtitle,
694
+			'id'        => $report_ID,
695
+			'regs'      => $regs,
696
+			'noResults' => empty($regs),
697
+			'noRegsMsg' => sprintf(
698
+				wp_strip_all_tags(
699
+					__(
700
+						'%sThere are currently no registration records in the last month for this report.%s',
701
+						'event_espresso'
702
+					)
703
+				),
704
+				'<h2>' . $report_title . '</h2><p>',
705
+				'</p>'
706
+			),
707
+		];
708
+		wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params);
709
+		return $report_ID;
710
+	}
711
+
712
+
713
+	/**
714
+	 * Generates Business Report showing total registrations per event.
715
+	 *
716
+	 * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
717
+	 * @return string
718
+	 * @throws EE_Error
719
+	 * @throws ReflectionException
720
+	 * @throws Exception
721
+	 * @throws Exception
722
+	 * @throws Exception
723
+	 */
724
+	private function _registrations_per_event_report(string $period = '-1 month'): string
725
+	{
726
+		$report_ID = 'reg-admin-registrations-per-event-report-dv';
727
+		$results   = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
728
+		$regs      = [];
729
+		$subtitle  = '';
730
+		if ($results) {
731
+			$column_titles = [];
732
+			$tracker       = 0;
733
+			foreach ($results as $result) {
734
+				$report_column_values = [];
735
+				foreach ($result as $property_name => $property_value) {
736
+					$property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
737
+						$property_value,
738
+						4,
739
+						'...'
740
+					) : (int) $property_value;
741
+					$report_column_values[] = $property_value;
742
+					if ($tracker === 0) {
743
+						if ($property_name === 'Registration_Event') {
744
+							$column_titles[] = esc_html__('Event', 'event_espresso');
745
+						} else {
746
+							$column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
747
+						}
748
+					}
749
+				}
750
+				$tracker++;
751
+				$regs[] = $report_column_values;
752
+			}
753
+			// make sure the column_titles is pushed to the beginning of the array
754
+			array_unshift($regs, $column_titles);
755
+			// setup the date range.
756
+			$DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
757
+			$beginning_date = new DateTime("now " . $period, $DateTimeZone);
758
+			$ending_date    = new DateTime("now", $DateTimeZone);
759
+			$subtitle       = sprintf(
760
+				wp_strip_all_tags(
761
+					_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
762
+				),
763
+				$beginning_date->format('Y-m-d'),
764
+				$ending_date->format('Y-m-d')
765
+			);
766
+		}
767
+		$report_title  = wp_strip_all_tags(__('Total Registrations per Event', 'event_espresso'));
768
+		$report_params = [
769
+			'title'     => $report_title,
770
+			'subtitle'  => $subtitle,
771
+			'id'        => $report_ID,
772
+			'regs'      => $regs,
773
+			'noResults' => empty($regs),
774
+			'noRegsMsg' => sprintf(
775
+				wp_strip_all_tags(
776
+					__(
777
+						'%sThere are currently no registration records in the last month for this report.%s',
778
+						'event_espresso'
779
+					)
780
+				),
781
+				'<h2>' . $report_title . '</h2><p>',
782
+				'</p>'
783
+			),
784
+		];
785
+		wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
786
+		return $report_ID;
787
+	}
788
+
789
+
790
+	/**
791
+	 * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
792
+	 *
793
+	 * @return void
794
+	 * @throws EE_Error
795
+	 * @throws EntityNotFoundException
796
+	 * @throws ReflectionException
797
+	 */
798
+	protected function _registration_checkin_list_table()
799
+	{
800
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, DataType::INTEGER);
801
+		/** @var EE_Registration $registration */
802
+		$registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
803
+		if (! $registration instanceof EE_Registration) {
804
+			throw new EE_Error(
805
+				sprintf(
806
+					esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
807
+					$REG_ID
808
+				)
809
+			);
810
+		}
811
+		$attendee                                 = $registration->attendee();
812
+		$this->_admin_page_title                  .= $this->get_action_link_or_button(
813
+			'new_registration',
814
+			'add-registrant',
815
+			['event_id' => $registration->event_ID()],
816
+			'add-new-h2'
817
+		);
818
+		$checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
819
+		$checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
820
+		$legend_items                             = [
821
+			'checkin'  => [
822
+				'class' => $checked_in->cssClasses(),
823
+				'desc'  => $checked_in->legendLabel(),
824
+			],
825
+			'checkout' => [
826
+				'class' => $checked_out->cssClasses(),
827
+				'desc'  => $checked_out->legendLabel(),
828
+			],
829
+		];
830
+		$this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
831
+
832
+		$DTT_ID         = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
833
+		$datetime       = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
834
+		$datetime_label = '';
835
+		if ($datetime instanceof EE_Datetime) {
836
+			$datetime_label = $datetime->get_dtt_display_name(true);
837
+			$datetime_label .= ! empty($datetime_label)
838
+				? ' (' . $datetime->get_dtt_display_name() . ')'
839
+				: $datetime->get_dtt_display_name();
840
+		}
841
+		$datetime_link                                    = ! $DTT_ID
842
+			? EE_Admin_Page::add_query_args_and_nonce(
843
+				[
844
+					'action'   => 'event_registrations',
845
+					'event_id' => $registration->event_ID(),
846
+					'DTT_ID'   => $DTT_ID,
847
+				],
848
+				$this->_admin_base_url
849
+			)
850
+			: '';
851
+		$datetime_link                                    = ! empty($datetime_link)
852
+			? '<a href="' . $datetime_link . '">'
853
+			. '<span id="checkin-dtt">'
854
+			. $datetime_label
855
+			. '</span></a>'
856
+			: $datetime_label;
857
+		$attendee_name                                    = $attendee instanceof EE_Attendee
858
+			? $attendee->full_name()
859
+			: '';
860
+		$attendee_link                                    = $attendee instanceof EE_Attendee
861
+			? $attendee->get_admin_details_link()
862
+			: '';
863
+		$attendee_link                                    = ! empty($attendee_link)
864
+			? '<a href="' . $attendee->get_admin_details_link() . '"'
865
+			. ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
866
+			. '<span id="checkin-attendee-name">'
867
+			. $attendee_name
868
+			. '</span></a>'
869
+			: '';
870
+		$event_link                                       = $registration->event() instanceof EE_Event
871
+			? $registration->event()->get_admin_details_link()
872
+			: '';
873
+		$event_link                                       = ! empty($event_link)
874
+			? '<a href="' . $event_link . '"'
875
+			. ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
876
+			. '<span id="checkin-event-name">'
877
+			. $registration->event_name()
878
+			. '</span>'
879
+			. '</a>'
880
+			: '';
881
+		$this->_template_args['before_list_table']        = $REG_ID && $DTT_ID
882
+			? '<h2>' . sprintf(
883
+				esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
884
+				$attendee_link,
885
+				$datetime_link,
886
+				$event_link
887
+			) . '</h2>'
888
+			: '';
889
+		$this->_template_args['list_table_hidden_fields'] = $REG_ID
890
+			? '<input type="hidden" name="_REG_ID" value="' . $REG_ID . '">'
891
+			: '';
892
+		$this->_template_args['list_table_hidden_fields'] .= $DTT_ID
893
+			? '<input type="hidden" name="DTT_ID" value="' . $DTT_ID . '">'
894
+			: '';
895
+		$this->display_admin_list_table_page_with_no_sidebar();
896
+	}
897
+
898
+
899
+	/**
900
+	 * toggle the Check-in status for the given registration (coming from ajax)
901
+	 *
902
+	 * @return void (JSON)
903
+	 * @throws EE_Error
904
+	 * @throws ReflectionException
905
+	 */
906
+	public function toggle_checkin_status()
907
+	{
908
+		if (! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
909
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
910
+		}
911
+		// first make sure we have the necessary data
912
+		if (! isset($this->_req_data['_regid'])) {
913
+			EE_Error::add_error(
914
+				esc_html__(
915
+					'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
916
+					'event_espresso'
917
+				),
918
+				__FILE__,
919
+				__FUNCTION__,
920
+				__LINE__
921
+			);
922
+			$this->_template_args['success'] = false;
923
+			$this->_template_args['error']   = true;
924
+			$this->_return_json();
925
+		}
926
+		// do a nonce check because we're not coming in from a normal route here.
927
+		$nonce     = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce'])
928
+			: '';
929
+		$nonce_ref = 'checkin_nonce';
930
+		$this->_verify_nonce($nonce, $nonce_ref);
931
+		// beautiful! Made it this far so let's get the status.
932
+		$new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
933
+		// setup new class to return via ajax
934
+		$this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
935
+		$this->_template_args['success']            = true;
936
+		$this->_return_json();
937
+	}
938
+
939
+
940
+	/**
941
+	 * handles toggling the checkin status for the registration,
942
+	 *
943
+	 * @return int|void
944
+	 * @throws EE_Error
945
+	 * @throws ReflectionException
946
+	 */
947
+	protected function _toggle_checkin_status()
948
+	{
949
+		// first let's get the query args out of the way for the redirect
950
+		$query_args = [
951
+			'action'   => 'event_registrations',
952
+			'event_id' => $this->_req_data['event_id'] ?? null,
953
+			'DTT_ID'   => $this->_req_data['DTT_ID'] ?? null,
954
+		];
955
+		$new_status = false;
956
+		// bulk action check in toggle
957
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
958
+			// cycle thru checkboxes
959
+			$checkboxes = $this->_req_data['checkbox'];
960
+			foreach (array_keys($checkboxes) as $REG_ID) {
961
+				$DTT_ID     = $this->_req_data['DTT_ID'] ?? null;
962
+				$new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
963
+			}
964
+		} elseif (isset($this->_req_data['_regid'])) {
965
+			// coming from ajax request
966
+			$DTT_ID               = $this->_req_data['dttid'] ?? null;
967
+			$query_args['DTT_ID'] = $DTT_ID;
968
+			$new_status           = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID);
969
+		} else {
970
+			EE_Error::add_error(
971
+				esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'),
972
+				__FILE__,
973
+				__FUNCTION__,
974
+				__LINE__
975
+			);
976
+		}
977
+		if (defined('DOING_AJAX')) {
978
+			return $new_status;
979
+		}
980
+		$this->_redirect_after_action(false, '', '', $query_args, true);
981
+	}
982
+
983
+
984
+	/**
985
+	 * This is toggles a single Check-in for the given registration and datetime.
986
+	 *
987
+	 * @param int $REG_ID The registration we're toggling
988
+	 * @param int $DTT_ID The datetime we're toggling
989
+	 * @return int The new status toggled to.
990
+	 * @throws EE_Error
991
+	 * @throws ReflectionException
992
+	 */
993
+	private function _toggle_checkin(int $REG_ID, int $DTT_ID)
994
+	{
995
+		/** @var EE_Registration $REG */
996
+		$REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
997
+		$new_status = $REG->toggle_checkin_status($DTT_ID);
998
+		if ($new_status !== false) {
999
+			EE_Error::add_success($REG->get_checkin_msg($DTT_ID));
1000
+		} else {
1001
+			EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__);
1002
+			$new_status = false;
1003
+		}
1004
+		return $new_status;
1005
+	}
1006
+
1007
+
1008
+	/**
1009
+	 * Takes care of deleting multiple EE_Checkin table rows
1010
+	 *
1011
+	 * @return void
1012
+	 * @throws EE_Error
1013
+	 * @throws ReflectionException
1014
+	 */
1015
+	protected function _delete_checkin_rows()
1016
+	{
1017
+		$query_args = [
1018
+			'action'  => 'registration_checkins',
1019
+			'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1020
+			'_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1021
+		];
1022
+		$errors     = 0;
1023
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1024
+			$checkboxes = $this->_req_data['checkbox'];
1025
+			foreach (array_keys($checkboxes) as $CHK_ID) {
1026
+				if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1027
+					$errors++;
1028
+				}
1029
+			}
1030
+		} else {
1031
+			EE_Error::add_error(
1032
+				esc_html__(
1033
+					'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!',
1034
+					'event_espresso'
1035
+				),
1036
+				__FILE__,
1037
+				__FUNCTION__,
1038
+				__LINE__
1039
+			);
1040
+			$this->_redirect_after_action(false, '', '', $query_args, true);
1041
+		}
1042
+		if ($errors > 0) {
1043
+			EE_Error::add_error(
1044
+				sprintf(
1045
+					esc_html__('There were %d records that did not delete successfully', 'event_espresso'),
1046
+					$errors
1047
+				),
1048
+				__FILE__,
1049
+				__FUNCTION__,
1050
+				__LINE__
1051
+			);
1052
+		} else {
1053
+			EE_Error::add_success(esc_html__('Records were successfully deleted', 'event_espresso'));
1054
+		}
1055
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1056
+	}
1057
+
1058
+
1059
+	/**
1060
+	 * Deletes a single EE_Checkin row
1061
+	 *
1062
+	 * @return void
1063
+	 * @throws EE_Error
1064
+	 * @throws ReflectionException
1065
+	 */
1066
+	protected function _delete_checkin_row()
1067
+	{
1068
+		$query_args = [
1069
+			'action'  => 'registration_checkins',
1070
+			'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1071
+			'_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1072
+		];
1073
+		if (! empty($this->_req_data['CHK_ID'])) {
1074
+			if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1075
+				EE_Error::add_error(
1076
+					esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1077
+					__FILE__,
1078
+					__FUNCTION__,
1079
+					__LINE__
1080
+				);
1081
+			} else {
1082
+				EE_Error::add_success(esc_html__('Check-In record successfully deleted', 'event_espresso'));
1083
+			}
1084
+		} else {
1085
+			EE_Error::add_error(
1086
+				esc_html__(
1087
+					'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code',
1088
+					'event_espresso'
1089
+				),
1090
+				__FILE__,
1091
+				__FUNCTION__,
1092
+				__LINE__
1093
+			);
1094
+		}
1095
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1096
+	}
1097
+
1098
+
1099
+	/**
1100
+	 * @return void
1101
+	 * @throws EE_Error
1102
+	 */
1103
+	protected function _event_registrations_list_table()
1104
+	{
1105
+		$EVT_ID                  = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1106
+		$this->_admin_page_title .= $EVT_ID
1107
+			? $this->get_action_link_or_button(
1108
+				'new_registration',
1109
+				'add-registrant',
1110
+				['event_id' => $EVT_ID],
1111
+				'add-new-h2'
1112
+			)
1113
+			: '';
1114
+
1115
+		$this->_template_args['before_list_table'] = $this->generateListTableHeaderText();
1116
+		$this->_template_args['after_list_table']  = $this->generateListTableLegend();
1117
+
1118
+		$this->display_admin_list_table_page_with_no_sidebar();
1119
+	}
1120
+
1121
+
1122
+	/**
1123
+	 * @return string
1124
+	 * @since 5.0.24.p
1125
+	 */
1126
+	private function generateListTableHeaderText(): string
1127
+	{
1128
+		$header_text                  = '';
1129
+		$admin_page_header_decorators = [
1130
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1131
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1132
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1133
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1134
+		];
1135
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1136
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1137
+			$header_text             = $filter_header_decorator->getHeaderText($header_text);
1138
+		}
1139
+		$header_text .= '
1140 1140
             <div class="description ee-status-outline ee-status-bg--info ee-status-outline--fit-content">
1141 1141
                 <strong>' . esc_html__(
1142
-                'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1143
-                'event_espresso'
1144
-            ) . '</strong>
1142
+				'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1143
+				'event_espresso'
1144
+			) . '</strong>
1145 1145
             </div>';
1146
-        return $header_text;
1147
-    }
1148
-
1149
-
1150
-    /**
1151
-     * @return string
1152
-     * @throws EE_Error
1153
-     * @since 5.0.24.p
1154
-     */
1155
-    private function generateListTableLegend(): string
1156
-    {
1157
-        $checked_in      = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
1158
-        $checked_out     = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
1159
-        $checked_never   = new CheckinStatusDashicon(EE_Checkin::status_checked_never);
1160
-        $checkin_invalid = new CheckinStatusDashicon(EE_Checkin::status_invalid);
1161
-
1162
-        $legend_items = [
1163
-            'star-icon'        => [
1164
-                'class' => 'dashicons dashicons-star-filled gold-icon',
1165
-                'desc'  => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'),
1166
-            ],
1167
-            'checkin'          => [
1168
-                'class' => $checked_in->cssClasses(),
1169
-                'desc'  => $checked_in->legendLabel(),
1170
-            ],
1171
-            'checkout'         => [
1172
-                'class' => $checked_out->cssClasses(),
1173
-                'desc'  => $checked_out->legendLabel(),
1174
-            ],
1175
-            'nocheckinrecord'  => [
1176
-                'class' => $checked_never->cssClasses(),
1177
-                'desc'  => $checked_never->legendLabel(),
1178
-            ],
1179
-            'canNotCheckin'    => [
1180
-                'class' => $checkin_invalid->cssClasses(),
1181
-                'desc'  => $checkin_invalid->legendLabel(),
1182
-            ],
1183
-            'approved_status'  => [
1184
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1185
-                'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1186
-            ],
1187
-            'cancelled_status' => [
1188
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1189
-                'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1190
-            ],
1191
-            'declined_status'  => [
1192
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1193
-                'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1194
-            ],
1195
-            'not_approved'     => [
1196
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1197
-                'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1198
-            ],
1199
-            'pending_status'   => [
1200
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1201
-                'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1202
-            ],
1203
-            'wait_list'        => [
1204
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1205
-                'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1206
-            ],
1207
-        ];
1208
-        return $this->_display_legend($legend_items);
1209
-    }
1210
-
1211
-
1212
-    /**
1213
-     * Download the registrations check-in report (same as the normal registration report, but with different where
1214
-     * conditions)
1215
-     *
1216
-     * @return void ends the request by a redirect or download
1217
-     */
1218
-    public function _registrations_checkin_report()
1219
-    {
1220
-        $this->_registrations_report_base('_get_checkin_query_params_from_request');
1221
-    }
1222
-
1223
-
1224
-    /**
1225
-     * Gets the query params from the request, plus adds a where condition for the registration status,
1226
-     * because on the checkin page we only ever want to see approved and pending-approval registrations
1227
-     *
1228
-     * @param array $query_params
1229
-     * @param int   $per_page
1230
-     * @param bool  $count
1231
-     * @return array
1232
-     * @throws EE_Error
1233
-     */
1234
-    protected function _get_checkin_query_params_from_request(
1235
-        array $query_params,
1236
-        int $per_page = 10,
1237
-        bool $count = false
1238
-    ): array {
1239
-        $query_params = $this->_get_registration_query_parameters($query_params, $per_page, $count);
1240
-        // unlike the regular registrations list table,
1241
-        $status_ids_array          = apply_filters(
1242
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1243
-            [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1244
-        );
1245
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
1246
-        return $query_params;
1247
-    }
1248
-
1249
-
1250
-    /**
1251
-     * Gets registrations for an event
1252
-     *
1253
-     * @param int    $per_page
1254
-     * @param bool   $count whether to return count or data.
1255
-     * @param bool   $trash
1256
-     * @param string $orderby
1257
-     * @return EE_Registration[]|int
1258
-     * @throws EE_Error
1259
-     * @throws ReflectionException
1260
-     */
1261
-    public function get_event_attendees(
1262
-        int $per_page = 10,
1263
-        bool $count = false,
1264
-        bool $trash = false,
1265
-        string $orderby = 'ATT_fname'
1266
-    ) {
1267
-        // set some defaults, these will get overridden if included in the actual request parameters
1268
-        $defaults = [
1269
-            'orderby' => $orderby,
1270
-            'order'   => 'ASC',
1271
-        ];
1272
-        if ($trash) {
1273
-            $defaults['status'] = 'trash';
1274
-        }
1275
-        $query_params = $this->_get_checkin_query_params_from_request($defaults, $per_page, $count);
1276
-
1277
-        /**
1278
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1279
-         *
1280
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1281
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1282
-         *                             or if you have the development copy of EE you can view this at the path:
1283
-         *                             /docs/G--Model-System/model-query-params.md
1284
-         */
1285
-        $query_params['group_by'] = '';
1286
-
1287
-        return $count
1288
-            ? EEM_Registration::instance()->count($query_params)
1289
-            /** @type EE_Registration[] */
1290
-            : EEM_Registration::instance()->get_all($query_params);
1291
-    }
1146
+		return $header_text;
1147
+	}
1148
+
1149
+
1150
+	/**
1151
+	 * @return string
1152
+	 * @throws EE_Error
1153
+	 * @since 5.0.24.p
1154
+	 */
1155
+	private function generateListTableLegend(): string
1156
+	{
1157
+		$checked_in      = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
1158
+		$checked_out     = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
1159
+		$checked_never   = new CheckinStatusDashicon(EE_Checkin::status_checked_never);
1160
+		$checkin_invalid = new CheckinStatusDashicon(EE_Checkin::status_invalid);
1161
+
1162
+		$legend_items = [
1163
+			'star-icon'        => [
1164
+				'class' => 'dashicons dashicons-star-filled gold-icon',
1165
+				'desc'  => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'),
1166
+			],
1167
+			'checkin'          => [
1168
+				'class' => $checked_in->cssClasses(),
1169
+				'desc'  => $checked_in->legendLabel(),
1170
+			],
1171
+			'checkout'         => [
1172
+				'class' => $checked_out->cssClasses(),
1173
+				'desc'  => $checked_out->legendLabel(),
1174
+			],
1175
+			'nocheckinrecord'  => [
1176
+				'class' => $checked_never->cssClasses(),
1177
+				'desc'  => $checked_never->legendLabel(),
1178
+			],
1179
+			'canNotCheckin'    => [
1180
+				'class' => $checkin_invalid->cssClasses(),
1181
+				'desc'  => $checkin_invalid->legendLabel(),
1182
+			],
1183
+			'approved_status'  => [
1184
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1185
+				'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1186
+			],
1187
+			'cancelled_status' => [
1188
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1189
+				'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1190
+			],
1191
+			'declined_status'  => [
1192
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1193
+				'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1194
+			],
1195
+			'not_approved'     => [
1196
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1197
+				'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1198
+			],
1199
+			'pending_status'   => [
1200
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1201
+				'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1202
+			],
1203
+			'wait_list'        => [
1204
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1205
+				'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1206
+			],
1207
+		];
1208
+		return $this->_display_legend($legend_items);
1209
+	}
1210
+
1211
+
1212
+	/**
1213
+	 * Download the registrations check-in report (same as the normal registration report, but with different where
1214
+	 * conditions)
1215
+	 *
1216
+	 * @return void ends the request by a redirect or download
1217
+	 */
1218
+	public function _registrations_checkin_report()
1219
+	{
1220
+		$this->_registrations_report_base('_get_checkin_query_params_from_request');
1221
+	}
1222
+
1223
+
1224
+	/**
1225
+	 * Gets the query params from the request, plus adds a where condition for the registration status,
1226
+	 * because on the checkin page we only ever want to see approved and pending-approval registrations
1227
+	 *
1228
+	 * @param array $query_params
1229
+	 * @param int   $per_page
1230
+	 * @param bool  $count
1231
+	 * @return array
1232
+	 * @throws EE_Error
1233
+	 */
1234
+	protected function _get_checkin_query_params_from_request(
1235
+		array $query_params,
1236
+		int $per_page = 10,
1237
+		bool $count = false
1238
+	): array {
1239
+		$query_params = $this->_get_registration_query_parameters($query_params, $per_page, $count);
1240
+		// unlike the regular registrations list table,
1241
+		$status_ids_array          = apply_filters(
1242
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1243
+			[RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1244
+		);
1245
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
1246
+		return $query_params;
1247
+	}
1248
+
1249
+
1250
+	/**
1251
+	 * Gets registrations for an event
1252
+	 *
1253
+	 * @param int    $per_page
1254
+	 * @param bool   $count whether to return count or data.
1255
+	 * @param bool   $trash
1256
+	 * @param string $orderby
1257
+	 * @return EE_Registration[]|int
1258
+	 * @throws EE_Error
1259
+	 * @throws ReflectionException
1260
+	 */
1261
+	public function get_event_attendees(
1262
+		int $per_page = 10,
1263
+		bool $count = false,
1264
+		bool $trash = false,
1265
+		string $orderby = 'ATT_fname'
1266
+	) {
1267
+		// set some defaults, these will get overridden if included in the actual request parameters
1268
+		$defaults = [
1269
+			'orderby' => $orderby,
1270
+			'order'   => 'ASC',
1271
+		];
1272
+		if ($trash) {
1273
+			$defaults['status'] = 'trash';
1274
+		}
1275
+		$query_params = $this->_get_checkin_query_params_from_request($defaults, $per_page, $count);
1276
+
1277
+		/**
1278
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1279
+		 *
1280
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1281
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1282
+		 *                             or if you have the development copy of EE you can view this at the path:
1283
+		 *                             /docs/G--Model-System/model-query-params.md
1284
+		 */
1285
+		$query_params['group_by'] = '';
1286
+
1287
+		return $count
1288
+			? EEM_Registration::instance()->count($query_params)
1289
+			/** @type EE_Registration[] */
1290
+			: EEM_Registration::instance()->get_all($query_params);
1291
+	}
1292 1292
 }
Please login to merge, or discard this patch.
Spacing   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -33,10 +33,10 @@  discard block
 block discarded – undo
33 33
     public function __construct($routing = true)
34 34
     {
35 35
         parent::__construct($routing);
36
-        if (! defined('REG_CAF_TEMPLATE_PATH')) {
37
-            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
38
-            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
39
-            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
36
+        if ( ! defined('REG_CAF_TEMPLATE_PATH')) {
37
+            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/');
38
+            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/');
39
+            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/');
40 40
         }
41 41
     }
42 42
 
@@ -45,12 +45,12 @@  discard block
 block discarded – undo
45 45
     {
46 46
         parent::_set_page_config();
47 47
 
48
-        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
48
+        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND.'registrations';
49 49
         $reg_id                                           =
50 50
             ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
51 51
                 ? $this->_req_data['_REG_ID']
52 52
                 : 0;
53
-        $new_page_routes                                  = [
53
+        $new_page_routes = [
54 54
             'reports'                      => [
55 55
                 'func'       => [$this, '_registration_reports'],
56 56
                 'capability' => 'ee_read_registrations',
@@ -188,14 +188,14 @@  discard block
 block discarded – undo
188 188
         if (EEH_MSG_Template::is_mt_active('newsletter')) {
189 189
             wp_enqueue_style(
190 190
                 'ee_message_shortcodes',
191
-                EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
191
+                EE_MSG_ASSETS_URL.'ee_message_shortcodes.css',
192 192
                 [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
193 193
                 EVENT_ESPRESSO_VERSION
194 194
             );
195 195
             // enqueue newsletter js
196 196
             wp_enqueue_script(
197 197
                 'ee-newsletter-trigger',
198
-                REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
198
+                REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js',
199 199
                 ['ee-dialog'],
200 200
                 EVENT_ESPRESSO_VERSION,
201 201
                 true
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
     {
220 220
         wp_register_script(
221 221
             'ee-reg-reports-js',
222
-            REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
222
+            REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js',
223 223
             ['google-charts'],
224 224
             EVENT_ESPRESSO_VERSION,
225 225
             true
@@ -296,7 +296,7 @@  discard block
 block discarded – undo
296 296
      */
297 297
     public function get_newsletter_form_content()
298 298
     {
299
-        if (! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
299
+        if ( ! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
300 300
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
301 301
         }
302 302
         // do a nonce check because we're not coming in from a normal route here.
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
         $nonce_ref = 'get_newsletter_form_content_nonce';
307 307
         $this->_verify_nonce($nonce, $nonce_ref);
308 308
         // let's get the mtp for the incoming MTP_ ID
309
-        if (! isset($this->_req_data['GRP_ID'])) {
309
+        if ( ! isset($this->_req_data['GRP_ID'])) {
310 310
             EE_Error::add_error(
311 311
                 esc_html__(
312 312
                     'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
             $this->_return_json();
322 322
         }
323 323
         $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
324
-        if (! $MTPG instanceof EE_Message_Template_Group) {
324
+        if ( ! $MTPG instanceof EE_Message_Template_Group) {
325 325
             EE_Error::add_error(
326 326
                 sprintf(
327 327
                     esc_html__(
@@ -346,12 +346,12 @@  discard block
 block discarded – undo
346 346
             $field = $MTP->get('MTP_template_field');
347 347
             if ($field === 'content') {
348 348
                 $content = $MTP->get('MTP_content');
349
-                if (! empty($content['newsletter_content'])) {
349
+                if ( ! empty($content['newsletter_content'])) {
350 350
                     $template_fields['newsletter_content'] = $content['newsletter_content'];
351 351
                 }
352 352
                 continue;
353 353
             }
354
-            $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
354
+            $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content');
355 355
         }
356 356
         $this->_template_args['success'] = true;
357 357
         $this->_template_args['error']   = false;
@@ -445,15 +445,15 @@  discard block
 block discarded – undo
445 445
                 $field_id               = "batch-message-$field_id";
446 446
                 $available_shortcodes[] = '
447 447
                 <span class="js-shortcode-selection"
448
-                      data-value="' . $shortcode . '"
449
-                      data-linked-input-id="' . $field_id . '"
450
-                >' . $shortcode . '</span>';
448
+                      data-value="' . $shortcode.'"
449
+                      data-linked-input-id="' . $field_id.'"
450
+                >' . $shortcode.'</span>';
451 451
             }
452
-            $codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
452
+            $codes[$field] = '<ul><li>'.implode('</li><li>', $available_shortcodes).'</li></ul>';
453 453
         }
454 454
 
455 455
         EEH_Template::display_template(
456
-            REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
456
+            REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php',
457 457
             [
458 458
                 'form_action'       => admin_url('admin.php?page=espresso_registrations'),
459 459
                 'form_route'        => 'newsletter_selected_send',
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
      */
623 623
     protected function _registration_reports()
624 624
     {
625
-        $template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
625
+        $template_path                              = EE_ADMIN_TEMPLATE.'admin_reports.template.php';
626 626
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
627 627
             $template_path,
628 628
             $this->_reports_template_data,
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
             array_unshift($regs, $column_titles);
678 678
             // setup the date range.
679 679
             $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
680
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
680
+            $beginning_date = new DateTime("now ".$period, $DateTimeZone);
681 681
             $ending_date    = new DateTime("now", $DateTimeZone);
682 682
             $subtitle       = sprintf(
683 683
                 wp_strip_all_tags(
@@ -701,7 +701,7 @@  discard block
 block discarded – undo
701 701
                         'event_espresso'
702 702
                     )
703 703
                 ),
704
-                '<h2>' . $report_title . '</h2><p>',
704
+                '<h2>'.$report_title.'</h2><p>',
705 705
                 '</p>'
706 706
             ),
707 707
         ];
@@ -733,7 +733,7 @@  discard block
 block discarded – undo
733 733
             foreach ($results as $result) {
734 734
                 $report_column_values = [];
735 735
                 foreach ($result as $property_name => $property_value) {
736
-                    $property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
736
+                    $property_value = $property_name === 'Registration_Event' ? wp_trim_words(
737 737
                         $property_value,
738 738
                         4,
739 739
                         '...'
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
             array_unshift($regs, $column_titles);
755 755
             // setup the date range.
756 756
             $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
757
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
757
+            $beginning_date = new DateTime("now ".$period, $DateTimeZone);
758 758
             $ending_date    = new DateTime("now", $DateTimeZone);
759 759
             $subtitle       = sprintf(
760 760
                 wp_strip_all_tags(
@@ -778,7 +778,7 @@  discard block
 block discarded – undo
778 778
                         'event_espresso'
779 779
                     )
780 780
                 ),
781
-                '<h2>' . $report_title . '</h2><p>',
781
+                '<h2>'.$report_title.'</h2><p>',
782 782
                 '</p>'
783 783
             ),
784 784
         ];
@@ -800,7 +800,7 @@  discard block
 block discarded – undo
800 800
         $REG_ID = $this->request->getRequestParam('_REG_ID', 0, DataType::INTEGER);
801 801
         /** @var EE_Registration $registration */
802 802
         $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
803
-        if (! $registration instanceof EE_Registration) {
803
+        if ( ! $registration instanceof EE_Registration) {
804 804
             throw new EE_Error(
805 805
                 sprintf(
806 806
                     esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
@@ -808,8 +808,8 @@  discard block
 block discarded – undo
808 808
                 )
809 809
             );
810 810
         }
811
-        $attendee                                 = $registration->attendee();
812
-        $this->_admin_page_title                  .= $this->get_action_link_or_button(
811
+        $attendee = $registration->attendee();
812
+        $this->_admin_page_title .= $this->get_action_link_or_button(
813 813
             'new_registration',
814 814
             'add-registrant',
815 815
             ['event_id' => $registration->event_ID()],
@@ -835,10 +835,10 @@  discard block
 block discarded – undo
835 835
         if ($datetime instanceof EE_Datetime) {
836 836
             $datetime_label = $datetime->get_dtt_display_name(true);
837 837
             $datetime_label .= ! empty($datetime_label)
838
-                ? ' (' . $datetime->get_dtt_display_name() . ')'
838
+                ? ' ('.$datetime->get_dtt_display_name().')'
839 839
                 : $datetime->get_dtt_display_name();
840 840
         }
841
-        $datetime_link                                    = ! $DTT_ID
841
+        $datetime_link = ! $DTT_ID
842 842
             ? EE_Admin_Page::add_query_args_and_nonce(
843 843
                 [
844 844
                     'action'   => 'event_registrations',
@@ -848,8 +848,8 @@  discard block
 block discarded – undo
848 848
                 $this->_admin_base_url
849 849
             )
850 850
             : '';
851
-        $datetime_link                                    = ! empty($datetime_link)
852
-            ? '<a href="' . $datetime_link . '">'
851
+        $datetime_link = ! empty($datetime_link)
852
+            ? '<a href="'.$datetime_link.'">'
853 853
             . '<span id="checkin-dtt">'
854 854
             . $datetime_label
855 855
             . '</span></a>'
@@ -861,8 +861,8 @@  discard block
 block discarded – undo
861 861
             ? $attendee->get_admin_details_link()
862 862
             : '';
863 863
         $attendee_link                                    = ! empty($attendee_link)
864
-            ? '<a href="' . $attendee->get_admin_details_link() . '"'
865
-            . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
864
+            ? '<a href="'.$attendee->get_admin_details_link().'"'
865
+            . ' aria-label="'.esc_html__('Click for attendee details', 'event_espresso').'">'
866 866
             . '<span id="checkin-attendee-name">'
867 867
             . $attendee_name
868 868
             . '</span></a>'
@@ -871,26 +871,26 @@  discard block
 block discarded – undo
871 871
             ? $registration->event()->get_admin_details_link()
872 872
             : '';
873 873
         $event_link                                       = ! empty($event_link)
874
-            ? '<a href="' . $event_link . '"'
875
-            . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
874
+            ? '<a href="'.$event_link.'"'
875
+            . ' aria-label="'.esc_html__('Click here to edit event.', 'event_espresso').'">'
876 876
             . '<span id="checkin-event-name">'
877 877
             . $registration->event_name()
878 878
             . '</span>'
879 879
             . '</a>'
880 880
             : '';
881
-        $this->_template_args['before_list_table']        = $REG_ID && $DTT_ID
882
-            ? '<h2>' . sprintf(
881
+        $this->_template_args['before_list_table'] = $REG_ID && $DTT_ID
882
+            ? '<h2>'.sprintf(
883 883
                 esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
884 884
                 $attendee_link,
885 885
                 $datetime_link,
886 886
                 $event_link
887
-            ) . '</h2>'
887
+            ).'</h2>'
888 888
             : '';
889 889
         $this->_template_args['list_table_hidden_fields'] = $REG_ID
890
-            ? '<input type="hidden" name="_REG_ID" value="' . $REG_ID . '">'
890
+            ? '<input type="hidden" name="_REG_ID" value="'.$REG_ID.'">'
891 891
             : '';
892 892
         $this->_template_args['list_table_hidden_fields'] .= $DTT_ID
893
-            ? '<input type="hidden" name="DTT_ID" value="' . $DTT_ID . '">'
893
+            ? '<input type="hidden" name="DTT_ID" value="'.$DTT_ID.'">'
894 894
             : '';
895 895
         $this->display_admin_list_table_page_with_no_sidebar();
896 896
     }
@@ -905,11 +905,11 @@  discard block
 block discarded – undo
905 905
      */
906 906
     public function toggle_checkin_status()
907 907
     {
908
-        if (! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
908
+        if ( ! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
909 909
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
910 910
         }
911 911
         // first make sure we have the necessary data
912
-        if (! isset($this->_req_data['_regid'])) {
912
+        if ( ! isset($this->_req_data['_regid'])) {
913 913
             EE_Error::add_error(
914 914
                 esc_html__(
915 915
                     'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
@@ -931,7 +931,7 @@  discard block
 block discarded – undo
931 931
         // beautiful! Made it this far so let's get the status.
932 932
         $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
933 933
         // setup new class to return via ajax
934
-        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
934
+        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses();
935 935
         $this->_template_args['success']            = true;
936 936
         $this->_return_json();
937 937
     }
@@ -954,7 +954,7 @@  discard block
 block discarded – undo
954 954
         ];
955 955
         $new_status = false;
956 956
         // bulk action check in toggle
957
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
957
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
958 958
             // cycle thru checkboxes
959 959
             $checkboxes = $this->_req_data['checkbox'];
960 960
             foreach (array_keys($checkboxes) as $REG_ID) {
@@ -1019,11 +1019,11 @@  discard block
 block discarded – undo
1019 1019
             'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1020 1020
             '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1021 1021
         ];
1022
-        $errors     = 0;
1023
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1022
+        $errors = 0;
1023
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1024 1024
             $checkboxes = $this->_req_data['checkbox'];
1025 1025
             foreach (array_keys($checkboxes) as $CHK_ID) {
1026
-                if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1026
+                if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1027 1027
                     $errors++;
1028 1028
                 }
1029 1029
             }
@@ -1070,8 +1070,8 @@  discard block
 block discarded – undo
1070 1070
             'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1071 1071
             '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1072 1072
         ];
1073
-        if (! empty($this->_req_data['CHK_ID'])) {
1074
-            if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1073
+        if ( ! empty($this->_req_data['CHK_ID'])) {
1074
+            if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1075 1075
                 EE_Error::add_error(
1076 1076
                     esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1077 1077
                     __FILE__,
@@ -1102,7 +1102,7 @@  discard block
 block discarded – undo
1102 1102
      */
1103 1103
     protected function _event_registrations_list_table()
1104 1104
     {
1105
-        $EVT_ID                  = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1105
+        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1106 1106
         $this->_admin_page_title .= $EVT_ID
1107 1107
             ? $this->get_action_link_or_button(
1108 1108
                 'new_registration',
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
                 <strong>' . esc_html__(
1142 1142
                 'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1143 1143
                 'event_espresso'
1144
-            ) . '</strong>
1144
+            ).'</strong>
1145 1145
             </div>';
1146 1146
         return $header_text;
1147 1147
     }
@@ -1181,27 +1181,27 @@  discard block
 block discarded – undo
1181 1181
                 'desc'  => $checkin_invalid->legendLabel(),
1182 1182
             ],
1183 1183
             'approved_status'  => [
1184
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1184
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::APPROVED,
1185 1185
                 'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1186 1186
             ],
1187 1187
             'cancelled_status' => [
1188
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1188
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::CANCELLED,
1189 1189
                 'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1190 1190
             ],
1191 1191
             'declined_status'  => [
1192
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1192
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::DECLINED,
1193 1193
                 'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1194 1194
             ],
1195 1195
             'not_approved'     => [
1196
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1196
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::AWAITING_REVIEW,
1197 1197
                 'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1198 1198
             ],
1199 1199
             'pending_status'   => [
1200
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1200
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::PENDING_PAYMENT,
1201 1201
                 'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1202 1202
             ],
1203 1203
             'wait_list'        => [
1204
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1204
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::WAIT_LIST,
1205 1205
                 'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1206 1206
             ],
1207 1207
         ];
@@ -1238,7 +1238,7 @@  discard block
 block discarded – undo
1238 1238
     ): array {
1239 1239
         $query_params = $this->_get_registration_query_parameters($query_params, $per_page, $count);
1240 1240
         // unlike the regular registrations list table,
1241
-        $status_ids_array          = apply_filters(
1241
+        $status_ids_array = apply_filters(
1242 1242
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1243 1243
             [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1244 1244
         );
Please login to merge, or discard this patch.
caffeinated/admin/extend/registrations/RegistrationsListTableFilters.php 2 patches
Indentation   +203 added lines, -203 removed lines patch added patch discarded remove patch
@@ -23,242 +23,242 @@
 block discarded – undo
23 23
  */
24 24
 class RegistrationsListTableFilters
25 25
 {
26
-    protected RequestInterface $request;
26
+	protected RequestInterface $request;
27 27
 
28
-    /**
29
-     * This property will hold the related Datetimes on an event IF the event ID is included in the request.
30
-     */
31
-    protected DatetimesForEventCheckIn $datetimes_for_event;
28
+	/**
29
+	 * This property will hold the related Datetimes on an event IF the event ID is included in the request.
30
+	 */
31
+	protected DatetimesForEventCheckIn $datetimes_for_event;
32 32
 
33
-    protected ?EE_Datetime $datetime = null;
33
+	protected ?EE_Datetime $datetime = null;
34 34
 
35
-    protected ?EE_Event $event = null;
35
+	protected ?EE_Event $event = null;
36 36
 
37
-    /**
38
-     * The DTT_ID if the current view has a specified datetime.
39
-     */
40
-    protected int $DTT_ID = 0;
37
+	/**
38
+	 * The DTT_ID if the current view has a specified datetime.
39
+	 */
40
+	protected int $DTT_ID = 0;
41 41
 
42
-    /**
43
-     * The event ID if one is specified in the request
44
-     */
45
-    protected int $EVT_ID = 0;
42
+	/**
43
+	 * The event ID if one is specified in the request
44
+	 */
45
+	protected int $EVT_ID = 0;
46 46
 
47
-    protected bool $hide_expired = false;
47
+	protected bool $hide_expired = false;
48 48
 
49
-    protected bool $hide_upcoming = false;
50
-
51
-    protected string $label = '';
52
-
53
-
54
-    /**
55
-     * @param RequestInterface $request
56
-     */
57
-    public function __construct(RequestInterface $request)
58
-    {
59
-        $this->request = $request;
60
-    }
61
-
62
-
63
-    /**
64
-     * @throws EE_Error
65
-     * @throws ReflectionException
66
-     * @since 5.0.0.p
67
-     */
68
-    public function resolveRequestVars()
69
-    {
70
-        $this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
71
-        $this->EVT_ID = $this->request->getRequestParam('event_id', $this->EVT_ID, DataType::INTEGER);
72
-        $this->event  = EEM_Event::instance()->get_one_by_ID($this->EVT_ID);
73
-        $this->datetimes_for_event = new DatetimesForEventCheckIn(EE_Capabilities::instance(), $this->event);
74
-        // if we're filtering for a specific event and it only has one datetime, then grab its ID
75
-        $this->datetime = $this->datetimes_for_event->getOneDatetimeForEvent();
76
-        $this->DTT_ID = $this->datetime instanceof EE_Datetime ? $this->datetime->ID() : 0;
77
-        // else check the request, but use the above as the default (and hope they match if BOTH exist, LOLZ)
78
-        $this->DTT_ID        = $this->request->getRequestParam('DTT_ID', $this->DTT_ID, DataType::INTEGER);
79
-        $this->DTT_ID        = $this->request->getRequestParam('datetime_id', $this->DTT_ID, DataType::INTEGER);
80
-        $this->hide_expired  = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
81
-        $this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
82
-    }
83
-
84
-
85
-    public function datetime(): ?EE_Datetime
86
-    {
87
-        return $this->datetime;
88
-    }
89
-
90
-
91
-    public function datetimeID(): int
92
-    {
93
-        return $this->DTT_ID;
94
-    }
95
-
96
-
97
-    public function event(): ?EE_Event
98
-    {
99
-        return $this->event;
100
-    }
101
-
102
-
103
-    public function eventID(): int
104
-    {
105
-        return $this->EVT_ID;
106
-    }
107
-
108
-
109
-    /**
110
-     * @throws EE_Error
111
-     * @throws ReflectionException
112
-     */
113
-    public function addFiltersAfter(array $filters): array
114
-    {
115
-        return array_merge($filters, $this->getFilters());
116
-    }
117
-
118
-
119
-    /**
120
-     * @throws EE_Error
121
-     * @throws ReflectionException
122
-     */
123
-    public function addFiltersBefore(array $filters): array
124
-    {
125
-        return array_merge($this->getFilters(), $filters);
126
-    }
127
-
128
-
129
-    public function setLabel(string $label): void
130
-    {
131
-        $this->label = $label;
132
-    }
133
-
134
-
135
-    private function getLabel(): string
136
-    {
137
-        return $this->label
138
-            ? '<label class="ee-event-filter-main-label">' . esc_html($this->label) . '</label>'
139
-            : '';
140
-    }
141
-
142
-
143
-    /**
144
-     * @throws EE_Error
145
-     * @throws ReflectionException
146
-     */
147
-    public function getFilters(): array
148
-    {
149
-        $filters               = [];
150
-        $hide_expired_checked  = $this->hide_expired ? 'checked' : '';
151
-        $hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
152
-        // get datetimes for ALL active events (note possible capability restrictions)
153
-        $events          = $this->datetimes_for_event->getAllEvents();
154
-        $event_options[] = [
155
-            'id'   => 0,
156
-            'text' => esc_html__('Select an Event', 'event_espresso'),
157
-        ];
158
-        foreach ($events as $event) {
159
-            // any registrations for this event?
160
-            if (! $event instanceof EE_Event) {
161
-                continue;
162
-            }
163
-            $expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
164
-            $upcoming_class = $event->is_upcoming() ? ' ee-upcoming-event' : '';
165
-
166
-            $event_options[] = [
167
-                'id'    => $event->ID(),
168
-                'text'  => apply_filters(
169
-                    'FHEE__EE_Event_Registrations___get_table_filters__event_name',
170
-                    $event->name(),
171
-                    $event
172
-                ),
173
-                'class' => $expired_class . $upcoming_class,
174
-            ];
175
-            if ($event->ID() === $this->EVT_ID) {
176
-                $this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
177
-                $hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
178
-                $this->hide_upcoming   = $upcoming_class === '' ? $this->hide_upcoming : false;
179
-                $hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
180
-            }
181
-        }
182
-
183
-        $select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
184
-        $select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
185
-        $select_input = EEH_Form_Fields::select_input(
186
-            'EVT_ID',
187
-            $event_options,
188
-            $this->EVT_ID,
189
-            '',
190
-            $select_class
191
-        );
192
-
193
-        $filters[] = $this->getLabel() . '
49
+	protected bool $hide_upcoming = false;
50
+
51
+	protected string $label = '';
52
+
53
+
54
+	/**
55
+	 * @param RequestInterface $request
56
+	 */
57
+	public function __construct(RequestInterface $request)
58
+	{
59
+		$this->request = $request;
60
+	}
61
+
62
+
63
+	/**
64
+	 * @throws EE_Error
65
+	 * @throws ReflectionException
66
+	 * @since 5.0.0.p
67
+	 */
68
+	public function resolveRequestVars()
69
+	{
70
+		$this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
71
+		$this->EVT_ID = $this->request->getRequestParam('event_id', $this->EVT_ID, DataType::INTEGER);
72
+		$this->event  = EEM_Event::instance()->get_one_by_ID($this->EVT_ID);
73
+		$this->datetimes_for_event = new DatetimesForEventCheckIn(EE_Capabilities::instance(), $this->event);
74
+		// if we're filtering for a specific event and it only has one datetime, then grab its ID
75
+		$this->datetime = $this->datetimes_for_event->getOneDatetimeForEvent();
76
+		$this->DTT_ID = $this->datetime instanceof EE_Datetime ? $this->datetime->ID() : 0;
77
+		// else check the request, but use the above as the default (and hope they match if BOTH exist, LOLZ)
78
+		$this->DTT_ID        = $this->request->getRequestParam('DTT_ID', $this->DTT_ID, DataType::INTEGER);
79
+		$this->DTT_ID        = $this->request->getRequestParam('datetime_id', $this->DTT_ID, DataType::INTEGER);
80
+		$this->hide_expired  = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
81
+		$this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
82
+	}
83
+
84
+
85
+	public function datetime(): ?EE_Datetime
86
+	{
87
+		return $this->datetime;
88
+	}
89
+
90
+
91
+	public function datetimeID(): int
92
+	{
93
+		return $this->DTT_ID;
94
+	}
95
+
96
+
97
+	public function event(): ?EE_Event
98
+	{
99
+		return $this->event;
100
+	}
101
+
102
+
103
+	public function eventID(): int
104
+	{
105
+		return $this->EVT_ID;
106
+	}
107
+
108
+
109
+	/**
110
+	 * @throws EE_Error
111
+	 * @throws ReflectionException
112
+	 */
113
+	public function addFiltersAfter(array $filters): array
114
+	{
115
+		return array_merge($filters, $this->getFilters());
116
+	}
117
+
118
+
119
+	/**
120
+	 * @throws EE_Error
121
+	 * @throws ReflectionException
122
+	 */
123
+	public function addFiltersBefore(array $filters): array
124
+	{
125
+		return array_merge($this->getFilters(), $filters);
126
+	}
127
+
128
+
129
+	public function setLabel(string $label): void
130
+	{
131
+		$this->label = $label;
132
+	}
133
+
134
+
135
+	private function getLabel(): string
136
+	{
137
+		return $this->label
138
+			? '<label class="ee-event-filter-main-label">' . esc_html($this->label) . '</label>'
139
+			: '';
140
+	}
141
+
142
+
143
+	/**
144
+	 * @throws EE_Error
145
+	 * @throws ReflectionException
146
+	 */
147
+	public function getFilters(): array
148
+	{
149
+		$filters               = [];
150
+		$hide_expired_checked  = $this->hide_expired ? 'checked' : '';
151
+		$hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
152
+		// get datetimes for ALL active events (note possible capability restrictions)
153
+		$events          = $this->datetimes_for_event->getAllEvents();
154
+		$event_options[] = [
155
+			'id'   => 0,
156
+			'text' => esc_html__('Select an Event', 'event_espresso'),
157
+		];
158
+		foreach ($events as $event) {
159
+			// any registrations for this event?
160
+			if (! $event instanceof EE_Event) {
161
+				continue;
162
+			}
163
+			$expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
164
+			$upcoming_class = $event->is_upcoming() ? ' ee-upcoming-event' : '';
165
+
166
+			$event_options[] = [
167
+				'id'    => $event->ID(),
168
+				'text'  => apply_filters(
169
+					'FHEE__EE_Event_Registrations___get_table_filters__event_name',
170
+					$event->name(),
171
+					$event
172
+				),
173
+				'class' => $expired_class . $upcoming_class,
174
+			];
175
+			if ($event->ID() === $this->EVT_ID) {
176
+				$this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
177
+				$hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
178
+				$this->hide_upcoming   = $upcoming_class === '' ? $this->hide_upcoming : false;
179
+				$hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
180
+			}
181
+		}
182
+
183
+		$select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
184
+		$select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
185
+		$select_input = EEH_Form_Fields::select_input(
186
+			'EVT_ID',
187
+			$event_options,
188
+			$this->EVT_ID,
189
+			'',
190
+			$select_class
191
+		);
192
+
193
+		$filters[] = $this->getLabel() . '
194 194
         <div class="ee-event-filter">
195 195
             <span class="ee-event-selector">
196 196
                 <label for="event_selector">' . esc_html__('Event', 'event_espresso') . '</label>
197 197
                 ' . $select_input . '
198 198
             </span>';
199
-        // DTT datetimes filter
200
-        $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
201
-            $hide_upcoming_checked === 'checked'
202
-        );
203
-        if (count($datetimes_for_event) > 1) {
204
-            $datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
205
-            foreach ($datetimes_for_event as $datetime) {
206
-                if ($datetime instanceof EE_Datetime) {
207
-                    $datetime_string = $datetime->name();
208
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
209
-                    $datetime_string .= $datetime->date_and_time_range();
210
-                    $datetime_string .= $datetime->is_active() ? ' ∗' : '';
211
-                    $datetime_string .= $datetime->is_expired() ? ' «' : '';
212
-                    $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
213
-                    // now put it all together
214
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
215
-                }
216
-            }
217
-            $filters[] = '
199
+		// DTT datetimes filter
200
+		$datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
201
+			$hide_upcoming_checked === 'checked'
202
+		);
203
+		if (count($datetimes_for_event) > 1) {
204
+			$datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
205
+			foreach ($datetimes_for_event as $datetime) {
206
+				if ($datetime instanceof EE_Datetime) {
207
+					$datetime_string = $datetime->name();
208
+					$datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
209
+					$datetime_string .= $datetime->date_and_time_range();
210
+					$datetime_string .= $datetime->is_active() ? ' ∗' : '';
211
+					$datetime_string .= $datetime->is_expired() ? ' «' : '';
212
+					$datetime_string .= $datetime->is_upcoming() ? ' »' : '';
213
+					// now put it all together
214
+					$datetimes[ $datetime->ID() ] = $datetime_string;
215
+				}
216
+			}
217
+			$filters[] = '
218 218
             <span class="ee-datetime-selector">
219 219
                 <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
220 220
                 ' . EEH_Form_Fields::select_input(
221
-                'DTT_ID',
222
-                $datetimes,
223
-                $this->DTT_ID
224
-            ) . '
221
+				'DTT_ID',
222
+				$datetimes,
223
+				$this->DTT_ID
224
+			) . '
225 225
             </span>';
226
-        }
227
-        $filters[] = '
226
+		}
227
+		$filters[] = '
228 228
             <span class="ee-hide-upcoming-check">
229 229
                 <label for="js-ee-hide-upcoming-events">
230 230
                     <input type="checkbox" id="js-ee-hide-upcoming-events" name="hide_upcoming" '
231
-            . $hide_upcoming_checked
232
-            . '>
231
+			. $hide_upcoming_checked
232
+			. '>
233 233
                             '
234
-            . esc_html__('Hide Upcoming Events', 'event_espresso')
235
-            . '
234
+			. esc_html__('Hide Upcoming Events', 'event_espresso')
235
+			. '
236 236
                 </label>
237 237
                 <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
238 238
                       aria-label="'
239
-            . esc_html__(
240
-                'Will not display events in the preceding event selector with start dates in the future (ie: have not yet begun)',
241
-                'event_espresso'
242
-            ) . '"
239
+			. esc_html__(
240
+				'Will not display events in the preceding event selector with start dates in the future (ie: have not yet begun)',
241
+				'event_espresso'
242
+			) . '"
243 243
                 ></span>
244 244
             </span>
245 245
             <span class="ee-hide-expired-check">
246 246
                 <label for="js-ee-hide-expired-events">
247 247
                     <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
248
-            . $hide_expired_checked
249
-            . '>
248
+			. $hide_expired_checked
249
+			. '>
250 250
                         ' . esc_html__('Hide Expired Events', 'event_espresso') . '
251 251
                 </label>
252 252
                 <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
253 253
                       aria-label="'
254
-            . esc_html__(
255
-                'Will not display events in the preceding event selector with end dates in the past (ie: have already finished)',
256
-                'event_espresso'
257
-            )
258
-            . '"
254
+			. esc_html__(
255
+				'Will not display events in the preceding event selector with end dates in the past (ie: have already finished)',
256
+				'event_espresso'
257
+			)
258
+			. '"
259 259
                 ></span>
260 260
             </span>
261 261
         </div>';
262
-        return $filters;
263
-    }
262
+		return $filters;
263
+	}
264 264
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
     private function getLabel(): string
136 136
     {
137 137
         return $this->label
138
-            ? '<label class="ee-event-filter-main-label">' . esc_html($this->label) . '</label>'
138
+            ? '<label class="ee-event-filter-main-label">'.esc_html($this->label).'</label>'
139 139
             : '';
140 140
     }
141 141
 
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
         ];
158 158
         foreach ($events as $event) {
159 159
             // any registrations for this event?
160
-            if (! $event instanceof EE_Event) {
160
+            if ( ! $event instanceof EE_Event) {
161 161
                 continue;
162 162
             }
163 163
             $expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
                     $event->name(),
171 171
                     $event
172 172
                 ),
173
-                'class' => $expired_class . $upcoming_class,
173
+                'class' => $expired_class.$upcoming_class,
174 174
             ];
175 175
             if ($event->ID() === $this->EVT_ID) {
176 176
                 $this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
@@ -190,11 +190,11 @@  discard block
 block discarded – undo
190 190
             $select_class
191 191
         );
192 192
 
193
-        $filters[] = $this->getLabel() . '
193
+        $filters[] = $this->getLabel().'
194 194
         <div class="ee-event-filter">
195 195
             <span class="ee-event-selector">
196
-                <label for="event_selector">' . esc_html__('Event', 'event_espresso') . '</label>
197
-                ' . $select_input . '
196
+                <label for="event_selector">' . esc_html__('Event', 'event_espresso').'</label>
197
+                ' . $select_input.'
198 198
             </span>';
199 199
         // DTT datetimes filter
200 200
         $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
@@ -205,23 +205,23 @@  discard block
 block discarded – undo
205 205
             foreach ($datetimes_for_event as $datetime) {
206 206
                 if ($datetime instanceof EE_Datetime) {
207 207
                     $datetime_string = $datetime->name();
208
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
208
+                    $datetime_string = ! empty($datetime_string) ? $datetime_string.': ' : '';
209 209
                     $datetime_string .= $datetime->date_and_time_range();
210 210
                     $datetime_string .= $datetime->is_active() ? ' ∗' : '';
211 211
                     $datetime_string .= $datetime->is_expired() ? ' «' : '';
212 212
                     $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
213 213
                     // now put it all together
214
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
214
+                    $datetimes[$datetime->ID()] = $datetime_string;
215 215
                 }
216 216
             }
217 217
             $filters[] = '
218 218
             <span class="ee-datetime-selector">
219
-                <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
219
+                <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso').'</label>
220 220
                 ' . EEH_Form_Fields::select_input(
221 221
                 'DTT_ID',
222 222
                 $datetimes,
223 223
                 $this->DTT_ID
224
-            ) . '
224
+            ).'
225 225
             </span>';
226 226
         }
227 227
         $filters[] = '
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
             . esc_html__(
240 240
                 'Will not display events in the preceding event selector with start dates in the future (ie: have not yet begun)',
241 241
                 'event_espresso'
242
-            ) . '"
242
+            ).'"
243 243
                 ></span>
244 244
             </span>
245 245
             <span class="ee-hide-expired-check">
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
                     <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
248 248
             . $hide_expired_checked
249 249
             . '>
250
-                        ' . esc_html__('Hide Expired Events', 'event_espresso') . '
250
+                        ' . esc_html__('Hide Expired Events', 'event_espresso').'
251 251
                 </label>
252 252
                 <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
253 253
                       aria-label="'
Please login to merge, or discard this patch.
admin/extend/registrations/Extend_EE_Registrations_List_Table.class.php 1 patch
Indentation   +149 added lines, -149 removed lines patch added patch discarded remove patch
@@ -13,175 +13,175 @@
 block discarded – undo
13 13
  */
14 14
 class Extend_EE_Registrations_List_Table extends EE_Registrations_List_Table
15 15
 {
16
-    private RegistrationsListTableFilters $filters;
16
+	private RegistrationsListTableFilters $filters;
17 17
 
18 18
 
19
-    /**
20
-     * @param Registrations_Admin_Page $admin_page
21
-     * @throws EE_Error
22
-     * @throws ReflectionException
23
-     */
24
-    public function __construct(Registrations_Admin_Page $admin_page)
25
-    {
26
-        parent::__construct($admin_page);
27
-        $this->filters = new RegistrationsListTableFilters($this->request);
28
-        $this->filters->resolveRequestVars();
29
-        add_filter(
30
-            'FHEE__Extend_EE_Registrations_List_Table__filters',
31
-            [$this->filters, 'addFiltersBefore'],
32
-        );
33
-    }
19
+	/**
20
+	 * @param Registrations_Admin_Page $admin_page
21
+	 * @throws EE_Error
22
+	 * @throws ReflectionException
23
+	 */
24
+	public function __construct(Registrations_Admin_Page $admin_page)
25
+	{
26
+		parent::__construct($admin_page);
27
+		$this->filters = new RegistrationsListTableFilters($this->request);
28
+		$this->filters->resolveRequestVars();
29
+		add_filter(
30
+			'FHEE__Extend_EE_Registrations_List_Table__filters',
31
+			[$this->filters, 'addFiltersBefore'],
32
+		);
33
+	}
34 34
 
35 35
 
36
-    /**
37
-     * @param EE_Registration $registration
38
-     * @return string
39
-     * @throws EE_Error
40
-     * @throws InvalidArgumentException
41
-     * @throws InvalidDataTypeException
42
-     * @throws InvalidInterfaceException
43
-     * @throws ReflectionException
44
-     */
45
-    public function column_event_name(EE_Registration $registration): string
46
-    {
47
-        $this->_set_related_details($registration);
48
-        $edit_event                = $this->editEventLink($registration);
49
-        $actions['event_filter']   = $this->eventFilterLink($registration);
50
-        $actions['event_checkins'] = $this->viewCheckinsLink($registration);
51
-        return $this->columnContent(
52
-            'event_name',
53
-             $edit_event . $this->row_actions($actions)
54
-        );
55
-    }
36
+	/**
37
+	 * @param EE_Registration $registration
38
+	 * @return string
39
+	 * @throws EE_Error
40
+	 * @throws InvalidArgumentException
41
+	 * @throws InvalidDataTypeException
42
+	 * @throws InvalidInterfaceException
43
+	 * @throws ReflectionException
44
+	 */
45
+	public function column_event_name(EE_Registration $registration): string
46
+	{
47
+		$this->_set_related_details($registration);
48
+		$edit_event                = $this->editEventLink($registration);
49
+		$actions['event_filter']   = $this->eventFilterLink($registration);
50
+		$actions['event_checkins'] = $this->viewCheckinsLink($registration);
51
+		return $this->columnContent(
52
+			'event_name',
53
+			 $edit_event . $this->row_actions($actions)
54
+		);
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * @param EE_Registration $registration
60
-     * @return string
61
-     * @throws EE_Error
62
-     * @throws InvalidArgumentException
63
-     * @throws InvalidDataTypeException
64
-     * @throws InvalidInterfaceException
65
-     * @throws ReflectionException
66
-     */
67
-    public function column_DTT_EVT_start(EE_Registration $registration): string
68
-    {
69
-        $ticket                = $registration->ticket();
70
-        $datetimes             = $ticket instanceof EE_Ticket
71
-            ? $ticket->datetimes(['default_where_conditions' => 'none'])
72
-            : [];
73
-        $datetimes_for_display = [];
74
-        foreach ($datetimes as $datetime) {
75
-            $datetime_string         = '<div class="ee-reg-list-dates-list-date">';
76
-            $datetime_string         .= $datetime->get_i18n_datetime('DTT_EVT_start', 'M jS Y g:i a');
77
-            $datetime_string         .= $this->row_actions(
78
-                [
79
-                    'datetime_filter'   => $this->datetimeFilterLink($registration, $datetime),
80
-                    'datetime_checkins' => $this->viewCheckinsLink($registration, $datetime),
81
-                ]
82
-            );
83
-            $datetime_string         .= '</div>';
84
-            $datetimes_for_display[] = $datetime_string;
85
-        }
86
-        return $this->columnContent(
87
-            'DTT_EVT_start',
88
-            $this->generateDisplayForDateTimes($datetimes_for_display)
89
-        );
90
-    }
58
+	/**
59
+	 * @param EE_Registration $registration
60
+	 * @return string
61
+	 * @throws EE_Error
62
+	 * @throws InvalidArgumentException
63
+	 * @throws InvalidDataTypeException
64
+	 * @throws InvalidInterfaceException
65
+	 * @throws ReflectionException
66
+	 */
67
+	public function column_DTT_EVT_start(EE_Registration $registration): string
68
+	{
69
+		$ticket                = $registration->ticket();
70
+		$datetimes             = $ticket instanceof EE_Ticket
71
+			? $ticket->datetimes(['default_where_conditions' => 'none'])
72
+			: [];
73
+		$datetimes_for_display = [];
74
+		foreach ($datetimes as $datetime) {
75
+			$datetime_string         = '<div class="ee-reg-list-dates-list-date">';
76
+			$datetime_string         .= $datetime->get_i18n_datetime('DTT_EVT_start', 'M jS Y g:i a');
77
+			$datetime_string         .= $this->row_actions(
78
+				[
79
+					'datetime_filter'   => $this->datetimeFilterLink($registration, $datetime),
80
+					'datetime_checkins' => $this->viewCheckinsLink($registration, $datetime),
81
+				]
82
+			);
83
+			$datetime_string         .= '</div>';
84
+			$datetimes_for_display[] = $datetime_string;
85
+		}
86
+		return $this->columnContent(
87
+			'DTT_EVT_start',
88
+			$this->generateDisplayForDateTimes($datetimes_for_display)
89
+		);
90
+	}
91 91
 
92 92
 
93
-    /**
94
-     * @param EE_Registration $registration
95
-     * @return string
96
-     * @throws EE_Error
97
-     * @throws ReflectionException
98
-     */
99
-    public function column_REG_ticket(EE_Registration $registration): string
100
-    {
101
-        $ticket      = $registration->ticket();
102
-        $ticket_name = $this->ticketName($ticket);
103
-        $actions     = [
104
-            'ticket_filter'   => $this->ticketFilterLink($ticket),
105
-            'ticket_checkins' => $this->viewCheckinsLink($registration, null, $ticket),
106
-        ];
107
-        return $this->columnContent(
108
-            'REG_ticket',
109
-            $ticket_name . $this->row_actions($actions)
110
-        );
111
-    }
93
+	/**
94
+	 * @param EE_Registration $registration
95
+	 * @return string
96
+	 * @throws EE_Error
97
+	 * @throws ReflectionException
98
+	 */
99
+	public function column_REG_ticket(EE_Registration $registration): string
100
+	{
101
+		$ticket      = $registration->ticket();
102
+		$ticket_name = $this->ticketName($ticket);
103
+		$actions     = [
104
+			'ticket_filter'   => $this->ticketFilterLink($ticket),
105
+			'ticket_checkins' => $this->viewCheckinsLink($registration, null, $ticket),
106
+		];
107
+		return $this->columnContent(
108
+			'REG_ticket',
109
+			$ticket_name . $this->row_actions($actions)
110
+		);
111
+	}
112 112
 
113 113
 
114
-    /**
115
-     * @param EE_Registration $registration
116
-     * @param EE_Datetime     $datetime
117
-     * @return string
118
-     * @throws EE_Error
119
-     * @throws ReflectionException
120
-     * @since 5.0.18.p
121
-     */
122
-    protected function datetimeFilterLink(EE_Registration $registration, EE_Datetime $datetime): string
123
-    {
124
-        $datetime_filter_url = EE_Admin_Page::add_query_args_and_nonce(
125
-            [
126
-                'event_id'    => $registration->event_ID(),
127
-                'datetime_id' => $datetime->ID(),
128
-            ],
129
-            REG_ADMIN_URL
130
-        );
131
-        return '
114
+	/**
115
+	 * @param EE_Registration $registration
116
+	 * @param EE_Datetime     $datetime
117
+	 * @return string
118
+	 * @throws EE_Error
119
+	 * @throws ReflectionException
120
+	 * @since 5.0.18.p
121
+	 */
122
+	protected function datetimeFilterLink(EE_Registration $registration, EE_Datetime $datetime): string
123
+	{
124
+		$datetime_filter_url = EE_Admin_Page::add_query_args_and_nonce(
125
+			[
126
+				'event_id'    => $registration->event_ID(),
127
+				'datetime_id' => $datetime->ID(),
128
+			],
129
+			REG_ADMIN_URL
130
+		);
131
+		return '
132 132
             <a  class="ee-aria-tooltip ee-datetime-filter-link"
133 133
                 href="' . $datetime_filter_url . '"
134 134
                 aria-label="' . sprintf(
135
-                esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
136
-                $datetime->name() ?: esc_attr__('this datetime', 'event_espresso'),
137
-            ) . '"
135
+				esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
136
+				$datetime->name() ?: esc_attr__('this datetime', 'event_espresso'),
137
+			) . '"
138 138
             >
139 139
                 <span class="dashicons dashicons-groups dashicons--small"></span>
140 140
             </a>';
141
-    }
141
+	}
142 142
 
143 143
 
144
-    /**
145
-     * @param EE_Registration  $registration
146
-     * @param EE_Datetime|null $datetime
147
-     * @param EE_Ticket|null   $ticket
148
-     * @return string
149
-     * @throws EE_Error
150
-     * @throws ReflectionException
151
-     * @since 5.0.18.p
152
-     */
153
-    private function viewCheckinsLink(
154
-        EE_Registration $registration,
155
-        ?EE_Datetime $datetime = null,
156
-        ?EE_Ticket $ticket = null
157
-    ): string {
158
-        if (! $this->caps_handler->userCanReadRegistrationCheckin($registration)) {
159
-            return '';
160
-        }
161
-        $text  = esc_html__('View Check-ins', 'event_espresso');
162
-        $label = esc_attr__('View Check-ins for this Event', 'event_espresso');
163
-        $class = 'ee-aria-tooltip';
144
+	/**
145
+	 * @param EE_Registration  $registration
146
+	 * @param EE_Datetime|null $datetime
147
+	 * @param EE_Ticket|null   $ticket
148
+	 * @return string
149
+	 * @throws EE_Error
150
+	 * @throws ReflectionException
151
+	 * @since 5.0.18.p
152
+	 */
153
+	private function viewCheckinsLink(
154
+		EE_Registration $registration,
155
+		?EE_Datetime $datetime = null,
156
+		?EE_Ticket $ticket = null
157
+	): string {
158
+		if (! $this->caps_handler->userCanReadRegistrationCheckin($registration)) {
159
+			return '';
160
+		}
161
+		$text  = esc_html__('View Check-ins', 'event_espresso');
162
+		$label = esc_attr__('View Check-ins for this Event', 'event_espresso');
163
+		$class = 'ee-aria-tooltip';
164 164
 
165
-        $url_params = [
166
-            'action'   => 'event_registrations',
167
-            'event_id' => $registration->event_ID(),
168
-        ];
169
-        if ($datetime instanceof EE_Datetime) {
170
-            $url_params['DTT_ID'] = $datetime->ID();
171
-            $text                 = '';
172
-            $label                = esc_attr__('View Check-ins for this Datetime', 'event_espresso');
173
-            $class                .= ' ee-status-color--' . $datetime->get_active_status();
174
-        }
175
-        if ($ticket instanceof EE_Ticket) {
176
-            $url_params['TKT_ID'] = $ticket->ID();
177
-            $text                 = esc_html__('View Check-ins', 'event_espresso');
178
-            $label                = esc_attr__('View Check-ins for this Ticket', 'event_espresso');
179
-            $class                .= ' ee-status-color--' . $ticket->ticket_status();
180
-        }
181
-        $url = EE_Admin_Page::add_query_args_and_nonce($url_params, REG_ADMIN_URL);
182
-        return "
165
+		$url_params = [
166
+			'action'   => 'event_registrations',
167
+			'event_id' => $registration->event_ID(),
168
+		];
169
+		if ($datetime instanceof EE_Datetime) {
170
+			$url_params['DTT_ID'] = $datetime->ID();
171
+			$text                 = '';
172
+			$label                = esc_attr__('View Check-ins for this Datetime', 'event_espresso');
173
+			$class                .= ' ee-status-color--' . $datetime->get_active_status();
174
+		}
175
+		if ($ticket instanceof EE_Ticket) {
176
+			$url_params['TKT_ID'] = $ticket->ID();
177
+			$text                 = esc_html__('View Check-ins', 'event_espresso');
178
+			$label                = esc_attr__('View Check-ins for this Ticket', 'event_espresso');
179
+			$class                .= ' ee-status-color--' . $ticket->ticket_status();
180
+		}
181
+		$url = EE_Admin_Page::add_query_args_and_nonce($url_params, REG_ADMIN_URL);
182
+		return "
183 183
         <a aria-label='$label' class='$class' href='$url'>
184 184
             <span class='dashicons dashicons-yes-alt dashicons--small'></span>$text
185 185
         </a>";
186
-    }
186
+	}
187 187
 }
Please login to merge, or discard this patch.
admin/extend/registrations/EE_Event_Registrations_List_Table.class.php 2 patches
Indentation   +348 added lines, -348 removed lines patch added patch discarded remove patch
@@ -18,371 +18,371 @@
 block discarded – undo
18 18
  */
19 19
 class EE_Event_Registrations_List_Table extends EE_Registrations_List_Table
20 20
 {
21
-    /**
22
-     * @var Extend_Registrations_Admin_Page
23
-     */
24
-    protected EE_Admin_Page $_admin_page;
25
-
26
-    /**
27
-     * This property will hold the related Datetimes on an event IF the event id is included in the request.
28
-     */
29
-    protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
30
-
31
-    protected array     $_status       = [];
32
-
33
-    private RegistrationsListTableFilters $filters;
34
-
35
-
36
-    /**
37
-     * EE_Event_Registrations_List_Table constructor.
38
-     *
39
-     * @param Registrations_Admin_Page $admin_page
40
-     * @throws EE_Error
41
-     * @throws ReflectionException
42
-     */
43
-    public function __construct($admin_page)
44
-    {
45
-        $this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
46
-        $this->filters = new RegistrationsListTableFilters($this->request);
47
-        $this->filters->resolveRequestVars();
48
-        $this->filters->setLabel( __('Check-in Status for', 'event_espresso') );
49
-        parent::__construct($admin_page);
50
-    }
51
-
52
-
53
-    /**
54
-     * @throws EE_Error
55
-     * @throws ReflectionException
56
-     */
57
-    protected function _setup_data()
58
-    {
59
-        $this->_data = $this->_view !== 'trash'
60
-            ? $this->_admin_page->get_event_attendees($this->_per_page)
61
-            : $this->_admin_page->get_event_attendees($this->_per_page, false, true);
62
-
63
-        $this->_all_data_count = $this->_view !== 'trash'
64
-            ? $this->_admin_page->get_event_attendees($this->_per_page, true)
65
-            : $this->_admin_page->get_event_attendees($this->_per_page, true, true);
66
-    }
67
-
68
-
69
-    protected function _set_properties()
70
-    {
71
-        $this->_wp_list_args = [
72
-            'singular' => esc_html__('registrant', 'event_espresso'),
73
-            'plural'   => esc_html__('registrants', 'event_espresso'),
74
-            'ajax'     => true,
75
-            'screen'   => $this->_admin_page->get_current_screen()->id,
76
-        ];
77
-        $columns             = [];
78
-
79
-        $this->_columns = [
80
-            '_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
81
-            'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
82
-            'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
83
-            'Event'               => esc_html__('Event', 'event_espresso'),
84
-            'REG_ticket'          => esc_html__('Ticket', 'event_espresso'),
85
-            '_REG_final_price'    => esc_html__('Price', 'event_espresso'),
86
-            '_REG_paid'           => esc_html__('REG Paid', 'event_espresso'),
87
-            'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
88
-        ];
89
-        // Add/remove columns when an event has been selected
90
-        if (! empty($this->filters->eventID())) {
91
-            // Render a checkbox column
92
-            $columns['cb']              = '<input type="checkbox" />';
93
-            $this->_has_checkbox_column = true;
94
-            // Remove the 'Event' column
95
-            unset($this->_columns['Event']);
96
-        }
97
-        $this->_columns        = array_merge($columns, $this->_columns);
98
-        $this->_primary_column = '_REG_att_checked_in';
99
-
100
-        $csv_report = RegistrationsCsvReportParams::getRequestParams(
101
-            $this->getReturnUrl(),
102
-            $this->_admin_page->get_request_data(),
103
-            $this->filters->eventID(),
104
-            $this->filters->datetimeID()
105
-        );
106
-        if (! empty($csv_report)) {
107
-            $this->_bottom_buttons['csv_reg_report'] = $csv_report;
108
-        }
109
-
110
-        $this->_sortable_columns = [
111
-            /**
112
-             * Allows users to change the default sort if they wish.
113
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
114
-             * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
115
-             * change the sorts on any list table involving registration contacts.  If you want to only change the filter
116
-             * for a specific list table you can use the provided reference to this object instance.
117
-             */
118
-            'ATT_name' => [
119
-                'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
120
-                true,
121
-                $this,
122
-            ]
123
-                ? ['ATT_lname' => true]
124
-                : ['ATT_fname' => true],
125
-            'Event'    => ['Event.EVT_name' => false],
126
-        ];
127
-        $this->_hidden_columns   = [];
128
-    }
129
-
130
-
131
-    /**
132
-     * @param EE_Registration $item
133
-     * @return string
134
-     */
135
-    protected function _get_row_class($item): string
136
-    {
137
-        $class = parent::_get_row_class($item);
138
-        if ($this->_has_checkbox_column) {
139
-            $class .= ' has-checkbox-column';
140
-        }
141
-        return $class;
142
-    }
143
-
144
-
145
-    /**
146
-     * @return array
147
-     * @throws EE_Error
148
-     * @throws ReflectionException
149
-     */
150
-    protected function _get_table_filters()
151
-    {
152
-        return $this->filters->getFilters();
153
-    }
154
-
155
-
156
-    /**
157
-     * @throws EE_Error
158
-     * @throws ReflectionException
159
-     */
160
-    protected function _add_view_counts()
161
-    {
162
-        $this->_views['all']['count'] = $this->_get_total_event_attendees();
163
-    }
164
-
165
-
166
-    /**
167
-     * @return int
168
-     * @throws EE_Error
169
-     * @throws ReflectionException
170
-     */
171
-    protected function _get_total_event_attendees(): int
172
-    {
173
-        $query_params = [];
174
-        if ($this->filters->eventID()) {
175
-            $query_params[0]['EVT_ID'] = $this->filters->eventID();
176
-        }
177
-        // if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
178
-        if ($this->filters->datetimeID()) {
179
-            $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->filters->datetimeID();
180
-        }
181
-        $status_ids_array          = apply_filters(
182
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
183
-            [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
184
-        );
185
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
186
-        return EEM_Registration::instance()->count($query_params);
187
-    }
188
-
189
-
190
-    /**
191
-     * @param EE_Registration $item
192
-     * @return string
193
-     * @throws EE_Error
194
-     * @throws ReflectionException
195
-     */
196
-    public function column_cb($item): string
197
-    {
198
-        return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
199
-    }
200
-
201
-
202
-    /**
203
-     * column_REG_att_checked_in
204
-     *
205
-     * @param EE_Registration $registration
206
-     * @return string
207
-     * @throws EE_Error
208
-     * @throws InvalidArgumentException
209
-     * @throws InvalidDataTypeException
210
-     * @throws InvalidInterfaceException
211
-     * @throws ReflectionException
212
-     */
213
-    public function column__REG_att_checked_in(EE_Registration $registration): string
214
-    {
215
-        // we need a local variable for the datetime for each row
216
-        // (so that we don't pollute state for the entire table)
217
-        // so let's try to get it from the registration's event
218
-        $DTT_ID = $this->filters->datetimeID();
219
-        if (! $DTT_ID) {
220
-            $reg_ticket_datetimes = $registration->ticket()->datetimes();
221
-            if (count($reg_ticket_datetimes) === 1) {
222
-                $reg_ticket_datetime = reset($reg_ticket_datetimes);
223
-                $DTT_ID              = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
224
-            }
225
-        }
226
-
227
-        if (! $DTT_ID) {
228
-            $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
229
-            $datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
230
-            $DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
231
-        }
232
-
233
-        $checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
234
-            $registration,
235
-            $DTT_ID
236
-        );
237
-
238
-        $aria_label     = $checkin_status_dashicon->ariaLabel();
239
-        $dashicon_class = $checkin_status_dashicon->cssClasses();
240
-        $attributes     = ' onClick="return false"';
241
-        $button_class   = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
242
-
243
-        if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
244
-            // overwrite the disabled attribute with data attributes for performing checkin
245
-            $attributes   = 'data-_regid="' . $registration->ID() . '"';
246
-            $attributes   .= ' data-dttid="' . $DTT_ID . '"';
247
-            $attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
248
-            $button_class .= ' clickable trigger-checkin';
249
-        }
250
-
251
-        $content = '
21
+	/**
22
+	 * @var Extend_Registrations_Admin_Page
23
+	 */
24
+	protected EE_Admin_Page $_admin_page;
25
+
26
+	/**
27
+	 * This property will hold the related Datetimes on an event IF the event id is included in the request.
28
+	 */
29
+	protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
30
+
31
+	protected array     $_status       = [];
32
+
33
+	private RegistrationsListTableFilters $filters;
34
+
35
+
36
+	/**
37
+	 * EE_Event_Registrations_List_Table constructor.
38
+	 *
39
+	 * @param Registrations_Admin_Page $admin_page
40
+	 * @throws EE_Error
41
+	 * @throws ReflectionException
42
+	 */
43
+	public function __construct($admin_page)
44
+	{
45
+		$this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
46
+		$this->filters = new RegistrationsListTableFilters($this->request);
47
+		$this->filters->resolveRequestVars();
48
+		$this->filters->setLabel( __('Check-in Status for', 'event_espresso') );
49
+		parent::__construct($admin_page);
50
+	}
51
+
52
+
53
+	/**
54
+	 * @throws EE_Error
55
+	 * @throws ReflectionException
56
+	 */
57
+	protected function _setup_data()
58
+	{
59
+		$this->_data = $this->_view !== 'trash'
60
+			? $this->_admin_page->get_event_attendees($this->_per_page)
61
+			: $this->_admin_page->get_event_attendees($this->_per_page, false, true);
62
+
63
+		$this->_all_data_count = $this->_view !== 'trash'
64
+			? $this->_admin_page->get_event_attendees($this->_per_page, true)
65
+			: $this->_admin_page->get_event_attendees($this->_per_page, true, true);
66
+	}
67
+
68
+
69
+	protected function _set_properties()
70
+	{
71
+		$this->_wp_list_args = [
72
+			'singular' => esc_html__('registrant', 'event_espresso'),
73
+			'plural'   => esc_html__('registrants', 'event_espresso'),
74
+			'ajax'     => true,
75
+			'screen'   => $this->_admin_page->get_current_screen()->id,
76
+		];
77
+		$columns             = [];
78
+
79
+		$this->_columns = [
80
+			'_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
81
+			'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
82
+			'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
83
+			'Event'               => esc_html__('Event', 'event_espresso'),
84
+			'REG_ticket'          => esc_html__('Ticket', 'event_espresso'),
85
+			'_REG_final_price'    => esc_html__('Price', 'event_espresso'),
86
+			'_REG_paid'           => esc_html__('REG Paid', 'event_espresso'),
87
+			'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
88
+		];
89
+		// Add/remove columns when an event has been selected
90
+		if (! empty($this->filters->eventID())) {
91
+			// Render a checkbox column
92
+			$columns['cb']              = '<input type="checkbox" />';
93
+			$this->_has_checkbox_column = true;
94
+			// Remove the 'Event' column
95
+			unset($this->_columns['Event']);
96
+		}
97
+		$this->_columns        = array_merge($columns, $this->_columns);
98
+		$this->_primary_column = '_REG_att_checked_in';
99
+
100
+		$csv_report = RegistrationsCsvReportParams::getRequestParams(
101
+			$this->getReturnUrl(),
102
+			$this->_admin_page->get_request_data(),
103
+			$this->filters->eventID(),
104
+			$this->filters->datetimeID()
105
+		);
106
+		if (! empty($csv_report)) {
107
+			$this->_bottom_buttons['csv_reg_report'] = $csv_report;
108
+		}
109
+
110
+		$this->_sortable_columns = [
111
+			/**
112
+			 * Allows users to change the default sort if they wish.
113
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
114
+			 * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
115
+			 * change the sorts on any list table involving registration contacts.  If you want to only change the filter
116
+			 * for a specific list table you can use the provided reference to this object instance.
117
+			 */
118
+			'ATT_name' => [
119
+				'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
120
+				true,
121
+				$this,
122
+			]
123
+				? ['ATT_lname' => true]
124
+				: ['ATT_fname' => true],
125
+			'Event'    => ['Event.EVT_name' => false],
126
+		];
127
+		$this->_hidden_columns   = [];
128
+	}
129
+
130
+
131
+	/**
132
+	 * @param EE_Registration $item
133
+	 * @return string
134
+	 */
135
+	protected function _get_row_class($item): string
136
+	{
137
+		$class = parent::_get_row_class($item);
138
+		if ($this->_has_checkbox_column) {
139
+			$class .= ' has-checkbox-column';
140
+		}
141
+		return $class;
142
+	}
143
+
144
+
145
+	/**
146
+	 * @return array
147
+	 * @throws EE_Error
148
+	 * @throws ReflectionException
149
+	 */
150
+	protected function _get_table_filters()
151
+	{
152
+		return $this->filters->getFilters();
153
+	}
154
+
155
+
156
+	/**
157
+	 * @throws EE_Error
158
+	 * @throws ReflectionException
159
+	 */
160
+	protected function _add_view_counts()
161
+	{
162
+		$this->_views['all']['count'] = $this->_get_total_event_attendees();
163
+	}
164
+
165
+
166
+	/**
167
+	 * @return int
168
+	 * @throws EE_Error
169
+	 * @throws ReflectionException
170
+	 */
171
+	protected function _get_total_event_attendees(): int
172
+	{
173
+		$query_params = [];
174
+		if ($this->filters->eventID()) {
175
+			$query_params[0]['EVT_ID'] = $this->filters->eventID();
176
+		}
177
+		// if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
178
+		if ($this->filters->datetimeID()) {
179
+			$query_params[0]['Ticket.Datetime.DTT_ID'] = $this->filters->datetimeID();
180
+		}
181
+		$status_ids_array          = apply_filters(
182
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
183
+			[RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
184
+		);
185
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
186
+		return EEM_Registration::instance()->count($query_params);
187
+	}
188
+
189
+
190
+	/**
191
+	 * @param EE_Registration $item
192
+	 * @return string
193
+	 * @throws EE_Error
194
+	 * @throws ReflectionException
195
+	 */
196
+	public function column_cb($item): string
197
+	{
198
+		return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
199
+	}
200
+
201
+
202
+	/**
203
+	 * column_REG_att_checked_in
204
+	 *
205
+	 * @param EE_Registration $registration
206
+	 * @return string
207
+	 * @throws EE_Error
208
+	 * @throws InvalidArgumentException
209
+	 * @throws InvalidDataTypeException
210
+	 * @throws InvalidInterfaceException
211
+	 * @throws ReflectionException
212
+	 */
213
+	public function column__REG_att_checked_in(EE_Registration $registration): string
214
+	{
215
+		// we need a local variable for the datetime for each row
216
+		// (so that we don't pollute state for the entire table)
217
+		// so let's try to get it from the registration's event
218
+		$DTT_ID = $this->filters->datetimeID();
219
+		if (! $DTT_ID) {
220
+			$reg_ticket_datetimes = $registration->ticket()->datetimes();
221
+			if (count($reg_ticket_datetimes) === 1) {
222
+				$reg_ticket_datetime = reset($reg_ticket_datetimes);
223
+				$DTT_ID              = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
224
+			}
225
+		}
226
+
227
+		if (! $DTT_ID) {
228
+			$this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
229
+			$datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
230
+			$DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
231
+		}
232
+
233
+		$checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
234
+			$registration,
235
+			$DTT_ID
236
+		);
237
+
238
+		$aria_label     = $checkin_status_dashicon->ariaLabel();
239
+		$dashicon_class = $checkin_status_dashicon->cssClasses();
240
+		$attributes     = ' onClick="return false"';
241
+		$button_class   = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
242
+
243
+		if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
244
+			// overwrite the disabled attribute with data attributes for performing checkin
245
+			$attributes   = 'data-_regid="' . $registration->ID() . '"';
246
+			$attributes   .= ' data-dttid="' . $DTT_ID . '"';
247
+			$attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
248
+			$button_class .= ' clickable trigger-checkin';
249
+		}
250
+
251
+		$content = '
252 252
         <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
253 253
             <span class="' . $dashicon_class . '" ></span>
254 254
         </button>
255 255
         <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
256
-        return $this->columnContent('_REG_att_checked_in', $content, 'center');
257
-    }
258
-
259
-
260
-    /**
261
-     * @param EE_Registration $registration
262
-     * @return string
263
-     * @throws EE_Error
264
-     * @throws ReflectionException
265
-     */
266
-    public function column_ATT_name(EE_Registration $registration): string
267
-    {
268
-        $attendee = $registration->attendee();
269
-        if (! $attendee instanceof EE_Attendee) {
270
-            return esc_html__('No contact record for this registration.', 'event_espresso');
271
-        }
272
-        // edit attendee link
273
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
274
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
275
-            REG_ADMIN_URL
276
-        );
277
-        $name_link    = '
256
+		return $this->columnContent('_REG_att_checked_in', $content, 'center');
257
+	}
258
+
259
+
260
+	/**
261
+	 * @param EE_Registration $registration
262
+	 * @return string
263
+	 * @throws EE_Error
264
+	 * @throws ReflectionException
265
+	 */
266
+	public function column_ATT_name(EE_Registration $registration): string
267
+	{
268
+		$attendee = $registration->attendee();
269
+		if (! $attendee instanceof EE_Attendee) {
270
+			return esc_html__('No contact record for this registration.', 'event_espresso');
271
+		}
272
+		// edit attendee link
273
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
274
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
275
+			REG_ADMIN_URL
276
+		);
277
+		$name_link    = '
278 278
             <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
279 279
             aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
280 280
             </span>';
281
-        $status        = esc_attr($registration->status_ID());
282
-        $name_link    .= $this->caps_handler->userCanEditContacts()
283
-            ? '
281
+		$status        = esc_attr($registration->status_ID());
282
+		$name_link    .= $this->caps_handler->userCanEditContacts()
283
+			? '
284 284
             <a class="ee-aria-tooltip ee-status-color--' . $status . '"
285 285
                href="' . $edit_lnk_url . '"
286 286
                aria-label="' . esc_attr__('View Registration Details', 'event_espresso') . '"
287 287
             >
288 288
                 ' . $registration->attendee()->full_name() . '
289 289
             </a>'
290
-            : $registration->attendee()->full_name();
291
-        $name_link    .= $registration->count() === 1
292
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
293
-            : '';
294
-        // add group details
295
-        $name_link .= '&nbsp;' . sprintf(
296
-            esc_html__('(%s of %s)', 'event_espresso'),
297
-            $registration->count(),
298
-            $registration->group_size()
299
-        );
300
-        // add regcode
301
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
302
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
303
-            REG_ADMIN_URL
304
-        );
305
-        $name_link .= '<br>';
306
-        $name_link .= $this->caps_handler->userCanReadRegistration($registration)
307
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
308
-                'View Registration Details',
309
-                'event_espresso'
310
-            ) . '">'
311
-              . $registration->reg_code()
312
-              . '</a>'
313
-            : $registration->reg_code();
314
-
315
-        $actions = [];
316
-        $DTT_ID = $this->filters->datetimeID();
317
-        if ($DTT_ID && $this->caps_handler->userCanReadRegistrationCheckins()) {
318
-            $checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
319
-                ['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $DTT_ID],
320
-                REG_ADMIN_URL
321
-            );
322
-            // get the timestamps for this registration's checkins, related to the selected datetime
323
-            /** @var EE_Checkin[] $checkins */
324
-            $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $DTT_ID]]);
325
-            if (! empty($checkins)) {
326
-                // get the last timestamp
327
-                $last_checkin = end($checkins);
328
-                // get timestamp string
329
-                $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
330
-                $actions['checkin'] = '
290
+			: $registration->attendee()->full_name();
291
+		$name_link    .= $registration->count() === 1
292
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
293
+			: '';
294
+		// add group details
295
+		$name_link .= '&nbsp;' . sprintf(
296
+			esc_html__('(%s of %s)', 'event_espresso'),
297
+			$registration->count(),
298
+			$registration->group_size()
299
+		);
300
+		// add regcode
301
+		$link      = EE_Admin_Page::add_query_args_and_nonce(
302
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
303
+			REG_ADMIN_URL
304
+		);
305
+		$name_link .= '<br>';
306
+		$name_link .= $this->caps_handler->userCanReadRegistration($registration)
307
+			? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
308
+				'View Registration Details',
309
+				'event_espresso'
310
+			) . '">'
311
+			  . $registration->reg_code()
312
+			  . '</a>'
313
+			: $registration->reg_code();
314
+
315
+		$actions = [];
316
+		$DTT_ID = $this->filters->datetimeID();
317
+		if ($DTT_ID && $this->caps_handler->userCanReadRegistrationCheckins()) {
318
+			$checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
319
+				['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $DTT_ID],
320
+				REG_ADMIN_URL
321
+			);
322
+			// get the timestamps for this registration's checkins, related to the selected datetime
323
+			/** @var EE_Checkin[] $checkins */
324
+			$checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $DTT_ID]]);
325
+			if (! empty($checkins)) {
326
+				// get the last timestamp
327
+				$last_checkin = end($checkins);
328
+				// get timestamp string
329
+				$timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
330
+				$actions['checkin'] = '
331 331
                     <a  class="ee-aria-tooltip"
332 332
                         href="' . $checkin_list_url . '"
333 333
                         aria-label="' . esc_attr__(
334
-                            'View this registrant\'s check-ins/checkouts for the datetime',
335
-                            'event_espresso'
336
-                        ) . '"
334
+							'View this registrant\'s check-ins/checkouts for the datetime',
335
+							'event_espresso'
336
+						) . '"
337 337
                     >
338 338
                         ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
339 339
                     </a>';
340
-            }
341
-        }
342
-        $content = (! empty($DTT_ID) && ! empty($checkins))
343
-            ? $name_link . $this->row_actions($actions, true)
344
-            : $name_link;
345
-        return $this->columnContent('ATT_name', $content);
346
-    }
347
-
348
-
349
-    /**
350
-     * @param EE_Registration $registration
351
-     * @return string
352
-     * @throws EE_Error
353
-     * @throws ReflectionException
354
-     */
355
-    public function column_Event(EE_Registration $registration): string
356
-    {
357
-        try {
358
-            $event = $this->filters->event() instanceof EE_Event
359
-                ? $this->filters->event()
360
-                : $registration->event();
361
-            $checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
362
-                ['action' => 'event_registrations', 'event_id' => $event->ID()],
363
-                REG_ADMIN_URL
364
-            );
365
-            $content          = $this->caps_handler->userCanReadRegistrationCheckins()
366
-                ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
367
-                . esc_attr__(
368
-                    'View Check-ins for this Event',
369
-                    'event_espresso'
370
-                ) . '">' . $event->name() . '</a>' : $event->name();
371
-        } catch (EntityNotFoundException $e) {
372
-            $content = esc_html__('Unknown', 'event_espresso');
373
-        }
374
-        return $this->columnContent('Event', $content);
375
-    }
376
-
377
-
378
-    /**
379
-     * @param EE_Registration $registration
380
-     * @return string
381
-     * @throws EE_Error
382
-     * @throws ReflectionException
383
-     */
384
-    public function column_PRC_name(EE_Registration $registration): string
385
-    {
386
-        return $this->column_REG_ticket($registration);
387
-    }
340
+			}
341
+		}
342
+		$content = (! empty($DTT_ID) && ! empty($checkins))
343
+			? $name_link . $this->row_actions($actions, true)
344
+			: $name_link;
345
+		return $this->columnContent('ATT_name', $content);
346
+	}
347
+
348
+
349
+	/**
350
+	 * @param EE_Registration $registration
351
+	 * @return string
352
+	 * @throws EE_Error
353
+	 * @throws ReflectionException
354
+	 */
355
+	public function column_Event(EE_Registration $registration): string
356
+	{
357
+		try {
358
+			$event = $this->filters->event() instanceof EE_Event
359
+				? $this->filters->event()
360
+				: $registration->event();
361
+			$checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
362
+				['action' => 'event_registrations', 'event_id' => $event->ID()],
363
+				REG_ADMIN_URL
364
+			);
365
+			$content          = $this->caps_handler->userCanReadRegistrationCheckins()
366
+				? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
367
+				. esc_attr__(
368
+					'View Check-ins for this Event',
369
+					'event_espresso'
370
+				) . '">' . $event->name() . '</a>' : $event->name();
371
+		} catch (EntityNotFoundException $e) {
372
+			$content = esc_html__('Unknown', 'event_espresso');
373
+		}
374
+		return $this->columnContent('Event', $content);
375
+	}
376
+
377
+
378
+	/**
379
+	 * @param EE_Registration $registration
380
+	 * @return string
381
+	 * @throws EE_Error
382
+	 * @throws ReflectionException
383
+	 */
384
+	public function column_PRC_name(EE_Registration $registration): string
385
+	{
386
+		return $this->column_REG_ticket($registration);
387
+	}
388 388
 }
Please login to merge, or discard this patch.
Spacing   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -28,7 +28,7 @@  discard block
 block discarded – undo
28 28
      */
29 29
     protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
30 30
 
31
-    protected array     $_status       = [];
31
+    protected array     $_status = [];
32 32
 
33 33
     private RegistrationsListTableFilters $filters;
34 34
 
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
         $this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
46 46
         $this->filters = new RegistrationsListTableFilters($this->request);
47 47
         $this->filters->resolveRequestVars();
48
-        $this->filters->setLabel( __('Check-in Status for', 'event_espresso') );
48
+        $this->filters->setLabel(__('Check-in Status for', 'event_espresso'));
49 49
         parent::__construct($admin_page);
50 50
     }
51 51
 
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
             'ajax'     => true,
75 75
             'screen'   => $this->_admin_page->get_current_screen()->id,
76 76
         ];
77
-        $columns             = [];
77
+        $columns = [];
78 78
 
79 79
         $this->_columns = [
80 80
             '_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
             'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
88 88
         ];
89 89
         // Add/remove columns when an event has been selected
90
-        if (! empty($this->filters->eventID())) {
90
+        if ( ! empty($this->filters->eventID())) {
91 91
             // Render a checkbox column
92 92
             $columns['cb']              = '<input type="checkbox" />';
93 93
             $this->_has_checkbox_column = true;
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
             $this->filters->eventID(),
104 104
             $this->filters->datetimeID()
105 105
         );
106
-        if (! empty($csv_report)) {
106
+        if ( ! empty($csv_report)) {
107 107
             $this->_bottom_buttons['csv_reg_report'] = $csv_report;
108 108
         }
109 109
 
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
                 : ['ATT_fname' => true],
125 125
             'Event'    => ['Event.EVT_name' => false],
126 126
         ];
127
-        $this->_hidden_columns   = [];
127
+        $this->_hidden_columns = [];
128 128
     }
129 129
 
130 130
 
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
         if ($this->filters->datetimeID()) {
179 179
             $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->filters->datetimeID();
180 180
         }
181
-        $status_ids_array          = apply_filters(
181
+        $status_ids_array = apply_filters(
182 182
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
183 183
             [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
184 184
         );
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
         // (so that we don't pollute state for the entire table)
217 217
         // so let's try to get it from the registration's event
218 218
         $DTT_ID = $this->filters->datetimeID();
219
-        if (! $DTT_ID) {
219
+        if ( ! $DTT_ID) {
220 220
             $reg_ticket_datetimes = $registration->ticket()->datetimes();
221 221
             if (count($reg_ticket_datetimes) === 1) {
222 222
                 $reg_ticket_datetime = reset($reg_ticket_datetimes);
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
             }
225 225
         }
226 226
 
227
-        if (! $DTT_ID) {
227
+        if ( ! $DTT_ID) {
228 228
             $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
229 229
             $datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
230 230
             $DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
@@ -242,17 +242,17 @@  discard block
 block discarded – undo
242 242
 
243 243
         if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
244 244
             // overwrite the disabled attribute with data attributes for performing checkin
245
-            $attributes   = 'data-_regid="' . $registration->ID() . '"';
246
-            $attributes   .= ' data-dttid="' . $DTT_ID . '"';
247
-            $attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
245
+            $attributes = 'data-_regid="'.$registration->ID().'"';
246
+            $attributes   .= ' data-dttid="'.$DTT_ID.'"';
247
+            $attributes   .= ' data-nonce="'.wp_create_nonce('checkin_nonce').'"';
248 248
             $button_class .= ' clickable trigger-checkin';
249 249
         }
250 250
 
251 251
         $content = '
252
-        <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
253
-            <span class="' . $dashicon_class . '" ></span>
252
+        <button aria-label="' . $aria_label.'" class="'.$button_class.'" '.$attributes.'>
253
+            <span class="' . $dashicon_class.'" ></span>
254 254
         </button>
255
-        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
255
+        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration).'</span>';
256 256
         return $this->columnContent('_REG_att_checked_in', $content, 'center');
257 257
     }
258 258
 
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
     public function column_ATT_name(EE_Registration $registration): string
267 267
     {
268 268
         $attendee = $registration->attendee();
269
-        if (! $attendee instanceof EE_Attendee) {
269
+        if ( ! $attendee instanceof EE_Attendee) {
270 270
             return esc_html__('No contact record for this registration.', 'event_espresso');
271 271
         }
272 272
         // edit attendee link
@@ -274,40 +274,40 @@  discard block
 block discarded – undo
274 274
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
275 275
             REG_ADMIN_URL
276 276
         );
277
-        $name_link    = '
278
-            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
279
-            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
277
+        $name_link = '
278
+            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()).' ee-aria-tooltip"
279
+            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence').'">
280 280
             </span>';
281 281
         $status        = esc_attr($registration->status_ID());
282 282
         $name_link    .= $this->caps_handler->userCanEditContacts()
283 283
             ? '
284
-            <a class="ee-aria-tooltip ee-status-color--' . $status . '"
285
-               href="' . $edit_lnk_url . '"
286
-               aria-label="' . esc_attr__('View Registration Details', 'event_espresso') . '"
284
+            <a class="ee-aria-tooltip ee-status-color--' . $status.'"
285
+               href="' . $edit_lnk_url.'"
286
+               aria-label="' . esc_attr__('View Registration Details', 'event_espresso').'"
287 287
             >
288
-                ' . $registration->attendee()->full_name() . '
288
+                ' . $registration->attendee()->full_name().'
289 289
             </a>'
290 290
             : $registration->attendee()->full_name();
291
-        $name_link    .= $registration->count() === 1
291
+        $name_link .= $registration->count() === 1
292 292
             ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
293 293
             : '';
294 294
         // add group details
295
-        $name_link .= '&nbsp;' . sprintf(
295
+        $name_link .= '&nbsp;'.sprintf(
296 296
             esc_html__('(%s of %s)', 'event_espresso'),
297 297
             $registration->count(),
298 298
             $registration->group_size()
299 299
         );
300 300
         // add regcode
301
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
301
+        $link = EE_Admin_Page::add_query_args_and_nonce(
302 302
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
303 303
             REG_ADMIN_URL
304 304
         );
305 305
         $name_link .= '<br>';
306 306
         $name_link .= $this->caps_handler->userCanReadRegistration($registration)
307
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
307
+            ? '<a class="ee-aria-tooltip" href="'.$link.'" aria-label="'.esc_attr__(
308 308
                 'View Registration Details',
309 309
                 'event_espresso'
310
-            ) . '">'
310
+            ).'">'
311 311
               . $registration->reg_code()
312 312
               . '</a>'
313 313
             : $registration->reg_code();
@@ -322,25 +322,25 @@  discard block
 block discarded – undo
322 322
             // get the timestamps for this registration's checkins, related to the selected datetime
323 323
             /** @var EE_Checkin[] $checkins */
324 324
             $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $DTT_ID]]);
325
-            if (! empty($checkins)) {
325
+            if ( ! empty($checkins)) {
326 326
                 // get the last timestamp
327 327
                 $last_checkin = end($checkins);
328 328
                 // get timestamp string
329 329
                 $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
330 330
                 $actions['checkin'] = '
331 331
                     <a  class="ee-aria-tooltip"
332
-                        href="' . $checkin_list_url . '"
332
+                        href="' . $checkin_list_url.'"
333 333
                         aria-label="' . esc_attr__(
334 334
                             'View this registrant\'s check-ins/checkouts for the datetime',
335 335
                             'event_espresso'
336
-                        ) . '"
336
+                        ).'"
337 337
                     >
338
-                        ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
338
+                        ' . $last_checkin->getCheckInText().': '.$timestamp_string.'
339 339
                     </a>';
340 340
             }
341 341
         }
342
-        $content = (! empty($DTT_ID) && ! empty($checkins))
343
-            ? $name_link . $this->row_actions($actions, true)
342
+        $content = ( ! empty($DTT_ID) && ! empty($checkins))
343
+            ? $name_link.$this->row_actions($actions, true)
344 344
             : $name_link;
345 345
         return $this->columnContent('ATT_name', $content);
346 346
     }
@@ -362,12 +362,12 @@  discard block
 block discarded – undo
362 362
                 ['action' => 'event_registrations', 'event_id' => $event->ID()],
363 363
                 REG_ADMIN_URL
364 364
             );
365
-            $content          = $this->caps_handler->userCanReadRegistrationCheckins()
366
-                ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
365
+            $content = $this->caps_handler->userCanReadRegistrationCheckins()
366
+                ? '<a class="ee-aria-tooltip" href="'.$checkin_link_url.'" aria-label="'
367 367
                 . esc_attr__(
368 368
                     'View Check-ins for this Event',
369 369
                     'event_espresso'
370
-                ) . '">' . $event->name() . '</a>' : $event->name();
370
+                ).'">'.$event->name().'</a>' : $event->name();
371 371
         } catch (EntityNotFoundException $e) {
372 372
             $content = esc_html__('Unknown', 'event_espresso');
373 373
         }
Please login to merge, or discard this patch.
caffeinated/core/domain/services/pue/Stats.php 2 patches
Indentation   +208 added lines, -208 removed lines patch added patch discarded remove patch
@@ -23,86 +23,86 @@  discard block
 block discarded – undo
23 23
  */
24 24
 class Stats
25 25
 {
26
-    public const OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS = 'ee_uxip_stats_expiry';
27
-
28
-    /**
29
-     * @var Config
30
-     */
31
-    private $config;
32
-
33
-
34
-    /**
35
-     * @var StatsGatherer
36
-     */
37
-    private $stats_gatherer;
38
-
39
-
40
-    /**
41
-     * @var EE_Maintenance_Mode
42
-     */
43
-    private $maintenance_mode;
44
-
45
-
46
-    public function __construct(
47
-        Config $config,
48
-        EE_Maintenance_Mode $maintenance_mode,
49
-        StatsGatherer $stats_gatherer
50
-    ) {
51
-        $this->config           = $config;
52
-        $this->maintenance_mode = $maintenance_mode;
53
-        $this->stats_gatherer   = $stats_gatherer;
54
-        $this->setUxipNotices();
55
-    }
56
-
57
-
58
-    /**
59
-     * Displays uxip opt-in notice if necessary.
60
-     */
61
-    private function setUxipNotices()
62
-    {
63
-        if ($this->canDisplayNotices()) {
64
-            add_action('admin_notices', [$this, 'optinNotice']);
65
-            add_action('admin_enqueue_scripts', [$this, 'enqueueScripts']);
66
-            add_action('wp_ajax_espresso_data_optin', [$this, 'ajaxHandler']);
67
-        }
68
-    }
69
-
70
-
71
-    /**
72
-     * This returns the callback that PluginUpdateEngineChecker will use for getting any extra stats to send.
73
-     *
74
-     * @return Closure
75
-     */
76
-    public function statsCallback(): Closure
77
-    {
78
-        // returns a callback that can is used to retrieve the stats to send along to the pue server.
79
-        return function () {
80
-            // we only send stats one a week, so let's see if our stat timestamp has expired.
81
-            if (! $this->sendStats()) {
82
-                return [];
83
-            }
84
-            return $this->stats_gatherer->stats();
85
-        };
86
-    }
87
-
88
-
89
-    /**
90
-     * Return whether notices can be displayed or not
91
-     *
92
-     * @return bool
93
-     */
94
-    private function canDisplayNotices(): bool
95
-    {
96
-        return MaintenanceStatus::isNotFullSite() && ! $this->config->hasNotifiedForUxip();
97
-    }
98
-
99
-
100
-    /**
101
-     * Callback for the admin_notices hook that outputs the UXIP optin-in notice.
102
-     */
103
-    public function optinNotice()
104
-    {
105
-        ?>
26
+	public const OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS = 'ee_uxip_stats_expiry';
27
+
28
+	/**
29
+	 * @var Config
30
+	 */
31
+	private $config;
32
+
33
+
34
+	/**
35
+	 * @var StatsGatherer
36
+	 */
37
+	private $stats_gatherer;
38
+
39
+
40
+	/**
41
+	 * @var EE_Maintenance_Mode
42
+	 */
43
+	private $maintenance_mode;
44
+
45
+
46
+	public function __construct(
47
+		Config $config,
48
+		EE_Maintenance_Mode $maintenance_mode,
49
+		StatsGatherer $stats_gatherer
50
+	) {
51
+		$this->config           = $config;
52
+		$this->maintenance_mode = $maintenance_mode;
53
+		$this->stats_gatherer   = $stats_gatherer;
54
+		$this->setUxipNotices();
55
+	}
56
+
57
+
58
+	/**
59
+	 * Displays uxip opt-in notice if necessary.
60
+	 */
61
+	private function setUxipNotices()
62
+	{
63
+		if ($this->canDisplayNotices()) {
64
+			add_action('admin_notices', [$this, 'optinNotice']);
65
+			add_action('admin_enqueue_scripts', [$this, 'enqueueScripts']);
66
+			add_action('wp_ajax_espresso_data_optin', [$this, 'ajaxHandler']);
67
+		}
68
+	}
69
+
70
+
71
+	/**
72
+	 * This returns the callback that PluginUpdateEngineChecker will use for getting any extra stats to send.
73
+	 *
74
+	 * @return Closure
75
+	 */
76
+	public function statsCallback(): Closure
77
+	{
78
+		// returns a callback that can is used to retrieve the stats to send along to the pue server.
79
+		return function () {
80
+			// we only send stats one a week, so let's see if our stat timestamp has expired.
81
+			if (! $this->sendStats()) {
82
+				return [];
83
+			}
84
+			return $this->stats_gatherer->stats();
85
+		};
86
+	}
87
+
88
+
89
+	/**
90
+	 * Return whether notices can be displayed or not
91
+	 *
92
+	 * @return bool
93
+	 */
94
+	private function canDisplayNotices(): bool
95
+	{
96
+		return MaintenanceStatus::isNotFullSite() && ! $this->config->hasNotifiedForUxip();
97
+	}
98
+
99
+
100
+	/**
101
+	 * Callback for the admin_notices hook that outputs the UXIP optin-in notice.
102
+	 */
103
+	public function optinNotice()
104
+	{
105
+		?>
106 106
         <div class="espresso-notices updated data-collect-optin" id="espresso-data-collect-optin-container">
107 107
             <div id="data-collect-optin-options-container">
108 108
                 <span class="dashicons dashicons-admin-site"></span>
@@ -115,133 +115,133 @@  discard block
 block discarded – undo
115 115
             </div>
116 116
         </div>
117 117
         <?php
118
-    }
119
-
120
-
121
-    /**
122
-     * Retrieves the optin text (static so it can be used in multiple places as necessary).
123
-     *
124
-     * @param bool $extra
125
-     * @return string|void
126
-     */
127
-    public static function optinText(bool $extra = true)
128
-    {
129
-        if (! $extra) {
130
-            return '
118
+	}
119
+
120
+
121
+	/**
122
+	 * Retrieves the optin text (static so it can be used in multiple places as necessary).
123
+	 *
124
+	 * @param bool $extra
125
+	 * @return string|void
126
+	 */
127
+	public static function optinText(bool $extra = true)
128
+	{
129
+		if (! $extra) {
130
+			return '
131 131
             <h2 class="ee-admin-settings-hdr" id="UXIP_settings">'
132
-                . esc_html__('User eXperience Improvement Program (UXIP)', 'event_espresso')
133
-                . EEH_Template::get_help_tab_link('organization_logo_info')
134
-            . '</h2>' . sprintf(
135
-                esc_html__(
136
-                    '%1$sPlease help us make Event Espresso better and vote for your favorite features.%2$s The %3$sUser eXperience Improvement Program (UXIP)%4$s, has been created so when you use Event Espresso you are voting for the features and settings that are important to you. The UXIP helps us understand how you use our products and services, track problems and in what context. If you opt-out of the UXIP you essentially elect for us to disregard how you use Event Espresso as we build new features and make changes. Participation in the program is completely voluntary and it is disabled by default. The end results of the UXIP are software improvements to better meet your needs. The data we collect will never be sold, traded, or misused in any way. %5$sPlease see our %6$sPrivacy Policy%7$s for more information.%8$s',
137
-                    'event_espresso'
138
-                ),
139
-                '<p><em>',
140
-                '</em></p><p>',
141
-                '<a href="https://eventespresso.com/about/user-experience-improvement-program-uxip/" target="_blank">',
142
-                '</a>',
143
-                '<br><br>',
144
-                '<a href="https://eventespresso.com/about/privacy-policy/" target="_blank">',
145
-                '</a>',
146
-                '</p>'
147
-            );
148
-        }
149
-
150
-        $settings_url = EEH_URL::add_query_args_and_nonce(
151
-            ['action' => 'default'],
152
-            admin_url('admin.php?page=espresso_general_settings')
153
-        );
154
-        $settings_url .= '#UXIP_settings';
155
-        printf(
156
-            esc_html__(
157
-                'The Event Espresso UXIP feature is not yet active on your site. For %1$smore info%2$s and to opt-in %3$sclick here%4$s.',
158
-                'event_espresso'
159
-            ),
160
-            '<a href="https://eventespresso.com/about/user-experience-improvement-program-uxip/" target="_blank">',
161
-            '</a>',
162
-            '<a href="' . $settings_url . '" target="_blank">',
163
-            '</a>'
164
-        );
165
-    }
166
-
167
-
168
-    /**
169
-     * Callback for admin_enqueue_scripts that sets up the scripts and styles for the uxip notice
170
-     */
171
-    public function enqueueScripts()
172
-    {
173
-        wp_register_script(
174
-            'ee-data-optin-js',
175
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-data-optin.js',
176
-            ['jquery'],
177
-            EVENT_ESPRESSO_VERSION,
178
-            true
179
-        );
180
-        wp_register_style(
181
-            'ee-data-optin-css',
182
-            EE_GLOBAL_ASSETS_URL . 'css/ee-data-optin.css',
183
-            [],
184
-            EVENT_ESPRESSO_VERSION
185
-        );
186
-
187
-        wp_enqueue_script('ee-data-optin-js');
188
-        wp_enqueue_style('ee-data-optin-css');
189
-    }
190
-
191
-
192
-    /**
193
-     * Callback for wp_ajax_espresso_data_optin that handles the ajax request
194
-     */
195
-    public function ajaxHandler()
196
-    {
197
-        /** @var EE_Capabilities $capabilities */
198
-        $capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class);
199
-        if (! $capabilities->current_user_can('manage_options', 'edit-uxip-settings')) {
200
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
201
-        }
202
-        /** @var RequestInterface $request */
203
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
204
-        $nonce   = $request->getRequestParam('nonce');
205
-        // verify nonce
206
-        if (! $nonce || ! wp_verify_nonce($nonce, 'ee-data-optin')) {
207
-            exit();
208
-        }
209
-
210
-        // update has notified option
211
-        $this->config->setHasNotifiedAboutUxip();
212
-        exit();
213
-    }
214
-
215
-
216
-    /**
217
-     * Used to determine whether additional stats are sent.
218
-     */
219
-    private function sendStats(): bool
220
-    {
221
-        return MaintenanceStatus::isNotFullSite()
222
-               && $this->config->isOptedInForUxip()
223
-               && $this->statSendTimestampExpired();
224
-    }
225
-
226
-
227
-    /**
228
-     * Returns true when the timestamp used to track whether stats get sent (currently a weekly interval) is expired.
229
-     * Returns false otherwise.
230
-     *
231
-     * @return bool
232
-     */
233
-    private function statSendTimestampExpired(): bool
234
-    {
235
-        $current_expiry = get_option(self::OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS, null);
236
-        if ($current_expiry === null) {
237
-            add_option(self::OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS, time() + WEEK_IN_SECONDS, '', 'no');
238
-            return true;
239
-        }
240
-
241
-        if (time() > (int) $current_expiry) {
242
-            update_option(self::OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS, time() + WEEK_IN_SECONDS);
243
-            return true;
244
-        }
245
-        return false;
246
-    }
132
+				. esc_html__('User eXperience Improvement Program (UXIP)', 'event_espresso')
133
+				. EEH_Template::get_help_tab_link('organization_logo_info')
134
+			. '</h2>' . sprintf(
135
+				esc_html__(
136
+					'%1$sPlease help us make Event Espresso better and vote for your favorite features.%2$s The %3$sUser eXperience Improvement Program (UXIP)%4$s, has been created so when you use Event Espresso you are voting for the features and settings that are important to you. The UXIP helps us understand how you use our products and services, track problems and in what context. If you opt-out of the UXIP you essentially elect for us to disregard how you use Event Espresso as we build new features and make changes. Participation in the program is completely voluntary and it is disabled by default. The end results of the UXIP are software improvements to better meet your needs. The data we collect will never be sold, traded, or misused in any way. %5$sPlease see our %6$sPrivacy Policy%7$s for more information.%8$s',
137
+					'event_espresso'
138
+				),
139
+				'<p><em>',
140
+				'</em></p><p>',
141
+				'<a href="https://eventespresso.com/about/user-experience-improvement-program-uxip/" target="_blank">',
142
+				'</a>',
143
+				'<br><br>',
144
+				'<a href="https://eventespresso.com/about/privacy-policy/" target="_blank">',
145
+				'</a>',
146
+				'</p>'
147
+			);
148
+		}
149
+
150
+		$settings_url = EEH_URL::add_query_args_and_nonce(
151
+			['action' => 'default'],
152
+			admin_url('admin.php?page=espresso_general_settings')
153
+		);
154
+		$settings_url .= '#UXIP_settings';
155
+		printf(
156
+			esc_html__(
157
+				'The Event Espresso UXIP feature is not yet active on your site. For %1$smore info%2$s and to opt-in %3$sclick here%4$s.',
158
+				'event_espresso'
159
+			),
160
+			'<a href="https://eventespresso.com/about/user-experience-improvement-program-uxip/" target="_blank">',
161
+			'</a>',
162
+			'<a href="' . $settings_url . '" target="_blank">',
163
+			'</a>'
164
+		);
165
+	}
166
+
167
+
168
+	/**
169
+	 * Callback for admin_enqueue_scripts that sets up the scripts and styles for the uxip notice
170
+	 */
171
+	public function enqueueScripts()
172
+	{
173
+		wp_register_script(
174
+			'ee-data-optin-js',
175
+			EE_GLOBAL_ASSETS_URL . 'scripts/ee-data-optin.js',
176
+			['jquery'],
177
+			EVENT_ESPRESSO_VERSION,
178
+			true
179
+		);
180
+		wp_register_style(
181
+			'ee-data-optin-css',
182
+			EE_GLOBAL_ASSETS_URL . 'css/ee-data-optin.css',
183
+			[],
184
+			EVENT_ESPRESSO_VERSION
185
+		);
186
+
187
+		wp_enqueue_script('ee-data-optin-js');
188
+		wp_enqueue_style('ee-data-optin-css');
189
+	}
190
+
191
+
192
+	/**
193
+	 * Callback for wp_ajax_espresso_data_optin that handles the ajax request
194
+	 */
195
+	public function ajaxHandler()
196
+	{
197
+		/** @var EE_Capabilities $capabilities */
198
+		$capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class);
199
+		if (! $capabilities->current_user_can('manage_options', 'edit-uxip-settings')) {
200
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
201
+		}
202
+		/** @var RequestInterface $request */
203
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
204
+		$nonce   = $request->getRequestParam('nonce');
205
+		// verify nonce
206
+		if (! $nonce || ! wp_verify_nonce($nonce, 'ee-data-optin')) {
207
+			exit();
208
+		}
209
+
210
+		// update has notified option
211
+		$this->config->setHasNotifiedAboutUxip();
212
+		exit();
213
+	}
214
+
215
+
216
+	/**
217
+	 * Used to determine whether additional stats are sent.
218
+	 */
219
+	private function sendStats(): bool
220
+	{
221
+		return MaintenanceStatus::isNotFullSite()
222
+			   && $this->config->isOptedInForUxip()
223
+			   && $this->statSendTimestampExpired();
224
+	}
225
+
226
+
227
+	/**
228
+	 * Returns true when the timestamp used to track whether stats get sent (currently a weekly interval) is expired.
229
+	 * Returns false otherwise.
230
+	 *
231
+	 * @return bool
232
+	 */
233
+	private function statSendTimestampExpired(): bool
234
+	{
235
+		$current_expiry = get_option(self::OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS, null);
236
+		if ($current_expiry === null) {
237
+			add_option(self::OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS, time() + WEEK_IN_SECONDS, '', 'no');
238
+			return true;
239
+		}
240
+
241
+		if (time() > (int) $current_expiry) {
242
+			update_option(self::OPTIONS_KEY_EXPIRY_TIMESTAMP_FOR_SENDING_STATS, time() + WEEK_IN_SECONDS);
243
+			return true;
244
+		}
245
+		return false;
246
+	}
247 247
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -76,9 +76,9 @@  discard block
 block discarded – undo
76 76
     public function statsCallback(): Closure
77 77
     {
78 78
         // returns a callback that can is used to retrieve the stats to send along to the pue server.
79
-        return function () {
79
+        return function() {
80 80
             // we only send stats one a week, so let's see if our stat timestamp has expired.
81
-            if (! $this->sendStats()) {
81
+            if ( ! $this->sendStats()) {
82 82
                 return [];
83 83
             }
84 84
             return $this->stats_gatherer->stats();
@@ -126,12 +126,12 @@  discard block
 block discarded – undo
126 126
      */
127 127
     public static function optinText(bool $extra = true)
128 128
     {
129
-        if (! $extra) {
129
+        if ( ! $extra) {
130 130
             return '
131 131
             <h2 class="ee-admin-settings-hdr" id="UXIP_settings">'
132 132
                 . esc_html__('User eXperience Improvement Program (UXIP)', 'event_espresso')
133 133
                 . EEH_Template::get_help_tab_link('organization_logo_info')
134
-            . '</h2>' . sprintf(
134
+            . '</h2>'.sprintf(
135 135
                 esc_html__(
136 136
                     '%1$sPlease help us make Event Espresso better and vote for your favorite features.%2$s The %3$sUser eXperience Improvement Program (UXIP)%4$s, has been created so when you use Event Espresso you are voting for the features and settings that are important to you. The UXIP helps us understand how you use our products and services, track problems and in what context. If you opt-out of the UXIP you essentially elect for us to disregard how you use Event Espresso as we build new features and make changes. Participation in the program is completely voluntary and it is disabled by default. The end results of the UXIP are software improvements to better meet your needs. The data we collect will never be sold, traded, or misused in any way. %5$sPlease see our %6$sPrivacy Policy%7$s for more information.%8$s',
137 137
                     'event_espresso'
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
             ),
160 160
             '<a href="https://eventespresso.com/about/user-experience-improvement-program-uxip/" target="_blank">',
161 161
             '</a>',
162
-            '<a href="' . $settings_url . '" target="_blank">',
162
+            '<a href="'.$settings_url.'" target="_blank">',
163 163
             '</a>'
164 164
         );
165 165
     }
@@ -172,14 +172,14 @@  discard block
 block discarded – undo
172 172
     {
173 173
         wp_register_script(
174 174
             'ee-data-optin-js',
175
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-data-optin.js',
175
+            EE_GLOBAL_ASSETS_URL.'scripts/ee-data-optin.js',
176 176
             ['jquery'],
177 177
             EVENT_ESPRESSO_VERSION,
178 178
             true
179 179
         );
180 180
         wp_register_style(
181 181
             'ee-data-optin-css',
182
-            EE_GLOBAL_ASSETS_URL . 'css/ee-data-optin.css',
182
+            EE_GLOBAL_ASSETS_URL.'css/ee-data-optin.css',
183 183
             [],
184 184
             EVENT_ESPRESSO_VERSION
185 185
         );
@@ -196,14 +196,14 @@  discard block
 block discarded – undo
196 196
     {
197 197
         /** @var EE_Capabilities $capabilities */
198 198
         $capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class);
199
-        if (! $capabilities->current_user_can('manage_options', 'edit-uxip-settings')) {
199
+        if ( ! $capabilities->current_user_can('manage_options', 'edit-uxip-settings')) {
200 200
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
201 201
         }
202 202
         /** @var RequestInterface $request */
203 203
         $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
204 204
         $nonce   = $request->getRequestParam('nonce');
205 205
         // verify nonce
206
-        if (! $nonce || ! wp_verify_nonce($nonce, 'ee-data-optin')) {
206
+        if ( ! $nonce || ! wp_verify_nonce($nonce, 'ee-data-optin')) {
207 207
             exit();
208 208
         }
209 209
 
Please login to merge, or discard this patch.