Completed
Branch models-cleanup/main (de94a1)
by
unknown
86:45 queued 77:08
created
core/db_models/EEM_Registration.model.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
      * be passed via a GET parameter.
442 442
      *
443 443
      * @param string $REG_url_link
444
-     * @return EE_Registration|null
444
+     * @return null|EE_Base_Class
445 445
      * @throws EE_Error
446 446
      * @throws ReflectionException
447 447
      */
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
      * @param int $ATT_ID
462 462
      * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the
463 463
      *                      attendee number is required
464
-     * @return EE_Registration|null
464
+     * @return null|EE_Base_Class
465 465
      * @throws EE_Error
466 466
      * @throws ReflectionException
467 467
      */
@@ -674,7 +674,7 @@  discard block
 block discarded – undo
674 674
      * Returns the EE_Registration of the primary attendee on the transaction id provided
675 675
      *
676 676
      * @param int $TXN_ID
677
-     * @return EE_Registration|null
677
+     * @return null|EE_Base_Class
678 678
      * @throws EE_Error
679 679
      * @throws ReflectionException
680 680
      */
Please login to merge, or discard this patch.
Indentation   +873 added lines, -873 removed lines patch added patch discarded remove patch
@@ -13,822 +13,822 @@  discard block
 block discarded – undo
13 13
 class EEM_Registration extends EEM_Soft_Delete_Base
14 14
 {
15 15
 
16
-    /**
17
-     * @var EEM_Registration
18
-     */
19
-    protected static $_instance;
20
-
21
-    /**
22
-     * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values
23
-     * are status codes (eg, approved, cancelled, etc)
24
-     *
25
-     * @var array
26
-     */
27
-    private static $_reg_status;
28
-
29
-    /**
30
-     * The value of REG_count for a primary registrant
31
-     */
32
-    const PRIMARY_REGISTRANT_COUNT = 1;
33
-
34
-    /**
35
-     * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration.
36
-     * Initial status for registrations when they are first created
37
-     * Payments are NOT allowed.
38
-     * Automatically toggled to whatever the default Event registration status is upon completion of the attendee
39
-     * information reg step NO space reserved. Registration is NOT active
40
-     */
41
-    const status_id_incomplete = 'RIC';
42
-
43
-    /**
44
-     * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration.
45
-     * Payments are NOT allowed.
46
-     * Event Admin must manually toggle STS_ID for it to change
47
-     * No space reserved.
48
-     * Registration is active
49
-     */
50
-    const status_id_not_approved = 'RNA';
51
-
52
-    /**
53
-     * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT .
54
-     * Payments are allowed.
55
-     * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
56
-     * No space reserved.
57
-     * Registration is active
58
-     */
59
-    const status_id_pending_payment = 'RPP';
60
-
61
-    /**
62
-     * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST .
63
-     * Payments are allowed.
64
-     * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
65
-     * No space reserved.
66
-     * Registration is active
67
-     */
68
-    const status_id_wait_list = 'RWL';
69
-
70
-    /**
71
-     * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration.
72
-     * the TXN may or may not be completed ( paid in full )
73
-     * Payments are allowed.
74
-     * A space IS reserved.
75
-     * Registration is active
76
-     */
77
-    const status_id_approved = 'RAP';
78
-
79
-    /**
80
-     * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee.
81
-     * Payments are NOT allowed.
82
-     * NO space reserved.
83
-     * Registration is NOT active
84
-     */
85
-    const status_id_cancelled = 'RCN';
86
-
87
-    /**
88
-     * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin
89
-     * Payments are NOT allowed.
90
-     * No space reserved.
91
-     * Registration is NOT active
92
-     */
93
-    const status_id_declined = 'RDC';
94
-
95
-    /**
96
-     * @var TableAnalysis $table_analysis
97
-     */
98
-    protected $_table_analysis;
99
-
100
-
101
-    /**
102
-     * private constructor to prevent direct creation
103
-     *
104
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any
105
-     *                         incoming timezone data that gets saved). Note this just sends the timezone info to the
106
-     *                         date time model field objects.  Default is NULL (and will be assumed using the set
107
-     *                         timezone in the 'timezone_string' wp option)
108
-     * @throws EE_Error
109
-     * @throws ReflectionException
110
-     */
111
-    protected function __construct(string $timezone = '')
112
-    {
113
-        $this->_table_analysis         = EE_Registry::instance()->create('TableAnalysis', [], true);
114
-        $this->singular_item           = esc_html__('Registration', 'event_espresso');
115
-        $this->plural_item             = esc_html__('Registrations', 'event_espresso');
116
-        $this->_tables                 = [
117
-            'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'),
118
-        ];
119
-        $this->_fields                 = [
120
-            'Registration' => [
121
-                'REG_ID'           => new EE_Primary_Key_Int_Field(
122
-                    'REG_ID',
123
-                    esc_html__('Registration ID', 'event_espresso')
124
-                ),
125
-                'EVT_ID'           => new EE_Foreign_Key_Int_Field(
126
-                    'EVT_ID',
127
-                    esc_html__('Event ID', 'event_espresso'),
128
-                    false,
129
-                    0,
130
-                    'Event'
131
-                ),
132
-                'ATT_ID'           => new EE_Foreign_Key_Int_Field(
133
-                    'ATT_ID',
134
-                    esc_html__('Attendee ID', 'event_espresso'),
135
-                    false,
136
-                    0,
137
-                    'Attendee'
138
-                ),
139
-                'TXN_ID'           => new EE_Foreign_Key_Int_Field(
140
-                    'TXN_ID',
141
-                    esc_html__('Transaction ID', 'event_espresso'),
142
-                    false,
143
-                    0,
144
-                    'Transaction'
145
-                ),
146
-                'TKT_ID'           => new EE_Foreign_Key_Int_Field(
147
-                    'TKT_ID',
148
-                    esc_html__('Ticket ID', 'event_espresso'),
149
-                    false,
150
-                    0,
151
-                    'Ticket'
152
-                ),
153
-                'STS_ID'           => new EE_Foreign_Key_String_Field(
154
-                    'STS_ID',
155
-                    esc_html__('Status ID', 'event_espresso'),
156
-                    false,
157
-                    EEM_Registration::status_id_incomplete,
158
-                    'Status'
159
-                ),
160
-                'REG_date'         => new EE_Datetime_Field(
161
-                    'REG_date',
162
-                    esc_html__('Time registration occurred', 'event_espresso'),
163
-                    false,
164
-                    EE_Datetime_Field::now,
165
-                    $timezone
166
-                ),
167
-                'REG_final_price'  => new EE_Money_Field(
168
-                    'REG_final_price',
169
-                    esc_html__('Registration\'s share of the transaction total', 'event_espresso'),
170
-                    false,
171
-                    0
172
-                ),
173
-                'REG_paid'         => new EE_Money_Field(
174
-                    'REG_paid',
175
-                    esc_html__('Amount paid to date towards registration', 'event_espresso'),
176
-                    false,
177
-                    0
178
-                ),
179
-                'REG_session'      => new EE_Plain_Text_Field(
180
-                    'REG_session',
181
-                    esc_html__('Session ID of registration', 'event_espresso'),
182
-                    false,
183
-                    ''
184
-                ),
185
-                'REG_code'         => new EE_Plain_Text_Field(
186
-                    'REG_code',
187
-                    esc_html__('Unique Code for this registration', 'event_espresso'),
188
-                    false,
189
-                    ''
190
-                ),
191
-                'REG_url_link'     => new EE_Plain_Text_Field(
192
-                    'REG_url_link',
193
-                    esc_html__('String to be used in URL for identifying registration', 'event_espresso'),
194
-                    false,
195
-                    ''
196
-                ),
197
-                'REG_count'        => new EE_Integer_Field(
198
-                    'REG_count',
199
-                    esc_html__('Count of this registration in the group registration ', 'event_espresso'),
200
-                    true,
201
-                    1
202
-                ),
203
-                'REG_group_size'   => new EE_Integer_Field(
204
-                    'REG_group_size',
205
-                    esc_html__('Number of registrations on this group', 'event_espresso'),
206
-                    false,
207
-                    1
208
-                ),
209
-                'REG_att_is_going' => new EE_Boolean_Field(
210
-                    'REG_att_is_going',
211
-                    esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'),
212
-                    false,
213
-                    false
214
-                ),
215
-                'REG_deleted'      => new EE_Trashed_Flag_Field(
216
-                    'REG_deleted',
217
-                    esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'),
218
-                    false,
219
-                    false
220
-                ),
221
-            ],
222
-        ];
223
-        $this->_model_relations        = [
224
-            'Event'                => new EE_Belongs_To_Relation(),
225
-            'Attendee'             => new EE_Belongs_To_Relation(),
226
-            'Transaction'          => new EE_Belongs_To_Relation(),
227
-            'Ticket'               => new EE_Belongs_To_Relation(),
228
-            'Status'               => new EE_Belongs_To_Relation(),
229
-            'Answer'               => new EE_Has_Many_Relation(),
230
-            'Checkin'              => new EE_Has_Many_Relation(),
231
-            'Registration_Payment' => new EE_Has_Many_Relation(),
232
-            'Payment'              => new EE_HABTM_Relation('Registration_Payment'),
233
-            'Message'              => new EE_Has_Many_Any_Relation(false)
234
-            // allow deletes even if there are messages in the queue related
235
-        ];
236
-        $this->_model_chain_to_wp_user = 'Event';
237
-        parent::__construct($timezone);
238
-    }
239
-
240
-
241
-    /**
242
-     * a list of ALL valid registration statuses currently in use within the system
243
-     * generated by combining the filterable active and inactive reg status arrays
244
-     *
245
-     * @return array
246
-     */
247
-    public static function reg_statuses(): array
248
-    {
249
-        return array_unique(
250
-            array_merge(
251
-                EEM_Registration::active_reg_statuses(),
252
-                EEM_Registration::inactive_reg_statuses()
253
-            )
254
-        );
255
-    }
256
-
257
-
258
-    /**
259
-     * reg_statuses_that_allow_payment
260
-     * a filterable list of registration statuses that allow a registrant to make a payment
261
-     *
262
-     * @return array
263
-     */
264
-    public static function reg_statuses_that_allow_payment(): array
265
-    {
266
-        return apply_filters(
267
-            'FHEE__EEM_Registration__reg_statuses_that_allow_payment',
268
-            [
269
-                EEM_Registration::status_id_approved,
270
-                EEM_Registration::status_id_pending_payment,
271
-            ]
272
-        );
273
-    }
274
-
275
-
276
-    /**
277
-     * active_reg_statuses
278
-     * a filterable list of registration statuses that are considered active
279
-     *
280
-     * @return array
281
-     */
282
-    public static function active_reg_statuses(): array
283
-    {
284
-        return apply_filters(
285
-            'FHEE__EEM_Registration__active_reg_statuses',
286
-            [
287
-                EEM_Registration::status_id_approved,
288
-                EEM_Registration::status_id_pending_payment,
289
-                EEM_Registration::status_id_wait_list,
290
-                EEM_Registration::status_id_not_approved,
291
-            ]
292
-        );
293
-    }
294
-
295
-
296
-    /**
297
-     * inactive_reg_statuses
298
-     * a filterable list of registration statuses that are not considered active
299
-     *
300
-     * @return array
301
-     */
302
-    public static function inactive_reg_statuses(): array
303
-    {
304
-        return apply_filters(
305
-            'FHEE__EEM_Registration__inactive_reg_statuses',
306
-            [
307
-                EEM_Registration::status_id_incomplete,
308
-                EEM_Registration::status_id_cancelled,
309
-                EEM_Registration::status_id_declined,
310
-            ]
311
-        );
312
-    }
313
-
314
-
315
-    /**
316
-     * closed_reg_statuses
317
-     * a filterable list of registration statuses that are considered "closed"
318
-     * meaning they should not be considered in any calculations involving monies owing
319
-     *
320
-     * @return array
321
-     */
322
-    public static function closed_reg_statuses(): array
323
-    {
324
-        return apply_filters(
325
-            'FHEE__EEM_Registration__closed_reg_statuses',
326
-            [
327
-                EEM_Registration::status_id_cancelled,
328
-                EEM_Registration::status_id_declined,
329
-                EEM_Registration::status_id_wait_list,
330
-            ]
331
-        );
332
-    }
333
-
334
-
335
-    /**
336
-     * get list of registration statuses
337
-     *
338
-     * @param array $exclude    The status ids to exclude from the returned results
339
-     * @param bool  $translated If true will return the values as singular localized strings
340
-     * @return array
341
-     * @throws EE_Error
342
-     */
343
-    public static function reg_status_array(array $exclude = [], bool $translated = false): array
344
-    {
345
-        EEM_Registration::instance()->_get_registration_status_array($exclude);
346
-        return $translated
347
-            ? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence')
348
-            : self::$_reg_status;
349
-    }
350
-
351
-
352
-    /**
353
-     * get list of registration statuses
354
-     *
355
-     * @access private
356
-     * @param array $exclude
357
-     * @return void
358
-     * @throws EE_Error
359
-     */
360
-    private function _get_registration_status_array(array $exclude = [])
361
-    {
362
-        // in the very rare circumstance that we are deleting a model's table's data
363
-        // and the table hasn't actually been created, this could have an error
364
-        global $wpdb;
365
-        if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) {
366
-            $results           = $wpdb->get_results(
367
-                "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'"
368
-            );
369
-            self::$_reg_status = [];
370
-            foreach ($results as $status) {
371
-                if (! in_array($status->STS_ID, $exclude, true)) {
372
-                    self::$_reg_status[ $status->STS_ID ] = $status->STS_code;
373
-                }
374
-            }
375
-        }
376
-    }
377
-
378
-
379
-    /**
380
-     * Gets the injected table analyzer, or throws an exception
381
-     *
382
-     * @return TableAnalysis
383
-     * @throws EE_Error
384
-     */
385
-    protected function _get_table_analysis(): TableAnalysis
386
-    {
387
-        if ($this->_table_analysis instanceof TableAnalysis) {
388
-            return $this->_table_analysis;
389
-        }
390
-        throw new EE_Error(
391
-            sprintf(
392
-                esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
393
-                get_class($this)
394
-            )
395
-        );
396
-    }
397
-
398
-
399
-    /**
400
-     * This returns a wpdb->results array of all registration date month and years matching the incoming query params
401
-     * and grouped by month and year.
402
-     *
403
-     * @param array $where_params @see
404
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
405
-     * @return array
406
-     * @throws EE_Error
407
-     * @throws ReflectionException
408
-     */
409
-    public function get_reg_months_and_years(array $where_params): array
410
-    {
411
-        $query_params[0]          = $where_params;
412
-        $query_params['group_by'] = ['reg_year', 'reg_month'];
413
-        $query_params['order_by'] = ['REG_date' => 'DESC'];
414
-        $columns_to_select        = [
415
-            'reg_year'  => ['YEAR(REG_date)', '%s'],
416
-            'reg_month' => ['MONTHNAME(REG_date)', '%s'],
417
-        ];
418
-        return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
419
-    }
420
-
421
-
422
-    /**
423
-     * retrieve ALL registrations for a particular Attendee from db
424
-     *
425
-     * @param int $ATT_ID
426
-     * @return EE_Registration[]
427
-     * @throws EE_Error
428
-     * @throws ReflectionException
429
-     */
430
-    public function get_all_registrations_for_attendee(int $ATT_ID = 0): array
431
-    {
432
-        if (! $ATT_ID) {
433
-            return [];
434
-        }
435
-        return $this->get_all([['ATT_ID' => $ATT_ID]]);
436
-    }
437
-
438
-
439
-    /**
440
-     * Gets a registration given their REG_url_link. Yes, this should usually
441
-     * be passed via a GET parameter.
442
-     *
443
-     * @param string $REG_url_link
444
-     * @return EE_Registration|null
445
-     * @throws EE_Error
446
-     * @throws ReflectionException
447
-     */
448
-    public function get_registration_for_reg_url_link(string $REG_url_link): ?EE_Registration
449
-    {
450
-        if (! $REG_url_link) {
451
-            return null;
452
-        }
453
-        return $this->get_one([['REG_url_link' => $REG_url_link]]);
454
-    }
455
-
456
-
457
-    /**
458
-     * retrieve registration for a specific transaction attendee from db
459
-     *
460
-     * @param int $TXN_ID
461
-     * @param int $ATT_ID
462
-     * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the
463
-     *                      attendee number is required
464
-     * @return EE_Registration|null
465
-     * @throws EE_Error
466
-     * @throws ReflectionException
467
-     */
468
-    public function get_registration_for_transaction_attendee(
469
-        int $TXN_ID = 0,
470
-        int $ATT_ID = 0,
471
-        int $att_nmbr = 0
472
-    ): ?EE_Registration {
473
-        return $this->get_one(
474
-            [
475
-                [
476
-                    'TXN_ID' => $TXN_ID,
477
-                    'ATT_ID' => $ATT_ID,
478
-                ],
479
-                'limit' => [min($att_nmbr - 1, 0), 1],
480
-            ]
481
-        );
482
-    }
483
-
484
-
485
-    /**
486
-     * get the number of registrations per day  for the Registration Admin page Reports Tab.
487
-     * (doesn't utilize models because it's a fairly specialized query)
488
-     *
489
-     * @param $period string which can be passed to php's strtotime function (eg "-1 month")
490
-     * @return stdClass[] with properties regDate and total
491
-     * @throws EE_Error
492
-     * @throws ReflectionException
493
-     */
494
-    public function get_registrations_per_day_report(string $period = '-1 month'): array
495
-    {
496
-        $sql_date = $this->convert_datetime_for_query(
497
-            'REG_date',
498
-            date('Y-m-d H:i:s', strtotime($period)),
499
-            'Y-m-d H:i:s',
500
-            'UTC'
501
-        );
502
-        $where    = [
503
-            'REG_date' => ['>=', $sql_date],
504
-            'STS_ID'   => ['!=', EEM_Registration::status_id_incomplete],
505
-        ];
506
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
507
-            $where['Event.EVT_wp_user'] = get_current_user_id();
508
-        }
509
-        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
510
-        return $this->_get_all_wpdb_results(
511
-            [
512
-                $where,
513
-                'group_by' => 'regDate',
514
-                'order_by' => ['REG_date' => 'ASC'],
515
-            ],
516
-            OBJECT,
517
-            [
518
-                'regDate' => ['DATE(' . $query_interval . ')', '%s'],
519
-                'total'   => ['count(REG_ID)', '%d'],
520
-            ]
521
-        );
522
-    }
523
-
524
-
525
-    /**
526
-     * Get the number of registrations per day including the count of registrations for each Registration Status.
527
-     * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
528
-     *
529
-     * @param string $period
530
-     * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID
531
-     * @throws EE_Error
532
-     * (i.e. RAP)
533
-     */
534
-    public function get_registrations_per_day_and_per_status_report(string $period = '-1 month'): array
535
-    {
536
-        global $wpdb;
537
-        $registration_table = $wpdb->prefix . 'esp_registration';
538
-        $event_table        = $wpdb->posts;
539
-        $sql_date           = date('Y-m-d H:i:s', strtotime($period));
540
-        // prepare the query interval for displaying offset
541
-        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date');
542
-        // inner date query
543
-        $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
544
-        $inner_where      = ' WHERE';
545
-        // exclude events not authored by user if permissions in effect
546
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
547
-            $inner_date_query .= "LEFT JOIN $event_table ON ID = EVT_ID";
548
-            $inner_where      .= ' post_author = ' . get_current_user_id() . ' AND';
549
-        }
550
-        $inner_where      .= " REG_date >= '{$sql_date}'";
551
-        $inner_date_query .= $inner_where;
552
-        // start main query
553
-        $select       = "SELECT DATE({$query_interval}) as Registration_REG_date, ";
554
-        $join         = '';
555
-        $join_parts   = [];
556
-        $select_parts = [];
557
-        // loop through registration statuses to do parts for each status.
558
-        foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
559
-            if ($STS_ID === EEM_Registration::status_id_incomplete) {
560
-                continue;
561
-            }
562
-            $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
563
-            $join_parts[]
564
-                            = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'";
565
-        }
566
-        // setup the selects
567
-        $select .= implode(', ', $select_parts);
568
-        $select .= " FROM ($inner_date_query) AS dates LEFT JOIN ";
569
-        // setup the joins
570
-        $join .= implode(' LEFT JOIN ', $join_parts);
571
-        // now let's put it all together
572
-        $query = $select . $join . ' GROUP BY Registration_REG_date';
573
-        // and execute it
574
-        return $wpdb->get_results($query, ARRAY_A);
575
-    }
576
-
577
-
578
-    /**
579
-     * get the number of registrations per event  for the Registration Admin page Reports Tab
580
-     *
581
-     * @param $period string which can be passed to php's strtotime function (eg "-1 month")
582
-     * @return stdClass[] each with properties event_name, reg_limit, and total
583
-     * @throws EE_Error
584
-     * @throws ReflectionException
585
-     */
586
-    public function get_registrations_per_event_report(string $period = '-1 month'): array
587
-    {
588
-        $date_sql = $this->convert_datetime_for_query(
589
-            'REG_date',
590
-            date('Y-m-d H:i:s', strtotime($period)),
591
-            'Y-m-d H:i:s',
592
-            'UTC'
593
-        );
594
-        $where    = [
595
-            'REG_date' => ['>=', $date_sql],
596
-            'STS_ID'   => ['!=', EEM_Registration::status_id_incomplete],
597
-        ];
598
-        if (
599
-        ! EE_Registry::instance()->CAP->current_user_can(
600
-            'ee_read_others_registrations',
601
-            'reg_per_event_report'
602
-        )
603
-        ) {
604
-            $where['Event.EVT_wp_user'] = get_current_user_id();
605
-        }
606
-        return $this->_get_all_wpdb_results(
607
-            [
608
-                $where,
609
-                'group_by' => 'Event.EVT_name',
610
-                'order_by' => 'Event.EVT_name',
611
-                'limit'    => [0, 24],
612
-            ],
613
-            OBJECT,
614
-            [
615
-                'event_name' => ['Event_CPT.post_title', '%s'],
616
-                'total'      => ['COUNT(REG_ID)', '%s'],
617
-            ]
618
-        );
619
-    }
620
-
621
-
622
-    /**
623
-     * Get the number of registrations per event grouped by registration status.
624
-     * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
625
-     *
626
-     * @param string $period
627
-     * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID
628
-     * @throws EE_Error
629
-     * (i.e. RAP)
630
-     */
631
-    public function get_registrations_per_event_and_per_status_report(string $period = '-1 month'): array
632
-    {
633
-        global $wpdb;
634
-        $registration_table = $wpdb->prefix . 'esp_registration';
635
-        $event_table        = $wpdb->posts;
636
-        $sql_date           = date('Y-m-d H:i:s', strtotime($period));
637
-        // inner date query
638
-        $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table ";
639
-        $inner_where      = ' WHERE';
640
-        // exclude events not authored by user if permissions in effect
641
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
642
-            $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
643
-            $inner_where      .= ' post_author = ' . get_current_user_id() . ' AND';
644
-        }
645
-        $inner_where      .= " REG_date >= '{$sql_date}'";
646
-        $inner_date_query .= $inner_where;
647
-        // build main query
648
-        $select       = 'SELECT Event.post_title as Registration_Event, ';
649
-        $join         = '';
650
-        $join_parts   = [];
651
-        $select_parts = [];
652
-        // loop through registration statuses to do parts for each status.
653
-        foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
654
-            if ($STS_ID === EEM_Registration::status_id_incomplete) {
655
-                continue;
656
-            }
657
-            $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
658
-            $join_parts[]
659
-                            = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date";
660
-        }
661
-        // setup the selects
662
-        $select .= implode(', ', $select_parts);
663
-        $select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN ";
664
-        // setup remaining joins
665
-        $join .= implode(' LEFT JOIN ', $join_parts);
666
-        // now put it all together
667
-        $query = $select . $join . ' GROUP BY Registration_Event';
668
-        // and execute
669
-        return $wpdb->get_results($query, ARRAY_A);
670
-    }
671
-
672
-
673
-    /**
674
-     * Returns the EE_Registration of the primary attendee on the transaction id provided
675
-     *
676
-     * @param int $TXN_ID
677
-     * @return EE_Registration|null
678
-     * @throws EE_Error
679
-     * @throws ReflectionException
680
-     */
681
-    public function get_primary_registration_for_transaction_ID(int $TXN_ID = 0): ?EE_Registration
682
-    {
683
-        if (! $TXN_ID) {
684
-            return null;
685
-        }
686
-        return $this->get_one(
687
-            [
688
-                [
689
-                    'TXN_ID'    => $TXN_ID,
690
-                    'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT,
691
-                ],
692
-            ]
693
-        );
694
-    }
695
-
696
-
697
-    /**
698
-     * get_event_registration_count
699
-     *
700
-     * @param int     $EVT_ID
701
-     * @param boolean $for_incomplete_payments
702
-     * @return int
703
-     * @throws EE_Error
704
-     * @throws ReflectionException
705
-     */
706
-    public function get_event_registration_count(int $EVT_ID, bool $for_incomplete_payments = false): int
707
-    {
708
-        // we only count approved registrations towards registration limits
709
-        $query_params = [['EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved]];
710
-        if ($for_incomplete_payments) {
711
-            $query_params[0]['Transaction.STS_ID'] = ['!=', EEM_Transaction::complete_status_code];
712
-        }
713
-        return $this->count($query_params);
714
-    }
715
-
716
-
717
-    /**
718
-     * Deletes all registrations with no transactions. Note that this needs to be very efficient
719
-     * and so it uses wpdb directly. Also, we can't put a limit on this because MySQL doesn't allow a limit on a delete
720
-     * when joining tables like this.
721
-     *
722
-     * @return int number deleted
723
-     * @throws EE_Error
724
-     * @global WPDB $wpdb
725
-     */
726
-    public function delete_registrations_with_no_transaction(): int
727
-    {
728
-        global $wpdb;
729
-        return $wpdb->query(
730
-            'DELETE r FROM '
731
-            . $this->table()
732
-            . ' r LEFT JOIN '
733
-            . EEM_Transaction::instance()->table()
734
-            . ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL'
735
-        );
736
-    }
737
-
738
-
739
-    /**
740
-     * Count registrations checked into (or out of) a datetime
741
-     *
742
-     * @param int     $DTT_ID     datetime ID
743
-     * @param boolean $checked_in whether to count registrations checked IN or OUT
744
-     * @return int
745
-     * @throws EE_Error
746
-     */
747
-    public function count_registrations_checked_into_datetime(int $DTT_ID, bool $checked_in = true): int
748
-    {
749
-        global $wpdb;
750
-        // subquery to get latest checkin
751
-        $query = $wpdb->prepare(
752
-            'SELECT '
753
-            . 'COUNT( DISTINCT checkins.REG_ID ) '
754
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
755
-            . '( SELECT '
756
-            . 'max( CHK_timestamp ) AS latest_checkin, '
757
-            . 'REG_ID AS REG_ID '
758
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' '
759
-            . 'WHERE DTT_ID=%d '
760
-            . 'GROUP BY REG_ID'
761
-            . ') AS most_recent_checkin_per_reg '
762
-            . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
763
-            . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
764
-            . 'WHERE '
765
-            . 'checkins.CHK_in=%d',
766
-            $DTT_ID,
767
-            $checked_in
768
-        );
769
-        return (int) $wpdb->get_var($query);
770
-    }
771
-
772
-
773
-    /**
774
-     * Count registrations checked into (or out of) an event.
775
-     *
776
-     * @param int     $EVT_ID     event ID
777
-     * @param boolean $checked_in whether to count registrations checked IN or OUT
778
-     * @return int
779
-     * @throws EE_Error
780
-     */
781
-    public function count_registrations_checked_into_event(int $EVT_ID, bool $checked_in = true): int
782
-    {
783
-        global $wpdb;
784
-        // subquery to get latest checkin
785
-        $query = $wpdb->prepare(
786
-            'SELECT '
787
-            . 'COUNT( DISTINCT checkins.REG_ID ) '
788
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
789
-            . '( SELECT '
790
-            . 'max( CHK_timestamp ) AS latest_checkin, '
791
-            . 'REG_ID AS REG_ID '
792
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c '
793
-            . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d '
794
-            . 'ON c.DTT_ID=d.DTT_ID '
795
-            . 'WHERE d.EVT_ID=%d '
796
-            . 'GROUP BY REG_ID'
797
-            . ') AS most_recent_checkin_per_reg '
798
-            . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
799
-            . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
800
-            . 'WHERE '
801
-            . 'checkins.CHK_in=%d',
802
-            $EVT_ID,
803
-            $checked_in
804
-        );
805
-        return (int) $wpdb->get_var($query);
806
-    }
807
-
808
-
809
-    /**
810
-     * The purpose of this method is to retrieve an array of
811
-     * EE_Registration objects that represent the latest registration
812
-     * for each ATT_ID given in the function argument.
813
-     *
814
-     * @param array $attendee_ids
815
-     * @return EE_Registration[]
816
-     * @throws EE_Error
817
-     * @throws ReflectionException
818
-     */
819
-    public function get_latest_registration_for_each_of_given_contacts(array $attendee_ids = []): array
820
-    {
821
-        // first do a native wp_query to get the latest REG_ID's matching these attendees.
822
-        global $wpdb;
823
-        $registration_table = $wpdb->prefix . 'esp_registration';
824
-        $attendee_table     = $wpdb->posts;
825
-        $attendee_ids       = is_array($attendee_ids)
826
-            ? array_map('absint', $attendee_ids)
827
-            : [(int) $attendee_ids];
828
-        $ATT_IDs            = implode(',', $attendee_ids);
829
-        // first we do a query to get the registration ids
830
-        // (because a group by before order by causes the order by to be ignored.)
831
-        $registration_id_query = "
16
+	/**
17
+	 * @var EEM_Registration
18
+	 */
19
+	protected static $_instance;
20
+
21
+	/**
22
+	 * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values
23
+	 * are status codes (eg, approved, cancelled, etc)
24
+	 *
25
+	 * @var array
26
+	 */
27
+	private static $_reg_status;
28
+
29
+	/**
30
+	 * The value of REG_count for a primary registrant
31
+	 */
32
+	const PRIMARY_REGISTRANT_COUNT = 1;
33
+
34
+	/**
35
+	 * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration.
36
+	 * Initial status for registrations when they are first created
37
+	 * Payments are NOT allowed.
38
+	 * Automatically toggled to whatever the default Event registration status is upon completion of the attendee
39
+	 * information reg step NO space reserved. Registration is NOT active
40
+	 */
41
+	const status_id_incomplete = 'RIC';
42
+
43
+	/**
44
+	 * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration.
45
+	 * Payments are NOT allowed.
46
+	 * Event Admin must manually toggle STS_ID for it to change
47
+	 * No space reserved.
48
+	 * Registration is active
49
+	 */
50
+	const status_id_not_approved = 'RNA';
51
+
52
+	/**
53
+	 * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT .
54
+	 * Payments are allowed.
55
+	 * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
56
+	 * No space reserved.
57
+	 * Registration is active
58
+	 */
59
+	const status_id_pending_payment = 'RPP';
60
+
61
+	/**
62
+	 * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST .
63
+	 * Payments are allowed.
64
+	 * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
65
+	 * No space reserved.
66
+	 * Registration is active
67
+	 */
68
+	const status_id_wait_list = 'RWL';
69
+
70
+	/**
71
+	 * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration.
72
+	 * the TXN may or may not be completed ( paid in full )
73
+	 * Payments are allowed.
74
+	 * A space IS reserved.
75
+	 * Registration is active
76
+	 */
77
+	const status_id_approved = 'RAP';
78
+
79
+	/**
80
+	 * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee.
81
+	 * Payments are NOT allowed.
82
+	 * NO space reserved.
83
+	 * Registration is NOT active
84
+	 */
85
+	const status_id_cancelled = 'RCN';
86
+
87
+	/**
88
+	 * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin
89
+	 * Payments are NOT allowed.
90
+	 * No space reserved.
91
+	 * Registration is NOT active
92
+	 */
93
+	const status_id_declined = 'RDC';
94
+
95
+	/**
96
+	 * @var TableAnalysis $table_analysis
97
+	 */
98
+	protected $_table_analysis;
99
+
100
+
101
+	/**
102
+	 * private constructor to prevent direct creation
103
+	 *
104
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any
105
+	 *                         incoming timezone data that gets saved). Note this just sends the timezone info to the
106
+	 *                         date time model field objects.  Default is NULL (and will be assumed using the set
107
+	 *                         timezone in the 'timezone_string' wp option)
108
+	 * @throws EE_Error
109
+	 * @throws ReflectionException
110
+	 */
111
+	protected function __construct(string $timezone = '')
112
+	{
113
+		$this->_table_analysis         = EE_Registry::instance()->create('TableAnalysis', [], true);
114
+		$this->singular_item           = esc_html__('Registration', 'event_espresso');
115
+		$this->plural_item             = esc_html__('Registrations', 'event_espresso');
116
+		$this->_tables                 = [
117
+			'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'),
118
+		];
119
+		$this->_fields                 = [
120
+			'Registration' => [
121
+				'REG_ID'           => new EE_Primary_Key_Int_Field(
122
+					'REG_ID',
123
+					esc_html__('Registration ID', 'event_espresso')
124
+				),
125
+				'EVT_ID'           => new EE_Foreign_Key_Int_Field(
126
+					'EVT_ID',
127
+					esc_html__('Event ID', 'event_espresso'),
128
+					false,
129
+					0,
130
+					'Event'
131
+				),
132
+				'ATT_ID'           => new EE_Foreign_Key_Int_Field(
133
+					'ATT_ID',
134
+					esc_html__('Attendee ID', 'event_espresso'),
135
+					false,
136
+					0,
137
+					'Attendee'
138
+				),
139
+				'TXN_ID'           => new EE_Foreign_Key_Int_Field(
140
+					'TXN_ID',
141
+					esc_html__('Transaction ID', 'event_espresso'),
142
+					false,
143
+					0,
144
+					'Transaction'
145
+				),
146
+				'TKT_ID'           => new EE_Foreign_Key_Int_Field(
147
+					'TKT_ID',
148
+					esc_html__('Ticket ID', 'event_espresso'),
149
+					false,
150
+					0,
151
+					'Ticket'
152
+				),
153
+				'STS_ID'           => new EE_Foreign_Key_String_Field(
154
+					'STS_ID',
155
+					esc_html__('Status ID', 'event_espresso'),
156
+					false,
157
+					EEM_Registration::status_id_incomplete,
158
+					'Status'
159
+				),
160
+				'REG_date'         => new EE_Datetime_Field(
161
+					'REG_date',
162
+					esc_html__('Time registration occurred', 'event_espresso'),
163
+					false,
164
+					EE_Datetime_Field::now,
165
+					$timezone
166
+				),
167
+				'REG_final_price'  => new EE_Money_Field(
168
+					'REG_final_price',
169
+					esc_html__('Registration\'s share of the transaction total', 'event_espresso'),
170
+					false,
171
+					0
172
+				),
173
+				'REG_paid'         => new EE_Money_Field(
174
+					'REG_paid',
175
+					esc_html__('Amount paid to date towards registration', 'event_espresso'),
176
+					false,
177
+					0
178
+				),
179
+				'REG_session'      => new EE_Plain_Text_Field(
180
+					'REG_session',
181
+					esc_html__('Session ID of registration', 'event_espresso'),
182
+					false,
183
+					''
184
+				),
185
+				'REG_code'         => new EE_Plain_Text_Field(
186
+					'REG_code',
187
+					esc_html__('Unique Code for this registration', 'event_espresso'),
188
+					false,
189
+					''
190
+				),
191
+				'REG_url_link'     => new EE_Plain_Text_Field(
192
+					'REG_url_link',
193
+					esc_html__('String to be used in URL for identifying registration', 'event_espresso'),
194
+					false,
195
+					''
196
+				),
197
+				'REG_count'        => new EE_Integer_Field(
198
+					'REG_count',
199
+					esc_html__('Count of this registration in the group registration ', 'event_espresso'),
200
+					true,
201
+					1
202
+				),
203
+				'REG_group_size'   => new EE_Integer_Field(
204
+					'REG_group_size',
205
+					esc_html__('Number of registrations on this group', 'event_espresso'),
206
+					false,
207
+					1
208
+				),
209
+				'REG_att_is_going' => new EE_Boolean_Field(
210
+					'REG_att_is_going',
211
+					esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'),
212
+					false,
213
+					false
214
+				),
215
+				'REG_deleted'      => new EE_Trashed_Flag_Field(
216
+					'REG_deleted',
217
+					esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'),
218
+					false,
219
+					false
220
+				),
221
+			],
222
+		];
223
+		$this->_model_relations        = [
224
+			'Event'                => new EE_Belongs_To_Relation(),
225
+			'Attendee'             => new EE_Belongs_To_Relation(),
226
+			'Transaction'          => new EE_Belongs_To_Relation(),
227
+			'Ticket'               => new EE_Belongs_To_Relation(),
228
+			'Status'               => new EE_Belongs_To_Relation(),
229
+			'Answer'               => new EE_Has_Many_Relation(),
230
+			'Checkin'              => new EE_Has_Many_Relation(),
231
+			'Registration_Payment' => new EE_Has_Many_Relation(),
232
+			'Payment'              => new EE_HABTM_Relation('Registration_Payment'),
233
+			'Message'              => new EE_Has_Many_Any_Relation(false)
234
+			// allow deletes even if there are messages in the queue related
235
+		];
236
+		$this->_model_chain_to_wp_user = 'Event';
237
+		parent::__construct($timezone);
238
+	}
239
+
240
+
241
+	/**
242
+	 * a list of ALL valid registration statuses currently in use within the system
243
+	 * generated by combining the filterable active and inactive reg status arrays
244
+	 *
245
+	 * @return array
246
+	 */
247
+	public static function reg_statuses(): array
248
+	{
249
+		return array_unique(
250
+			array_merge(
251
+				EEM_Registration::active_reg_statuses(),
252
+				EEM_Registration::inactive_reg_statuses()
253
+			)
254
+		);
255
+	}
256
+
257
+
258
+	/**
259
+	 * reg_statuses_that_allow_payment
260
+	 * a filterable list of registration statuses that allow a registrant to make a payment
261
+	 *
262
+	 * @return array
263
+	 */
264
+	public static function reg_statuses_that_allow_payment(): array
265
+	{
266
+		return apply_filters(
267
+			'FHEE__EEM_Registration__reg_statuses_that_allow_payment',
268
+			[
269
+				EEM_Registration::status_id_approved,
270
+				EEM_Registration::status_id_pending_payment,
271
+			]
272
+		);
273
+	}
274
+
275
+
276
+	/**
277
+	 * active_reg_statuses
278
+	 * a filterable list of registration statuses that are considered active
279
+	 *
280
+	 * @return array
281
+	 */
282
+	public static function active_reg_statuses(): array
283
+	{
284
+		return apply_filters(
285
+			'FHEE__EEM_Registration__active_reg_statuses',
286
+			[
287
+				EEM_Registration::status_id_approved,
288
+				EEM_Registration::status_id_pending_payment,
289
+				EEM_Registration::status_id_wait_list,
290
+				EEM_Registration::status_id_not_approved,
291
+			]
292
+		);
293
+	}
294
+
295
+
296
+	/**
297
+	 * inactive_reg_statuses
298
+	 * a filterable list of registration statuses that are not considered active
299
+	 *
300
+	 * @return array
301
+	 */
302
+	public static function inactive_reg_statuses(): array
303
+	{
304
+		return apply_filters(
305
+			'FHEE__EEM_Registration__inactive_reg_statuses',
306
+			[
307
+				EEM_Registration::status_id_incomplete,
308
+				EEM_Registration::status_id_cancelled,
309
+				EEM_Registration::status_id_declined,
310
+			]
311
+		);
312
+	}
313
+
314
+
315
+	/**
316
+	 * closed_reg_statuses
317
+	 * a filterable list of registration statuses that are considered "closed"
318
+	 * meaning they should not be considered in any calculations involving monies owing
319
+	 *
320
+	 * @return array
321
+	 */
322
+	public static function closed_reg_statuses(): array
323
+	{
324
+		return apply_filters(
325
+			'FHEE__EEM_Registration__closed_reg_statuses',
326
+			[
327
+				EEM_Registration::status_id_cancelled,
328
+				EEM_Registration::status_id_declined,
329
+				EEM_Registration::status_id_wait_list,
330
+			]
331
+		);
332
+	}
333
+
334
+
335
+	/**
336
+	 * get list of registration statuses
337
+	 *
338
+	 * @param array $exclude    The status ids to exclude from the returned results
339
+	 * @param bool  $translated If true will return the values as singular localized strings
340
+	 * @return array
341
+	 * @throws EE_Error
342
+	 */
343
+	public static function reg_status_array(array $exclude = [], bool $translated = false): array
344
+	{
345
+		EEM_Registration::instance()->_get_registration_status_array($exclude);
346
+		return $translated
347
+			? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence')
348
+			: self::$_reg_status;
349
+	}
350
+
351
+
352
+	/**
353
+	 * get list of registration statuses
354
+	 *
355
+	 * @access private
356
+	 * @param array $exclude
357
+	 * @return void
358
+	 * @throws EE_Error
359
+	 */
360
+	private function _get_registration_status_array(array $exclude = [])
361
+	{
362
+		// in the very rare circumstance that we are deleting a model's table's data
363
+		// and the table hasn't actually been created, this could have an error
364
+		global $wpdb;
365
+		if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) {
366
+			$results           = $wpdb->get_results(
367
+				"SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'"
368
+			);
369
+			self::$_reg_status = [];
370
+			foreach ($results as $status) {
371
+				if (! in_array($status->STS_ID, $exclude, true)) {
372
+					self::$_reg_status[ $status->STS_ID ] = $status->STS_code;
373
+				}
374
+			}
375
+		}
376
+	}
377
+
378
+
379
+	/**
380
+	 * Gets the injected table analyzer, or throws an exception
381
+	 *
382
+	 * @return TableAnalysis
383
+	 * @throws EE_Error
384
+	 */
385
+	protected function _get_table_analysis(): TableAnalysis
386
+	{
387
+		if ($this->_table_analysis instanceof TableAnalysis) {
388
+			return $this->_table_analysis;
389
+		}
390
+		throw new EE_Error(
391
+			sprintf(
392
+				esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
393
+				get_class($this)
394
+			)
395
+		);
396
+	}
397
+
398
+
399
+	/**
400
+	 * This returns a wpdb->results array of all registration date month and years matching the incoming query params
401
+	 * and grouped by month and year.
402
+	 *
403
+	 * @param array $where_params @see
404
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
405
+	 * @return array
406
+	 * @throws EE_Error
407
+	 * @throws ReflectionException
408
+	 */
409
+	public function get_reg_months_and_years(array $where_params): array
410
+	{
411
+		$query_params[0]          = $where_params;
412
+		$query_params['group_by'] = ['reg_year', 'reg_month'];
413
+		$query_params['order_by'] = ['REG_date' => 'DESC'];
414
+		$columns_to_select        = [
415
+			'reg_year'  => ['YEAR(REG_date)', '%s'],
416
+			'reg_month' => ['MONTHNAME(REG_date)', '%s'],
417
+		];
418
+		return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
419
+	}
420
+
421
+
422
+	/**
423
+	 * retrieve ALL registrations for a particular Attendee from db
424
+	 *
425
+	 * @param int $ATT_ID
426
+	 * @return EE_Registration[]
427
+	 * @throws EE_Error
428
+	 * @throws ReflectionException
429
+	 */
430
+	public function get_all_registrations_for_attendee(int $ATT_ID = 0): array
431
+	{
432
+		if (! $ATT_ID) {
433
+			return [];
434
+		}
435
+		return $this->get_all([['ATT_ID' => $ATT_ID]]);
436
+	}
437
+
438
+
439
+	/**
440
+	 * Gets a registration given their REG_url_link. Yes, this should usually
441
+	 * be passed via a GET parameter.
442
+	 *
443
+	 * @param string $REG_url_link
444
+	 * @return EE_Registration|null
445
+	 * @throws EE_Error
446
+	 * @throws ReflectionException
447
+	 */
448
+	public function get_registration_for_reg_url_link(string $REG_url_link): ?EE_Registration
449
+	{
450
+		if (! $REG_url_link) {
451
+			return null;
452
+		}
453
+		return $this->get_one([['REG_url_link' => $REG_url_link]]);
454
+	}
455
+
456
+
457
+	/**
458
+	 * retrieve registration for a specific transaction attendee from db
459
+	 *
460
+	 * @param int $TXN_ID
461
+	 * @param int $ATT_ID
462
+	 * @param int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the
463
+	 *                      attendee number is required
464
+	 * @return EE_Registration|null
465
+	 * @throws EE_Error
466
+	 * @throws ReflectionException
467
+	 */
468
+	public function get_registration_for_transaction_attendee(
469
+		int $TXN_ID = 0,
470
+		int $ATT_ID = 0,
471
+		int $att_nmbr = 0
472
+	): ?EE_Registration {
473
+		return $this->get_one(
474
+			[
475
+				[
476
+					'TXN_ID' => $TXN_ID,
477
+					'ATT_ID' => $ATT_ID,
478
+				],
479
+				'limit' => [min($att_nmbr - 1, 0), 1],
480
+			]
481
+		);
482
+	}
483
+
484
+
485
+	/**
486
+	 * get the number of registrations per day  for the Registration Admin page Reports Tab.
487
+	 * (doesn't utilize models because it's a fairly specialized query)
488
+	 *
489
+	 * @param $period string which can be passed to php's strtotime function (eg "-1 month")
490
+	 * @return stdClass[] with properties regDate and total
491
+	 * @throws EE_Error
492
+	 * @throws ReflectionException
493
+	 */
494
+	public function get_registrations_per_day_report(string $period = '-1 month'): array
495
+	{
496
+		$sql_date = $this->convert_datetime_for_query(
497
+			'REG_date',
498
+			date('Y-m-d H:i:s', strtotime($period)),
499
+			'Y-m-d H:i:s',
500
+			'UTC'
501
+		);
502
+		$where    = [
503
+			'REG_date' => ['>=', $sql_date],
504
+			'STS_ID'   => ['!=', EEM_Registration::status_id_incomplete],
505
+		];
506
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
507
+			$where['Event.EVT_wp_user'] = get_current_user_id();
508
+		}
509
+		$query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
510
+		return $this->_get_all_wpdb_results(
511
+			[
512
+				$where,
513
+				'group_by' => 'regDate',
514
+				'order_by' => ['REG_date' => 'ASC'],
515
+			],
516
+			OBJECT,
517
+			[
518
+				'regDate' => ['DATE(' . $query_interval . ')', '%s'],
519
+				'total'   => ['count(REG_ID)', '%d'],
520
+			]
521
+		);
522
+	}
523
+
524
+
525
+	/**
526
+	 * Get the number of registrations per day including the count of registrations for each Registration Status.
527
+	 * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
528
+	 *
529
+	 * @param string $period
530
+	 * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID
531
+	 * @throws EE_Error
532
+	 * (i.e. RAP)
533
+	 */
534
+	public function get_registrations_per_day_and_per_status_report(string $period = '-1 month'): array
535
+	{
536
+		global $wpdb;
537
+		$registration_table = $wpdb->prefix . 'esp_registration';
538
+		$event_table        = $wpdb->posts;
539
+		$sql_date           = date('Y-m-d H:i:s', strtotime($period));
540
+		// prepare the query interval for displaying offset
541
+		$query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date');
542
+		// inner date query
543
+		$inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
544
+		$inner_where      = ' WHERE';
545
+		// exclude events not authored by user if permissions in effect
546
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
547
+			$inner_date_query .= "LEFT JOIN $event_table ON ID = EVT_ID";
548
+			$inner_where      .= ' post_author = ' . get_current_user_id() . ' AND';
549
+		}
550
+		$inner_where      .= " REG_date >= '{$sql_date}'";
551
+		$inner_date_query .= $inner_where;
552
+		// start main query
553
+		$select       = "SELECT DATE({$query_interval}) as Registration_REG_date, ";
554
+		$join         = '';
555
+		$join_parts   = [];
556
+		$select_parts = [];
557
+		// loop through registration statuses to do parts for each status.
558
+		foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
559
+			if ($STS_ID === EEM_Registration::status_id_incomplete) {
560
+				continue;
561
+			}
562
+			$select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
563
+			$join_parts[]
564
+							= "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'";
565
+		}
566
+		// setup the selects
567
+		$select .= implode(', ', $select_parts);
568
+		$select .= " FROM ($inner_date_query) AS dates LEFT JOIN ";
569
+		// setup the joins
570
+		$join .= implode(' LEFT JOIN ', $join_parts);
571
+		// now let's put it all together
572
+		$query = $select . $join . ' GROUP BY Registration_REG_date';
573
+		// and execute it
574
+		return $wpdb->get_results($query, ARRAY_A);
575
+	}
576
+
577
+
578
+	/**
579
+	 * get the number of registrations per event  for the Registration Admin page Reports Tab
580
+	 *
581
+	 * @param $period string which can be passed to php's strtotime function (eg "-1 month")
582
+	 * @return stdClass[] each with properties event_name, reg_limit, and total
583
+	 * @throws EE_Error
584
+	 * @throws ReflectionException
585
+	 */
586
+	public function get_registrations_per_event_report(string $period = '-1 month'): array
587
+	{
588
+		$date_sql = $this->convert_datetime_for_query(
589
+			'REG_date',
590
+			date('Y-m-d H:i:s', strtotime($period)),
591
+			'Y-m-d H:i:s',
592
+			'UTC'
593
+		);
594
+		$where    = [
595
+			'REG_date' => ['>=', $date_sql],
596
+			'STS_ID'   => ['!=', EEM_Registration::status_id_incomplete],
597
+		];
598
+		if (
599
+		! EE_Registry::instance()->CAP->current_user_can(
600
+			'ee_read_others_registrations',
601
+			'reg_per_event_report'
602
+		)
603
+		) {
604
+			$where['Event.EVT_wp_user'] = get_current_user_id();
605
+		}
606
+		return $this->_get_all_wpdb_results(
607
+			[
608
+				$where,
609
+				'group_by' => 'Event.EVT_name',
610
+				'order_by' => 'Event.EVT_name',
611
+				'limit'    => [0, 24],
612
+			],
613
+			OBJECT,
614
+			[
615
+				'event_name' => ['Event_CPT.post_title', '%s'],
616
+				'total'      => ['COUNT(REG_ID)', '%s'],
617
+			]
618
+		);
619
+	}
620
+
621
+
622
+	/**
623
+	 * Get the number of registrations per event grouped by registration status.
624
+	 * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
625
+	 *
626
+	 * @param string $period
627
+	 * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID
628
+	 * @throws EE_Error
629
+	 * (i.e. RAP)
630
+	 */
631
+	public function get_registrations_per_event_and_per_status_report(string $period = '-1 month'): array
632
+	{
633
+		global $wpdb;
634
+		$registration_table = $wpdb->prefix . 'esp_registration';
635
+		$event_table        = $wpdb->posts;
636
+		$sql_date           = date('Y-m-d H:i:s', strtotime($period));
637
+		// inner date query
638
+		$inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table ";
639
+		$inner_where      = ' WHERE';
640
+		// exclude events not authored by user if permissions in effect
641
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
642
+			$inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
643
+			$inner_where      .= ' post_author = ' . get_current_user_id() . ' AND';
644
+		}
645
+		$inner_where      .= " REG_date >= '{$sql_date}'";
646
+		$inner_date_query .= $inner_where;
647
+		// build main query
648
+		$select       = 'SELECT Event.post_title as Registration_Event, ';
649
+		$join         = '';
650
+		$join_parts   = [];
651
+		$select_parts = [];
652
+		// loop through registration statuses to do parts for each status.
653
+		foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
654
+			if ($STS_ID === EEM_Registration::status_id_incomplete) {
655
+				continue;
656
+			}
657
+			$select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
658
+			$join_parts[]
659
+							= "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date";
660
+		}
661
+		// setup the selects
662
+		$select .= implode(', ', $select_parts);
663
+		$select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN ";
664
+		// setup remaining joins
665
+		$join .= implode(' LEFT JOIN ', $join_parts);
666
+		// now put it all together
667
+		$query = $select . $join . ' GROUP BY Registration_Event';
668
+		// and execute
669
+		return $wpdb->get_results($query, ARRAY_A);
670
+	}
671
+
672
+
673
+	/**
674
+	 * Returns the EE_Registration of the primary attendee on the transaction id provided
675
+	 *
676
+	 * @param int $TXN_ID
677
+	 * @return EE_Registration|null
678
+	 * @throws EE_Error
679
+	 * @throws ReflectionException
680
+	 */
681
+	public function get_primary_registration_for_transaction_ID(int $TXN_ID = 0): ?EE_Registration
682
+	{
683
+		if (! $TXN_ID) {
684
+			return null;
685
+		}
686
+		return $this->get_one(
687
+			[
688
+				[
689
+					'TXN_ID'    => $TXN_ID,
690
+					'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT,
691
+				],
692
+			]
693
+		);
694
+	}
695
+
696
+
697
+	/**
698
+	 * get_event_registration_count
699
+	 *
700
+	 * @param int     $EVT_ID
701
+	 * @param boolean $for_incomplete_payments
702
+	 * @return int
703
+	 * @throws EE_Error
704
+	 * @throws ReflectionException
705
+	 */
706
+	public function get_event_registration_count(int $EVT_ID, bool $for_incomplete_payments = false): int
707
+	{
708
+		// we only count approved registrations towards registration limits
709
+		$query_params = [['EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved]];
710
+		if ($for_incomplete_payments) {
711
+			$query_params[0]['Transaction.STS_ID'] = ['!=', EEM_Transaction::complete_status_code];
712
+		}
713
+		return $this->count($query_params);
714
+	}
715
+
716
+
717
+	/**
718
+	 * Deletes all registrations with no transactions. Note that this needs to be very efficient
719
+	 * and so it uses wpdb directly. Also, we can't put a limit on this because MySQL doesn't allow a limit on a delete
720
+	 * when joining tables like this.
721
+	 *
722
+	 * @return int number deleted
723
+	 * @throws EE_Error
724
+	 * @global WPDB $wpdb
725
+	 */
726
+	public function delete_registrations_with_no_transaction(): int
727
+	{
728
+		global $wpdb;
729
+		return $wpdb->query(
730
+			'DELETE r FROM '
731
+			. $this->table()
732
+			. ' r LEFT JOIN '
733
+			. EEM_Transaction::instance()->table()
734
+			. ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL'
735
+		);
736
+	}
737
+
738
+
739
+	/**
740
+	 * Count registrations checked into (or out of) a datetime
741
+	 *
742
+	 * @param int     $DTT_ID     datetime ID
743
+	 * @param boolean $checked_in whether to count registrations checked IN or OUT
744
+	 * @return int
745
+	 * @throws EE_Error
746
+	 */
747
+	public function count_registrations_checked_into_datetime(int $DTT_ID, bool $checked_in = true): int
748
+	{
749
+		global $wpdb;
750
+		// subquery to get latest checkin
751
+		$query = $wpdb->prepare(
752
+			'SELECT '
753
+			. 'COUNT( DISTINCT checkins.REG_ID ) '
754
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
755
+			. '( SELECT '
756
+			. 'max( CHK_timestamp ) AS latest_checkin, '
757
+			. 'REG_ID AS REG_ID '
758
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' '
759
+			. 'WHERE DTT_ID=%d '
760
+			. 'GROUP BY REG_ID'
761
+			. ') AS most_recent_checkin_per_reg '
762
+			. 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
763
+			. 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
764
+			. 'WHERE '
765
+			. 'checkins.CHK_in=%d',
766
+			$DTT_ID,
767
+			$checked_in
768
+		);
769
+		return (int) $wpdb->get_var($query);
770
+	}
771
+
772
+
773
+	/**
774
+	 * Count registrations checked into (or out of) an event.
775
+	 *
776
+	 * @param int     $EVT_ID     event ID
777
+	 * @param boolean $checked_in whether to count registrations checked IN or OUT
778
+	 * @return int
779
+	 * @throws EE_Error
780
+	 */
781
+	public function count_registrations_checked_into_event(int $EVT_ID, bool $checked_in = true): int
782
+	{
783
+		global $wpdb;
784
+		// subquery to get latest checkin
785
+		$query = $wpdb->prepare(
786
+			'SELECT '
787
+			. 'COUNT( DISTINCT checkins.REG_ID ) '
788
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
789
+			. '( SELECT '
790
+			. 'max( CHK_timestamp ) AS latest_checkin, '
791
+			. 'REG_ID AS REG_ID '
792
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' AS c '
793
+			. 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d '
794
+			. 'ON c.DTT_ID=d.DTT_ID '
795
+			. 'WHERE d.EVT_ID=%d '
796
+			. 'GROUP BY REG_ID'
797
+			. ') AS most_recent_checkin_per_reg '
798
+			. 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
799
+			. 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
800
+			. 'WHERE '
801
+			. 'checkins.CHK_in=%d',
802
+			$EVT_ID,
803
+			$checked_in
804
+		);
805
+		return (int) $wpdb->get_var($query);
806
+	}
807
+
808
+
809
+	/**
810
+	 * The purpose of this method is to retrieve an array of
811
+	 * EE_Registration objects that represent the latest registration
812
+	 * for each ATT_ID given in the function argument.
813
+	 *
814
+	 * @param array $attendee_ids
815
+	 * @return EE_Registration[]
816
+	 * @throws EE_Error
817
+	 * @throws ReflectionException
818
+	 */
819
+	public function get_latest_registration_for_each_of_given_contacts(array $attendee_ids = []): array
820
+	{
821
+		// first do a native wp_query to get the latest REG_ID's matching these attendees.
822
+		global $wpdb;
823
+		$registration_table = $wpdb->prefix . 'esp_registration';
824
+		$attendee_table     = $wpdb->posts;
825
+		$attendee_ids       = is_array($attendee_ids)
826
+			? array_map('absint', $attendee_ids)
827
+			: [(int) $attendee_ids];
828
+		$ATT_IDs            = implode(',', $attendee_ids);
829
+		// first we do a query to get the registration ids
830
+		// (because a group by before order by causes the order by to be ignored.)
831
+		$registration_id_query = "
832 832
 			SELECT registrations.registration_ids as registration_id
833 833
 			FROM (
834 834
 				SELECT
@@ -842,61 +842,61 @@  discard block
 block discarded – undo
842 842
 			  ) AS registrations
843 843
 			  GROUP BY registrations.attendee_ids
844 844
 		";
845
-        $registration_ids      = $wpdb->get_results($registration_id_query, ARRAY_A);
846
-        if (empty($registration_ids)) {
847
-            return [];
848
-        }
849
-        $ids_for_model_query = [];
850
-        // let's flatten the ids so they can be used in the model query.
851
-        foreach ($registration_ids as $registration_id) {
852
-            if (isset($registration_id['registration_id'])) {
853
-                $ids_for_model_query[] = $registration_id['registration_id'];
854
-            }
855
-        }
856
-        // construct query
857
-        $_where = [
858
-            'REG_ID' => ['IN', $ids_for_model_query],
859
-        ];
860
-        return $this->get_all([$_where]);
861
-    }
862
-
863
-
864
-    /**
865
-     * returns a count of registrations for the supplied event having the status as specified
866
-     *
867
-     * @param int   $EVT_ID
868
-     * @param array $statuses
869
-     * @return int
870
-     * @throws InvalidArgumentException
871
-     * @throws InvalidStatusException
872
-     * @throws EE_Error
873
-     * @throws ReflectionException
874
-     */
875
-    public function event_reg_count_for_statuses(int $EVT_ID, array $statuses = []): int
876
-    {
877
-        $EVT_ID = absint($EVT_ID);
878
-        if (! $EVT_ID) {
879
-            throw new InvalidArgumentException(
880
-                esc_html__('An invalid Event ID was supplied.', 'event_espresso')
881
-            );
882
-        }
883
-        $statuses           = is_array($statuses) ? $statuses : [$statuses];
884
-        $statuses           = ! empty($statuses) ? $statuses : [EEM_Registration::status_id_approved];
885
-        $valid_reg_statuses = EEM_Registration::reg_statuses();
886
-        foreach ($statuses as $status) {
887
-            if (! in_array($status, $valid_reg_statuses, true)) {
888
-                throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso'));
889
-            }
890
-        }
891
-        return $this->count(
892
-            [
893
-                [
894
-                    'EVT_ID' => $EVT_ID,
895
-                    'STS_ID' => ['IN', $statuses],
896
-                ],
897
-            ],
898
-            'REG_ID',
899
-            true
900
-        );
901
-    }
845
+		$registration_ids      = $wpdb->get_results($registration_id_query, ARRAY_A);
846
+		if (empty($registration_ids)) {
847
+			return [];
848
+		}
849
+		$ids_for_model_query = [];
850
+		// let's flatten the ids so they can be used in the model query.
851
+		foreach ($registration_ids as $registration_id) {
852
+			if (isset($registration_id['registration_id'])) {
853
+				$ids_for_model_query[] = $registration_id['registration_id'];
854
+			}
855
+		}
856
+		// construct query
857
+		$_where = [
858
+			'REG_ID' => ['IN', $ids_for_model_query],
859
+		];
860
+		return $this->get_all([$_where]);
861
+	}
862
+
863
+
864
+	/**
865
+	 * returns a count of registrations for the supplied event having the status as specified
866
+	 *
867
+	 * @param int   $EVT_ID
868
+	 * @param array $statuses
869
+	 * @return int
870
+	 * @throws InvalidArgumentException
871
+	 * @throws InvalidStatusException
872
+	 * @throws EE_Error
873
+	 * @throws ReflectionException
874
+	 */
875
+	public function event_reg_count_for_statuses(int $EVT_ID, array $statuses = []): int
876
+	{
877
+		$EVT_ID = absint($EVT_ID);
878
+		if (! $EVT_ID) {
879
+			throw new InvalidArgumentException(
880
+				esc_html__('An invalid Event ID was supplied.', 'event_espresso')
881
+			);
882
+		}
883
+		$statuses           = is_array($statuses) ? $statuses : [$statuses];
884
+		$statuses           = ! empty($statuses) ? $statuses : [EEM_Registration::status_id_approved];
885
+		$valid_reg_statuses = EEM_Registration::reg_statuses();
886
+		foreach ($statuses as $status) {
887
+			if (! in_array($status, $valid_reg_statuses, true)) {
888
+				throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso'));
889
+			}
890
+		}
891
+		return $this->count(
892
+			[
893
+				[
894
+					'EVT_ID' => $EVT_ID,
895
+					'STS_ID' => ['IN', $statuses],
896
+				],
897
+			],
898
+			'REG_ID',
899
+			true
900
+		);
901
+	}
902 902
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
                 ),
221 221
             ],
222 222
         ];
223
-        $this->_model_relations        = [
223
+        $this->_model_relations = [
224 224
             'Event'                => new EE_Belongs_To_Relation(),
225 225
             'Attendee'             => new EE_Belongs_To_Relation(),
226 226
             'Transaction'          => new EE_Belongs_To_Relation(),
@@ -362,14 +362,14 @@  discard block
 block discarded – undo
362 362
         // in the very rare circumstance that we are deleting a model's table's data
363 363
         // and the table hasn't actually been created, this could have an error
364 364
         global $wpdb;
365
-        if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) {
365
+        if ($this->_get_table_analysis()->tableExists($wpdb->prefix.'esp_status')) {
366 366
             $results           = $wpdb->get_results(
367 367
                 "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'"
368 368
             );
369 369
             self::$_reg_status = [];
370 370
             foreach ($results as $status) {
371
-                if (! in_array($status->STS_ID, $exclude, true)) {
372
-                    self::$_reg_status[ $status->STS_ID ] = $status->STS_code;
371
+                if ( ! in_array($status->STS_ID, $exclude, true)) {
372
+                    self::$_reg_status[$status->STS_ID] = $status->STS_code;
373 373
                 }
374 374
             }
375 375
         }
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
      */
430 430
     public function get_all_registrations_for_attendee(int $ATT_ID = 0): array
431 431
     {
432
-        if (! $ATT_ID) {
432
+        if ( ! $ATT_ID) {
433 433
             return [];
434 434
         }
435 435
         return $this->get_all([['ATT_ID' => $ATT_ID]]);
@@ -447,7 +447,7 @@  discard block
 block discarded – undo
447 447
      */
448 448
     public function get_registration_for_reg_url_link(string $REG_url_link): ?EE_Registration
449 449
     {
450
-        if (! $REG_url_link) {
450
+        if ( ! $REG_url_link) {
451 451
             return null;
452 452
         }
453 453
         return $this->get_one([['REG_url_link' => $REG_url_link]]);
@@ -499,11 +499,11 @@  discard block
 block discarded – undo
499 499
             'Y-m-d H:i:s',
500 500
             'UTC'
501 501
         );
502
-        $where    = [
502
+        $where = [
503 503
             'REG_date' => ['>=', $sql_date],
504 504
             'STS_ID'   => ['!=', EEM_Registration::status_id_incomplete],
505 505
         ];
506
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
506
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
507 507
             $where['Event.EVT_wp_user'] = get_current_user_id();
508 508
         }
509 509
         $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
@@ -515,7 +515,7 @@  discard block
 block discarded – undo
515 515
             ],
516 516
             OBJECT,
517 517
             [
518
-                'regDate' => ['DATE(' . $query_interval . ')', '%s'],
518
+                'regDate' => ['DATE('.$query_interval.')', '%s'],
519 519
                 'total'   => ['count(REG_ID)', '%d'],
520 520
             ]
521 521
         );
@@ -534,7 +534,7 @@  discard block
 block discarded – undo
534 534
     public function get_registrations_per_day_and_per_status_report(string $period = '-1 month'): array
535 535
     {
536 536
         global $wpdb;
537
-        $registration_table = $wpdb->prefix . 'esp_registration';
537
+        $registration_table = $wpdb->prefix.'esp_registration';
538 538
         $event_table        = $wpdb->posts;
539 539
         $sql_date           = date('Y-m-d H:i:s', strtotime($period));
540 540
         // prepare the query interval for displaying offset
@@ -543,9 +543,9 @@  discard block
 block discarded – undo
543 543
         $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
544 544
         $inner_where      = ' WHERE';
545 545
         // exclude events not authored by user if permissions in effect
546
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
546
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
547 547
             $inner_date_query .= "LEFT JOIN $event_table ON ID = EVT_ID";
548
-            $inner_where      .= ' post_author = ' . get_current_user_id() . ' AND';
548
+            $inner_where      .= ' post_author = '.get_current_user_id().' AND';
549 549
         }
550 550
         $inner_where      .= " REG_date >= '{$sql_date}'";
551 551
         $inner_date_query .= $inner_where;
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
         // setup the joins
570 570
         $join .= implode(' LEFT JOIN ', $join_parts);
571 571
         // now let's put it all together
572
-        $query = $select . $join . ' GROUP BY Registration_REG_date';
572
+        $query = $select.$join.' GROUP BY Registration_REG_date';
573 573
         // and execute it
574 574
         return $wpdb->get_results($query, ARRAY_A);
575 575
     }
@@ -591,7 +591,7 @@  discard block
 block discarded – undo
591 591
             'Y-m-d H:i:s',
592 592
             'UTC'
593 593
         );
594
-        $where    = [
594
+        $where = [
595 595
             'REG_date' => ['>=', $date_sql],
596 596
             'STS_ID'   => ['!=', EEM_Registration::status_id_incomplete],
597 597
         ];
@@ -631,16 +631,16 @@  discard block
 block discarded – undo
631 631
     public function get_registrations_per_event_and_per_status_report(string $period = '-1 month'): array
632 632
     {
633 633
         global $wpdb;
634
-        $registration_table = $wpdb->prefix . 'esp_registration';
634
+        $registration_table = $wpdb->prefix.'esp_registration';
635 635
         $event_table        = $wpdb->posts;
636 636
         $sql_date           = date('Y-m-d H:i:s', strtotime($period));
637 637
         // inner date query
638 638
         $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table ";
639 639
         $inner_where      = ' WHERE';
640 640
         // exclude events not authored by user if permissions in effect
641
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
641
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
642 642
             $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
643
-            $inner_where      .= ' post_author = ' . get_current_user_id() . ' AND';
643
+            $inner_where      .= ' post_author = '.get_current_user_id().' AND';
644 644
         }
645 645
         $inner_where      .= " REG_date >= '{$sql_date}'";
646 646
         $inner_date_query .= $inner_where;
@@ -664,7 +664,7 @@  discard block
 block discarded – undo
664 664
         // setup remaining joins
665 665
         $join .= implode(' LEFT JOIN ', $join_parts);
666 666
         // now put it all together
667
-        $query = $select . $join . ' GROUP BY Registration_Event';
667
+        $query = $select.$join.' GROUP BY Registration_Event';
668 668
         // and execute
669 669
         return $wpdb->get_results($query, ARRAY_A);
670 670
     }
@@ -680,7 +680,7 @@  discard block
 block discarded – undo
680 680
      */
681 681
     public function get_primary_registration_for_transaction_ID(int $TXN_ID = 0): ?EE_Registration
682 682
     {
683
-        if (! $TXN_ID) {
683
+        if ( ! $TXN_ID) {
684 684
             return null;
685 685
         }
686 686
         return $this->get_one(
@@ -751,11 +751,11 @@  discard block
 block discarded – undo
751 751
         $query = $wpdb->prepare(
752 752
             'SELECT '
753 753
             . 'COUNT( DISTINCT checkins.REG_ID ) '
754
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
754
+            . 'FROM '.EEM_Checkin::instance()->table().' AS checkins INNER JOIN'
755 755
             . '( SELECT '
756 756
             . 'max( CHK_timestamp ) AS latest_checkin, '
757 757
             . 'REG_ID AS REG_ID '
758
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' '
758
+            . 'FROM '.EEM_Checkin::instance()->table().' '
759 759
             . 'WHERE DTT_ID=%d '
760 760
             . 'GROUP BY REG_ID'
761 761
             . ') AS most_recent_checkin_per_reg '
@@ -785,12 +785,12 @@  discard block
 block discarded – undo
785 785
         $query = $wpdb->prepare(
786 786
             'SELECT '
787 787
             . 'COUNT( DISTINCT checkins.REG_ID ) '
788
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
788
+            . 'FROM '.EEM_Checkin::instance()->table().' AS checkins INNER JOIN'
789 789
             . '( SELECT '
790 790
             . 'max( CHK_timestamp ) AS latest_checkin, '
791 791
             . 'REG_ID AS REG_ID '
792
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c '
793
-            . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d '
792
+            . 'FROM '.EEM_Checkin::instance()->table().' AS c '
793
+            . 'INNER JOIN '.EEM_Datetime::instance()->table().' AS d '
794 794
             . 'ON c.DTT_ID=d.DTT_ID '
795 795
             . 'WHERE d.EVT_ID=%d '
796 796
             . 'GROUP BY REG_ID'
@@ -820,7 +820,7 @@  discard block
 block discarded – undo
820 820
     {
821 821
         // first do a native wp_query to get the latest REG_ID's matching these attendees.
822 822
         global $wpdb;
823
-        $registration_table = $wpdb->prefix . 'esp_registration';
823
+        $registration_table = $wpdb->prefix.'esp_registration';
824 824
         $attendee_table     = $wpdb->posts;
825 825
         $attendee_ids       = is_array($attendee_ids)
826 826
             ? array_map('absint', $attendee_ids)
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
 			  ) AS registrations
843 843
 			  GROUP BY registrations.attendee_ids
844 844
 		";
845
-        $registration_ids      = $wpdb->get_results($registration_id_query, ARRAY_A);
845
+        $registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A);
846 846
         if (empty($registration_ids)) {
847 847
             return [];
848 848
         }
@@ -875,7 +875,7 @@  discard block
 block discarded – undo
875 875
     public function event_reg_count_for_statuses(int $EVT_ID, array $statuses = []): int
876 876
     {
877 877
         $EVT_ID = absint($EVT_ID);
878
-        if (! $EVT_ID) {
878
+        if ( ! $EVT_ID) {
879 879
             throw new InvalidArgumentException(
880 880
                 esc_html__('An invalid Event ID was supplied.', 'event_espresso')
881 881
             );
@@ -884,7 +884,7 @@  discard block
 block discarded – undo
884 884
         $statuses           = ! empty($statuses) ? $statuses : [EEM_Registration::status_id_approved];
885 885
         $valid_reg_statuses = EEM_Registration::reg_statuses();
886 886
         foreach ($statuses as $status) {
887
-            if (! in_array($status, $valid_reg_statuses, true)) {
887
+            if ( ! in_array($status, $valid_reg_statuses, true)) {
888 888
                 throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso'));
889 889
             }
890 890
         }
Please login to merge, or discard this patch.
core/db_models/EEM_Soft_Delete_Base.model.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -330,7 +330,7 @@
 block discarded – undo
330 330
      * this function will ignore whether the items have been soft-deleted or not.
331 331
      *
332 332
      * @param boolean    $delete true for delete, false for restore
333
-     * @param int|string $ID     int if primary key is an int, string otherwise
333
+     * @param integer $ID     int if primary key is an int, string otherwise
334 334
      * @return boolean
335 335
      * @throws EE_Error
336 336
      * @throws ReflectionException
Please login to merge, or discard this patch.
Indentation   +398 added lines, -398 removed lines patch added patch discarded remove patch
@@ -27,402 +27,402 @@
 block discarded – undo
27 27
 abstract class EEM_Soft_Delete_Base extends EEM_Base
28 28
 {
29 29
 
30
-    /**
31
-     * @param string $timezone
32
-     * @throws EE_Error
33
-     */
34
-    protected function __construct(string $timezone = '')
35
-    {
36
-        if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
37
-            $this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions();
38
-        }
39
-        parent::__construct($timezone);
40
-    }
41
-
42
-
43
-    /**
44
-     * Searches for field on this model of type 'deleted_flag'. if it is found,
45
-     * returns it's name.
46
-     *
47
-     * @return string
48
-     * @throws EE_Error
49
-     */
50
-    public function deleted_field_name()
51
-    {
52
-        $field = $this->get_a_field_of_type('EE_Trashed_Flag_Field');
53
-        if ($field) {
54
-            return $field->get_name();
55
-        } else {
56
-            throw new EE_Error(
57
-                sprintf(
58
-                    esc_html__(
59
-                        'We are trying to find the deleted flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
60
-                        'event_espresso'
61
-                    ),
62
-                    get_class($this),
63
-                    get_class($this)
64
-                )
65
-            );
66
-        }
67
-    }
68
-
69
-
70
-    /**
71
-     * Gets one item that's been deleted, according to $query_params
72
-     *
73
-     * @param array $query_params @see
74
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
75
-     * @return EE_Soft_Delete_Base_Class
76
-     * @throws EE_Error
77
-     * @throws ReflectionException
78
-     */
79
-    public function get_one_deleted(array $query_params = []): EE_Soft_Delete_Base_Class
80
-    {
81
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
82
-        return parent::get_one($query_params);
83
-    }
84
-
85
-
86
-    /**
87
-     * Gets one item from the DB, regardless of whether it's been soft-deleted or not
88
-     *
89
-     * @param array $query_params like EEM_base::get_all's $query_params
90
-     * @return EE_Soft_Delete_Base_Class
91
-     * @throws EE_Error
92
-     * @throws ReflectionException
93
-     */
94
-    public function get_one_deleted_or_undeleted(array $query_params = []): EE_Soft_Delete_Base_Class
95
-    {
96
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
97
-        return parent::get_one($query_params);
98
-    }
99
-
100
-
101
-    /**
102
-     * Gets the item indicated by its ID. But if it's soft-deleted, pretends it doesn't exist.
103
-     *
104
-     * @param int|string $id
105
-     * @return EE_Soft_Delete_Base_Class
106
-     * @throws EE_Error
107
-     * @throws ReflectionException
108
-     */
109
-    public function get_one_by_ID_but_ignore_deleted($id): EE_Soft_Delete_Base_Class
110
-    {
111
-        return $this->get_one(
112
-            $this->alter_query_params_to_restrict_by_ID(
113
-                $id,
114
-                ['default_where_conditions' => 'default']
115
-            )
116
-        );
117
-    }
118
-
119
-
120
-    /**
121
-     * Counts all the deleted/trashed items
122
-     *
123
-     * @param array  $query_params @see
124
-     *                             https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
125
-     * @param string $field_to_count
126
-     * @param bool   $distinct     if we want to only count the distinct values for the column
127
-     *                             then you can trigger that by the setting $distinct to TRUE;
128
-     * @return int
129
-     * @throws EE_Error
130
-     * @throws ReflectionException
131
-     */
132
-    public function count_deleted(array $query_params = [], string $field_to_count = '', bool $distinct = false): int
133
-    {
134
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
135
-        return parent::count($query_params, $field_to_count, $distinct);
136
-    }
137
-
138
-
139
-    /**
140
-     * Alters the query params so that only trashed/soft-deleted items are considered
141
-     *
142
-     * @param array $query_params @see
143
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
144
-     * @return array @see
145
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
146
-     * @throws EE_Error
147
-     */
148
-    protected function _alter_query_params_so_only_trashed_items_included(array $query_params): array
149
-    {
150
-        $deletedFlagFieldName                     = $this->deleted_field_name();
151
-        $query_params[0][ $deletedFlagFieldName ] = true;
152
-        return $query_params;
153
-    }
154
-
155
-
156
-    /**
157
-     * Alters the query params so that only trashed/soft-deleted items are considered
158
-     *
159
-     * @param array $query_params @see
160
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
161
-     * @return array @see
162
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
163
-     * @throws EE_Error
164
-     */
165
-    public function alter_query_params_so_only_trashed_items_included(array $query_params): array
166
-    {
167
-        return $this->_alter_query_params_so_only_trashed_items_included($query_params);
168
-    }
169
-
170
-
171
-    /**
172
-     * Alters the query params so each item's deleted status is ignored.
173
-     *
174
-     * @param array $query_params
175
-     * @return array
176
-     */
177
-    public function alter_query_params_so_deleted_and_undeleted_items_included(array $query_params = []): array
178
-    {
179
-        return $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
180
-    }
181
-
182
-
183
-    /**
184
-     * Alters the query params so each item's deleted status is ignored.
185
-     *
186
-     * @param array $query_params
187
-     * @return array
188
-     */
189
-    protected function _alter_query_params_so_deleted_and_undeleted_items_included(array $query_params): array
190
-    {
191
-        if (! isset($query_params['default_where_conditions'])) {
192
-            $query_params['default_where_conditions'] = 'minimum';
193
-        }
194
-        return $query_params;
195
-    }
196
-
197
-
198
-    /**
199
-     * Counts all deleted and undeleted items
200
-     *
201
-     * @param array  $query_params @see
202
-     *                             https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
203
-     * @param string $field_to_count
204
-     * @param bool   $distinct     if we want to only count the distinct values for the column then you can trigger
205
-     *                             that
206
-     *                             by the setting $distinct to TRUE;
207
-     * @return int
208
-     * @throws EE_Error
209
-     * @throws ReflectionException
210
-     */
211
-    public function count_deleted_and_undeleted(
212
-        array $query_params = [],
213
-        string $field_to_count = '',
214
-        bool $distinct = false
215
-    ): int {
216
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
217
-        return parent::count($query_params, $field_to_count, $distinct);
218
-    }
219
-
220
-
221
-    /**
222
-     * Sum all the deleted items.
223
-     *
224
-     * @param array $query_params @see
225
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
226
-     * @param null  $field_to_sum
227
-     * @return float
228
-     * @throws EE_Error
229
-     * @throws ReflectionException
230
-     */
231
-    public function sum_deleted(array $query_params = [], $field_to_sum = null): float
232
-    {
233
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
234
-        return parent::sum($query_params, $field_to_sum);
235
-    }
236
-
237
-
238
-    /**
239
-     * Sums all the deleted and undeleted items.
240
-     *
241
-     * @param array $query_params @see
242
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
243
-     * @param null  $field_to_sum
244
-     * @return float
245
-     * @throws EE_Error
246
-     * @throws ReflectionException
247
-     */
248
-    public function sum_deleted_and_undeleted(array $query_params = [], $field_to_sum = null): float
249
-    {
250
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
251
-        return parent::sum($query_params, $field_to_sum);
252
-    }
253
-
254
-
255
-    /**
256
-     * Gets all deleted and undeleted mode objects from the db that meet the criteria, regardless of
257
-     * whether they've been soft-deleted or not
258
-     *
259
-     * @param array $query_params @see
260
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
261
-     * @return EE_Soft_Delete_Base_Class[]
262
-     * @throws EE_Error
263
-     * @throws ReflectionException
264
-     */
265
-    public function get_all_deleted_and_undeleted(array $query_params = []): array
266
-    {
267
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
268
-        return parent::get_all($query_params);
269
-    }
270
-
271
-
272
-    /**
273
-     * For 'soft deletable' models, gets all which ARE deleted, according to conditions specified in $query_params.
274
-     *
275
-     * @param array $query_params @see
276
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
277
-     * @return EE_Soft_Delete_Base_Class[]
278
-     * @throws EE_Error
279
-     * @throws ReflectionException
280
-     */
281
-    public function get_all_deleted(array $query_params = []): array
282
-    {
283
-        $query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
284
-        return parent::get_all($query_params);
285
-    }
286
-
287
-
288
-    /**
289
-     * Permanently deletes the selected rows. When selecting rows for deletion, ignores
290
-     * whether they've been soft-deleted or not. (ie, you don't have to soft-delete objects
291
-     * before you can permanently delete them).
292
-     * Because this will cause a real deletion, related models may block this deletion (ie, add an error
293
-     * and abort the delete)
294
-     *
295
-     * @param array   $query_params   @see
296
-     *                                https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
297
-     * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info
298
-     *                                that blocks it (ie, there' sno other data that depends on this data); if false,
299
-     *                                deletes regardless of other objects which may depend on it. Its generally
300
-     *                                advisable to always leave this as TRUE, otherwise you could easily corrupt your
301
-     *                                DB
302
-     * @return boolean success
303
-     * @throws EE_Error
304
-     * @throws ReflectionException
305
-     */
306
-    public function delete_permanently($query_params = [], $allow_blocking = true): bool
307
-    {
308
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
309
-        return parent::delete_permanently($query_params, $allow_blocking);
310
-    }
311
-
312
-
313
-    /**
314
-     * Restores a particular item by its ID (primary key). Ignores the fact whether the item
315
-     * has been soft-deleted or not.
316
-     *
317
-     * @param mixed $ID int if primary key is an int, string otherwise
318
-     * @return boolean success
319
-     * @throws EE_Error
320
-     * @throws ReflectionException
321
-     */
322
-    public function restore_by_ID($ID = false): bool
323
-    {
324
-        return $this->delete_or_restore_by_ID(false, $ID);
325
-    }
326
-
327
-
328
-    /**
329
-     * For deleting or restoring a particular item. Note that this model is a SOFT-DELETABLE model! However,
330
-     * this function will ignore whether the items have been soft-deleted or not.
331
-     *
332
-     * @param boolean    $delete true for delete, false for restore
333
-     * @param int|string $ID     int if primary key is an int, string otherwise
334
-     * @return boolean
335
-     * @throws EE_Error
336
-     * @throws ReflectionException
337
-     */
338
-    public function delete_or_restore_by_ID(bool $delete = true, $ID = 0): bool
339
-    {
340
-        if (empty($ID)) {
341
-            return false;
342
-        }
343
-        return $this->delete_or_restore(
344
-            $delete,
345
-            $this->alter_query_params_to_restrict_by_ID($ID)
346
-        );
347
-    }
348
-
349
-
350
-    /**
351
-     * Overrides parent's 'delete' method to instead do a soft delete on all rows that
352
-     * meet the criteria in $where_col_n_values. This particular function ignores whether the items have been
353
-     * soft-deleted or not. Note: because this item will be soft-deleted only, doesn't block because of model
354
-     * dependencies
355
-     *
356
-     * @param array $query_params @see
357
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
358
-     * @param bool  $allow_blocking
359
-     * @return boolean
360
-     * @throws EE_Error
361
-     * @throws ReflectionException
362
-     */
363
-    public function delete($query_params = [], $allow_blocking = false): bool
364
-    {
365
-        // no matter what, we WON'T block soft deletes.
366
-        return $this->delete_or_restore(true, $query_params);
367
-    }
368
-
369
-
370
-    /**
371
-     * 'Un-deletes' the chosen items. Note that this model is a SOFT-DELETABLE model! That means that, by default,
372
-     * trashed/soft-deleted items are ignored in queries. However, this particular function ignores whether the items
373
-     * have been soft-deleted or not.
374
-     *
375
-     * @param array $query_params @see
376
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
377
-     * @return boolean
378
-     * @throws EE_Error
379
-     * @throws ReflectionException
380
-     */
381
-    public function restore(array $query_params = []): bool
382
-    {
383
-        return $this->delete_or_restore(false, $query_params);
384
-    }
385
-
386
-
387
-    /**
388
-     * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
389
-     *
390
-     * @param boolean $delete       true to indicate deletion, false to indicate restoration
391
-     * @param array   $query_params @see
392
-     *                              https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
393
-     * @return boolean
394
-     * @throws EE_Error
395
-     * @throws ReflectionException
396
-     */
397
-    public function delete_or_restore(bool $delete = true, array $query_params = []): bool
398
-    {
399
-        $deletedFlagFieldName = $this->deleted_field_name();
400
-        $query_params         = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
401
-        return $this->update([$deletedFlagFieldName => $delete], $query_params);
402
-    }
403
-
404
-
405
-    /**
406
-     * Updates all the items of this model which match the $query params, regardless of whether
407
-     * they've been soft-deleted or not
408
-     *
409
-     * @param array   $fields_n_values         like EEM_Base::update's $fields_n_value
410
-     * @param array   $query_params            like EEM_base::get_all's $query_params
411
-     * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects
412
-     *                                         in this model's entity map according to $fields_n_values that match
413
-     *                                         $query_params. This obviously has some overhead, so you can disable it
414
-     *                                         by setting this to FALSE, but be aware that model objects being used
415
-     *                                         could get out-of-sync with the database
416
-     * @return int number of items updated
417
-     * @throws EE_Error
418
-     * @throws ReflectionException
419
-     */
420
-    public function update_deleted_and_undeleted(
421
-        array $fields_n_values,
422
-        array $query_params,
423
-        bool $keep_model_objs_in_sync = true
424
-    ): int {
425
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
426
-        return $this->update($fields_n_values, $query_params, $keep_model_objs_in_sync);
427
-    }
30
+	/**
31
+	 * @param string $timezone
32
+	 * @throws EE_Error
33
+	 */
34
+	protected function __construct(string $timezone = '')
35
+	{
36
+		if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
37
+			$this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions();
38
+		}
39
+		parent::__construct($timezone);
40
+	}
41
+
42
+
43
+	/**
44
+	 * Searches for field on this model of type 'deleted_flag'. if it is found,
45
+	 * returns it's name.
46
+	 *
47
+	 * @return string
48
+	 * @throws EE_Error
49
+	 */
50
+	public function deleted_field_name()
51
+	{
52
+		$field = $this->get_a_field_of_type('EE_Trashed_Flag_Field');
53
+		if ($field) {
54
+			return $field->get_name();
55
+		} else {
56
+			throw new EE_Error(
57
+				sprintf(
58
+					esc_html__(
59
+						'We are trying to find the deleted flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
60
+						'event_espresso'
61
+					),
62
+					get_class($this),
63
+					get_class($this)
64
+				)
65
+			);
66
+		}
67
+	}
68
+
69
+
70
+	/**
71
+	 * Gets one item that's been deleted, according to $query_params
72
+	 *
73
+	 * @param array $query_params @see
74
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
75
+	 * @return EE_Soft_Delete_Base_Class
76
+	 * @throws EE_Error
77
+	 * @throws ReflectionException
78
+	 */
79
+	public function get_one_deleted(array $query_params = []): EE_Soft_Delete_Base_Class
80
+	{
81
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
82
+		return parent::get_one($query_params);
83
+	}
84
+
85
+
86
+	/**
87
+	 * Gets one item from the DB, regardless of whether it's been soft-deleted or not
88
+	 *
89
+	 * @param array $query_params like EEM_base::get_all's $query_params
90
+	 * @return EE_Soft_Delete_Base_Class
91
+	 * @throws EE_Error
92
+	 * @throws ReflectionException
93
+	 */
94
+	public function get_one_deleted_or_undeleted(array $query_params = []): EE_Soft_Delete_Base_Class
95
+	{
96
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
97
+		return parent::get_one($query_params);
98
+	}
99
+
100
+
101
+	/**
102
+	 * Gets the item indicated by its ID. But if it's soft-deleted, pretends it doesn't exist.
103
+	 *
104
+	 * @param int|string $id
105
+	 * @return EE_Soft_Delete_Base_Class
106
+	 * @throws EE_Error
107
+	 * @throws ReflectionException
108
+	 */
109
+	public function get_one_by_ID_but_ignore_deleted($id): EE_Soft_Delete_Base_Class
110
+	{
111
+		return $this->get_one(
112
+			$this->alter_query_params_to_restrict_by_ID(
113
+				$id,
114
+				['default_where_conditions' => 'default']
115
+			)
116
+		);
117
+	}
118
+
119
+
120
+	/**
121
+	 * Counts all the deleted/trashed items
122
+	 *
123
+	 * @param array  $query_params @see
124
+	 *                             https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
125
+	 * @param string $field_to_count
126
+	 * @param bool   $distinct     if we want to only count the distinct values for the column
127
+	 *                             then you can trigger that by the setting $distinct to TRUE;
128
+	 * @return int
129
+	 * @throws EE_Error
130
+	 * @throws ReflectionException
131
+	 */
132
+	public function count_deleted(array $query_params = [], string $field_to_count = '', bool $distinct = false): int
133
+	{
134
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
135
+		return parent::count($query_params, $field_to_count, $distinct);
136
+	}
137
+
138
+
139
+	/**
140
+	 * Alters the query params so that only trashed/soft-deleted items are considered
141
+	 *
142
+	 * @param array $query_params @see
143
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
144
+	 * @return array @see
145
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
146
+	 * @throws EE_Error
147
+	 */
148
+	protected function _alter_query_params_so_only_trashed_items_included(array $query_params): array
149
+	{
150
+		$deletedFlagFieldName                     = $this->deleted_field_name();
151
+		$query_params[0][ $deletedFlagFieldName ] = true;
152
+		return $query_params;
153
+	}
154
+
155
+
156
+	/**
157
+	 * Alters the query params so that only trashed/soft-deleted items are considered
158
+	 *
159
+	 * @param array $query_params @see
160
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
161
+	 * @return array @see
162
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
163
+	 * @throws EE_Error
164
+	 */
165
+	public function alter_query_params_so_only_trashed_items_included(array $query_params): array
166
+	{
167
+		return $this->_alter_query_params_so_only_trashed_items_included($query_params);
168
+	}
169
+
170
+
171
+	/**
172
+	 * Alters the query params so each item's deleted status is ignored.
173
+	 *
174
+	 * @param array $query_params
175
+	 * @return array
176
+	 */
177
+	public function alter_query_params_so_deleted_and_undeleted_items_included(array $query_params = []): array
178
+	{
179
+		return $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
180
+	}
181
+
182
+
183
+	/**
184
+	 * Alters the query params so each item's deleted status is ignored.
185
+	 *
186
+	 * @param array $query_params
187
+	 * @return array
188
+	 */
189
+	protected function _alter_query_params_so_deleted_and_undeleted_items_included(array $query_params): array
190
+	{
191
+		if (! isset($query_params['default_where_conditions'])) {
192
+			$query_params['default_where_conditions'] = 'minimum';
193
+		}
194
+		return $query_params;
195
+	}
196
+
197
+
198
+	/**
199
+	 * Counts all deleted and undeleted items
200
+	 *
201
+	 * @param array  $query_params @see
202
+	 *                             https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
203
+	 * @param string $field_to_count
204
+	 * @param bool   $distinct     if we want to only count the distinct values for the column then you can trigger
205
+	 *                             that
206
+	 *                             by the setting $distinct to TRUE;
207
+	 * @return int
208
+	 * @throws EE_Error
209
+	 * @throws ReflectionException
210
+	 */
211
+	public function count_deleted_and_undeleted(
212
+		array $query_params = [],
213
+		string $field_to_count = '',
214
+		bool $distinct = false
215
+	): int {
216
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
217
+		return parent::count($query_params, $field_to_count, $distinct);
218
+	}
219
+
220
+
221
+	/**
222
+	 * Sum all the deleted items.
223
+	 *
224
+	 * @param array $query_params @see
225
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
226
+	 * @param null  $field_to_sum
227
+	 * @return float
228
+	 * @throws EE_Error
229
+	 * @throws ReflectionException
230
+	 */
231
+	public function sum_deleted(array $query_params = [], $field_to_sum = null): float
232
+	{
233
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
234
+		return parent::sum($query_params, $field_to_sum);
235
+	}
236
+
237
+
238
+	/**
239
+	 * Sums all the deleted and undeleted items.
240
+	 *
241
+	 * @param array $query_params @see
242
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
243
+	 * @param null  $field_to_sum
244
+	 * @return float
245
+	 * @throws EE_Error
246
+	 * @throws ReflectionException
247
+	 */
248
+	public function sum_deleted_and_undeleted(array $query_params = [], $field_to_sum = null): float
249
+	{
250
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
251
+		return parent::sum($query_params, $field_to_sum);
252
+	}
253
+
254
+
255
+	/**
256
+	 * Gets all deleted and undeleted mode objects from the db that meet the criteria, regardless of
257
+	 * whether they've been soft-deleted or not
258
+	 *
259
+	 * @param array $query_params @see
260
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
261
+	 * @return EE_Soft_Delete_Base_Class[]
262
+	 * @throws EE_Error
263
+	 * @throws ReflectionException
264
+	 */
265
+	public function get_all_deleted_and_undeleted(array $query_params = []): array
266
+	{
267
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
268
+		return parent::get_all($query_params);
269
+	}
270
+
271
+
272
+	/**
273
+	 * For 'soft deletable' models, gets all which ARE deleted, according to conditions specified in $query_params.
274
+	 *
275
+	 * @param array $query_params @see
276
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
277
+	 * @return EE_Soft_Delete_Base_Class[]
278
+	 * @throws EE_Error
279
+	 * @throws ReflectionException
280
+	 */
281
+	public function get_all_deleted(array $query_params = []): array
282
+	{
283
+		$query_params = $this->_alter_query_params_so_only_trashed_items_included($query_params);
284
+		return parent::get_all($query_params);
285
+	}
286
+
287
+
288
+	/**
289
+	 * Permanently deletes the selected rows. When selecting rows for deletion, ignores
290
+	 * whether they've been soft-deleted or not. (ie, you don't have to soft-delete objects
291
+	 * before you can permanently delete them).
292
+	 * Because this will cause a real deletion, related models may block this deletion (ie, add an error
293
+	 * and abort the delete)
294
+	 *
295
+	 * @param array   $query_params   @see
296
+	 *                                https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
297
+	 * @param boolean $allow_blocking if TRUE, matched objects will only be deleted if there is no related model info
298
+	 *                                that blocks it (ie, there' sno other data that depends on this data); if false,
299
+	 *                                deletes regardless of other objects which may depend on it. Its generally
300
+	 *                                advisable to always leave this as TRUE, otherwise you could easily corrupt your
301
+	 *                                DB
302
+	 * @return boolean success
303
+	 * @throws EE_Error
304
+	 * @throws ReflectionException
305
+	 */
306
+	public function delete_permanently($query_params = [], $allow_blocking = true): bool
307
+	{
308
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
309
+		return parent::delete_permanently($query_params, $allow_blocking);
310
+	}
311
+
312
+
313
+	/**
314
+	 * Restores a particular item by its ID (primary key). Ignores the fact whether the item
315
+	 * has been soft-deleted or not.
316
+	 *
317
+	 * @param mixed $ID int if primary key is an int, string otherwise
318
+	 * @return boolean success
319
+	 * @throws EE_Error
320
+	 * @throws ReflectionException
321
+	 */
322
+	public function restore_by_ID($ID = false): bool
323
+	{
324
+		return $this->delete_or_restore_by_ID(false, $ID);
325
+	}
326
+
327
+
328
+	/**
329
+	 * For deleting or restoring a particular item. Note that this model is a SOFT-DELETABLE model! However,
330
+	 * this function will ignore whether the items have been soft-deleted or not.
331
+	 *
332
+	 * @param boolean    $delete true for delete, false for restore
333
+	 * @param int|string $ID     int if primary key is an int, string otherwise
334
+	 * @return boolean
335
+	 * @throws EE_Error
336
+	 * @throws ReflectionException
337
+	 */
338
+	public function delete_or_restore_by_ID(bool $delete = true, $ID = 0): bool
339
+	{
340
+		if (empty($ID)) {
341
+			return false;
342
+		}
343
+		return $this->delete_or_restore(
344
+			$delete,
345
+			$this->alter_query_params_to_restrict_by_ID($ID)
346
+		);
347
+	}
348
+
349
+
350
+	/**
351
+	 * Overrides parent's 'delete' method to instead do a soft delete on all rows that
352
+	 * meet the criteria in $where_col_n_values. This particular function ignores whether the items have been
353
+	 * soft-deleted or not. Note: because this item will be soft-deleted only, doesn't block because of model
354
+	 * dependencies
355
+	 *
356
+	 * @param array $query_params @see
357
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
358
+	 * @param bool  $allow_blocking
359
+	 * @return boolean
360
+	 * @throws EE_Error
361
+	 * @throws ReflectionException
362
+	 */
363
+	public function delete($query_params = [], $allow_blocking = false): bool
364
+	{
365
+		// no matter what, we WON'T block soft deletes.
366
+		return $this->delete_or_restore(true, $query_params);
367
+	}
368
+
369
+
370
+	/**
371
+	 * 'Un-deletes' the chosen items. Note that this model is a SOFT-DELETABLE model! That means that, by default,
372
+	 * trashed/soft-deleted items are ignored in queries. However, this particular function ignores whether the items
373
+	 * have been soft-deleted or not.
374
+	 *
375
+	 * @param array $query_params @see
376
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
377
+	 * @return boolean
378
+	 * @throws EE_Error
379
+	 * @throws ReflectionException
380
+	 */
381
+	public function restore(array $query_params = []): bool
382
+	{
383
+		return $this->delete_or_restore(false, $query_params);
384
+	}
385
+
386
+
387
+	/**
388
+	 * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
389
+	 *
390
+	 * @param boolean $delete       true to indicate deletion, false to indicate restoration
391
+	 * @param array   $query_params @see
392
+	 *                              https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
393
+	 * @return boolean
394
+	 * @throws EE_Error
395
+	 * @throws ReflectionException
396
+	 */
397
+	public function delete_or_restore(bool $delete = true, array $query_params = []): bool
398
+	{
399
+		$deletedFlagFieldName = $this->deleted_field_name();
400
+		$query_params         = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
401
+		return $this->update([$deletedFlagFieldName => $delete], $query_params);
402
+	}
403
+
404
+
405
+	/**
406
+	 * Updates all the items of this model which match the $query params, regardless of whether
407
+	 * they've been soft-deleted or not
408
+	 *
409
+	 * @param array   $fields_n_values         like EEM_Base::update's $fields_n_value
410
+	 * @param array   $query_params            like EEM_base::get_all's $query_params
411
+	 * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects
412
+	 *                                         in this model's entity map according to $fields_n_values that match
413
+	 *                                         $query_params. This obviously has some overhead, so you can disable it
414
+	 *                                         by setting this to FALSE, but be aware that model objects being used
415
+	 *                                         could get out-of-sync with the database
416
+	 * @return int number of items updated
417
+	 * @throws EE_Error
418
+	 * @throws ReflectionException
419
+	 */
420
+	public function update_deleted_and_undeleted(
421
+		array $fields_n_values,
422
+		array $query_params,
423
+		bool $keep_model_objs_in_sync = true
424
+	): int {
425
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
426
+		return $this->update($fields_n_values, $query_params, $keep_model_objs_in_sync);
427
+	}
428 428
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -33,7 +33,7 @@  discard block
 block discarded – undo
33 33
      */
34 34
     protected function __construct(string $timezone = '')
35 35
     {
36
-        if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
36
+        if ( ! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
37 37
             $this->_default_where_conditions_strategy = new EE_Soft_Delete_Where_Conditions();
38 38
         }
39 39
         parent::__construct($timezone);
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
     protected function _alter_query_params_so_only_trashed_items_included(array $query_params): array
149 149
     {
150 150
         $deletedFlagFieldName                     = $this->deleted_field_name();
151
-        $query_params[0][ $deletedFlagFieldName ] = true;
151
+        $query_params[0][$deletedFlagFieldName] = true;
152 152
         return $query_params;
153 153
     }
154 154
 
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
      */
189 189
     protected function _alter_query_params_so_deleted_and_undeleted_items_included(array $query_params): array
190 190
     {
191
-        if (! isset($query_params['default_where_conditions'])) {
191
+        if ( ! isset($query_params['default_where_conditions'])) {
192 192
             $query_params['default_where_conditions'] = 'minimum';
193 193
         }
194 194
         return $query_params;
Please login to merge, or discard this patch.
core/db_models/EEM_Term_Relationship.model.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -128,7 +128,7 @@
 block discarded – undo
128 128
     /**
129 129
      * Makes sure all term-taxonomy counts are correct
130 130
      *
131
-     * @param int|null $term_taxonomy_id the id of the term taxonomy to update. If NULL, updates ALL
131
+     * @param integer $term_taxonomy_id the id of the term taxonomy to update. If NULL, updates ALL
132 132
      * @return int the number of rows affected
133 133
      * @throws EE_Error
134 134
      * @global wpdb    $wpdb
Please login to merge, or discard this patch.
Indentation   +236 added lines, -236 removed lines patch added patch discarded remove patch
@@ -10,246 +10,246 @@
 block discarded – undo
10 10
 class EEM_Term_Relationship extends EEM_Base
11 11
 {
12 12
 
13
-    /**
14
-     * @var EEM_Term_Relationship
15
-     */
16
-    protected static $_instance;
17
-
18
-
19
-    /**
20
-     * EEM_Term_Relationship constructor.
21
-     *
22
-     * @param string $timezone
23
-     * @throws EE_Error
24
-     */
25
-    protected function __construct(string $timezone = '')
26
-    {
27
-        $this->singular_item       = esc_html__('Term Relationship', 'event_espresso');
28
-        $this->plural_item         = esc_html__('Term Relationships', 'event_espresso');
29
-        $this->_tables             = [
30
-            'Term_Relationship' => new EE_Primary_Table('term_relationships'),
31
-        ];
32
-        $models_this_can_attach_to = array_keys(EE_Registry::instance()->cpt_models());
33
-        $this->_fields             = [
34
-            'Term_Relationship' => [
35
-                'object_id'        => new EE_Foreign_Key_Int_Field(
36
-                    'object_id',
37
-                    esc_html__('Object(Post) ID', 'event_espresso'),
38
-                    false,
39
-                    0,
40
-                    $models_this_can_attach_to
41
-                ),
42
-                'term_taxonomy_id' => new EE_Foreign_Key_Int_Field(
43
-                    'term_taxonomy_id',
44
-                    esc_html__(
45
-                        'Term (in context of a taxonomy) ID',
46
-                        'event_espresso'
47
-                    ),
48
-                    false,
49
-                    0,
50
-                    'Term_Taxonomy'
51
-                ),
52
-                'term_order'       => new EE_Integer_Field(
53
-                    'term_order',
54
-                    esc_html__('Term Order', 'event_espresso'),
55
-                    false,
56
-                    0
57
-                ),
58
-            ],
59
-        ];
60
-        $this->_model_relations    = [
61
-            'Term_Taxonomy' => new EE_Belongs_To_Relation(),
62
-        ];
63
-        foreach ($models_this_can_attach_to as $model_name) {
64
-            $this->_model_relations[ $model_name ] = new EE_Belongs_To_Relation();
65
-        }
66
-        $this->_wp_core_model = true;
67
-        $this->_indexes       = [
68
-            'PRIMARY' => new EE_Primary_Key_Index(['object_id', 'term_taxonomy_id']),
69
-        ];
70
-        $path_to_event_model  = 'Event';
71
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]
72
-                              = new EE_Restriction_Generator_Event_Related_Public(
73
-            $path_to_event_model
74
-        );
75
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ]
76
-                              = new EE_Restriction_Generator_Event_Related_Protected(
77
-            $path_to_event_model
78
-        );
79
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]
80
-                              = new EE_Restriction_Generator_Event_Related_Protected(
81
-            $path_to_event_model
82
-        );
83
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]
84
-                              = new EE_Restriction_Generator_Event_Related_Protected(
85
-            $path_to_event_model,
86
-            EEM_Base::caps_edit
87
-        );
88
-        $path_to_tax_model    = 'Term_Taxonomy.';
89
-        // add cap restrictions for editing term relations to the "ee_assign_*"
90
-        // and for deleting term relations too
91
-        $cap_contexts_affected = [EEM_Base::caps_edit, EEM_Base::caps_delete];
92
-        foreach ($cap_contexts_affected as $cap_context_affected) {
93
-            $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_category']
94
-                = new EE_Default_Where_Conditions(
95
-                [
96
-                    $path_to_tax_model . 'taxonomy*ee_assign_event_category' => [
97
-                        '!=',
98
-                        'espresso_event_categories',
99
-                    ],
100
-                ]
101
-            );
102
-            $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_venue_category']
103
-                = new EE_Default_Where_Conditions(
104
-                [
105
-                    $path_to_tax_model . 'taxonomy*ee_assign_venue_category' => [
106
-                        '!=',
107
-                        'espresso_venue_categories',
108
-                    ],
109
-                ]
110
-            );
111
-            $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_type']
112
-                = new EE_Default_Where_Conditions(
113
-                [
114
-                    $path_to_tax_model . 'taxonomy*ee_assign_event_type' => ['!=', 'espresso_event_type'],
115
-                ]
116
-            );
117
-        }
118
-        parent::__construct($timezone);
119
-        add_filter(
120
-            'FHEE__Read__create_model_query_params',
121
-            ['EEM_Term_Relationship', 'rest_api_query_params'],
122
-            10,
123
-            3
124
-        );
125
-    }
126
-
127
-
128
-    /**
129
-     * Makes sure all term-taxonomy counts are correct
130
-     *
131
-     * @param int|null $term_taxonomy_id the id of the term taxonomy to update. If NULL, updates ALL
132
-     * @return int the number of rows affected
133
-     * @throws EE_Error
134
-     * @global wpdb    $wpdb
135
-     */
136
-    public function update_term_taxonomy_counts(int $term_taxonomy_id = 0): int
137
-    {
138
-        // because this uses a subquery and sometimes assigning to column to be another column's
139
-        // value, we just write the SQL directly.
140
-        global $wpdb;
141
-
142
-        $query = "
13
+	/**
14
+	 * @var EEM_Term_Relationship
15
+	 */
16
+	protected static $_instance;
17
+
18
+
19
+	/**
20
+	 * EEM_Term_Relationship constructor.
21
+	 *
22
+	 * @param string $timezone
23
+	 * @throws EE_Error
24
+	 */
25
+	protected function __construct(string $timezone = '')
26
+	{
27
+		$this->singular_item       = esc_html__('Term Relationship', 'event_espresso');
28
+		$this->plural_item         = esc_html__('Term Relationships', 'event_espresso');
29
+		$this->_tables             = [
30
+			'Term_Relationship' => new EE_Primary_Table('term_relationships'),
31
+		];
32
+		$models_this_can_attach_to = array_keys(EE_Registry::instance()->cpt_models());
33
+		$this->_fields             = [
34
+			'Term_Relationship' => [
35
+				'object_id'        => new EE_Foreign_Key_Int_Field(
36
+					'object_id',
37
+					esc_html__('Object(Post) ID', 'event_espresso'),
38
+					false,
39
+					0,
40
+					$models_this_can_attach_to
41
+				),
42
+				'term_taxonomy_id' => new EE_Foreign_Key_Int_Field(
43
+					'term_taxonomy_id',
44
+					esc_html__(
45
+						'Term (in context of a taxonomy) ID',
46
+						'event_espresso'
47
+					),
48
+					false,
49
+					0,
50
+					'Term_Taxonomy'
51
+				),
52
+				'term_order'       => new EE_Integer_Field(
53
+					'term_order',
54
+					esc_html__('Term Order', 'event_espresso'),
55
+					false,
56
+					0
57
+				),
58
+			],
59
+		];
60
+		$this->_model_relations    = [
61
+			'Term_Taxonomy' => new EE_Belongs_To_Relation(),
62
+		];
63
+		foreach ($models_this_can_attach_to as $model_name) {
64
+			$this->_model_relations[ $model_name ] = new EE_Belongs_To_Relation();
65
+		}
66
+		$this->_wp_core_model = true;
67
+		$this->_indexes       = [
68
+			'PRIMARY' => new EE_Primary_Key_Index(['object_id', 'term_taxonomy_id']),
69
+		];
70
+		$path_to_event_model  = 'Event';
71
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ]
72
+							  = new EE_Restriction_Generator_Event_Related_Public(
73
+			$path_to_event_model
74
+		);
75
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ]
76
+							  = new EE_Restriction_Generator_Event_Related_Protected(
77
+			$path_to_event_model
78
+		);
79
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]
80
+							  = new EE_Restriction_Generator_Event_Related_Protected(
81
+			$path_to_event_model
82
+		);
83
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ]
84
+							  = new EE_Restriction_Generator_Event_Related_Protected(
85
+			$path_to_event_model,
86
+			EEM_Base::caps_edit
87
+		);
88
+		$path_to_tax_model    = 'Term_Taxonomy.';
89
+		// add cap restrictions for editing term relations to the "ee_assign_*"
90
+		// and for deleting term relations too
91
+		$cap_contexts_affected = [EEM_Base::caps_edit, EEM_Base::caps_delete];
92
+		foreach ($cap_contexts_affected as $cap_context_affected) {
93
+			$this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_category']
94
+				= new EE_Default_Where_Conditions(
95
+				[
96
+					$path_to_tax_model . 'taxonomy*ee_assign_event_category' => [
97
+						'!=',
98
+						'espresso_event_categories',
99
+					],
100
+				]
101
+			);
102
+			$this->_cap_restrictions[ $cap_context_affected ]['ee_assign_venue_category']
103
+				= new EE_Default_Where_Conditions(
104
+				[
105
+					$path_to_tax_model . 'taxonomy*ee_assign_venue_category' => [
106
+						'!=',
107
+						'espresso_venue_categories',
108
+					],
109
+				]
110
+			);
111
+			$this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_type']
112
+				= new EE_Default_Where_Conditions(
113
+				[
114
+					$path_to_tax_model . 'taxonomy*ee_assign_event_type' => ['!=', 'espresso_event_type'],
115
+				]
116
+			);
117
+		}
118
+		parent::__construct($timezone);
119
+		add_filter(
120
+			'FHEE__Read__create_model_query_params',
121
+			['EEM_Term_Relationship', 'rest_api_query_params'],
122
+			10,
123
+			3
124
+		);
125
+	}
126
+
127
+
128
+	/**
129
+	 * Makes sure all term-taxonomy counts are correct
130
+	 *
131
+	 * @param int|null $term_taxonomy_id the id of the term taxonomy to update. If NULL, updates ALL
132
+	 * @return int the number of rows affected
133
+	 * @throws EE_Error
134
+	 * @global wpdb    $wpdb
135
+	 */
136
+	public function update_term_taxonomy_counts(int $term_taxonomy_id = 0): int
137
+	{
138
+		// because this uses a subquery and sometimes assigning to column to be another column's
139
+		// value, we just write the SQL directly.
140
+		global $wpdb;
141
+
142
+		$query = "
143 143
                 UPDATE {$wpdb->term_taxonomy} AS tt 
144 144
                 SET count = (
145 145
                     select count(*) as proper_count from {$wpdb->term_relationships} AS tr 
146 146
                     WHERE tt.term_taxonomy_id = tr.term_taxonomy_id
147 147
                 )";
148 148
 
149
-        if ($term_taxonomy_id) {
150
-            $query .= ' WHERE tt.term_taxonomy_id = %d';
151
-            $query = $wpdb->prepare(
152
-                $query,
153
-                $term_taxonomy_id
154
-            );
155
-        }
156
-        return $this->_do_wpdb_query(
157
-            'query',
158
-            [
159
-                $query,
160
-            ]
161
-        );
162
-    }
163
-
164
-
165
-    /**
166
-     * Overrides the parent to also make sure term-taxonomy counts are up-to-date after
167
-     * inserting
168
-     *
169
-     * @param array $field_n_values @see EEM_Base::insert
170
-     * @return boolean
171
-     * @throws EE_Error
172
-     * @throws ReflectionException
173
-     */
174
-    public function insert($field_n_values): bool
175
-    {
176
-        $return = parent::insert($field_n_values);
177
-        if (isset($field_n_values['term_taxonomy_id'])) {
178
-            $this->update_term_taxonomy_counts($field_n_values['term_taxonomy_id']);
179
-        }
180
-        return $return;
181
-    }
182
-
183
-
184
-    /**
185
-     * Overrides parent so that after an update, we also check the term_taxonomy_counts are
186
-     * all ok
187
-     *
188
-     * @param array   $fields_n_values         see EEM_Base::update
189
-     * @param array   $query_params            @see
190
-     *                                         https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
191
-     * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects
192
-     *                                         in this model's entity map according to $fields_n_values that match
193
-     *                                         $query_params. This obviously has some overhead, so you can disable it
194
-     *                                         by setting this to FALSE, but be aware that model objects being used
195
-     *                                         could get out-of-sync with the database
196
-     * @return int
197
-     * @throws EE_Error
198
-     * @throws ReflectionException
199
-     */
200
-    public function update($fields_n_values, $query_params, $keep_model_objs_in_sync = true): int
201
-    {
202
-        $count = parent::update($fields_n_values, $query_params, $keep_model_objs_in_sync);
203
-        if ($count) {
204
-            $this->update_term_taxonomy_counts();
205
-        }
206
-        return $count;
207
-    }
208
-
209
-
210
-    /**
211
-     * Overrides parent so that after running this, we also double-check
212
-     * the term taxonomy counts are up-to-date
213
-     *
214
-     * @param array   $query_params @see
215
-     *                              https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
216
-     * @param boolean $allow_blocking
217
-     * @return int @see EEM_Base::delete
218
-     * @throws EE_Error
219
-     * @throws ReflectionException
220
-     */
221
-    public function delete($query_params, $allow_blocking = true): int
222
-    {
223
-        $count = parent::delete($query_params, $allow_blocking);
224
-        if ($count) {
225
-            $this->update_term_taxonomy_counts();
226
-        }
227
-        return $count;
228
-    }
229
-
230
-
231
-    /**
232
-     * Makes sure that during REST API queries, we only return term relationships
233
-     * for term taxonomies which should be shown in the rest api
234
-     *
235
-     * @param array    $model_query_params
236
-     * @param array    $querystring_query_params
237
-     * @param EEM_Base $model
238
-     * @return array
239
-     * @throws EE_Error
240
-     * @throws EE_Error
241
-     */
242
-    public static function rest_api_query_params(
243
-        array $model_query_params,
244
-        array $querystring_query_params,
245
-        EEM_Base $model
246
-    ): array {
247
-        if ($model === EEM_Term_Relationship::instance()) {
248
-            $taxonomies = get_taxonomies(['show_in_rest' => true]);
249
-            if (! empty($taxonomies)) {
250
-                $model_query_params[0]['Term_Taxonomy.taxonomy'] = ['IN', $taxonomies];
251
-            }
252
-        }
253
-        return $model_query_params;
254
-    }
149
+		if ($term_taxonomy_id) {
150
+			$query .= ' WHERE tt.term_taxonomy_id = %d';
151
+			$query = $wpdb->prepare(
152
+				$query,
153
+				$term_taxonomy_id
154
+			);
155
+		}
156
+		return $this->_do_wpdb_query(
157
+			'query',
158
+			[
159
+				$query,
160
+			]
161
+		);
162
+	}
163
+
164
+
165
+	/**
166
+	 * Overrides the parent to also make sure term-taxonomy counts are up-to-date after
167
+	 * inserting
168
+	 *
169
+	 * @param array $field_n_values @see EEM_Base::insert
170
+	 * @return boolean
171
+	 * @throws EE_Error
172
+	 * @throws ReflectionException
173
+	 */
174
+	public function insert($field_n_values): bool
175
+	{
176
+		$return = parent::insert($field_n_values);
177
+		if (isset($field_n_values['term_taxonomy_id'])) {
178
+			$this->update_term_taxonomy_counts($field_n_values['term_taxonomy_id']);
179
+		}
180
+		return $return;
181
+	}
182
+
183
+
184
+	/**
185
+	 * Overrides parent so that after an update, we also check the term_taxonomy_counts are
186
+	 * all ok
187
+	 *
188
+	 * @param array   $fields_n_values         see EEM_Base::update
189
+	 * @param array   $query_params            @see
190
+	 *                                         https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
191
+	 * @param boolean $keep_model_objs_in_sync if TRUE, makes sure we ALSO update model objects
192
+	 *                                         in this model's entity map according to $fields_n_values that match
193
+	 *                                         $query_params. This obviously has some overhead, so you can disable it
194
+	 *                                         by setting this to FALSE, but be aware that model objects being used
195
+	 *                                         could get out-of-sync with the database
196
+	 * @return int
197
+	 * @throws EE_Error
198
+	 * @throws ReflectionException
199
+	 */
200
+	public function update($fields_n_values, $query_params, $keep_model_objs_in_sync = true): int
201
+	{
202
+		$count = parent::update($fields_n_values, $query_params, $keep_model_objs_in_sync);
203
+		if ($count) {
204
+			$this->update_term_taxonomy_counts();
205
+		}
206
+		return $count;
207
+	}
208
+
209
+
210
+	/**
211
+	 * Overrides parent so that after running this, we also double-check
212
+	 * the term taxonomy counts are up-to-date
213
+	 *
214
+	 * @param array   $query_params @see
215
+	 *                              https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
216
+	 * @param boolean $allow_blocking
217
+	 * @return int @see EEM_Base::delete
218
+	 * @throws EE_Error
219
+	 * @throws ReflectionException
220
+	 */
221
+	public function delete($query_params, $allow_blocking = true): int
222
+	{
223
+		$count = parent::delete($query_params, $allow_blocking);
224
+		if ($count) {
225
+			$this->update_term_taxonomy_counts();
226
+		}
227
+		return $count;
228
+	}
229
+
230
+
231
+	/**
232
+	 * Makes sure that during REST API queries, we only return term relationships
233
+	 * for term taxonomies which should be shown in the rest api
234
+	 *
235
+	 * @param array    $model_query_params
236
+	 * @param array    $querystring_query_params
237
+	 * @param EEM_Base $model
238
+	 * @return array
239
+	 * @throws EE_Error
240
+	 * @throws EE_Error
241
+	 */
242
+	public static function rest_api_query_params(
243
+		array $model_query_params,
244
+		array $querystring_query_params,
245
+		EEM_Base $model
246
+	): array {
247
+		if ($model === EEM_Term_Relationship::instance()) {
248
+			$taxonomies = get_taxonomies(['show_in_rest' => true]);
249
+			if (! empty($taxonomies)) {
250
+				$model_query_params[0]['Term_Taxonomy.taxonomy'] = ['IN', $taxonomies];
251
+			}
252
+		}
253
+		return $model_query_params;
254
+	}
255 255
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -57,61 +57,61 @@  discard block
 block discarded – undo
57 57
                 ),
58 58
             ],
59 59
         ];
60
-        $this->_model_relations    = [
60
+        $this->_model_relations = [
61 61
             'Term_Taxonomy' => new EE_Belongs_To_Relation(),
62 62
         ];
63 63
         foreach ($models_this_can_attach_to as $model_name) {
64
-            $this->_model_relations[ $model_name ] = new EE_Belongs_To_Relation();
64
+            $this->_model_relations[$model_name] = new EE_Belongs_To_Relation();
65 65
         }
66 66
         $this->_wp_core_model = true;
67 67
         $this->_indexes       = [
68 68
             'PRIMARY' => new EE_Primary_Key_Index(['object_id', 'term_taxonomy_id']),
69 69
         ];
70 70
         $path_to_event_model  = 'Event';
71
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]
71
+        $this->_cap_restriction_generators[EEM_Base::caps_read]
72 72
                               = new EE_Restriction_Generator_Event_Related_Public(
73 73
             $path_to_event_model
74 74
         );
75
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ]
75
+        $this->_cap_restriction_generators[EEM_Base::caps_read_admin]
76 76
                               = new EE_Restriction_Generator_Event_Related_Protected(
77 77
             $path_to_event_model
78 78
         );
79
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]
79
+        $this->_cap_restriction_generators[EEM_Base::caps_edit]
80 80
                               = new EE_Restriction_Generator_Event_Related_Protected(
81 81
             $path_to_event_model
82 82
         );
83
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]
83
+        $this->_cap_restriction_generators[EEM_Base::caps_delete]
84 84
                               = new EE_Restriction_Generator_Event_Related_Protected(
85 85
             $path_to_event_model,
86 86
             EEM_Base::caps_edit
87 87
         );
88
-        $path_to_tax_model    = 'Term_Taxonomy.';
88
+        $path_to_tax_model = 'Term_Taxonomy.';
89 89
         // add cap restrictions for editing term relations to the "ee_assign_*"
90 90
         // and for deleting term relations too
91 91
         $cap_contexts_affected = [EEM_Base::caps_edit, EEM_Base::caps_delete];
92 92
         foreach ($cap_contexts_affected as $cap_context_affected) {
93
-            $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_category']
93
+            $this->_cap_restrictions[$cap_context_affected]['ee_assign_event_category']
94 94
                 = new EE_Default_Where_Conditions(
95 95
                 [
96
-                    $path_to_tax_model . 'taxonomy*ee_assign_event_category' => [
96
+                    $path_to_tax_model.'taxonomy*ee_assign_event_category' => [
97 97
                         '!=',
98 98
                         'espresso_event_categories',
99 99
                     ],
100 100
                 ]
101 101
             );
102
-            $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_venue_category']
102
+            $this->_cap_restrictions[$cap_context_affected]['ee_assign_venue_category']
103 103
                 = new EE_Default_Where_Conditions(
104 104
                 [
105
-                    $path_to_tax_model . 'taxonomy*ee_assign_venue_category' => [
105
+                    $path_to_tax_model.'taxonomy*ee_assign_venue_category' => [
106 106
                         '!=',
107 107
                         'espresso_venue_categories',
108 108
                     ],
109 109
                 ]
110 110
             );
111
-            $this->_cap_restrictions[ $cap_context_affected ]['ee_assign_event_type']
111
+            $this->_cap_restrictions[$cap_context_affected]['ee_assign_event_type']
112 112
                 = new EE_Default_Where_Conditions(
113 113
                 [
114
-                    $path_to_tax_model . 'taxonomy*ee_assign_event_type' => ['!=', 'espresso_event_type'],
114
+                    $path_to_tax_model.'taxonomy*ee_assign_event_type' => ['!=', 'espresso_event_type'],
115 115
                 ]
116 116
             );
117 117
         }
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
     ): array {
247 247
         if ($model === EEM_Term_Relationship::instance()) {
248 248
             $taxonomies = get_taxonomies(['show_in_rest' => true]);
249
-            if (! empty($taxonomies)) {
249
+            if ( ! empty($taxonomies)) {
250 250
                 $model_query_params[0]['Term_Taxonomy.taxonomy'] = ['IN', $taxonomies];
251 251
             }
252 252
         }
Please login to merge, or discard this patch.
core/db_models/EEM_Transaction.model.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
      * returns an array of EE_Transaction objects whose timestamp is greater than
440 440
      * the current time minus the session lifespan, which defaults to 60 minutes
441 441
      *
442
-     * @return EE_Base_Class[]|EE_Transaction[]
442
+     * @return EE_Transaction[]
443 443
      * @throws EE_Error
444 444
      * @throws InvalidArgumentException
445 445
      * @throws InvalidDataTypeException
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      * returns an array of EE_Transaction objects whose timestamp is less than
457 457
      * the current time minus the session lifespan, which defaults to 60 minutes
458 458
      *
459
-     * @return EE_Base_Class[]|EE_Transaction[]
459
+     * @return EE_Transaction[]
460 460
      * @throws EE_Error
461 461
      * @throws InvalidArgumentException
462 462
      * @throws InvalidDataTypeException
Please login to merge, or discard this patch.
Indentation   +456 added lines, -456 removed lines patch added patch discarded remove patch
@@ -16,228 +16,228 @@  discard block
 block discarded – undo
16 16
 class EEM_Transaction extends EEM_Base
17 17
 {
18 18
 
19
-    // private instance of the Transaction object
20
-    protected static $_instance;
21
-
22
-    /**
23
-     * Status ID(STS_ID on esp_status table) to indicate the transaction is complete,
24
-     * but payment is pending. This is the state for transactions where payment is promised
25
-     * from an offline gateway.
26
-     */
27
-    //  const open_status_code = 'TPN';
28
-
29
-    /**
30
-     * Status ID(STS_ID on esp_status table) to indicate the transaction failed,
31
-     * either due to a technical reason (server or computer crash during registration),
32
-     *  or some other reason that prevent the collection of any useful contact information from any of the registrants
33
-     */
34
-    const failed_status_code = 'TFL';
35
-
36
-    /**
37
-     * Status ID(STS_ID on esp_status table) to indicate the transaction was abandoned,
38
-     * either due to a technical reason (server or computer crash during registration),
39
-     * or due to an abandoned cart after registrant chose not to complete the registration process
40
-     * HOWEVER...
41
-     * an abandoned TXN differs from a failed TXN in that it was able to capture contact information for at least one
42
-     * registrant
43
-     */
44
-    const abandoned_status_code = 'TAB';
45
-
46
-    /**
47
-     * Status ID(STS_ID on esp_status table) to indicate an incomplete transaction,
48
-     * meaning that monies are still owing: TXN_paid < TXN_total
49
-     */
50
-    const incomplete_status_code = 'TIN';
51
-
52
-    /**
53
-     * Status ID (STS_ID on esp_status table) to indicate a complete transaction.
54
-     * meaning that NO monies are owing: TXN_paid == TXN_total
55
-     */
56
-    const complete_status_code = 'TCM';
57
-
58
-    /**
59
-     *  Status ID(STS_ID on esp_status table) to indicate the transaction is overpaid.
60
-     *  This is the same as complete, but site admins actually owe clients the moneys!  TXN_paid > TXN_total
61
-     */
62
-    const overpaid_status_code = 'TOP';
63
-
64
-
65
-    /**
66
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings
67
-     *                         (and any incoming timezone data that gets saved).
68
-     *                         Note this just sends the timezone info to the date time model field objects.
69
-     *                         Will use 'timezone_string' wp option if no value is provided
70
-     * @throws EE_Error
71
-     */
72
-    protected function __construct(string $timezone = '')
73
-    {
74
-        $this->singular_item = esc_html__('Transaction', 'event_espresso');
75
-        $this->plural_item   = esc_html__('Transactions', 'event_espresso');
76
-
77
-        $this->_tables                 = [
78
-            'TransactionTable' => new EE_Primary_Table('esp_transaction', 'TXN_ID'),
79
-        ];
80
-        $this->_fields                 = [
81
-            'TransactionTable' => [
82
-                'TXN_ID'           => new EE_Primary_Key_Int_Field(
83
-                    'TXN_ID',
84
-                    esc_html__('Transaction ID', 'event_espresso')
85
-                ),
86
-                'TXN_timestamp'    => new EE_Datetime_Field(
87
-                    'TXN_timestamp',
88
-                    esc_html__('date when transaction was created', 'event_espresso'),
89
-                    false,
90
-                    EE_Datetime_Field::now,
91
-                    $timezone
92
-                ),
93
-                'TXN_total'        => new EE_Money_Field(
94
-                    'TXN_total',
95
-                    esc_html__('Total value of Transaction', 'event_espresso'),
96
-                    false,
97
-                    0
98
-                ),
99
-                'TXN_paid'         => new EE_Money_Field(
100
-                    'TXN_paid',
101
-                    esc_html__('Amount paid towards transaction to date', 'event_espresso'),
102
-                    false,
103
-                    0
104
-                ),
105
-                'STS_ID'           => new EE_Foreign_Key_String_Field(
106
-                    'STS_ID',
107
-                    esc_html__('Status ID', 'event_espresso'),
108
-                    false,
109
-                    EEM_Transaction::failed_status_code,
110
-                    'Status'
111
-                ),
112
-                'TXN_session_data' => new EE_Serialized_Text_Field(
113
-                    'TXN_session_data',
114
-                    esc_html__('Serialized session data', 'event_espresso'),
115
-                    true,
116
-                    ''
117
-                ),
118
-                'TXN_hash_salt'    => new EE_Plain_Text_Field(
119
-                    'TXN_hash_salt',
120
-                    esc_html__('Transaction Hash Salt', 'event_espresso'),
121
-                    true,
122
-                    ''
123
-                ),
124
-                'PMD_ID'           => new EE_Foreign_Key_Int_Field(
125
-                    'PMD_ID',
126
-                    esc_html__("Last Used Payment Method", 'event_espresso'),
127
-                    true,
128
-                    null,
129
-                    'Payment_Method'
130
-                ),
131
-                'TXN_reg_steps'    => new EE_Serialized_Text_Field(
132
-                    'TXN_reg_steps',
133
-                    esc_html__('Registration Steps', 'event_espresso'),
134
-                    false,
135
-                    []
136
-                ),
137
-            ],
138
-        ];
139
-        $this->_model_relations        = [
140
-            'Registration'   => new EE_Has_Many_Relation(),
141
-            'Payment'        => new EE_Has_Many_Relation(),
142
-            'Status'         => new EE_Belongs_To_Relation(),
143
-            'Line_Item'      => new EE_Has_Many_Relation(false),
144
-            // you can delete a transaction without needing to delete its line items
145
-            'Payment_Method' => new EE_Belongs_To_Relation(),
146
-            'Message'        => new EE_Has_Many_Relation(),
147
-        ];
148
-        $this->_model_chain_to_wp_user = 'Registration.Event';
149
-        parent::__construct($timezone);
150
-    }
151
-
152
-
153
-    /**
154
-     * get list of transaction statuses
155
-     *
156
-     * @return array
157
-     */
158
-    public static function txn_status_array(): array
159
-    {
160
-        return apply_filters(
161
-            'FHEE__EEM_Transaction__txn_status_array',
162
-            [
163
-                EEM_Transaction::overpaid_status_code,
164
-                EEM_Transaction::complete_status_code,
165
-                EEM_Transaction::incomplete_status_code,
166
-                EEM_Transaction::abandoned_status_code,
167
-                EEM_Transaction::failed_status_code,
168
-            ]
169
-        );
170
-    }
171
-
172
-
173
-    /**
174
-     * get the revenue per day  for the Transaction Admin page Reports Tab
175
-     *
176
-     * @param string $period
177
-     * @return stdClass[]
178
-     * @throws EE_Error
179
-     * @throws ReflectionException
180
-     */
181
-    public function get_revenue_per_day_report(string $period = '-1 month'): array
182
-    {
183
-        $sql_date = $this->convert_datetime_for_query(
184
-            'TXN_timestamp',
185
-            date('Y-m-d H:i:s', strtotime($period)),
186
-            'Y-m-d H:i:s',
187
-            'UTC'
188
-        );
189
-
190
-        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset(
191
-            $this->get_timezone(),
192
-            'TXN_timestamp'
193
-        );
194
-
195
-        return $this->_get_all_wpdb_results(
196
-            [
197
-                [
198
-                    'TXN_timestamp' => ['>=', $sql_date],
199
-                ],
200
-                'group_by' => 'txnDate',
201
-                'order_by' => ['TXN_timestamp' => 'ASC'],
202
-            ],
203
-            OBJECT,
204
-            [
205
-                'txnDate' => ['DATE(' . $query_interval . ')', '%s'],
206
-                'revenue' => ['SUM(TransactionTable.TXN_paid)', '%d'],
207
-            ]
208
-        );
209
-    }
210
-
211
-
212
-    /**
213
-     * get the revenue per event  for the Transaction Admin page Reports Tab
214
-     *
215
-     * @param string $period
216
-     * @return stdClass[]
217
-     */
218
-    public function get_revenue_per_event_report(string $period = '-1 month'): array
219
-    {
220
-        global $wpdb;
221
-        $transaction_table          = $wpdb->prefix . 'esp_transaction';
222
-        $registration_table         = $wpdb->prefix . 'esp_registration';
223
-        $registration_payment_table = $wpdb->prefix . 'esp_registration_payment';
224
-        $event_table                = $wpdb->posts;
225
-        $payment_table              = $wpdb->prefix . 'esp_payment';
226
-        $sql_date                   = date('Y-m-d H:i:s', strtotime($period));
227
-        $approved_payment_status    = EEM_Payment::status_id_approved;
228
-        $extra_event_on_join        = '';
229
-        // exclude events not authored by user if permissions in effect
230
-        if (
231
-            ! EE_Registry::instance()->CAP->current_user_can(
232
-                'ee_read_others_registrations',
233
-                'reg_per_event_report'
234
-            )
235
-        ) {
236
-            $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id();
237
-        }
238
-
239
-        return $wpdb->get_results(
240
-            "SELECT
19
+	// private instance of the Transaction object
20
+	protected static $_instance;
21
+
22
+	/**
23
+	 * Status ID(STS_ID on esp_status table) to indicate the transaction is complete,
24
+	 * but payment is pending. This is the state for transactions where payment is promised
25
+	 * from an offline gateway.
26
+	 */
27
+	//  const open_status_code = 'TPN';
28
+
29
+	/**
30
+	 * Status ID(STS_ID on esp_status table) to indicate the transaction failed,
31
+	 * either due to a technical reason (server or computer crash during registration),
32
+	 *  or some other reason that prevent the collection of any useful contact information from any of the registrants
33
+	 */
34
+	const failed_status_code = 'TFL';
35
+
36
+	/**
37
+	 * Status ID(STS_ID on esp_status table) to indicate the transaction was abandoned,
38
+	 * either due to a technical reason (server or computer crash during registration),
39
+	 * or due to an abandoned cart after registrant chose not to complete the registration process
40
+	 * HOWEVER...
41
+	 * an abandoned TXN differs from a failed TXN in that it was able to capture contact information for at least one
42
+	 * registrant
43
+	 */
44
+	const abandoned_status_code = 'TAB';
45
+
46
+	/**
47
+	 * Status ID(STS_ID on esp_status table) to indicate an incomplete transaction,
48
+	 * meaning that monies are still owing: TXN_paid < TXN_total
49
+	 */
50
+	const incomplete_status_code = 'TIN';
51
+
52
+	/**
53
+	 * Status ID (STS_ID on esp_status table) to indicate a complete transaction.
54
+	 * meaning that NO monies are owing: TXN_paid == TXN_total
55
+	 */
56
+	const complete_status_code = 'TCM';
57
+
58
+	/**
59
+	 *  Status ID(STS_ID on esp_status table) to indicate the transaction is overpaid.
60
+	 *  This is the same as complete, but site admins actually owe clients the moneys!  TXN_paid > TXN_total
61
+	 */
62
+	const overpaid_status_code = 'TOP';
63
+
64
+
65
+	/**
66
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings
67
+	 *                         (and any incoming timezone data that gets saved).
68
+	 *                         Note this just sends the timezone info to the date time model field objects.
69
+	 *                         Will use 'timezone_string' wp option if no value is provided
70
+	 * @throws EE_Error
71
+	 */
72
+	protected function __construct(string $timezone = '')
73
+	{
74
+		$this->singular_item = esc_html__('Transaction', 'event_espresso');
75
+		$this->plural_item   = esc_html__('Transactions', 'event_espresso');
76
+
77
+		$this->_tables                 = [
78
+			'TransactionTable' => new EE_Primary_Table('esp_transaction', 'TXN_ID'),
79
+		];
80
+		$this->_fields                 = [
81
+			'TransactionTable' => [
82
+				'TXN_ID'           => new EE_Primary_Key_Int_Field(
83
+					'TXN_ID',
84
+					esc_html__('Transaction ID', 'event_espresso')
85
+				),
86
+				'TXN_timestamp'    => new EE_Datetime_Field(
87
+					'TXN_timestamp',
88
+					esc_html__('date when transaction was created', 'event_espresso'),
89
+					false,
90
+					EE_Datetime_Field::now,
91
+					$timezone
92
+				),
93
+				'TXN_total'        => new EE_Money_Field(
94
+					'TXN_total',
95
+					esc_html__('Total value of Transaction', 'event_espresso'),
96
+					false,
97
+					0
98
+				),
99
+				'TXN_paid'         => new EE_Money_Field(
100
+					'TXN_paid',
101
+					esc_html__('Amount paid towards transaction to date', 'event_espresso'),
102
+					false,
103
+					0
104
+				),
105
+				'STS_ID'           => new EE_Foreign_Key_String_Field(
106
+					'STS_ID',
107
+					esc_html__('Status ID', 'event_espresso'),
108
+					false,
109
+					EEM_Transaction::failed_status_code,
110
+					'Status'
111
+				),
112
+				'TXN_session_data' => new EE_Serialized_Text_Field(
113
+					'TXN_session_data',
114
+					esc_html__('Serialized session data', 'event_espresso'),
115
+					true,
116
+					''
117
+				),
118
+				'TXN_hash_salt'    => new EE_Plain_Text_Field(
119
+					'TXN_hash_salt',
120
+					esc_html__('Transaction Hash Salt', 'event_espresso'),
121
+					true,
122
+					''
123
+				),
124
+				'PMD_ID'           => new EE_Foreign_Key_Int_Field(
125
+					'PMD_ID',
126
+					esc_html__("Last Used Payment Method", 'event_espresso'),
127
+					true,
128
+					null,
129
+					'Payment_Method'
130
+				),
131
+				'TXN_reg_steps'    => new EE_Serialized_Text_Field(
132
+					'TXN_reg_steps',
133
+					esc_html__('Registration Steps', 'event_espresso'),
134
+					false,
135
+					[]
136
+				),
137
+			],
138
+		];
139
+		$this->_model_relations        = [
140
+			'Registration'   => new EE_Has_Many_Relation(),
141
+			'Payment'        => new EE_Has_Many_Relation(),
142
+			'Status'         => new EE_Belongs_To_Relation(),
143
+			'Line_Item'      => new EE_Has_Many_Relation(false),
144
+			// you can delete a transaction without needing to delete its line items
145
+			'Payment_Method' => new EE_Belongs_To_Relation(),
146
+			'Message'        => new EE_Has_Many_Relation(),
147
+		];
148
+		$this->_model_chain_to_wp_user = 'Registration.Event';
149
+		parent::__construct($timezone);
150
+	}
151
+
152
+
153
+	/**
154
+	 * get list of transaction statuses
155
+	 *
156
+	 * @return array
157
+	 */
158
+	public static function txn_status_array(): array
159
+	{
160
+		return apply_filters(
161
+			'FHEE__EEM_Transaction__txn_status_array',
162
+			[
163
+				EEM_Transaction::overpaid_status_code,
164
+				EEM_Transaction::complete_status_code,
165
+				EEM_Transaction::incomplete_status_code,
166
+				EEM_Transaction::abandoned_status_code,
167
+				EEM_Transaction::failed_status_code,
168
+			]
169
+		);
170
+	}
171
+
172
+
173
+	/**
174
+	 * get the revenue per day  for the Transaction Admin page Reports Tab
175
+	 *
176
+	 * @param string $period
177
+	 * @return stdClass[]
178
+	 * @throws EE_Error
179
+	 * @throws ReflectionException
180
+	 */
181
+	public function get_revenue_per_day_report(string $period = '-1 month'): array
182
+	{
183
+		$sql_date = $this->convert_datetime_for_query(
184
+			'TXN_timestamp',
185
+			date('Y-m-d H:i:s', strtotime($period)),
186
+			'Y-m-d H:i:s',
187
+			'UTC'
188
+		);
189
+
190
+		$query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset(
191
+			$this->get_timezone(),
192
+			'TXN_timestamp'
193
+		);
194
+
195
+		return $this->_get_all_wpdb_results(
196
+			[
197
+				[
198
+					'TXN_timestamp' => ['>=', $sql_date],
199
+				],
200
+				'group_by' => 'txnDate',
201
+				'order_by' => ['TXN_timestamp' => 'ASC'],
202
+			],
203
+			OBJECT,
204
+			[
205
+				'txnDate' => ['DATE(' . $query_interval . ')', '%s'],
206
+				'revenue' => ['SUM(TransactionTable.TXN_paid)', '%d'],
207
+			]
208
+		);
209
+	}
210
+
211
+
212
+	/**
213
+	 * get the revenue per event  for the Transaction Admin page Reports Tab
214
+	 *
215
+	 * @param string $period
216
+	 * @return stdClass[]
217
+	 */
218
+	public function get_revenue_per_event_report(string $period = '-1 month'): array
219
+	{
220
+		global $wpdb;
221
+		$transaction_table          = $wpdb->prefix . 'esp_transaction';
222
+		$registration_table         = $wpdb->prefix . 'esp_registration';
223
+		$registration_payment_table = $wpdb->prefix . 'esp_registration_payment';
224
+		$event_table                = $wpdb->posts;
225
+		$payment_table              = $wpdb->prefix . 'esp_payment';
226
+		$sql_date                   = date('Y-m-d H:i:s', strtotime($period));
227
+		$approved_payment_status    = EEM_Payment::status_id_approved;
228
+		$extra_event_on_join        = '';
229
+		// exclude events not authored by user if permissions in effect
230
+		if (
231
+			! EE_Registry::instance()->CAP->current_user_can(
232
+				'ee_read_others_registrations',
233
+				'reg_per_event_report'
234
+			)
235
+		) {
236
+			$extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id();
237
+		}
238
+
239
+		return $wpdb->get_results(
240
+			"SELECT
241 241
 			Transaction_Event.event_name AS event_name,
242 242
 			SUM(Transaction_Event.paid) AS revenue
243 243
 			FROM
@@ -265,238 +265,238 @@  discard block
 block discarded – undo
265 265
 					$extra_event_on_join
266 266
 				) AS Transaction_Event
267 267
 			GROUP BY event_name"
268
-        );
269
-    }
270
-
271
-
272
-    /**
273
-     * Gets the current transaction given the reg_url_link, or assumes the reg_url_link is in the
274
-     * $_REQUEST global variable. Either way, tries to find the current transaction (through
275
-     * the registration pointed to by reg_url_link), if not returns null
276
-     *
277
-     * @param string $reg_url_link
278
-     *
279
-     * @return EE_Transaction
280
-     * @throws EE_Error
281
-     * @throws ReflectionException
282
-     */
283
-    public function get_transaction_from_reg_url_link(string $reg_url_link = ''): EE_Transaction
284
-    {
285
-        return $this->get_one(
286
-            [
287
-                [
288
-                    'Registration.REG_url_link' => ! empty($reg_url_link)
289
-                        ? $reg_url_link
290
-                        : EE_Registry::instance()->REQ->get(
291
-                            'e_reg_url_link',
292
-                            ''
293
-                        ),
294
-                ],
295
-            ]
296
-        );
297
-    }
298
-
299
-
300
-    /**
301
-     * Updates the provided EE_Transaction with all the applicable payments
302
-     * (or fetch the EE_Transaction from its ID)
303
-     *
304
-     * @param EE_Transaction|int $transaction_obj_or_id
305
-     * @param boolean            $save_txn whether or not to save the transaction during this function call
306
-     *
307
-     * @return array
308
-     * @throws EE_Error
309
-     * @throws ReflectionException
310
-     * @deprecated
311
-     *
312
-     */
313
-    public function update_based_on_payments($transaction_obj_or_id, bool $save_txn = true): array
314
-    {
315
-        EE_Error::doing_it_wrong(
316
-            __CLASS__ . '::' . __FUNCTION__,
317
-            sprintf(
318
-                esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
319
-                'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()'
320
-            ),
321
-            '4.6.0'
322
-        );
323
-        /** @type EE_Transaction_Processor $transaction_processor */
324
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
325
-
326
-        return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment(
327
-            $this->ensure_is_obj($transaction_obj_or_id)
328
-        );
329
-    }
330
-
331
-
332
-    /**
333
-     * Deletes "junk" transactions that were probably added by bots. There might be TONS
334
-     * of these, so we are very careful to NOT select (which the models do even when deleting),
335
-     * and so we only use wpdb directly and only do minimal joins.
336
-     * Transactions are considered "junk" if they're failed for longer than a week.
337
-     * Also, there is an extra check for payments related to the transaction, because if a transaction has a payment on
338
-     * it, it's probably not junk (regardless of what status it has).
339
-     * The downside to this approach is that is addons are listening for object deletions
340
-     * on EEM_Base::delete() they won't be notified of this.  However, there is an action that plugins can hook into
341
-     * to catch these types of deletions.
342
-     *
343
-     * @return bool|int
344
-     * @throws EE_Error
345
-     * @throws ReflectionException
346
-     * @global WPDB $wpdb
347
-     */
348
-    public function delete_junk_transactions()
349
-    {
350
-        global $wpdb;
351
-        $deleted             = false;
352
-        $time_to_leave_alone = apply_filters(
353
-            'FHEE__EEM_Transaction__delete_junk_transactions__time_to_leave_alone',
354
-            WEEK_IN_SECONDS
355
-        );
356
-
357
-
358
-        /**
359
-         * This allows code to filter the query arguments used for retrieving the transaction IDs to delete.
360
-         * Useful for plugins that want to exclude transactions matching certain query parameters.
361
-         * The query parameters should be in the format accepted by the EEM_Base model queries.
362
-         */
363
-        $ids_query = apply_filters(
364
-            'FHEE__EEM_Transaction__delete_junk_transactions__initial_query_args',
365
-            [
366
-                0          => [
367
-                    'STS_ID'         => EEM_Transaction::failed_status_code,
368
-                    'Payment.PAY_ID' => ['IS NULL'],
369
-                    'TXN_timestamp'  => ['<', time() - $time_to_leave_alone],
370
-                ],
371
-                'order_by' => ['TXN_timestamp' => 'ASC'],
372
-                'limit'    => 1000,
373
-            ],
374
-            $time_to_leave_alone
375
-        );
376
-
377
-
378
-        /**
379
-         * This filter is for when code needs to filter the list of transaction ids that represent transactions
380
-         * about to be deleted based on some other criteria that isn't easily done via the query args filter.
381
-         */
382
-        $txn_ids = apply_filters(
383
-            'FHEE__EEM_Transaction__delete_junk_transactions__transaction_ids_to_delete',
384
-            EEM_Transaction::instance()->get_col($ids_query, 'TXN_ID'),
385
-            $time_to_leave_alone
386
-        );
387
-        // now that we have the ids to delete
388
-        if (! empty($txn_ids) && is_array($txn_ids)) {
389
-            // first, make sure these TXN's are removed the "ee_locked_transactions" array
390
-            EEM_Transaction::unset_locked_transactions($txn_ids);
391
-
392
-            // Create IDs placeholder.
393
-            $placeholders = array_fill(0, count($txn_ids), '%d');
394
-
395
-            // Glue it together to use inside $wpdb->prepare.
396
-            $format = implode(', ', $placeholders);
397
-
398
-            // let's get deletin'...
399
-            // We got the ids from the original query to get them FROM
400
-            // the db (which is sanitized) so no need to prepare them again.
401
-            $query   = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids);
402
-            $deleted = $wpdb->query($query);
403
-        }
404
-        if ($deleted) {
405
-            /**
406
-             * Allows code to do something after the transactions have been deleted.
407
-             */
408
-            do_action('AHEE__EEM_Transaction__delete_junk_transactions__successful_deletion', $txn_ids);
409
-        }
410
-
411
-        return $deleted;
412
-    }
413
-
414
-
415
-    /**
416
-     * @param array $transaction_IDs
417
-     *
418
-     * @return bool
419
-     */
420
-    public static function unset_locked_transactions(array $transaction_IDs): bool
421
-    {
422
-        $locked_transactions = get_option('ee_locked_transactions', []);
423
-        $update              = false;
424
-        foreach ($transaction_IDs as $TXN_ID) {
425
-            if (isset($locked_transactions[ $TXN_ID ])) {
426
-                unset($locked_transactions[ $TXN_ID ]);
427
-                $update = true;
428
-            }
429
-        }
430
-        if ($update) {
431
-            update_option('ee_locked_transactions', $locked_transactions);
432
-        }
433
-
434
-        return $update;
435
-    }
436
-
437
-
438
-    /**
439
-     * returns an array of EE_Transaction objects whose timestamp is greater than
440
-     * the current time minus the session lifespan, which defaults to 60 minutes
441
-     *
442
-     * @return EE_Base_Class[]|EE_Transaction[]
443
-     * @throws EE_Error
444
-     * @throws InvalidArgumentException
445
-     * @throws InvalidDataTypeException
446
-     * @throws InvalidInterfaceException
447
-     * @throws ReflectionException
448
-     */
449
-    public function get_transactions_in_progress()
450
-    {
451
-        return $this->_get_transactions_in_progress();
452
-    }
453
-
454
-
455
-    /**
456
-     * returns an array of EE_Transaction objects whose timestamp is less than
457
-     * the current time minus the session lifespan, which defaults to 60 minutes
458
-     *
459
-     * @return EE_Base_Class[]|EE_Transaction[]
460
-     * @throws EE_Error
461
-     * @throws InvalidArgumentException
462
-     * @throws InvalidDataTypeException
463
-     * @throws InvalidInterfaceException
464
-     * @throws ReflectionException
465
-     */
466
-    public function get_transactions_not_in_progress()
467
-    {
468
-        return $this->_get_transactions_in_progress('<=');
469
-    }
470
-
471
-
472
-    /**
473
-     * @param string $comparison
474
-     * @return EE_Transaction[]
475
-     * @throws EE_Error
476
-     * @throws ReflectionException
477
-     */
478
-    private function _get_transactions_in_progress(string $comparison = '>='): array
479
-    {
480
-        $comparison = $comparison === '>=' || $comparison === '<='
481
-            ? $comparison
482
-            : '>=';
483
-        /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
484
-        $session_lifespan = LoaderFactory::getLoader()->getShared(
485
-            'EventEspresso\core\domain\values\session\SessionLifespan'
486
-        );
487
-        return $this->get_all(
488
-            [
489
-                [
490
-                    'TXN_timestamp' => [
491
-                        $comparison,
492
-                        $session_lifespan->expiration(),
493
-                    ],
494
-                    'STS_ID'        => [
495
-                        '!=',
496
-                        EEM_Transaction::complete_status_code,
497
-                    ],
498
-                ],
499
-            ]
500
-        );
501
-    }
268
+		);
269
+	}
270
+
271
+
272
+	/**
273
+	 * Gets the current transaction given the reg_url_link, or assumes the reg_url_link is in the
274
+	 * $_REQUEST global variable. Either way, tries to find the current transaction (through
275
+	 * the registration pointed to by reg_url_link), if not returns null
276
+	 *
277
+	 * @param string $reg_url_link
278
+	 *
279
+	 * @return EE_Transaction
280
+	 * @throws EE_Error
281
+	 * @throws ReflectionException
282
+	 */
283
+	public function get_transaction_from_reg_url_link(string $reg_url_link = ''): EE_Transaction
284
+	{
285
+		return $this->get_one(
286
+			[
287
+				[
288
+					'Registration.REG_url_link' => ! empty($reg_url_link)
289
+						? $reg_url_link
290
+						: EE_Registry::instance()->REQ->get(
291
+							'e_reg_url_link',
292
+							''
293
+						),
294
+				],
295
+			]
296
+		);
297
+	}
298
+
299
+
300
+	/**
301
+	 * Updates the provided EE_Transaction with all the applicable payments
302
+	 * (or fetch the EE_Transaction from its ID)
303
+	 *
304
+	 * @param EE_Transaction|int $transaction_obj_or_id
305
+	 * @param boolean            $save_txn whether or not to save the transaction during this function call
306
+	 *
307
+	 * @return array
308
+	 * @throws EE_Error
309
+	 * @throws ReflectionException
310
+	 * @deprecated
311
+	 *
312
+	 */
313
+	public function update_based_on_payments($transaction_obj_or_id, bool $save_txn = true): array
314
+	{
315
+		EE_Error::doing_it_wrong(
316
+			__CLASS__ . '::' . __FUNCTION__,
317
+			sprintf(
318
+				esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
319
+				'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()'
320
+			),
321
+			'4.6.0'
322
+		);
323
+		/** @type EE_Transaction_Processor $transaction_processor */
324
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
325
+
326
+		return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment(
327
+			$this->ensure_is_obj($transaction_obj_or_id)
328
+		);
329
+	}
330
+
331
+
332
+	/**
333
+	 * Deletes "junk" transactions that were probably added by bots. There might be TONS
334
+	 * of these, so we are very careful to NOT select (which the models do even when deleting),
335
+	 * and so we only use wpdb directly and only do minimal joins.
336
+	 * Transactions are considered "junk" if they're failed for longer than a week.
337
+	 * Also, there is an extra check for payments related to the transaction, because if a transaction has a payment on
338
+	 * it, it's probably not junk (regardless of what status it has).
339
+	 * The downside to this approach is that is addons are listening for object deletions
340
+	 * on EEM_Base::delete() they won't be notified of this.  However, there is an action that plugins can hook into
341
+	 * to catch these types of deletions.
342
+	 *
343
+	 * @return bool|int
344
+	 * @throws EE_Error
345
+	 * @throws ReflectionException
346
+	 * @global WPDB $wpdb
347
+	 */
348
+	public function delete_junk_transactions()
349
+	{
350
+		global $wpdb;
351
+		$deleted             = false;
352
+		$time_to_leave_alone = apply_filters(
353
+			'FHEE__EEM_Transaction__delete_junk_transactions__time_to_leave_alone',
354
+			WEEK_IN_SECONDS
355
+		);
356
+
357
+
358
+		/**
359
+		 * This allows code to filter the query arguments used for retrieving the transaction IDs to delete.
360
+		 * Useful for plugins that want to exclude transactions matching certain query parameters.
361
+		 * The query parameters should be in the format accepted by the EEM_Base model queries.
362
+		 */
363
+		$ids_query = apply_filters(
364
+			'FHEE__EEM_Transaction__delete_junk_transactions__initial_query_args',
365
+			[
366
+				0          => [
367
+					'STS_ID'         => EEM_Transaction::failed_status_code,
368
+					'Payment.PAY_ID' => ['IS NULL'],
369
+					'TXN_timestamp'  => ['<', time() - $time_to_leave_alone],
370
+				],
371
+				'order_by' => ['TXN_timestamp' => 'ASC'],
372
+				'limit'    => 1000,
373
+			],
374
+			$time_to_leave_alone
375
+		);
376
+
377
+
378
+		/**
379
+		 * This filter is for when code needs to filter the list of transaction ids that represent transactions
380
+		 * about to be deleted based on some other criteria that isn't easily done via the query args filter.
381
+		 */
382
+		$txn_ids = apply_filters(
383
+			'FHEE__EEM_Transaction__delete_junk_transactions__transaction_ids_to_delete',
384
+			EEM_Transaction::instance()->get_col($ids_query, 'TXN_ID'),
385
+			$time_to_leave_alone
386
+		);
387
+		// now that we have the ids to delete
388
+		if (! empty($txn_ids) && is_array($txn_ids)) {
389
+			// first, make sure these TXN's are removed the "ee_locked_transactions" array
390
+			EEM_Transaction::unset_locked_transactions($txn_ids);
391
+
392
+			// Create IDs placeholder.
393
+			$placeholders = array_fill(0, count($txn_ids), '%d');
394
+
395
+			// Glue it together to use inside $wpdb->prepare.
396
+			$format = implode(', ', $placeholders);
397
+
398
+			// let's get deletin'...
399
+			// We got the ids from the original query to get them FROM
400
+			// the db (which is sanitized) so no need to prepare them again.
401
+			$query   = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids);
402
+			$deleted = $wpdb->query($query);
403
+		}
404
+		if ($deleted) {
405
+			/**
406
+			 * Allows code to do something after the transactions have been deleted.
407
+			 */
408
+			do_action('AHEE__EEM_Transaction__delete_junk_transactions__successful_deletion', $txn_ids);
409
+		}
410
+
411
+		return $deleted;
412
+	}
413
+
414
+
415
+	/**
416
+	 * @param array $transaction_IDs
417
+	 *
418
+	 * @return bool
419
+	 */
420
+	public static function unset_locked_transactions(array $transaction_IDs): bool
421
+	{
422
+		$locked_transactions = get_option('ee_locked_transactions', []);
423
+		$update              = false;
424
+		foreach ($transaction_IDs as $TXN_ID) {
425
+			if (isset($locked_transactions[ $TXN_ID ])) {
426
+				unset($locked_transactions[ $TXN_ID ]);
427
+				$update = true;
428
+			}
429
+		}
430
+		if ($update) {
431
+			update_option('ee_locked_transactions', $locked_transactions);
432
+		}
433
+
434
+		return $update;
435
+	}
436
+
437
+
438
+	/**
439
+	 * returns an array of EE_Transaction objects whose timestamp is greater than
440
+	 * the current time minus the session lifespan, which defaults to 60 minutes
441
+	 *
442
+	 * @return EE_Base_Class[]|EE_Transaction[]
443
+	 * @throws EE_Error
444
+	 * @throws InvalidArgumentException
445
+	 * @throws InvalidDataTypeException
446
+	 * @throws InvalidInterfaceException
447
+	 * @throws ReflectionException
448
+	 */
449
+	public function get_transactions_in_progress()
450
+	{
451
+		return $this->_get_transactions_in_progress();
452
+	}
453
+
454
+
455
+	/**
456
+	 * returns an array of EE_Transaction objects whose timestamp is less than
457
+	 * the current time minus the session lifespan, which defaults to 60 minutes
458
+	 *
459
+	 * @return EE_Base_Class[]|EE_Transaction[]
460
+	 * @throws EE_Error
461
+	 * @throws InvalidArgumentException
462
+	 * @throws InvalidDataTypeException
463
+	 * @throws InvalidInterfaceException
464
+	 * @throws ReflectionException
465
+	 */
466
+	public function get_transactions_not_in_progress()
467
+	{
468
+		return $this->_get_transactions_in_progress('<=');
469
+	}
470
+
471
+
472
+	/**
473
+	 * @param string $comparison
474
+	 * @return EE_Transaction[]
475
+	 * @throws EE_Error
476
+	 * @throws ReflectionException
477
+	 */
478
+	private function _get_transactions_in_progress(string $comparison = '>='): array
479
+	{
480
+		$comparison = $comparison === '>=' || $comparison === '<='
481
+			? $comparison
482
+			: '>=';
483
+		/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
484
+		$session_lifespan = LoaderFactory::getLoader()->getShared(
485
+			'EventEspresso\core\domain\values\session\SessionLifespan'
486
+		);
487
+		return $this->get_all(
488
+			[
489
+				[
490
+					'TXN_timestamp' => [
491
+						$comparison,
492
+						$session_lifespan->expiration(),
493
+					],
494
+					'STS_ID'        => [
495
+						'!=',
496
+						EEM_Transaction::complete_status_code,
497
+					],
498
+				],
499
+			]
500
+		);
501
+	}
502 502
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
                 ),
137 137
             ],
138 138
         ];
139
-        $this->_model_relations        = [
139
+        $this->_model_relations = [
140 140
             'Registration'   => new EE_Has_Many_Relation(),
141 141
             'Payment'        => new EE_Has_Many_Relation(),
142 142
             'Status'         => new EE_Belongs_To_Relation(),
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
             ],
203 203
             OBJECT,
204 204
             [
205
-                'txnDate' => ['DATE(' . $query_interval . ')', '%s'],
205
+                'txnDate' => ['DATE('.$query_interval.')', '%s'],
206 206
                 'revenue' => ['SUM(TransactionTable.TXN_paid)', '%d'],
207 207
             ]
208 208
         );
@@ -218,11 +218,11 @@  discard block
 block discarded – undo
218 218
     public function get_revenue_per_event_report(string $period = '-1 month'): array
219 219
     {
220 220
         global $wpdb;
221
-        $transaction_table          = $wpdb->prefix . 'esp_transaction';
222
-        $registration_table         = $wpdb->prefix . 'esp_registration';
223
-        $registration_payment_table = $wpdb->prefix . 'esp_registration_payment';
221
+        $transaction_table          = $wpdb->prefix.'esp_transaction';
222
+        $registration_table         = $wpdb->prefix.'esp_registration';
223
+        $registration_payment_table = $wpdb->prefix.'esp_registration_payment';
224 224
         $event_table                = $wpdb->posts;
225
-        $payment_table              = $wpdb->prefix . 'esp_payment';
225
+        $payment_table              = $wpdb->prefix.'esp_payment';
226 226
         $sql_date                   = date('Y-m-d H:i:s', strtotime($period));
227 227
         $approved_payment_status    = EEM_Payment::status_id_approved;
228 228
         $extra_event_on_join        = '';
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
                 'reg_per_event_report'
234 234
             )
235 235
         ) {
236
-            $extra_event_on_join = ' AND Event.post_author = ' . get_current_user_id();
236
+            $extra_event_on_join = ' AND Event.post_author = '.get_current_user_id();
237 237
         }
238 238
 
239 239
         return $wpdb->get_results(
@@ -313,7 +313,7 @@  discard block
 block discarded – undo
313 313
     public function update_based_on_payments($transaction_obj_or_id, bool $save_txn = true): array
314 314
     {
315 315
         EE_Error::doing_it_wrong(
316
-            __CLASS__ . '::' . __FUNCTION__,
316
+            __CLASS__.'::'.__FUNCTION__,
317 317
             sprintf(
318 318
                 esc_html__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
319 319
                 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()'
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
             $time_to_leave_alone
386 386
         );
387 387
         // now that we have the ids to delete
388
-        if (! empty($txn_ids) && is_array($txn_ids)) {
388
+        if ( ! empty($txn_ids) && is_array($txn_ids)) {
389 389
             // first, make sure these TXN's are removed the "ee_locked_transactions" array
390 390
             EEM_Transaction::unset_locked_transactions($txn_ids);
391 391
 
@@ -398,7 +398,7 @@  discard block
 block discarded – undo
398 398
             // let's get deletin'...
399 399
             // We got the ids from the original query to get them FROM
400 400
             // the db (which is sanitized) so no need to prepare them again.
401
-            $query   = $wpdb->prepare("DELETE FROM " . $this->table() . " WHERE TXN_ID IN ( $format )", $txn_ids);
401
+            $query   = $wpdb->prepare("DELETE FROM ".$this->table()." WHERE TXN_ID IN ( $format )", $txn_ids);
402 402
             $deleted = $wpdb->query($query);
403 403
         }
404 404
         if ($deleted) {
@@ -422,8 +422,8 @@  discard block
 block discarded – undo
422 422
         $locked_transactions = get_option('ee_locked_transactions', []);
423 423
         $update              = false;
424 424
         foreach ($transaction_IDs as $TXN_ID) {
425
-            if (isset($locked_transactions[ $TXN_ID ])) {
426
-                unset($locked_transactions[ $TXN_ID ]);
425
+            if (isset($locked_transactions[$TXN_ID])) {
426
+                unset($locked_transactions[$TXN_ID]);
427 427
                 $update = true;
428 428
             }
429 429
         }
Please login to merge, or discard this patch.
core/db_models/fields/EE_Datetime_Field.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -563,7 +563,7 @@  discard block
 block discarded – undo
563 563
      * allowed)
564 564
      *
565 565
      * @param string $datetime_string mysql timestamp in UTC
566
-     * @return  mixed null | DateTime
566
+     * @return  null|DbSafeDateTime null | DateTime
567 567
      * @throws EE_Error
568 568
      */
569 569
     public function prepare_for_set_from_db($datetime_string)
@@ -702,7 +702,7 @@  discard block
 block discarded – undo
702 702
      *
703 703
      * @param DateTimeZone $DateTimeZone
704 704
      * @param int          $time
705
-     * @return mixed
705
+     * @return integer
706 706
      * @throws DomainException
707 707
      */
708 708
     public function get_timezone_offset(DateTimeZone $DateTimeZone, $time = null)
@@ -745,7 +745,7 @@  discard block
 block discarded – undo
745 745
     /**
746 746
      * Gets the default datetime object from the field's default time
747 747
      *
748
-     * @return DbSafeDateTime|null
748
+     * @return DateTime|null
749 749
      * @throws InvalidArgumentException
750 750
      * @throws InvalidDataTypeException
751 751
      * @throws InvalidInterfaceException
Please login to merge, or discard this patch.
Indentation   +757 added lines, -757 removed lines patch added patch discarded remove patch
@@ -16,762 +16,762 @@
 block discarded – undo
16 16
 class EE_Datetime_Field extends EE_Model_Field_Base
17 17
 {
18 18
 
19
-    /**
20
-     * The pattern we're looking for is if only the characters 0-9 are found and there are only
21
-     * 10 or more numbers (because 9 numbers even with all 9's would be sometime in 2001 )
22
-     *
23
-     * @type string unix_timestamp_regex
24
-     */
25
-    const unix_timestamp_regex = '/[0-9]{10,}/';
26
-
27
-    /**
28
-     * @type string mysql_timestamp_format
29
-     */
30
-    const mysql_timestamp_format = 'Y-m-d H:i:s';
31
-
32
-    /**
33
-     * @type string mysql_date_format
34
-     */
35
-    const mysql_date_format = 'Y-m-d';
36
-
37
-    /**
38
-     * @type string mysql_time_format
39
-     */
40
-    const mysql_time_format = 'H:i:s';
41
-
42
-    /**
43
-     * Const for using in the default value. If the field's default is set to this,
44
-     * then we will return the time of calling `get_default_value()`, not
45
-     * just the current time at construction
46
-     */
47
-    const now = 'now';
48
-
49
-    /**
50
-     * The following properties hold the default formats for date and time.
51
-     * Defaults are set via the constructor and can be overridden on class instantiation.
52
-     * However they can also be overridden later by the set_format() method
53
-     * (and corresponding set_date_format, set_time_format methods);
54
-     */
55
-    /**
56
-     * @type string $_date_format
57
-     */
58
-    protected $_date_format = '';
59
-
60
-    /**
61
-     * @type string $_time_format
62
-     */
63
-    protected $_time_format = '';
64
-
65
-    /**
66
-     * @type string $_pretty_date_format
67
-     */
68
-    protected $_pretty_date_format = '';
69
-
70
-    /**
71
-     * @type string $_pretty_time_format
72
-     */
73
-    protected $_pretty_time_format = '';
74
-
75
-    /**
76
-     * @type DateTimeZone $_DateTimeZone
77
-     */
78
-    protected $_DateTimeZone;
79
-
80
-    /**
81
-     * @type DateTimeZone $_UTC_DateTimeZone
82
-     */
83
-    protected $_UTC_DateTimeZone;
84
-
85
-    /**
86
-     * @type DateTimeZone $_blog_DateTimeZone
87
-     */
88
-    protected $_blog_DateTimeZone;
89
-
90
-
91
-    /**
92
-     * This property holds how we want the output returned when getting a datetime string.  It is set for the
93
-     * set_date_time_output() method.  By default this is empty.  When empty, we are assuming that we want both date
94
-     * and time returned via getters.
95
-     *
96
-     * @var string
97
-     */
98
-    protected $_date_time_output = '';
99
-
100
-
101
-    /**
102
-     * timezone string
103
-     * This gets set by the constructor and can be changed by the "set_timezone()" method so that we know what timezone
104
-     * incoming strings|timestamps are in.  This can also be used before a get to set what timezone you want strings
105
-     * coming out of the object to be in.  Default timezone is the current WP timezone option setting
106
-     *
107
-     * @var string
108
-     */
109
-    protected $_timezone_string;
110
-
111
-
112
-    /**
113
-     * This holds whatever UTC offset for the blog (we automatically convert timezone strings into their related
114
-     * offsets for comparison purposes).
115
-     *
116
-     * @var int
117
-     */
118
-    protected $_blog_offset;
119
-
120
-
121
-    /**
122
-     * @param string $table_column
123
-     * @param string $nice_name
124
-     * @param bool   $nullable
125
-     * @param string $default_value
126
-     * @param string $timezone_string
127
-     * @param string $date_format
128
-     * @param string $time_format
129
-     * @param string $pretty_date_format
130
-     * @param string $pretty_time_format
131
-     */
132
-    public function __construct(
133
-        string $table_column,
134
-        string $nice_name,
135
-        bool $nullable,
136
-        string $default_value,
137
-        string $timezone_string = '',
138
-        string $date_format = '',
139
-        string $time_format = '',
140
-        string $pretty_date_format = '',
141
-        string $pretty_time_format = ''
142
-    ) {
143
-
144
-        $this->_date_format        = ! empty($date_format)
145
-            ? $date_format
146
-            : get_option('date_format');
147
-        $this->_time_format        = ! empty($time_format)
148
-            ? $time_format
149
-            : get_option('time_format');
150
-        $this->_pretty_date_format = ! empty($pretty_date_format)
151
-            ? $pretty_date_format
152
-            : get_option('date_format');
153
-        $this->_pretty_time_format = ! empty($pretty_time_format)
154
-            ? $pretty_time_format
155
-            : get_option('time_format');
156
-
157
-        parent::__construct($table_column, $nice_name, $nullable, $default_value);
158
-        $this->set_timezone($timezone_string);
159
-        $this->setSchemaFormat('date-time');
160
-    }
161
-
162
-
163
-    /**
164
-     * @return DateTimeZone
165
-     */
166
-    public function get_UTC_DateTimeZone(): DateTimeZone
167
-    {
168
-        return $this->_UTC_DateTimeZone instanceof DateTimeZone
169
-            ? $this->_UTC_DateTimeZone
170
-            : $this->_create_timezone_object_from_timezone_string('UTC');
171
-    }
172
-
173
-
174
-    /**
175
-     * @return DateTimeZone
176
-     */
177
-    public function get_blog_DateTimeZone(): DateTimeZone
178
-    {
179
-        return $this->_blog_DateTimeZone instanceof DateTimeZone
180
-            ? $this->_blog_DateTimeZone
181
-            : $this->_create_timezone_object_from_timezone_string();
182
-    }
183
-
184
-
185
-    /**
186
-     * this prepares any incoming date data and make sure its converted to a utc unix timestamp
187
-     *
188
-     * @param string|int $value_inputted_for_field_on_model_object  could be a string formatted date time or int unix
189
-     *                                                              timestamp
190
-     * @return DateTime
191
-     */
192
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
193
-    {
194
-        return $this->_get_date_object($value_inputted_for_field_on_model_object);
195
-    }
196
-
197
-
198
-    /**
199
-     * This returns the format string to be used by getters depending on what the $_date_time_output property is set at.
200
-     * getters need to know whether we're just returning the date or the time or both.  By default we return both.
201
-     *
202
-     * @param bool $pretty If we're returning the pretty formats or standard format string.
203
-     * @return string    The final assembled format string.
204
-     */
205
-    protected function _get_date_time_output(bool $pretty = false): string
206
-    {
207
-        $pretty = filter_var($pretty, FILTER_VALIDATE_BOOLEAN);
208
-        switch ($this->_date_time_output) {
209
-            case 'time':
210
-                return $pretty
211
-                    ? $this->_pretty_time_format
212
-                    : $this->_time_format;
213
-
214
-            case 'date':
215
-                return $pretty
216
-                    ? $this->_pretty_date_format
217
-                    : $this->_date_format;
218
-
219
-            default:
220
-                return $pretty
221
-                    ? $this->_pretty_date_format . ' ' . $this->_pretty_time_format
222
-                    : $this->_date_format . ' ' . $this->_time_format;
223
-        }
224
-    }
225
-
226
-
227
-    /**
228
-     * This just sets the $_date_time_output property so we can flag how date and times are formatted before being
229
-     * returned (using the format properties)
230
-     *
231
-     * @param string $what acceptable values are 'time' or 'date'.
232
-     *                     Any other value will be set but will always result
233
-     *                     in both 'date' and 'time' being returned.
234
-     * @return void
235
-     */
236
-    public function set_date_time_output(string $what = '')
237
-    {
238
-        $this->_date_time_output = $what;
239
-    }
240
-
241
-
242
-    /**
243
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
244
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
245
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp).
246
-     * We also set some other properties in this method.
247
-     *
248
-     * @param string $timezone_string A valid timezone string as described by @link
249
-     *                                http://www.php.net/manual/en/timezones.php
250
-     * @return void
251
-     * @throws InvalidArgumentException
252
-     * @throws InvalidDataTypeException
253
-     * @throws InvalidInterfaceException
254
-     */
255
-    public function set_timezone(string $timezone_string)
256
-    {
257
-        if (empty($timezone_string) && ! empty($this->_timezone_string)) {
258
-            // leave the timezone AS-IS if we already have one and
259
-            // the function arg didn't provide one
260
-            return;
261
-        }
262
-        $timezone_string        = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
263
-        $this->_timezone_string = ! empty($timezone_string)
264
-            ? $timezone_string
265
-            : 'UTC';
266
-        $this->_DateTimeZone    = $this->_create_timezone_object_from_timezone_string($this->_timezone_string);
267
-    }
268
-
269
-
270
-    /**
271
-     * _create_timezone_object_from_timezone_name
272
-     *
273
-     * @param string $timezone_string
274
-     * @return DateTimeZone
275
-     * @throws InvalidArgumentException
276
-     * @throws InvalidDataTypeException
277
-     * @throws InvalidInterfaceException
278
-     */
279
-    protected function _create_timezone_object_from_timezone_string(string $timezone_string = ''): DateTimeZone
280
-    {
281
-        return new DateTimeZone(EEH_DTT_Helper::get_valid_timezone_string($timezone_string));
282
-    }
283
-
284
-
285
-    /**
286
-     * This just returns whatever is set for the current timezone.
287
-     *
288
-     * @return string timezone string
289
-     */
290
-    public function get_timezone(): string
291
-    {
292
-        return $this->_timezone_string;
293
-    }
294
-
295
-
296
-    /**
297
-     * set the $_date_format property
298
-     *
299
-     * @param string $format a new date format (corresponding to formats accepted by PHP date() function)
300
-     * @param bool   $pretty Whether to set pretty format or not.
301
-     * @return void
302
-     */
303
-    public function set_date_format(string $format, bool $pretty = false)
304
-    {
305
-        if ($pretty) {
306
-            $this->_pretty_date_format = $format;
307
-        } else {
308
-            $this->_date_format = $format;
309
-        }
310
-    }
311
-
312
-
313
-    /**
314
-     * return the $_date_format property value.
315
-     *
316
-     * @param bool $pretty Whether to get pretty format or not.
317
-     * @return string
318
-     */
319
-    public function get_date_format(bool $pretty = false): string
320
-    {
321
-        return $pretty
322
-            ? $this->_pretty_date_format
323
-            : $this->_date_format;
324
-    }
325
-
326
-
327
-    /**
328
-     * set the $_time_format property
329
-     *
330
-     * @param string $format a new time format (corresponding to formats accepted by PHP date() function)
331
-     * @param bool   $pretty Whether to set pretty format or not.
332
-     * @return void
333
-     */
334
-    public function set_time_format(string $format, bool $pretty = false)
335
-    {
336
-        if ($pretty) {
337
-            $this->_pretty_time_format = $format;
338
-        } else {
339
-            $this->_time_format = $format;
340
-        }
341
-    }
342
-
343
-
344
-    /**
345
-     * return the $_time_format property value.
346
-     *
347
-     * @param bool $pretty Whether to get pretty format or not.
348
-     * @return string
349
-     */
350
-    public function get_time_format(bool $pretty = false): string
351
-    {
352
-        return $pretty
353
-            ? $this->_pretty_time_format
354
-            : $this->_time_format;
355
-    }
356
-
357
-
358
-    /**
359
-     * set the $_pretty_date_format property
360
-     *
361
-     * @param string $format a new pretty date format (corresponding to formats accepted by PHP date() function)
362
-     * @return void
363
-     */
364
-    public function set_pretty_date_format(string $format)
365
-    {
366
-        $this->_pretty_date_format = $format;
367
-    }
368
-
369
-
370
-    /**
371
-     * set the $_pretty_time_format property
372
-     *
373
-     * @param string $format a new pretty time format (corresponding to formats accepted by PHP date() function)
374
-     * @return void
375
-     */
376
-    public function set_pretty_time_format(string $format)
377
-    {
378
-        $this->_pretty_time_format = $format;
379
-    }
380
-
381
-
382
-    /**
383
-     * Only sets the time portion of the datetime.
384
-     *
385
-     * @param string|DateTime $time_to_set_string like 8am OR a DateTime object.
386
-     * @param DateTime        $current            current DateTime object for the datetime field
387
-     * @return DateTime
388
-     */
389
-    public function prepare_for_set_with_new_time($time_to_set_string, DateTime $current): DateTime
390
-    {
391
-        // if $time_to_set_string is datetime object, then let's use it to set the parse array.
392
-        // Otherwise parse the string.
393
-        if ($time_to_set_string instanceof DateTime) {
394
-            $parsed = [
395
-                'hour'   => $time_to_set_string->format('H'),
396
-                'minute' => $time_to_set_string->format('i'),
397
-                'second' => $time_to_set_string->format('s'),
398
-            ];
399
-        } else {
400
-            // parse incoming string
401
-            $parsed = date_parse_from_format($this->_time_format, $time_to_set_string);
402
-        }
403
-        EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
404
-        return $current->setTime($parsed['hour'], $parsed['minute'], $parsed['second']);
405
-    }
406
-
407
-
408
-    /**
409
-     * Only sets the date portion of the datetime.
410
-     *
411
-     * @param string|DateTime $date_to_set_string like Friday, January 8th or a DateTime object.
412
-     * @param DateTime        $current            current DateTime object for the datetime field
413
-     * @return DateTime
414
-     */
415
-    public function prepare_for_set_with_new_date($date_to_set_string, DateTime $current): DateTime
416
-    {
417
-        // if $time_to_set_string is datetime object, then let's use it to set the parse array.
418
-        // Otherwise parse the string.
419
-        if ($date_to_set_string instanceof DateTime) {
420
-            $parsed = [
421
-                'year'  => $date_to_set_string->format('Y'),
422
-                'month' => $date_to_set_string->format('m'),
423
-                'day'   => $date_to_set_string->format('d'),
424
-            ];
425
-        } else {
426
-            // parse incoming string
427
-            $parsed = date_parse_from_format($this->_date_format, $date_to_set_string);
428
-        }
429
-        EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
430
-        return $current->setDate($parsed['year'], $parsed['month'], $parsed['day']);
431
-    }
432
-
433
-
434
-    /**
435
-     * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0 timezone).  When the
436
-     * datetime gets to this stage it should ALREADY be in UTC time
437
-     *
438
-     * @param DateTime $DateTime
439
-     * @return string formatted date time for given timezone
440
-     * @throws EE_Error
441
-     */
442
-    public function prepare_for_get($DateTime): string
443
-    {
444
-        return $this->_prepare_for_display($DateTime);
445
-    }
446
-
447
-
448
-    /**
449
-     * This differs from prepare_for_get in that it considers whether the internal $_timezone differs
450
-     * from the set wp timezone.  If so, then it returns the datetime string formatted via
451
-     * _pretty_date_format, and _pretty_time_format.  However, it also appends a timezone
452
-     * abbreviation to the date_string.
453
-     *
454
-     * @param DateTime $DateTime
455
-     * @param string $schema
456
-     * @return string
457
-     * @throws EE_Error
458
-     */
459
-    public function prepare_for_pretty_echoing($DateTime, string $schema = 'pretty'): string
460
-    {
461
-        return $this->_prepare_for_display($DateTime, $schema);
462
-    }
463
-
464
-
465
-    /**
466
-     * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
467
-     * timezone).
468
-     *
469
-     * @param DateTime $DateTime
470
-     * @param string   $schema
471
-     * @return string
472
-     * @throws EE_Error
473
-     */
474
-    protected function _prepare_for_display(DateTime $DateTime, string $schema = ''): string
475
-    {
476
-        if (! $DateTime instanceof DateTime) {
477
-            if ($this->_nullable) {
478
-                return '';
479
-            } else {
480
-                if (WP_DEBUG) {
481
-                    throw new EE_Error(
482
-                        sprintf(
483
-                            esc_html__(
484
-                                'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.',
485
-                                'event_espresso'
486
-                            ),
487
-                            $this->_nicename
488
-                        )
489
-                    );
490
-                } else {
491
-                    $DateTime = new DbSafeDateTime(EE_Datetime_Field::now);
492
-                    EE_Error::add_error(
493
-                        sprintf(
494
-                            esc_html__(
495
-                                'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.  When WP_DEBUG is false, the value is set to "now" instead of throwing an exception.',
496
-                                'event_espresso'
497
-                            ),
498
-                            $this->_nicename
499
-                        )
500
-                    );
501
-                }
502
-            }
503
-        }
504
-        $pretty = $schema === 'pretty';
505
-        $format_string = $this->_get_date_time_output($pretty);
506
-        EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
507
-
508
-        $timezone_string = '';
509
-        if ($this->_display_timezone()) {
510
-            // must be explicit because schema could equal true.
511
-            $timezone_string = $schema === 'no_html'
512
-                ? ' (' . $DateTime->format('T') . ')'
513
-                : ' <span class="ee_dtt_timezone_string">(' . $DateTime->format('T') . ')</span>';
514
-        }
515
-        return $DateTime->format($format_string) . $timezone_string;
516
-    }
517
-
518
-
519
-    /**
520
-     * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
521
-     * timezone).
522
-     *
523
-     * @param DateTime|null $datetime_value
524
-     * @return string mysql timestamp in UTC
525
-     * @throws EE_Error
526
-     */
527
-    public function prepare_for_use_in_db($datetime_value)
528
-    {
529
-        // we allow an empty value or DateTime object, but nothing else.
530
-        if (! empty($datetime_value) && ! $datetime_value instanceof DateTime) {
531
-            throw new EE_Error(
532
-                sprintf(
533
-                    esc_html__(
534
-                        'The incoming value being prepared for setting in the database must either be empty or a php 
19
+	/**
20
+	 * The pattern we're looking for is if only the characters 0-9 are found and there are only
21
+	 * 10 or more numbers (because 9 numbers even with all 9's would be sometime in 2001 )
22
+	 *
23
+	 * @type string unix_timestamp_regex
24
+	 */
25
+	const unix_timestamp_regex = '/[0-9]{10,}/';
26
+
27
+	/**
28
+	 * @type string mysql_timestamp_format
29
+	 */
30
+	const mysql_timestamp_format = 'Y-m-d H:i:s';
31
+
32
+	/**
33
+	 * @type string mysql_date_format
34
+	 */
35
+	const mysql_date_format = 'Y-m-d';
36
+
37
+	/**
38
+	 * @type string mysql_time_format
39
+	 */
40
+	const mysql_time_format = 'H:i:s';
41
+
42
+	/**
43
+	 * Const for using in the default value. If the field's default is set to this,
44
+	 * then we will return the time of calling `get_default_value()`, not
45
+	 * just the current time at construction
46
+	 */
47
+	const now = 'now';
48
+
49
+	/**
50
+	 * The following properties hold the default formats for date and time.
51
+	 * Defaults are set via the constructor and can be overridden on class instantiation.
52
+	 * However they can also be overridden later by the set_format() method
53
+	 * (and corresponding set_date_format, set_time_format methods);
54
+	 */
55
+	/**
56
+	 * @type string $_date_format
57
+	 */
58
+	protected $_date_format = '';
59
+
60
+	/**
61
+	 * @type string $_time_format
62
+	 */
63
+	protected $_time_format = '';
64
+
65
+	/**
66
+	 * @type string $_pretty_date_format
67
+	 */
68
+	protected $_pretty_date_format = '';
69
+
70
+	/**
71
+	 * @type string $_pretty_time_format
72
+	 */
73
+	protected $_pretty_time_format = '';
74
+
75
+	/**
76
+	 * @type DateTimeZone $_DateTimeZone
77
+	 */
78
+	protected $_DateTimeZone;
79
+
80
+	/**
81
+	 * @type DateTimeZone $_UTC_DateTimeZone
82
+	 */
83
+	protected $_UTC_DateTimeZone;
84
+
85
+	/**
86
+	 * @type DateTimeZone $_blog_DateTimeZone
87
+	 */
88
+	protected $_blog_DateTimeZone;
89
+
90
+
91
+	/**
92
+	 * This property holds how we want the output returned when getting a datetime string.  It is set for the
93
+	 * set_date_time_output() method.  By default this is empty.  When empty, we are assuming that we want both date
94
+	 * and time returned via getters.
95
+	 *
96
+	 * @var string
97
+	 */
98
+	protected $_date_time_output = '';
99
+
100
+
101
+	/**
102
+	 * timezone string
103
+	 * This gets set by the constructor and can be changed by the "set_timezone()" method so that we know what timezone
104
+	 * incoming strings|timestamps are in.  This can also be used before a get to set what timezone you want strings
105
+	 * coming out of the object to be in.  Default timezone is the current WP timezone option setting
106
+	 *
107
+	 * @var string
108
+	 */
109
+	protected $_timezone_string;
110
+
111
+
112
+	/**
113
+	 * This holds whatever UTC offset for the blog (we automatically convert timezone strings into their related
114
+	 * offsets for comparison purposes).
115
+	 *
116
+	 * @var int
117
+	 */
118
+	protected $_blog_offset;
119
+
120
+
121
+	/**
122
+	 * @param string $table_column
123
+	 * @param string $nice_name
124
+	 * @param bool   $nullable
125
+	 * @param string $default_value
126
+	 * @param string $timezone_string
127
+	 * @param string $date_format
128
+	 * @param string $time_format
129
+	 * @param string $pretty_date_format
130
+	 * @param string $pretty_time_format
131
+	 */
132
+	public function __construct(
133
+		string $table_column,
134
+		string $nice_name,
135
+		bool $nullable,
136
+		string $default_value,
137
+		string $timezone_string = '',
138
+		string $date_format = '',
139
+		string $time_format = '',
140
+		string $pretty_date_format = '',
141
+		string $pretty_time_format = ''
142
+	) {
143
+
144
+		$this->_date_format        = ! empty($date_format)
145
+			? $date_format
146
+			: get_option('date_format');
147
+		$this->_time_format        = ! empty($time_format)
148
+			? $time_format
149
+			: get_option('time_format');
150
+		$this->_pretty_date_format = ! empty($pretty_date_format)
151
+			? $pretty_date_format
152
+			: get_option('date_format');
153
+		$this->_pretty_time_format = ! empty($pretty_time_format)
154
+			? $pretty_time_format
155
+			: get_option('time_format');
156
+
157
+		parent::__construct($table_column, $nice_name, $nullable, $default_value);
158
+		$this->set_timezone($timezone_string);
159
+		$this->setSchemaFormat('date-time');
160
+	}
161
+
162
+
163
+	/**
164
+	 * @return DateTimeZone
165
+	 */
166
+	public function get_UTC_DateTimeZone(): DateTimeZone
167
+	{
168
+		return $this->_UTC_DateTimeZone instanceof DateTimeZone
169
+			? $this->_UTC_DateTimeZone
170
+			: $this->_create_timezone_object_from_timezone_string('UTC');
171
+	}
172
+
173
+
174
+	/**
175
+	 * @return DateTimeZone
176
+	 */
177
+	public function get_blog_DateTimeZone(): DateTimeZone
178
+	{
179
+		return $this->_blog_DateTimeZone instanceof DateTimeZone
180
+			? $this->_blog_DateTimeZone
181
+			: $this->_create_timezone_object_from_timezone_string();
182
+	}
183
+
184
+
185
+	/**
186
+	 * this prepares any incoming date data and make sure its converted to a utc unix timestamp
187
+	 *
188
+	 * @param string|int $value_inputted_for_field_on_model_object  could be a string formatted date time or int unix
189
+	 *                                                              timestamp
190
+	 * @return DateTime
191
+	 */
192
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
193
+	{
194
+		return $this->_get_date_object($value_inputted_for_field_on_model_object);
195
+	}
196
+
197
+
198
+	/**
199
+	 * This returns the format string to be used by getters depending on what the $_date_time_output property is set at.
200
+	 * getters need to know whether we're just returning the date or the time or both.  By default we return both.
201
+	 *
202
+	 * @param bool $pretty If we're returning the pretty formats or standard format string.
203
+	 * @return string    The final assembled format string.
204
+	 */
205
+	protected function _get_date_time_output(bool $pretty = false): string
206
+	{
207
+		$pretty = filter_var($pretty, FILTER_VALIDATE_BOOLEAN);
208
+		switch ($this->_date_time_output) {
209
+			case 'time':
210
+				return $pretty
211
+					? $this->_pretty_time_format
212
+					: $this->_time_format;
213
+
214
+			case 'date':
215
+				return $pretty
216
+					? $this->_pretty_date_format
217
+					: $this->_date_format;
218
+
219
+			default:
220
+				return $pretty
221
+					? $this->_pretty_date_format . ' ' . $this->_pretty_time_format
222
+					: $this->_date_format . ' ' . $this->_time_format;
223
+		}
224
+	}
225
+
226
+
227
+	/**
228
+	 * This just sets the $_date_time_output property so we can flag how date and times are formatted before being
229
+	 * returned (using the format properties)
230
+	 *
231
+	 * @param string $what acceptable values are 'time' or 'date'.
232
+	 *                     Any other value will be set but will always result
233
+	 *                     in both 'date' and 'time' being returned.
234
+	 * @return void
235
+	 */
236
+	public function set_date_time_output(string $what = '')
237
+	{
238
+		$this->_date_time_output = $what;
239
+	}
240
+
241
+
242
+	/**
243
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
244
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
245
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp).
246
+	 * We also set some other properties in this method.
247
+	 *
248
+	 * @param string $timezone_string A valid timezone string as described by @link
249
+	 *                                http://www.php.net/manual/en/timezones.php
250
+	 * @return void
251
+	 * @throws InvalidArgumentException
252
+	 * @throws InvalidDataTypeException
253
+	 * @throws InvalidInterfaceException
254
+	 */
255
+	public function set_timezone(string $timezone_string)
256
+	{
257
+		if (empty($timezone_string) && ! empty($this->_timezone_string)) {
258
+			// leave the timezone AS-IS if we already have one and
259
+			// the function arg didn't provide one
260
+			return;
261
+		}
262
+		$timezone_string        = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
263
+		$this->_timezone_string = ! empty($timezone_string)
264
+			? $timezone_string
265
+			: 'UTC';
266
+		$this->_DateTimeZone    = $this->_create_timezone_object_from_timezone_string($this->_timezone_string);
267
+	}
268
+
269
+
270
+	/**
271
+	 * _create_timezone_object_from_timezone_name
272
+	 *
273
+	 * @param string $timezone_string
274
+	 * @return DateTimeZone
275
+	 * @throws InvalidArgumentException
276
+	 * @throws InvalidDataTypeException
277
+	 * @throws InvalidInterfaceException
278
+	 */
279
+	protected function _create_timezone_object_from_timezone_string(string $timezone_string = ''): DateTimeZone
280
+	{
281
+		return new DateTimeZone(EEH_DTT_Helper::get_valid_timezone_string($timezone_string));
282
+	}
283
+
284
+
285
+	/**
286
+	 * This just returns whatever is set for the current timezone.
287
+	 *
288
+	 * @return string timezone string
289
+	 */
290
+	public function get_timezone(): string
291
+	{
292
+		return $this->_timezone_string;
293
+	}
294
+
295
+
296
+	/**
297
+	 * set the $_date_format property
298
+	 *
299
+	 * @param string $format a new date format (corresponding to formats accepted by PHP date() function)
300
+	 * @param bool   $pretty Whether to set pretty format or not.
301
+	 * @return void
302
+	 */
303
+	public function set_date_format(string $format, bool $pretty = false)
304
+	{
305
+		if ($pretty) {
306
+			$this->_pretty_date_format = $format;
307
+		} else {
308
+			$this->_date_format = $format;
309
+		}
310
+	}
311
+
312
+
313
+	/**
314
+	 * return the $_date_format property value.
315
+	 *
316
+	 * @param bool $pretty Whether to get pretty format or not.
317
+	 * @return string
318
+	 */
319
+	public function get_date_format(bool $pretty = false): string
320
+	{
321
+		return $pretty
322
+			? $this->_pretty_date_format
323
+			: $this->_date_format;
324
+	}
325
+
326
+
327
+	/**
328
+	 * set the $_time_format property
329
+	 *
330
+	 * @param string $format a new time format (corresponding to formats accepted by PHP date() function)
331
+	 * @param bool   $pretty Whether to set pretty format or not.
332
+	 * @return void
333
+	 */
334
+	public function set_time_format(string $format, bool $pretty = false)
335
+	{
336
+		if ($pretty) {
337
+			$this->_pretty_time_format = $format;
338
+		} else {
339
+			$this->_time_format = $format;
340
+		}
341
+	}
342
+
343
+
344
+	/**
345
+	 * return the $_time_format property value.
346
+	 *
347
+	 * @param bool $pretty Whether to get pretty format or not.
348
+	 * @return string
349
+	 */
350
+	public function get_time_format(bool $pretty = false): string
351
+	{
352
+		return $pretty
353
+			? $this->_pretty_time_format
354
+			: $this->_time_format;
355
+	}
356
+
357
+
358
+	/**
359
+	 * set the $_pretty_date_format property
360
+	 *
361
+	 * @param string $format a new pretty date format (corresponding to formats accepted by PHP date() function)
362
+	 * @return void
363
+	 */
364
+	public function set_pretty_date_format(string $format)
365
+	{
366
+		$this->_pretty_date_format = $format;
367
+	}
368
+
369
+
370
+	/**
371
+	 * set the $_pretty_time_format property
372
+	 *
373
+	 * @param string $format a new pretty time format (corresponding to formats accepted by PHP date() function)
374
+	 * @return void
375
+	 */
376
+	public function set_pretty_time_format(string $format)
377
+	{
378
+		$this->_pretty_time_format = $format;
379
+	}
380
+
381
+
382
+	/**
383
+	 * Only sets the time portion of the datetime.
384
+	 *
385
+	 * @param string|DateTime $time_to_set_string like 8am OR a DateTime object.
386
+	 * @param DateTime        $current            current DateTime object for the datetime field
387
+	 * @return DateTime
388
+	 */
389
+	public function prepare_for_set_with_new_time($time_to_set_string, DateTime $current): DateTime
390
+	{
391
+		// if $time_to_set_string is datetime object, then let's use it to set the parse array.
392
+		// Otherwise parse the string.
393
+		if ($time_to_set_string instanceof DateTime) {
394
+			$parsed = [
395
+				'hour'   => $time_to_set_string->format('H'),
396
+				'minute' => $time_to_set_string->format('i'),
397
+				'second' => $time_to_set_string->format('s'),
398
+			];
399
+		} else {
400
+			// parse incoming string
401
+			$parsed = date_parse_from_format($this->_time_format, $time_to_set_string);
402
+		}
403
+		EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
404
+		return $current->setTime($parsed['hour'], $parsed['minute'], $parsed['second']);
405
+	}
406
+
407
+
408
+	/**
409
+	 * Only sets the date portion of the datetime.
410
+	 *
411
+	 * @param string|DateTime $date_to_set_string like Friday, January 8th or a DateTime object.
412
+	 * @param DateTime        $current            current DateTime object for the datetime field
413
+	 * @return DateTime
414
+	 */
415
+	public function prepare_for_set_with_new_date($date_to_set_string, DateTime $current): DateTime
416
+	{
417
+		// if $time_to_set_string is datetime object, then let's use it to set the parse array.
418
+		// Otherwise parse the string.
419
+		if ($date_to_set_string instanceof DateTime) {
420
+			$parsed = [
421
+				'year'  => $date_to_set_string->format('Y'),
422
+				'month' => $date_to_set_string->format('m'),
423
+				'day'   => $date_to_set_string->format('d'),
424
+			];
425
+		} else {
426
+			// parse incoming string
427
+			$parsed = date_parse_from_format($this->_date_format, $date_to_set_string);
428
+		}
429
+		EEH_DTT_Helper::setTimezone($current, $this->_DateTimeZone);
430
+		return $current->setDate($parsed['year'], $parsed['month'], $parsed['day']);
431
+	}
432
+
433
+
434
+	/**
435
+	 * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0 timezone).  When the
436
+	 * datetime gets to this stage it should ALREADY be in UTC time
437
+	 *
438
+	 * @param DateTime $DateTime
439
+	 * @return string formatted date time for given timezone
440
+	 * @throws EE_Error
441
+	 */
442
+	public function prepare_for_get($DateTime): string
443
+	{
444
+		return $this->_prepare_for_display($DateTime);
445
+	}
446
+
447
+
448
+	/**
449
+	 * This differs from prepare_for_get in that it considers whether the internal $_timezone differs
450
+	 * from the set wp timezone.  If so, then it returns the datetime string formatted via
451
+	 * _pretty_date_format, and _pretty_time_format.  However, it also appends a timezone
452
+	 * abbreviation to the date_string.
453
+	 *
454
+	 * @param DateTime $DateTime
455
+	 * @param string $schema
456
+	 * @return string
457
+	 * @throws EE_Error
458
+	 */
459
+	public function prepare_for_pretty_echoing($DateTime, string $schema = 'pretty'): string
460
+	{
461
+		return $this->_prepare_for_display($DateTime, $schema);
462
+	}
463
+
464
+
465
+	/**
466
+	 * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
467
+	 * timezone).
468
+	 *
469
+	 * @param DateTime $DateTime
470
+	 * @param string   $schema
471
+	 * @return string
472
+	 * @throws EE_Error
473
+	 */
474
+	protected function _prepare_for_display(DateTime $DateTime, string $schema = ''): string
475
+	{
476
+		if (! $DateTime instanceof DateTime) {
477
+			if ($this->_nullable) {
478
+				return '';
479
+			} else {
480
+				if (WP_DEBUG) {
481
+					throw new EE_Error(
482
+						sprintf(
483
+							esc_html__(
484
+								'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.',
485
+								'event_espresso'
486
+							),
487
+							$this->_nicename
488
+						)
489
+					);
490
+				} else {
491
+					$DateTime = new DbSafeDateTime(EE_Datetime_Field::now);
492
+					EE_Error::add_error(
493
+						sprintf(
494
+							esc_html__(
495
+								'EE_Datetime_Field::_prepare_for_display requires a DateTime class to be the value for the $DateTime argument because the %s field is not nullable.  When WP_DEBUG is false, the value is set to "now" instead of throwing an exception.',
496
+								'event_espresso'
497
+							),
498
+							$this->_nicename
499
+						)
500
+					);
501
+				}
502
+			}
503
+		}
504
+		$pretty = $schema === 'pretty';
505
+		$format_string = $this->_get_date_time_output($pretty);
506
+		EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
507
+
508
+		$timezone_string = '';
509
+		if ($this->_display_timezone()) {
510
+			// must be explicit because schema could equal true.
511
+			$timezone_string = $schema === 'no_html'
512
+				? ' (' . $DateTime->format('T') . ')'
513
+				: ' <span class="ee_dtt_timezone_string">(' . $DateTime->format('T') . ')</span>';
514
+		}
515
+		return $DateTime->format($format_string) . $timezone_string;
516
+	}
517
+
518
+
519
+	/**
520
+	 * This prepares the EE_DateTime value to be saved to the db as mysql timestamp (UTC +0
521
+	 * timezone).
522
+	 *
523
+	 * @param DateTime|null $datetime_value
524
+	 * @return string mysql timestamp in UTC
525
+	 * @throws EE_Error
526
+	 */
527
+	public function prepare_for_use_in_db($datetime_value)
528
+	{
529
+		// we allow an empty value or DateTime object, but nothing else.
530
+		if (! empty($datetime_value) && ! $datetime_value instanceof DateTime) {
531
+			throw new EE_Error(
532
+				sprintf(
533
+					esc_html__(
534
+						'The incoming value being prepared for setting in the database must either be empty or a php 
535 535
             		    DateTime object, instead of: %1$s %2$s',
536
-                        'event_espresso'
537
-                    ),
538
-                    '<br />',
539
-                    print_r($datetime_value, true)
540
-                )
541
-            );
542
-        }
543
-
544
-        if ($datetime_value instanceof DateTime) {
545
-            if (! $datetime_value instanceof DbSafeDateTime) {
546
-                $datetime_value = DbSafeDateTime::createFromDateTime($datetime_value);
547
-            }
548
-            EEH_DTT_Helper::setTimezone($datetime_value, $this->get_UTC_DateTimeZone());
549
-            return $datetime_value->format(
550
-                EE_Datetime_Field::mysql_timestamp_format
551
-            );
552
-        }
553
-
554
-        // if $datetime_value is empty, and ! $this->_nullable, use current_time() but set the GMT flag to true
555
-        return ! $this->_nullable && empty($datetime_value)
556
-            ? current_time('mysql', true)
557
-            : null;
558
-    }
559
-
560
-
561
-    /**
562
-     * This prepares the datetime for internal usage as a PHP DateTime object OR null (if nullable is
563
-     * allowed)
564
-     *
565
-     * @param string $datetime_string mysql timestamp in UTC
566
-     * @return  mixed null | DateTime
567
-     * @throws EE_Error
568
-     */
569
-    public function prepare_for_set_from_db($datetime_string)
570
-    {
571
-        // if $datetime_value is empty, and ! $this->_nullable, just use time()
572
-        if (empty($datetime_string) && $this->_nullable) {
573
-            return null;
574
-        }
575
-        // datetime strings from the db should ALWAYS be in UTC+0, so use UTC_DateTimeZone when creating
576
-        if (empty($datetime_string)) {
577
-            $DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
578
-        } else {
579
-            $DateTime = DbSafeDateTime::createFromFormat(
580
-                EE_Datetime_Field::mysql_timestamp_format,
581
-                $datetime_string,
582
-                $this->get_UTC_DateTimeZone()
583
-            );
584
-        }
585
-
586
-        if (! $DateTime instanceof DbSafeDateTime) {
587
-            // if still no datetime object, then let's just use now
588
-            $DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
589
-        }
590
-        // THEN apply the field's set DateTimeZone
591
-        EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
592
-        return $DateTime;
593
-    }
594
-
595
-
596
-    /**
597
-     * All this method does is determine if we're going to display the timezone string or not on any output.
598
-     * To determine this we check if the set timezone offset is different than the blog's set timezone offset.
599
-     * If so, then true.
600
-     *
601
-     * @return bool true for yes false for no
602
-     * @throws EE_Error
603
-     */
604
-    protected function _display_timezone()
605
-    {
606
-
607
-        // first let's do a comparison of timezone strings.
608
-        // If they match then we can get out without any further calculations
609
-        $blog_string = get_option('timezone_string');
610
-        if ($blog_string === $this->_timezone_string) {
611
-            return false;
612
-        }
613
-        // now we need to calc the offset for the timezone string so we can compare with the blog offset.
614
-        $this_offset = $this->get_timezone_offset($this->_DateTimeZone);
615
-        $blog_offset = $this->get_timezone_offset($this->get_blog_DateTimeZone());
616
-        // now compare
617
-        return $blog_offset !== $this_offset;
618
-    }
619
-
620
-
621
-    /**
622
-     * This method returns a php DateTime object for setting on the EE_Base_Class model.
623
-     * EE passes around DateTime objects because they are MUCH easier to manipulate and deal
624
-     * with.
625
-     *
626
-     * @param int|string|DateTime $date_string            This should be the incoming date string.  It's assumed to be
627
-     *                                                    in the format that is set on the date_field (or DateTime
628
-     *                                                    object)!
629
-     * @return DateTime
630
-     */
631
-    protected function _get_date_object($date_string)
632
-    {
633
-        // first if this is an empty date_string and nullable is allowed, just return null.
634
-        if ($this->_nullable && empty($date_string)) {
635
-            return null;
636
-        }
637
-
638
-        // if incoming date
639
-        if ($date_string instanceof DateTime) {
640
-            EEH_DTT_Helper::setTimezone($date_string, $this->_DateTimeZone);
641
-            return $date_string;
642
-        }
643
-        // if empty date_string and made it here.
644
-        // Return a datetime object for now in the given timezone.
645
-        if (empty($date_string)) {
646
-            return new DbSafeDateTime(EE_Datetime_Field::now, $this->_DateTimeZone);
647
-        }
648
-        // if $date_string is matches something that looks like a Unix timestamp let's just use it.
649
-        if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $date_string)) {
650
-            try {
651
-                // This is operating under the assumption that the incoming Unix timestamp
652
-                // is an ACTUAL Unix timestamp and not the calculated one output by current_time('timestamp');
653
-                $DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->_DateTimeZone);
654
-                $DateTime->setTimestamp($date_string);
655
-
656
-                return $DateTime;
657
-            } catch (Exception $e) {
658
-                // should be rare, but if things got fooled then let's just continue
659
-            }
660
-        }
661
-        // not a unix timestamp.  So we will use the set format on this object and set timezone to
662
-        // create the DateTime object.
663
-        $format = $this->_date_format . ' ' . $this->_time_format;
664
-        try {
665
-            $DateTime = DbSafeDateTime::createFromFormat($format, $date_string, $this->_DateTimeZone);
666
-            if (! $DateTime instanceof DbSafeDateTime) {
667
-                throw new EE_Error(
668
-                    sprintf(
669
-                        esc_html__('"%1$s" does not represent a valid Date Time in the format "%2$s".',
670
-                                   'event_espresso'),
671
-                        $date_string,
672
-                        $format
673
-                    )
674
-                );
675
-            }
676
-        } catch (Exception $e) {
677
-            // if we made it here then likely then something went really wrong.
678
-            // Instead of throwing an exception, let's just return a DateTime object for now, in the set timezone.
679
-            $DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->_DateTimeZone);
680
-        }
681
-
682
-        return $DateTime;
683
-    }
684
-
685
-
686
-    /**
687
-     * get_timezone_transitions
688
-     *
689
-     * @param DateTimeZone $DateTimeZone
690
-     * @param int          $time
691
-     * @param bool         $first_only
692
-     * @return mixed
693
-     */
694
-    public function get_timezone_transitions(DateTimeZone $DateTimeZone, $time = null, $first_only = true)
695
-    {
696
-        return EEH_DTT_Helper::get_timezone_transitions($DateTimeZone, $time, $first_only);
697
-    }
698
-
699
-
700
-    /**
701
-     * get_timezone_offset
702
-     *
703
-     * @param DateTimeZone $DateTimeZone
704
-     * @param int          $time
705
-     * @return mixed
706
-     * @throws DomainException
707
-     */
708
-    public function get_timezone_offset(DateTimeZone $DateTimeZone, $time = null)
709
-    {
710
-        return EEH_DTT_Helper::get_timezone_offset($DateTimeZone, $time);
711
-    }
712
-
713
-
714
-    /**
715
-     * This will take an incoming timezone string and return the abbreviation for that timezone
716
-     *
717
-     * @param string $timezone_string
718
-     * @return string           abbreviation
719
-     * @throws Exception
720
-     */
721
-    public function get_timezone_abbrev($timezone_string)
722
-    {
723
-        $timezone_string = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
724
-        $dateTime        = new DateTime(EE_Datetime_Field::now, new DateTimeZone($timezone_string));
725
-
726
-        return $dateTime->format('T');
727
-    }
728
-
729
-
730
-    /**
731
-     * Overrides the parent to allow for having a dynamic "now" value
732
-     *
733
-     * @return mixed
734
-     */
735
-    public function get_default_value()
736
-    {
737
-        if ($this->_default_value === EE_Datetime_Field::now) {
738
-            return time();
739
-        } else {
740
-            return parent::get_default_value();
741
-        }
742
-    }
743
-
744
-
745
-    /**
746
-     * Gets the default datetime object from the field's default time
747
-     *
748
-     * @return DbSafeDateTime|null
749
-     * @throws InvalidArgumentException
750
-     * @throws InvalidDataTypeException
751
-     * @throws InvalidInterfaceException
752
-     * @since 4.9.66.p
753
-     */
754
-    public function getDefaultDateTimeObj()
755
-    {
756
-        $default_raw = $this->get_default_value();
757
-        if ($default_raw instanceof DateTime) {
758
-            return $default_raw;
759
-        } elseif (is_null($default_raw)) {
760
-            return $default_raw;
761
-        } else {
762
-            return new DbSafeDateTime(
763
-                $this->get_default_value(),
764
-                EEH_DTT_Helper::get_valid_timezone_string($this->get_timezone())
765
-            );
766
-        }
767
-    }
768
-
769
-
770
-    public function getSchemaDescription()
771
-    {
772
-        return sprintf(
773
-            esc_html__('%s - the value for this field is in the timezone of the site.', 'event_espresso'),
774
-            $this->get_nicename()
775
-        );
776
-    }
536
+						'event_espresso'
537
+					),
538
+					'<br />',
539
+					print_r($datetime_value, true)
540
+				)
541
+			);
542
+		}
543
+
544
+		if ($datetime_value instanceof DateTime) {
545
+			if (! $datetime_value instanceof DbSafeDateTime) {
546
+				$datetime_value = DbSafeDateTime::createFromDateTime($datetime_value);
547
+			}
548
+			EEH_DTT_Helper::setTimezone($datetime_value, $this->get_UTC_DateTimeZone());
549
+			return $datetime_value->format(
550
+				EE_Datetime_Field::mysql_timestamp_format
551
+			);
552
+		}
553
+
554
+		// if $datetime_value is empty, and ! $this->_nullable, use current_time() but set the GMT flag to true
555
+		return ! $this->_nullable && empty($datetime_value)
556
+			? current_time('mysql', true)
557
+			: null;
558
+	}
559
+
560
+
561
+	/**
562
+	 * This prepares the datetime for internal usage as a PHP DateTime object OR null (if nullable is
563
+	 * allowed)
564
+	 *
565
+	 * @param string $datetime_string mysql timestamp in UTC
566
+	 * @return  mixed null | DateTime
567
+	 * @throws EE_Error
568
+	 */
569
+	public function prepare_for_set_from_db($datetime_string)
570
+	{
571
+		// if $datetime_value is empty, and ! $this->_nullable, just use time()
572
+		if (empty($datetime_string) && $this->_nullable) {
573
+			return null;
574
+		}
575
+		// datetime strings from the db should ALWAYS be in UTC+0, so use UTC_DateTimeZone when creating
576
+		if (empty($datetime_string)) {
577
+			$DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
578
+		} else {
579
+			$DateTime = DbSafeDateTime::createFromFormat(
580
+				EE_Datetime_Field::mysql_timestamp_format,
581
+				$datetime_string,
582
+				$this->get_UTC_DateTimeZone()
583
+			);
584
+		}
585
+
586
+		if (! $DateTime instanceof DbSafeDateTime) {
587
+			// if still no datetime object, then let's just use now
588
+			$DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
589
+		}
590
+		// THEN apply the field's set DateTimeZone
591
+		EEH_DTT_Helper::setTimezone($DateTime, $this->_DateTimeZone);
592
+		return $DateTime;
593
+	}
594
+
595
+
596
+	/**
597
+	 * All this method does is determine if we're going to display the timezone string or not on any output.
598
+	 * To determine this we check if the set timezone offset is different than the blog's set timezone offset.
599
+	 * If so, then true.
600
+	 *
601
+	 * @return bool true for yes false for no
602
+	 * @throws EE_Error
603
+	 */
604
+	protected function _display_timezone()
605
+	{
606
+
607
+		// first let's do a comparison of timezone strings.
608
+		// If they match then we can get out without any further calculations
609
+		$blog_string = get_option('timezone_string');
610
+		if ($blog_string === $this->_timezone_string) {
611
+			return false;
612
+		}
613
+		// now we need to calc the offset for the timezone string so we can compare with the blog offset.
614
+		$this_offset = $this->get_timezone_offset($this->_DateTimeZone);
615
+		$blog_offset = $this->get_timezone_offset($this->get_blog_DateTimeZone());
616
+		// now compare
617
+		return $blog_offset !== $this_offset;
618
+	}
619
+
620
+
621
+	/**
622
+	 * This method returns a php DateTime object for setting on the EE_Base_Class model.
623
+	 * EE passes around DateTime objects because they are MUCH easier to manipulate and deal
624
+	 * with.
625
+	 *
626
+	 * @param int|string|DateTime $date_string            This should be the incoming date string.  It's assumed to be
627
+	 *                                                    in the format that is set on the date_field (or DateTime
628
+	 *                                                    object)!
629
+	 * @return DateTime
630
+	 */
631
+	protected function _get_date_object($date_string)
632
+	{
633
+		// first if this is an empty date_string and nullable is allowed, just return null.
634
+		if ($this->_nullable && empty($date_string)) {
635
+			return null;
636
+		}
637
+
638
+		// if incoming date
639
+		if ($date_string instanceof DateTime) {
640
+			EEH_DTT_Helper::setTimezone($date_string, $this->_DateTimeZone);
641
+			return $date_string;
642
+		}
643
+		// if empty date_string and made it here.
644
+		// Return a datetime object for now in the given timezone.
645
+		if (empty($date_string)) {
646
+			return new DbSafeDateTime(EE_Datetime_Field::now, $this->_DateTimeZone);
647
+		}
648
+		// if $date_string is matches something that looks like a Unix timestamp let's just use it.
649
+		if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $date_string)) {
650
+			try {
651
+				// This is operating under the assumption that the incoming Unix timestamp
652
+				// is an ACTUAL Unix timestamp and not the calculated one output by current_time('timestamp');
653
+				$DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->_DateTimeZone);
654
+				$DateTime->setTimestamp($date_string);
655
+
656
+				return $DateTime;
657
+			} catch (Exception $e) {
658
+				// should be rare, but if things got fooled then let's just continue
659
+			}
660
+		}
661
+		// not a unix timestamp.  So we will use the set format on this object and set timezone to
662
+		// create the DateTime object.
663
+		$format = $this->_date_format . ' ' . $this->_time_format;
664
+		try {
665
+			$DateTime = DbSafeDateTime::createFromFormat($format, $date_string, $this->_DateTimeZone);
666
+			if (! $DateTime instanceof DbSafeDateTime) {
667
+				throw new EE_Error(
668
+					sprintf(
669
+						esc_html__('"%1$s" does not represent a valid Date Time in the format "%2$s".',
670
+								   'event_espresso'),
671
+						$date_string,
672
+						$format
673
+					)
674
+				);
675
+			}
676
+		} catch (Exception $e) {
677
+			// if we made it here then likely then something went really wrong.
678
+			// Instead of throwing an exception, let's just return a DateTime object for now, in the set timezone.
679
+			$DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->_DateTimeZone);
680
+		}
681
+
682
+		return $DateTime;
683
+	}
684
+
685
+
686
+	/**
687
+	 * get_timezone_transitions
688
+	 *
689
+	 * @param DateTimeZone $DateTimeZone
690
+	 * @param int          $time
691
+	 * @param bool         $first_only
692
+	 * @return mixed
693
+	 */
694
+	public function get_timezone_transitions(DateTimeZone $DateTimeZone, $time = null, $first_only = true)
695
+	{
696
+		return EEH_DTT_Helper::get_timezone_transitions($DateTimeZone, $time, $first_only);
697
+	}
698
+
699
+
700
+	/**
701
+	 * get_timezone_offset
702
+	 *
703
+	 * @param DateTimeZone $DateTimeZone
704
+	 * @param int          $time
705
+	 * @return mixed
706
+	 * @throws DomainException
707
+	 */
708
+	public function get_timezone_offset(DateTimeZone $DateTimeZone, $time = null)
709
+	{
710
+		return EEH_DTT_Helper::get_timezone_offset($DateTimeZone, $time);
711
+	}
712
+
713
+
714
+	/**
715
+	 * This will take an incoming timezone string and return the abbreviation for that timezone
716
+	 *
717
+	 * @param string $timezone_string
718
+	 * @return string           abbreviation
719
+	 * @throws Exception
720
+	 */
721
+	public function get_timezone_abbrev($timezone_string)
722
+	{
723
+		$timezone_string = EEH_DTT_Helper::get_valid_timezone_string($timezone_string);
724
+		$dateTime        = new DateTime(EE_Datetime_Field::now, new DateTimeZone($timezone_string));
725
+
726
+		return $dateTime->format('T');
727
+	}
728
+
729
+
730
+	/**
731
+	 * Overrides the parent to allow for having a dynamic "now" value
732
+	 *
733
+	 * @return mixed
734
+	 */
735
+	public function get_default_value()
736
+	{
737
+		if ($this->_default_value === EE_Datetime_Field::now) {
738
+			return time();
739
+		} else {
740
+			return parent::get_default_value();
741
+		}
742
+	}
743
+
744
+
745
+	/**
746
+	 * Gets the default datetime object from the field's default time
747
+	 *
748
+	 * @return DbSafeDateTime|null
749
+	 * @throws InvalidArgumentException
750
+	 * @throws InvalidDataTypeException
751
+	 * @throws InvalidInterfaceException
752
+	 * @since 4.9.66.p
753
+	 */
754
+	public function getDefaultDateTimeObj()
755
+	{
756
+		$default_raw = $this->get_default_value();
757
+		if ($default_raw instanceof DateTime) {
758
+			return $default_raw;
759
+		} elseif (is_null($default_raw)) {
760
+			return $default_raw;
761
+		} else {
762
+			return new DbSafeDateTime(
763
+				$this->get_default_value(),
764
+				EEH_DTT_Helper::get_valid_timezone_string($this->get_timezone())
765
+			);
766
+		}
767
+	}
768
+
769
+
770
+	public function getSchemaDescription()
771
+	{
772
+		return sprintf(
773
+			esc_html__('%s - the value for this field is in the timezone of the site.', 'event_espresso'),
774
+			$this->get_nicename()
775
+		);
776
+	}
777 777
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -218,8 +218,8 @@  discard block
 block discarded – undo
218 218
 
219 219
             default:
220 220
                 return $pretty
221
-                    ? $this->_pretty_date_format . ' ' . $this->_pretty_time_format
222
-                    : $this->_date_format . ' ' . $this->_time_format;
221
+                    ? $this->_pretty_date_format.' '.$this->_pretty_time_format
222
+                    : $this->_date_format.' '.$this->_time_format;
223 223
         }
224 224
     }
225 225
 
@@ -473,7 +473,7 @@  discard block
 block discarded – undo
473 473
      */
474 474
     protected function _prepare_for_display(DateTime $DateTime, string $schema = ''): string
475 475
     {
476
-        if (! $DateTime instanceof DateTime) {
476
+        if ( ! $DateTime instanceof DateTime) {
477 477
             if ($this->_nullable) {
478 478
                 return '';
479 479
             } else {
@@ -509,10 +509,10 @@  discard block
 block discarded – undo
509 509
         if ($this->_display_timezone()) {
510 510
             // must be explicit because schema could equal true.
511 511
             $timezone_string = $schema === 'no_html'
512
-                ? ' (' . $DateTime->format('T') . ')'
513
-                : ' <span class="ee_dtt_timezone_string">(' . $DateTime->format('T') . ')</span>';
512
+                ? ' ('.$DateTime->format('T').')'
513
+                : ' <span class="ee_dtt_timezone_string">('.$DateTime->format('T').')</span>';
514 514
         }
515
-        return $DateTime->format($format_string) . $timezone_string;
515
+        return $DateTime->format($format_string).$timezone_string;
516 516
     }
517 517
 
518 518
 
@@ -527,7 +527,7 @@  discard block
 block discarded – undo
527 527
     public function prepare_for_use_in_db($datetime_value)
528 528
     {
529 529
         // we allow an empty value or DateTime object, but nothing else.
530
-        if (! empty($datetime_value) && ! $datetime_value instanceof DateTime) {
530
+        if ( ! empty($datetime_value) && ! $datetime_value instanceof DateTime) {
531 531
             throw new EE_Error(
532 532
                 sprintf(
533 533
                     esc_html__(
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
         }
543 543
 
544 544
         if ($datetime_value instanceof DateTime) {
545
-            if (! $datetime_value instanceof DbSafeDateTime) {
545
+            if ( ! $datetime_value instanceof DbSafeDateTime) {
546 546
                 $datetime_value = DbSafeDateTime::createFromDateTime($datetime_value);
547 547
             }
548 548
             EEH_DTT_Helper::setTimezone($datetime_value, $this->get_UTC_DateTimeZone());
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
             );
584 584
         }
585 585
 
586
-        if (! $DateTime instanceof DbSafeDateTime) {
586
+        if ( ! $DateTime instanceof DbSafeDateTime) {
587 587
             // if still no datetime object, then let's just use now
588 588
             $DateTime = new DbSafeDateTime(EE_Datetime_Field::now, $this->get_UTC_DateTimeZone());
589 589
         }
@@ -660,10 +660,10 @@  discard block
 block discarded – undo
660 660
         }
661 661
         // not a unix timestamp.  So we will use the set format on this object and set timezone to
662 662
         // create the DateTime object.
663
-        $format = $this->_date_format . ' ' . $this->_time_format;
663
+        $format = $this->_date_format.' '.$this->_time_format;
664 664
         try {
665 665
             $DateTime = DbSafeDateTime::createFromFormat($format, $date_string, $this->_DateTimeZone);
666
-            if (! $DateTime instanceof DbSafeDateTime) {
666
+            if ( ! $DateTime instanceof DbSafeDateTime) {
667 667
                 throw new EE_Error(
668 668
                     sprintf(
669 669
                         esc_html__('"%1$s" does not represent a valid Date Time in the format "%2$s".',
Please login to merge, or discard this patch.
core/EE_Data_Mapper.core.php 1 patch
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -16,99 +16,99 @@
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * instance of the EE_Data_Mapper Object
21
-     *
22
-     * @private _instance
23
-     */
24
-    private static $_instance;
25
-
26
-
27
-    public $data = array();
28
-
29
-
30
-    /**
31
-     *private constructor to prevent direct creation
32
-     *
33
-     * @Constructor
34
-     * @access private
35
-     * @return void
36
-     */
37
-    private function __construct()
38
-    {
39
-    }
40
-
41
-
42
-    /**
43
-     *@ singleton method used to instantiate class object
44
-     *@ access public
45
-     *@ return class instance
46
-     */
47
-    public function &instance()
48
-    {
49
-        // check if class object is instantiated
50
-        if (
51
-            self::$_instance === null
52
-            || ! is_object(self::$_instance)
53
-            || ! self::$_instance instanceof EE_Data_Mapper
54
-        ) {
55
-            self::$_instance = new self();
56
-        }
57
-        return self::$_instance;
58
-    }
59
-
60
-
61
-    /**
62
-     *        @ override magic methods
63
-     *        @ return void
64
-     */
65
-    final public function __destruct()
66
-    {
67
-    }
68
-
69
-    final public function __call($a, $b)
70
-    {
71
-    }
72
-
73
-    public static function __callStatic($a, $b)
74
-    {
75
-    }
76
-
77
-    final public function __get($a)
78
-    {
79
-    }
80
-
81
-    final public function __set($a, $b)
82
-    {
83
-    }
84
-
85
-    final public function __isset($a)
86
-    {
87
-    }
88
-
89
-    final public function __unset($a)
90
-    {
91
-    }
92
-
93
-    final public function __sleep()
94
-    {
95
-        return array();
96
-    }
97
-
98
-    final public function __wakeup()
99
-    {
100
-    }
101
-
102
-    final public function __toString()
103
-    {
104
-        return '';
105
-    }
106
-
107
-    final public function __invoke()
108
-    {
109
-    }
110
-
111
-    final public function __clone()
112
-    {
113
-    }
19
+	/**
20
+	 * instance of the EE_Data_Mapper Object
21
+	 *
22
+	 * @private _instance
23
+	 */
24
+	private static $_instance;
25
+
26
+
27
+	public $data = array();
28
+
29
+
30
+	/**
31
+	 *private constructor to prevent direct creation
32
+	 *
33
+	 * @Constructor
34
+	 * @access private
35
+	 * @return void
36
+	 */
37
+	private function __construct()
38
+	{
39
+	}
40
+
41
+
42
+	/**
43
+	 *@ singleton method used to instantiate class object
44
+	 *@ access public
45
+	 *@ return class instance
46
+	 */
47
+	public function &instance()
48
+	{
49
+		// check if class object is instantiated
50
+		if (
51
+			self::$_instance === null
52
+			|| ! is_object(self::$_instance)
53
+			|| ! self::$_instance instanceof EE_Data_Mapper
54
+		) {
55
+			self::$_instance = new self();
56
+		}
57
+		return self::$_instance;
58
+	}
59
+
60
+
61
+	/**
62
+	 *        @ override magic methods
63
+	 *        @ return void
64
+	 */
65
+	final public function __destruct()
66
+	{
67
+	}
68
+
69
+	final public function __call($a, $b)
70
+	{
71
+	}
72
+
73
+	public static function __callStatic($a, $b)
74
+	{
75
+	}
76
+
77
+	final public function __get($a)
78
+	{
79
+	}
80
+
81
+	final public function __set($a, $b)
82
+	{
83
+	}
84
+
85
+	final public function __isset($a)
86
+	{
87
+	}
88
+
89
+	final public function __unset($a)
90
+	{
91
+	}
92
+
93
+	final public function __sleep()
94
+	{
95
+		return array();
96
+	}
97
+
98
+	final public function __wakeup()
99
+	{
100
+	}
101
+
102
+	final public function __toString()
103
+	{
104
+		return '';
105
+	}
106
+
107
+	final public function __invoke()
108
+	{
109
+	}
110
+
111
+	final public function __clone()
112
+	{
113
+	}
114 114
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Autoloader.helper.php 1 patch
Indentation   +271 added lines, -271 removed lines patch added patch discarded remove patch
@@ -15,275 +15,275 @@
 block discarded – undo
15 15
 {
16 16
 
17 17
 
18
-    /**
19
-     *    instance of the EE_System object
20
-     *
21
-     * @var    $_instance
22
-     */
23
-    private static $_instance;
24
-
25
-    /**
26
-     *   $_autoloaders
27
-     * @var array $_autoloaders
28
-     */
29
-    private static $_autoloaders;
30
-
31
-    /**
32
-     * set to "paths" to display autoloader class => path mappings
33
-     * set to "times" to display autoloader loading times
34
-     * set to "all" to display both
35
-     *
36
-     * @var string $debug
37
-     */
38
-    public static $debug = false;
39
-
40
-
41
-    /**
42
-     * @throws EE_Error
43
-     */
44
-    private function __construct()
45
-    {
46
-        if (EEH_Autoloader::$_autoloaders === null) {
47
-            EEH_Autoloader::$_autoloaders = [];
48
-            $this->_register_custom_autoloaders();
49
-            spl_autoload_register([$this, 'espresso_autoloader']);
50
-        }
51
-    }
52
-
53
-
54
-    /**
55
-     * @return EEH_Autoloader
56
-     */
57
-    public static function instance(): EEH_Autoloader
58
-    {
59
-        // check if class object is instantiated
60
-        if (! EEH_Autoloader::$_instance instanceof EEH_Autoloader) {
61
-            EEH_Autoloader::$_instance = new EEH_Autoloader();
62
-        }
63
-        return EEH_Autoloader::$_instance;
64
-    }
65
-
66
-
67
-    /**
68
-     * @param   $class_name
69
-     * @return  void
70
-     * @internal  param string $class_name - simple class name ie: session
71
-     * @internal  param $className
72
-     */
73
-    public static function espresso_autoloader($class_name)
74
-    {
75
-        if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
76
-            require_once(EEH_Autoloader::$_autoloaders[ $class_name ]);
77
-        }
78
-    }
79
-
80
-
81
-    /**
82
-     * @param array | string $class_paths - array of key => value pairings between class names and paths
83
-     * @param bool           $read_check  true if we need to check whether the file is readable or not.
84
-     * @param bool           $debug       **deprecated**
85
-     * @throws EE_Error
86
-     */
87
-    public static function register_autoloader($class_paths, $read_check = true, $debug = false)
88
-    {
89
-        $class_paths = is_array($class_paths) ? $class_paths : [$class_paths];
90
-        foreach ($class_paths as $class => $path) {
91
-            // skip all files that are not PHP
92
-            if (substr($path, strlen($path) - 3) !== 'php') {
93
-                continue;
94
-            }
95
-            // don't give up! you gotta...
96
-            // get some class
97
-            if (empty($class)) {
98
-                throw new EE_Error(
99
-                    sprintf(
100
-                        esc_html__(
101
-                            'No Class name was specified while registering an autoloader for the following path: %s.',
102
-                            'event_espresso'
103
-                        ),
104
-                        $path
105
-                    )
106
-                );
107
-            }
108
-            // one day you will find the path young grasshopper
109
-            if (empty($path)) {
110
-                throw new EE_Error(
111
-                    sprintf(
112
-                        esc_html__('No path was specified while registering an autoloader for the %s class.', 'event_espresso'),
113
-                        $class
114
-                    )
115
-                );
116
-            }
117
-            // is file readable ?
118
-            if ($read_check && ! is_readable($path)) {
119
-                throw new EE_Error(
120
-                    sprintf(
121
-                        esc_html__(
122
-                            'The file for the %s class could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
123
-                            'event_espresso'
124
-                        ),
125
-                        $class,
126
-                        $path
127
-                    )
128
-                );
129
-            }
130
-            if (! isset(EEH_Autoloader::$_autoloaders[ $class ])) {
131
-                EEH_Autoloader::$_autoloaders[ $class ] = str_replace(['/', '\\'], '/', $path);
132
-                if (EE_DEBUG && (EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug)) {
133
-                    EEH_Debug_Tools::printr(EEH_Autoloader::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
134
-                }
135
-            }
136
-        }
137
-    }
138
-
139
-
140
-    /**
141
-     * @return array
142
-     */
143
-    public static function get_autoloaders(): array
144
-    {
145
-        return EEH_Autoloader::$_autoloaders;
146
-    }
147
-
148
-
149
-    /**
150
-     * @return void
151
-     * @throws EE_Error
152
-     */
153
-    private function _register_custom_autoloaders()
154
-    {
155
-        EEH_Autoloader::$debug = '';
156
-        EEH_Autoloader::register_helpers_autoloaders();
157
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
158
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
159
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
160
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
161
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
162
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
163
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
164
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
165
-            Benchmark::displayResults();
166
-        }
167
-    }
168
-
169
-
170
-    /**
171
-     * @throws EE_Error
172
-     */
173
-    public static function register_helpers_autoloaders()
174
-    {
175
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
176
-    }
177
-
178
-
179
-    /**
180
-     * @return void
181
-     */
182
-    public static function register_form_sections_autoloaders()
183
-    {
184
-        // EEH_Autoloader::register_autoloaders_for_each_file_in_folder( EE_FORM_SECTIONS, true );
185
-    }
186
-
187
-
188
-    /**
189
-     * @return void
190
-     * @throws EE_Error
191
-     */
192
-    public static function register_line_item_display_autoloaders()
193
-    {
194
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
195
-    }
196
-
197
-
198
-    /**
199
-     * @return void
200
-     * @throws EE_Error
201
-     */
202
-    public static function register_line_item_filter_autoloaders()
203
-    {
204
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
205
-    }
206
-
207
-
208
-    /**
209
-     * @return void
210
-     * @throws EE_Error
211
-     */
212
-    public static function register_template_part_autoloaders()
213
-    {
214
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
215
-    }
216
-
217
-
218
-    /**
219
-     * @return void
220
-     * @throws EE_Error
221
-     */
222
-    public static function register_business_classes()
223
-    {
224
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
225
-    }
226
-
227
-
228
-    /**
229
-     * Assumes all the files in this folder have the normal naming scheme (namely that their classname
230
-     * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
231
-     * If that's not the case, you'll need to improve this function or just use
232
-     * EEH_File::get_classname_from_filepath_with_standard_filename() directly. Yes this has to scan the directory for
233
-     * files, but it only does it once -- not on EACH time the autoloader is used
234
-     *
235
-     * @param string $folder name, with or without trailing /, doesn't matter
236
-     * @param bool   $recursive
237
-     * @param bool   $debug  **deprecated**
238
-     * @throws EE_Error
239
-     */
240
-    public static function register_autoloaders_for_each_file_in_folder(
241
-        string $folder,
242
-        bool $recursive = false,
243
-        bool $debug = false
244
-    ) {
245
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all' || $debug) {
246
-            Benchmark::startTimer(basename($folder));
247
-        }
248
-        // make sure last char is a /
249
-        $folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
250
-        $class_to_filepath_map = [];
251
-        $exclude = ['index'];
252
-        // get all the files in that folder that end in php
253
-        $filepaths = glob($folder . '*');
254
-
255
-        if (empty($filepaths)) {
256
-            return;
257
-        }
258
-
259
-        foreach ($filepaths as $filepath) {
260
-            if (substr($filepath, -4, 4) === '.php') {
261
-                $class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
262
-                if (! in_array($class_name, $exclude)) {
263
-                    $class_to_filepath_map [ $class_name ] = $filepath;
264
-                }
265
-            } elseif ($recursive) {
266
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
267
-            }
268
-        }
269
-        // we remove the necessity to do a is_readable() check via the $read_check flag because glob by nature will not return non_readable files/directories.
270
-        EEH_Autoloader::register_autoloader($class_to_filepath_map, false, $debug);
271
-        if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
272
-            Benchmark::stopTimer(basename($folder));
273
-        }
274
-    }
275
-
276
-
277
-    /**
278
-     * register additional autoloader based on variation of the classname for an existing autoloader
279
-     *
280
-     * @param string $class_name - simple class name ie: EE_Session
281
-     * @param string $alias      - variation on class name ie: EE_session, session, etc
282
-     */
283
-    public static function add_alias(string $class_name, string $alias)
284
-    {
285
-        if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
286
-            EEH_Autoloader::$_autoloaders[ $alias ] = EEH_Autoloader::$_autoloaders[ $class_name ];
287
-        }
288
-    }
18
+	/**
19
+	 *    instance of the EE_System object
20
+	 *
21
+	 * @var    $_instance
22
+	 */
23
+	private static $_instance;
24
+
25
+	/**
26
+	 *   $_autoloaders
27
+	 * @var array $_autoloaders
28
+	 */
29
+	private static $_autoloaders;
30
+
31
+	/**
32
+	 * set to "paths" to display autoloader class => path mappings
33
+	 * set to "times" to display autoloader loading times
34
+	 * set to "all" to display both
35
+	 *
36
+	 * @var string $debug
37
+	 */
38
+	public static $debug = false;
39
+
40
+
41
+	/**
42
+	 * @throws EE_Error
43
+	 */
44
+	private function __construct()
45
+	{
46
+		if (EEH_Autoloader::$_autoloaders === null) {
47
+			EEH_Autoloader::$_autoloaders = [];
48
+			$this->_register_custom_autoloaders();
49
+			spl_autoload_register([$this, 'espresso_autoloader']);
50
+		}
51
+	}
52
+
53
+
54
+	/**
55
+	 * @return EEH_Autoloader
56
+	 */
57
+	public static function instance(): EEH_Autoloader
58
+	{
59
+		// check if class object is instantiated
60
+		if (! EEH_Autoloader::$_instance instanceof EEH_Autoloader) {
61
+			EEH_Autoloader::$_instance = new EEH_Autoloader();
62
+		}
63
+		return EEH_Autoloader::$_instance;
64
+	}
65
+
66
+
67
+	/**
68
+	 * @param   $class_name
69
+	 * @return  void
70
+	 * @internal  param string $class_name - simple class name ie: session
71
+	 * @internal  param $className
72
+	 */
73
+	public static function espresso_autoloader($class_name)
74
+	{
75
+		if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
76
+			require_once(EEH_Autoloader::$_autoloaders[ $class_name ]);
77
+		}
78
+	}
79
+
80
+
81
+	/**
82
+	 * @param array | string $class_paths - array of key => value pairings between class names and paths
83
+	 * @param bool           $read_check  true if we need to check whether the file is readable or not.
84
+	 * @param bool           $debug       **deprecated**
85
+	 * @throws EE_Error
86
+	 */
87
+	public static function register_autoloader($class_paths, $read_check = true, $debug = false)
88
+	{
89
+		$class_paths = is_array($class_paths) ? $class_paths : [$class_paths];
90
+		foreach ($class_paths as $class => $path) {
91
+			// skip all files that are not PHP
92
+			if (substr($path, strlen($path) - 3) !== 'php') {
93
+				continue;
94
+			}
95
+			// don't give up! you gotta...
96
+			// get some class
97
+			if (empty($class)) {
98
+				throw new EE_Error(
99
+					sprintf(
100
+						esc_html__(
101
+							'No Class name was specified while registering an autoloader for the following path: %s.',
102
+							'event_espresso'
103
+						),
104
+						$path
105
+					)
106
+				);
107
+			}
108
+			// one day you will find the path young grasshopper
109
+			if (empty($path)) {
110
+				throw new EE_Error(
111
+					sprintf(
112
+						esc_html__('No path was specified while registering an autoloader for the %s class.', 'event_espresso'),
113
+						$class
114
+					)
115
+				);
116
+			}
117
+			// is file readable ?
118
+			if ($read_check && ! is_readable($path)) {
119
+				throw new EE_Error(
120
+					sprintf(
121
+						esc_html__(
122
+							'The file for the %s class could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
123
+							'event_espresso'
124
+						),
125
+						$class,
126
+						$path
127
+					)
128
+				);
129
+			}
130
+			if (! isset(EEH_Autoloader::$_autoloaders[ $class ])) {
131
+				EEH_Autoloader::$_autoloaders[ $class ] = str_replace(['/', '\\'], '/', $path);
132
+				if (EE_DEBUG && (EEH_Autoloader::$debug === 'paths' || EEH_Autoloader::$debug === 'all' || $debug)) {
133
+					EEH_Debug_Tools::printr(EEH_Autoloader::$_autoloaders[ $class ], $class, __FILE__, __LINE__);
134
+				}
135
+			}
136
+		}
137
+	}
138
+
139
+
140
+	/**
141
+	 * @return array
142
+	 */
143
+	public static function get_autoloaders(): array
144
+	{
145
+		return EEH_Autoloader::$_autoloaders;
146
+	}
147
+
148
+
149
+	/**
150
+	 * @return void
151
+	 * @throws EE_Error
152
+	 */
153
+	private function _register_custom_autoloaders()
154
+	{
155
+		EEH_Autoloader::$debug = '';
156
+		EEH_Autoloader::register_helpers_autoloaders();
157
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces');
158
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE);
159
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_INTERFACES, true);
160
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_MODELS, true);
161
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CLASSES);
162
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_FORM_SECTIONS, true);
163
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'messages');
164
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
165
+			Benchmark::displayResults();
166
+		}
167
+	}
168
+
169
+
170
+	/**
171
+	 * @throws EE_Error
172
+	 */
173
+	public static function register_helpers_autoloaders()
174
+	{
175
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
176
+	}
177
+
178
+
179
+	/**
180
+	 * @return void
181
+	 */
182
+	public static function register_form_sections_autoloaders()
183
+	{
184
+		// EEH_Autoloader::register_autoloaders_for_each_file_in_folder( EE_FORM_SECTIONS, true );
185
+	}
186
+
187
+
188
+	/**
189
+	 * @return void
190
+	 * @throws EE_Error
191
+	 */
192
+	public static function register_line_item_display_autoloaders()
193
+	{
194
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_display', true);
195
+	}
196
+
197
+
198
+	/**
199
+	 * @return void
200
+	 * @throws EE_Error
201
+	 */
202
+	public static function register_line_item_filter_autoloaders()
203
+	{
204
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'line_item_filters', true);
205
+	}
206
+
207
+
208
+	/**
209
+	 * @return void
210
+	 * @throws EE_Error
211
+	 */
212
+	public static function register_template_part_autoloaders()
213
+	{
214
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'template_parts', true);
215
+	}
216
+
217
+
218
+	/**
219
+	 * @return void
220
+	 * @throws EE_Error
221
+	 */
222
+	public static function register_business_classes()
223
+	{
224
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'business');
225
+	}
226
+
227
+
228
+	/**
229
+	 * Assumes all the files in this folder have the normal naming scheme (namely that their classname
230
+	 * is the file's name, plus ".whatever.php".) and adds each of them to the autoloader list.
231
+	 * If that's not the case, you'll need to improve this function or just use
232
+	 * EEH_File::get_classname_from_filepath_with_standard_filename() directly. Yes this has to scan the directory for
233
+	 * files, but it only does it once -- not on EACH time the autoloader is used
234
+	 *
235
+	 * @param string $folder name, with or without trailing /, doesn't matter
236
+	 * @param bool   $recursive
237
+	 * @param bool   $debug  **deprecated**
238
+	 * @throws EE_Error
239
+	 */
240
+	public static function register_autoloaders_for_each_file_in_folder(
241
+		string $folder,
242
+		bool $recursive = false,
243
+		bool $debug = false
244
+	) {
245
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all' || $debug) {
246
+			Benchmark::startTimer(basename($folder));
247
+		}
248
+		// make sure last char is a /
249
+		$folder .= $folder[ strlen($folder) - 1 ] !== '/' ? '/' : '';
250
+		$class_to_filepath_map = [];
251
+		$exclude = ['index'];
252
+		// get all the files in that folder that end in php
253
+		$filepaths = glob($folder . '*');
254
+
255
+		if (empty($filepaths)) {
256
+			return;
257
+		}
258
+
259
+		foreach ($filepaths as $filepath) {
260
+			if (substr($filepath, -4, 4) === '.php') {
261
+				$class_name = EEH_File::get_classname_from_filepath_with_standard_filename($filepath);
262
+				if (! in_array($class_name, $exclude)) {
263
+					$class_to_filepath_map [ $class_name ] = $filepath;
264
+				}
265
+			} elseif ($recursive) {
266
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($filepath, $recursive, $debug);
267
+			}
268
+		}
269
+		// we remove the necessity to do a is_readable() check via the $read_check flag because glob by nature will not return non_readable files/directories.
270
+		EEH_Autoloader::register_autoloader($class_to_filepath_map, false, $debug);
271
+		if (EEH_Autoloader::$debug === 'times' || EEH_Autoloader::$debug === 'all') {
272
+			Benchmark::stopTimer(basename($folder));
273
+		}
274
+	}
275
+
276
+
277
+	/**
278
+	 * register additional autoloader based on variation of the classname for an existing autoloader
279
+	 *
280
+	 * @param string $class_name - simple class name ie: EE_Session
281
+	 * @param string $alias      - variation on class name ie: EE_session, session, etc
282
+	 */
283
+	public static function add_alias(string $class_name, string $alias)
284
+	{
285
+		if (isset(EEH_Autoloader::$_autoloaders[ $class_name ])) {
286
+			EEH_Autoloader::$_autoloaders[ $alias ] = EEH_Autoloader::$_autoloaders[ $class_name ];
287
+		}
288
+	}
289 289
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Form_Fields.helper.php 2 patches
Indentation   +1464 added lines, -1464 removed lines patch added patch discarded remove patch
@@ -29,1034 +29,1034 @@  discard block
 block discarded – undo
29 29
 {
30 30
 
31 31
 
32
-    /**
33
-     *  Generates HTML for the forms used on admin pages
34
-     *
35
-     *
36
-     *  @static
37
-     *  @access public
38
-     *  @param  array $input_vars - array of input field details
39
-     *  format:
40
-     *  $template_form_fields['field-id'] = array(
41
-     *      'name' => 'name_attribute',
42
-     *      'label' => __('Field Label', 'event_espresso'), //or false
43
-     *      'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden', 'checkbox', 'wp_editor'
44
-     *      'type' => 'int', //what "type" the value is (i.e. string, int etc)
45
-     *      'required' => false, //boolean for whether the field is required
46
-     *      'validation' => true, //boolean, whether to validate the field (todo)
47
-     *      'value' => 'some_value_for_field', //what value is used for field
48
-     *      'format' => '%d', //what format the value is (%d, %f, or %s)
49
-     *      'db-col' => 'column_in_db' //used to indicate which column the field corresponds with in the db
50
-     *      'options' => optiona, optionb || array('value' => 'label', '') //if the input type is "select", this allows you to set the args for the different <option> tags.
51
-     *      'tabindex' => 1 //this allows you to set the tabindex for the field.
52
-     *      'append_content' => '' //this allows you to send in html content to append to the field.
53
-     *  )
54
-     *  @param  array $id - used for defining unique identifiers for the form.
55
-     *  @return string
56
-     *  @todo: at some point we can break this down into other static methods to abstract it a bit better.
57
-     */
58
-    public static function get_form_fields($input_vars = array(), $id = false)
59
-    {
60
-
61
-        if (empty($input_vars)) {
62
-            EE_Error::add_error(__('missing required variables for the form field generator', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
63
-            return false;
64
-        }
65
-
66
-        // if you don't behave - this is what you're gonna get !!!
67
-        $close = true;
68
-        $output = '<ul>'; // this is for using built-in wp styles... watch carefully...
69
-
70
-        // cycle thru inputs
71
-        foreach ($input_vars as $input_key => $input_value) {
72
-            $defaults = array(
73
-                'name' => $input_key,
74
-                'label' => __('No label', 'event_espresso'),
75
-                'input' => 'hidden',
76
-                'type' => 'int',
77
-                'required' => false,
78
-                'validation' => true,
79
-                'value' => 'some_value_for_field',
80
-                'format' => '%d',
81
-                'db-col' => 'column_in_db',
82
-                'options' => array(),
83
-                'tabindex' => '',
84
-                'append_content' => ''
85
-                );
86
-
87
-            $input_value = wp_parse_args($input_value, $defaults);
88
-
89
-            // required fields get a *
90
-            $required = isset($input_value['required']) && $input_value['required'] ? ' <span>*</span>: ' : ': ';
91
-            // and the css class "required"
92
-            $css_class = isset($input_value['css_class']) ? $input_value['css_class'] : '';
93
-            $styles = $input_value['required'] ? 'required ' . $css_class : $css_class;
94
-
95
-            $field_id = ($id) ? $id . '-' . $input_key : $input_key;
96
-            $tabindex = !empty($input_value['tabindex']) ? ' tabindex="' . $input_value['tabindex'] . '"' : '';
97
-
98
-            // rows or cols?
99
-            $rows = isset($input_value['rows']) ? $input_value['rows'] : '10';
100
-            $cols = isset($input_value['cols']) ? $input_value['cols'] : '80';
101
-
102
-            // any content?
103
-            $append_content = $input_value['append_content'];
104
-
105
-            $output .= (!$close) ? '<ul>' : '';
106
-            $output .= '<li>';
107
-
108
-            // what type of input are we dealing with ?
109
-            switch ($input_value['input']) {
110
-                // text inputs
111
-                case 'text':
112
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
113
-                    $output .= "\n\t\t\t" . '<input id="' . $field_id . '" class="' . $styles . '" type="text" value="' . esc_textarea($input_value['value']) . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
114
-                    break;
115
-
116
-                // dropdowns
117
-                case 'select':
118
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
119
-                    $output .= "\n\t\t\t" . '<select id="' . $field_id . '" class="' . $styles . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
120
-
121
-                    if (is_array($input_value['options'])) {
122
-                        $options = $input_value['options'];
123
-                    } else {
124
-                        $options = explode(',', $input_value['options']);
125
-                    }
126
-
127
-                    foreach ($options as $key => $value) {
128
-                        $selected = isset($input_value['value']) && $input_value['value'] == $key ? 'selected=selected' : '';
129
-                        // $key = str_replace( ' ', '_', sanitize_key( $value ));
130
-                        $output .= "\n\t\t\t\t" . '<option ' . $selected . ' value="' . $key . '">' . $value . '</option>';
131
-                    }
132
-                    $output .= "\n\t\t\t" . '</select>';
133
-
134
-                    break;
135
-
136
-                case 'textarea':
137
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
138
-                    $output .= "\n\t\t\t" . '<textarea id="' . $field_id . '" class="' . $styles . '" rows="' . $rows . '" cols="' . $cols . '" name="' . $input_value['name'] . '"' . $tabindex . '>' . esc_textarea($input_value['value']) . '</textarea>';
139
-                    break;
140
-
141
-                case 'hidden':
142
-                    $close = false;
143
-                    $output .= "</li></ul>";
144
-                    $output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="hidden" name="' . $input_value['name'] . '" value="' . $input_value['value'] . '">';
145
-                    break;
146
-
147
-                case 'checkbox':
148
-                    $checked = ( $input_value['value'] == 1 ) ? 'checked="checked"' : '';
149
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
150
-                    $output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="checkbox" name="' . $input_value['name'] . '" value="1"' . $checked . $tabindex . ' />';
151
-                    break;
152
-
153
-                case 'wp_editor':
154
-                    $close = false;
155
-                    $editor_settings = array(
156
-                        'textarea_name' => $input_value['name'],
157
-                        'textarea_rows' => $rows,
158
-                        'editor_class' => $styles,
159
-                        'tabindex' => $input_value['tabindex']
160
-                    );
161
-                    $output .= '</li>';
162
-                    $output .= '</ul>';
163
-                    $output .= '<h4>' . $input_value['label'] . '</h4>';
164
-                    if ($append_content) {
165
-                        $output .= $append_content;
166
-                    }
167
-                    ob_start();
168
-                    wp_editor($input_value['value'], $field_id, $editor_settings);
169
-                    $editor = ob_get_contents();
170
-                    ob_end_clean();
171
-                    $output .= $editor;
172
-                    break;
173
-            }
174
-            if ($append_content && $input_value['input'] !== 'wp_editor') {
175
-                $output .= $append_content;
176
-            }
177
-                $output .= ($close) ? '</li>' : '';
178
-        } // end foreach( $input_vars as $input_key => $input_value )
179
-        $output .= ($close) ? '</ul>' : '';
180
-
181
-        return $output;
182
-    }
183
-
184
-    /**
185
-     * form_fields_array
186
-     * This utility function assembles form fields from a given structured array with field information.
187
-     * //TODO: This is an alternate generator that we may want to use instead.
188
-     *
189
-     * @param  array $fields structured array of fields to assemble in the following format:
190
-     * [field_name] => array(
191
-     *      ['label'] => 'label for field',
192
-     *      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select type of field you can indicated the labels for each option via this index
193
-     *      ['extra_desc'] => 'extra description for the field', //optional
194
-     *      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults to text
195
-     *      ['value'] => 'value that goes in the field', //(if multi then this is an array of values and the 'default' paramater will be used for what is selected)
196
-     *      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
197
-     *      ['class'] => 'name-of-class(es)-for-input',
198
-     *      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi select type of field you can indicate the css class for each option via this index.
199
-     *      ['id'] => 'css-id-for-input') //defaults to 'field_name'
200
-     *      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields generated are going to be used in a loop and you want to make sure that the field identifiers are unique from each other.
201
-     *      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types such as textarea to indicate cols/rows.
202
-     *      ['tabindex'] => '' //this allows you to set the tabindex for the field.
203
-     *      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally contain an array of arguments for the editor setup.
204
-     *
205
-     * @return array         an array of inputs for form indexed by field name, and in the following structure:
206
-     *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
207
-     */
208
-    public static function get_form_fields_array($fields)
209
-    {
210
-
211
-        $form_fields = array();
212
-        $fields = (array) $fields;
213
-
214
-        foreach ($fields as $field_name => $field_atts) {
215
-            // defaults:
216
-            $defaults = array(
217
-                'label' => '',
218
-                'labels' => '',
219
-                'extra_desc' => '',
220
-                'type' => 'text',
221
-                'value' => '',
222
-                'default' => '',
223
-                'class' => '',
224
-                'classes' => '',
225
-                'id' => $field_name,
226
-                'unique_id' => '',
227
-                'dimensions' => array('10', '5'),
228
-                'tabindex' => '',
229
-                'wpeditor_args' => array()
230
-                );
231
-            // merge defaults with passed arguments
232
-            $_fields = wp_parse_args($field_atts, $defaults);
233
-            extract($_fields);
234
-            // generate label
235
-            $label = empty($label) ? '' : '<label for="' . $id . '">' . $label . '</label>';
236
-            // generate field name
237
-            $f_name = !empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
238
-
239
-            // tabindex
240
-            $tabindex_str = !empty($tabindex) ? ' tabindex="' . $tabindex . '"' : '';
241
-
242
-            // we determine what we're building based on the type
243
-            switch ($type) {
244
-                case 'textarea':
245
-                        $fld = '<textarea id="' . $id . '" class="' . $class . '" rows="' . $dimensions[1] . '" cols="' . $dimensions[0] . '" name="' . $f_name . '"' . $tabindex_str . '>' . $value . '</textarea>';
246
-                        $fld .= $extra_desc;
247
-                    break;
248
-
249
-                case 'checkbox':
250
-                        $c_input = '';
251
-                    if (is_array($value)) {
252
-                        foreach ($value as $key => $val) {
253
-                            $c_id = $field_name . '_' . $value;
254
-                            $c_class = isset($classes[ $key ]) ? ' class="' . $classes[ $key ] . '" ' : '';
255
-                            $c_label = isset($labels[ $key ]) ? '<label for="' . $c_id . '">' . $labels[ $key ] . '</label>' : '';
256
-                            $checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
257
-                            $c_input .= '<input name="' . $f_name . '[]" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
258
-                        }
259
-                        $fld = $c_input;
260
-                    } else {
261
-                        $checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
262
-                        $fld = '<input name="' . $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
263
-                    }
264
-                    break;
265
-
266
-                case 'radio':
267
-                        $c_input = '';
268
-                    if (is_array($value)) {
269
-                        foreach ($value as $key => $val) {
270
-                            $c_id = $field_name . '_' . $value;
271
-                            $c_class = isset($classes[ $key ]) ? 'class="' . $classes[ $key ] . '" ' : '';
272
-                            $c_label = isset($labels[ $key ]) ? '<label for="' . $c_id . '">' . $labels[ $key ] . '</label>' : '';
273
-                            $checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
274
-                            $c_input .= '<input name="' . $f_name . '" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
275
-                        }
276
-                        $fld = $c_input;
277
-                    } else {
278
-                        $checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
279
-                        $fld = '<input name="' . $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
280
-                    }
281
-                    break;
282
-
283
-                case 'hidden':
284
-                        $fld = '<input name="' . $f_name . '" type="hidden" id="' . $id . '" class="' . $class . '" value="' . $value . '" />' . "\n";
285
-                    break;
286
-
287
-                case 'select':
288
-                        $fld = '<select name="' . $f_name . '" class="' . $class . '" id="' . $id . '"' . $tabindex_str . '>' . "\n";
289
-                    foreach ($value as $key => $val) {
290
-                        $checked = !empty($default) && $default == $val ? ' selected="selected"' : '';
291
-                        $fld .= "\t" . '<option value="' . $val . '"' . $checked . '>' . $labels[ $key ] . '</option>' . "\n";
292
-                    }
293
-                        $fld .= '</select>';
294
-                    break;
295
-
296
-                case 'wp_editor':
297
-                        $editor_settings = array(
298
-                            'textarea_name' => $f_name,
299
-                            'textarea_rows' => $dimensions[1],
300
-                            'editor_class' => $class,
301
-                            'tabindex' => $tabindex
302
-                            );
303
-                        $editor_settings = array_merge($wpeditor_args, $editor_settings);
304
-                        ob_start();
305
-                        wp_editor($value, $id, $editor_settings);
306
-                        $editor = ob_get_contents();
307
-                        ob_end_clean();
308
-                        $fld = $editor;
309
-                    break;
310
-
311
-                default: // 'text fields'
312
-                        $fld = '<input name="' . $f_name . '" type="text" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $tabindex_str . ' />' . "\n";
313
-                        $fld .= $extra_desc;
314
-            }
315
-
316
-            $form_fields[ $field_name ] = array( 'label' => $label, 'field' => $fld );
317
-        }
318
-
319
-        return $form_fields;
320
-    }
321
-
322
-
323
-
324
-
325
-
326
-
327
-    /**
328
-     * espresso admin page select_input
329
-     * Turns an array into a select fields
330
-     *
331
-     * @static
332
-     * @access public
333
-     * @param  string  $name       field name
334
-     * @param  array  $values     option values, numbered array starting at 0, where each value is an array with a key 'text' (meaning text to display' and 'id' (meaning the internal value)
335
-     * eg: array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or as an array of key-value pairs, where the key is to be used for the
336
-     * select input's name, and the value will be the text shown to the user.  Optionally you can also include an additional key of "class" which will add a specific class to the option for that value.
337
-     * @param  string  $default    default value
338
-     * @param  string  $parameters extra paramaters
339
-     * @param  string  $class      css class
340
-     * @param  boolean $autosize   whether to autosize the select or not
341
-     * @return string              html string for the select input
342
-     */
343
-    public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
344
-    {
345
-        // if $values was submitted in the wrong format, convert it over
346
-        if (!empty($values) && (!array_key_exists(0, $values) || !is_array($values[0]))) {
347
-            $converted_values = array();
348
-            foreach ($values as $id => $text) {
349
-                $converted_values[] = array('id' => $id,'text' => $text);
350
-            }
351
-            $values = $converted_values;
352
-        }
353
-
354
-        $field = '<select id="' . EEH_Formatter::ee_tep_output_string($name) . '" name="' . EEH_Formatter::ee_tep_output_string($name) . '"';
355
-        // Debug
356
-        // EEH_Debug_Tools::printr( $values, '$values  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
357
-        if (EEH_Formatter::ee_tep_not_null($parameters)) {
358
-            $field .= ' ' . $parameters;
359
-        }
360
-        if ($autosize) {
361
-            $size = 'med';
362
-            for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
363
-                if ($values[ $ii ]['text']) {
364
-                    if (strlen($values[ $ii ]['text']) > 5) {
365
-                        $size = 'wide';
366
-                    }
367
-                }
368
-            }
369
-        } else {
370
-            $size = '';
371
-        }
372
-
373
-        $field .= ' class="' . $class . ' ' . $size . '">';
374
-
375
-        if (empty($default) && isset($GLOBALS[ $name ])) {
376
-            $default = stripslashes($GLOBALS[ $name ]);
377
-        }
378
-
379
-
380
-        for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
381
-            $field .= '<option value="' . $values[ $i ]['id'] . '"';
382
-            if ($default == $values[ $i ]['id']) {
383
-                $field .= ' selected = "selected"';
384
-            }
385
-            if (isset($values[ $i ]['class'])) {
386
-                $field .= ' class="' . $values[ $i ]['class'] . '"';
387
-            }
388
-            $field .= '>' . $values[ $i ]['text'] . '</option>';
389
-        }
390
-        $field .= '</select>';
391
-
392
-        return $field;
393
-    }
394
-
395
-
396
-
397
-
398
-
399
-
400
-    /**
401
-     * generate_question_groups_html
402
-     *
403
-     * @param string $question_groups
404
-     * @return string HTML
405
-     */
406
-    public static function generate_question_groups_html($question_groups = array(), $group_wrapper = 'fieldset')
407
-    {
408
-
409
-        $html = '';
410
-        $before_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
411
-        $after_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
412
-
413
-        if (! empty($question_groups)) {
414
-            // EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
415
-            // loop thru question groups
416
-            foreach ($question_groups as $QSG) {
417
-                // check that questions exist
418
-                if (! empty($QSG['QSG_questions'])) {
419
-                    // use fieldsets
420
-                    $html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG['QSG_identifier'] . '">';
421
-                    // group_name
422
-                    $html .= $QSG['QSG_show_group_name'] ? "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . self::prep_answer($QSG['QSG_name']) . '</h5>' : '';
423
-                    // group_desc
424
-                    $html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc']) ? '<div class="espresso-question-group-desc-pg">' . self::prep_answer($QSG['QSG_desc']) . '</div>' : '';
425
-
426
-                    $html .= $before_question_group_questions;
427
-                    // loop thru questions
428
-                    foreach ($QSG['QSG_questions'] as $question) {
32
+	/**
33
+	 *  Generates HTML for the forms used on admin pages
34
+	 *
35
+	 *
36
+	 *  @static
37
+	 *  @access public
38
+	 *  @param  array $input_vars - array of input field details
39
+	 *  format:
40
+	 *  $template_form_fields['field-id'] = array(
41
+	 *      'name' => 'name_attribute',
42
+	 *      'label' => __('Field Label', 'event_espresso'), //or false
43
+	 *      'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden', 'checkbox', 'wp_editor'
44
+	 *      'type' => 'int', //what "type" the value is (i.e. string, int etc)
45
+	 *      'required' => false, //boolean for whether the field is required
46
+	 *      'validation' => true, //boolean, whether to validate the field (todo)
47
+	 *      'value' => 'some_value_for_field', //what value is used for field
48
+	 *      'format' => '%d', //what format the value is (%d, %f, or %s)
49
+	 *      'db-col' => 'column_in_db' //used to indicate which column the field corresponds with in the db
50
+	 *      'options' => optiona, optionb || array('value' => 'label', '') //if the input type is "select", this allows you to set the args for the different <option> tags.
51
+	 *      'tabindex' => 1 //this allows you to set the tabindex for the field.
52
+	 *      'append_content' => '' //this allows you to send in html content to append to the field.
53
+	 *  )
54
+	 *  @param  array $id - used for defining unique identifiers for the form.
55
+	 *  @return string
56
+	 *  @todo: at some point we can break this down into other static methods to abstract it a bit better.
57
+	 */
58
+	public static function get_form_fields($input_vars = array(), $id = false)
59
+	{
60
+
61
+		if (empty($input_vars)) {
62
+			EE_Error::add_error(__('missing required variables for the form field generator', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
63
+			return false;
64
+		}
65
+
66
+		// if you don't behave - this is what you're gonna get !!!
67
+		$close = true;
68
+		$output = '<ul>'; // this is for using built-in wp styles... watch carefully...
69
+
70
+		// cycle thru inputs
71
+		foreach ($input_vars as $input_key => $input_value) {
72
+			$defaults = array(
73
+				'name' => $input_key,
74
+				'label' => __('No label', 'event_espresso'),
75
+				'input' => 'hidden',
76
+				'type' => 'int',
77
+				'required' => false,
78
+				'validation' => true,
79
+				'value' => 'some_value_for_field',
80
+				'format' => '%d',
81
+				'db-col' => 'column_in_db',
82
+				'options' => array(),
83
+				'tabindex' => '',
84
+				'append_content' => ''
85
+				);
86
+
87
+			$input_value = wp_parse_args($input_value, $defaults);
88
+
89
+			// required fields get a *
90
+			$required = isset($input_value['required']) && $input_value['required'] ? ' <span>*</span>: ' : ': ';
91
+			// and the css class "required"
92
+			$css_class = isset($input_value['css_class']) ? $input_value['css_class'] : '';
93
+			$styles = $input_value['required'] ? 'required ' . $css_class : $css_class;
94
+
95
+			$field_id = ($id) ? $id . '-' . $input_key : $input_key;
96
+			$tabindex = !empty($input_value['tabindex']) ? ' tabindex="' . $input_value['tabindex'] . '"' : '';
97
+
98
+			// rows or cols?
99
+			$rows = isset($input_value['rows']) ? $input_value['rows'] : '10';
100
+			$cols = isset($input_value['cols']) ? $input_value['cols'] : '80';
101
+
102
+			// any content?
103
+			$append_content = $input_value['append_content'];
104
+
105
+			$output .= (!$close) ? '<ul>' : '';
106
+			$output .= '<li>';
107
+
108
+			// what type of input are we dealing with ?
109
+			switch ($input_value['input']) {
110
+				// text inputs
111
+				case 'text':
112
+					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
113
+					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" class="' . $styles . '" type="text" value="' . esc_textarea($input_value['value']) . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
114
+					break;
115
+
116
+				// dropdowns
117
+				case 'select':
118
+					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
119
+					$output .= "\n\t\t\t" . '<select id="' . $field_id . '" class="' . $styles . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
120
+
121
+					if (is_array($input_value['options'])) {
122
+						$options = $input_value['options'];
123
+					} else {
124
+						$options = explode(',', $input_value['options']);
125
+					}
126
+
127
+					foreach ($options as $key => $value) {
128
+						$selected = isset($input_value['value']) && $input_value['value'] == $key ? 'selected=selected' : '';
129
+						// $key = str_replace( ' ', '_', sanitize_key( $value ));
130
+						$output .= "\n\t\t\t\t" . '<option ' . $selected . ' value="' . $key . '">' . $value . '</option>';
131
+					}
132
+					$output .= "\n\t\t\t" . '</select>';
133
+
134
+					break;
135
+
136
+				case 'textarea':
137
+					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
138
+					$output .= "\n\t\t\t" . '<textarea id="' . $field_id . '" class="' . $styles . '" rows="' . $rows . '" cols="' . $cols . '" name="' . $input_value['name'] . '"' . $tabindex . '>' . esc_textarea($input_value['value']) . '</textarea>';
139
+					break;
140
+
141
+				case 'hidden':
142
+					$close = false;
143
+					$output .= "</li></ul>";
144
+					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="hidden" name="' . $input_value['name'] . '" value="' . $input_value['value'] . '">';
145
+					break;
146
+
147
+				case 'checkbox':
148
+					$checked = ( $input_value['value'] == 1 ) ? 'checked="checked"' : '';
149
+					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
150
+					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="checkbox" name="' . $input_value['name'] . '" value="1"' . $checked . $tabindex . ' />';
151
+					break;
152
+
153
+				case 'wp_editor':
154
+					$close = false;
155
+					$editor_settings = array(
156
+						'textarea_name' => $input_value['name'],
157
+						'textarea_rows' => $rows,
158
+						'editor_class' => $styles,
159
+						'tabindex' => $input_value['tabindex']
160
+					);
161
+					$output .= '</li>';
162
+					$output .= '</ul>';
163
+					$output .= '<h4>' . $input_value['label'] . '</h4>';
164
+					if ($append_content) {
165
+						$output .= $append_content;
166
+					}
167
+					ob_start();
168
+					wp_editor($input_value['value'], $field_id, $editor_settings);
169
+					$editor = ob_get_contents();
170
+					ob_end_clean();
171
+					$output .= $editor;
172
+					break;
173
+			}
174
+			if ($append_content && $input_value['input'] !== 'wp_editor') {
175
+				$output .= $append_content;
176
+			}
177
+				$output .= ($close) ? '</li>' : '';
178
+		} // end foreach( $input_vars as $input_key => $input_value )
179
+		$output .= ($close) ? '</ul>' : '';
180
+
181
+		return $output;
182
+	}
183
+
184
+	/**
185
+	 * form_fields_array
186
+	 * This utility function assembles form fields from a given structured array with field information.
187
+	 * //TODO: This is an alternate generator that we may want to use instead.
188
+	 *
189
+	 * @param  array $fields structured array of fields to assemble in the following format:
190
+	 * [field_name] => array(
191
+	 *      ['label'] => 'label for field',
192
+	 *      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select type of field you can indicated the labels for each option via this index
193
+	 *      ['extra_desc'] => 'extra description for the field', //optional
194
+	 *      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults to text
195
+	 *      ['value'] => 'value that goes in the field', //(if multi then this is an array of values and the 'default' paramater will be used for what is selected)
196
+	 *      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
197
+	 *      ['class'] => 'name-of-class(es)-for-input',
198
+	 *      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi select type of field you can indicate the css class for each option via this index.
199
+	 *      ['id'] => 'css-id-for-input') //defaults to 'field_name'
200
+	 *      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields generated are going to be used in a loop and you want to make sure that the field identifiers are unique from each other.
201
+	 *      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types such as textarea to indicate cols/rows.
202
+	 *      ['tabindex'] => '' //this allows you to set the tabindex for the field.
203
+	 *      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally contain an array of arguments for the editor setup.
204
+	 *
205
+	 * @return array         an array of inputs for form indexed by field name, and in the following structure:
206
+	 *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
207
+	 */
208
+	public static function get_form_fields_array($fields)
209
+	{
210
+
211
+		$form_fields = array();
212
+		$fields = (array) $fields;
213
+
214
+		foreach ($fields as $field_name => $field_atts) {
215
+			// defaults:
216
+			$defaults = array(
217
+				'label' => '',
218
+				'labels' => '',
219
+				'extra_desc' => '',
220
+				'type' => 'text',
221
+				'value' => '',
222
+				'default' => '',
223
+				'class' => '',
224
+				'classes' => '',
225
+				'id' => $field_name,
226
+				'unique_id' => '',
227
+				'dimensions' => array('10', '5'),
228
+				'tabindex' => '',
229
+				'wpeditor_args' => array()
230
+				);
231
+			// merge defaults with passed arguments
232
+			$_fields = wp_parse_args($field_atts, $defaults);
233
+			extract($_fields);
234
+			// generate label
235
+			$label = empty($label) ? '' : '<label for="' . $id . '">' . $label . '</label>';
236
+			// generate field name
237
+			$f_name = !empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
238
+
239
+			// tabindex
240
+			$tabindex_str = !empty($tabindex) ? ' tabindex="' . $tabindex . '"' : '';
241
+
242
+			// we determine what we're building based on the type
243
+			switch ($type) {
244
+				case 'textarea':
245
+						$fld = '<textarea id="' . $id . '" class="' . $class . '" rows="' . $dimensions[1] . '" cols="' . $dimensions[0] . '" name="' . $f_name . '"' . $tabindex_str . '>' . $value . '</textarea>';
246
+						$fld .= $extra_desc;
247
+					break;
248
+
249
+				case 'checkbox':
250
+						$c_input = '';
251
+					if (is_array($value)) {
252
+						foreach ($value as $key => $val) {
253
+							$c_id = $field_name . '_' . $value;
254
+							$c_class = isset($classes[ $key ]) ? ' class="' . $classes[ $key ] . '" ' : '';
255
+							$c_label = isset($labels[ $key ]) ? '<label for="' . $c_id . '">' . $labels[ $key ] . '</label>' : '';
256
+							$checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
257
+							$c_input .= '<input name="' . $f_name . '[]" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
258
+						}
259
+						$fld = $c_input;
260
+					} else {
261
+						$checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
262
+						$fld = '<input name="' . $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
263
+					}
264
+					break;
265
+
266
+				case 'radio':
267
+						$c_input = '';
268
+					if (is_array($value)) {
269
+						foreach ($value as $key => $val) {
270
+							$c_id = $field_name . '_' . $value;
271
+							$c_class = isset($classes[ $key ]) ? 'class="' . $classes[ $key ] . '" ' : '';
272
+							$c_label = isset($labels[ $key ]) ? '<label for="' . $c_id . '">' . $labels[ $key ] . '</label>' : '';
273
+							$checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
274
+							$c_input .= '<input name="' . $f_name . '" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
275
+						}
276
+						$fld = $c_input;
277
+					} else {
278
+						$checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
279
+						$fld = '<input name="' . $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
280
+					}
281
+					break;
282
+
283
+				case 'hidden':
284
+						$fld = '<input name="' . $f_name . '" type="hidden" id="' . $id . '" class="' . $class . '" value="' . $value . '" />' . "\n";
285
+					break;
286
+
287
+				case 'select':
288
+						$fld = '<select name="' . $f_name . '" class="' . $class . '" id="' . $id . '"' . $tabindex_str . '>' . "\n";
289
+					foreach ($value as $key => $val) {
290
+						$checked = !empty($default) && $default == $val ? ' selected="selected"' : '';
291
+						$fld .= "\t" . '<option value="' . $val . '"' . $checked . '>' . $labels[ $key ] . '</option>' . "\n";
292
+					}
293
+						$fld .= '</select>';
294
+					break;
295
+
296
+				case 'wp_editor':
297
+						$editor_settings = array(
298
+							'textarea_name' => $f_name,
299
+							'textarea_rows' => $dimensions[1],
300
+							'editor_class' => $class,
301
+							'tabindex' => $tabindex
302
+							);
303
+						$editor_settings = array_merge($wpeditor_args, $editor_settings);
304
+						ob_start();
305
+						wp_editor($value, $id, $editor_settings);
306
+						$editor = ob_get_contents();
307
+						ob_end_clean();
308
+						$fld = $editor;
309
+					break;
310
+
311
+				default: // 'text fields'
312
+						$fld = '<input name="' . $f_name . '" type="text" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $tabindex_str . ' />' . "\n";
313
+						$fld .= $extra_desc;
314
+			}
315
+
316
+			$form_fields[ $field_name ] = array( 'label' => $label, 'field' => $fld );
317
+		}
318
+
319
+		return $form_fields;
320
+	}
321
+
322
+
323
+
324
+
325
+
326
+
327
+	/**
328
+	 * espresso admin page select_input
329
+	 * Turns an array into a select fields
330
+	 *
331
+	 * @static
332
+	 * @access public
333
+	 * @param  string  $name       field name
334
+	 * @param  array  $values     option values, numbered array starting at 0, where each value is an array with a key 'text' (meaning text to display' and 'id' (meaning the internal value)
335
+	 * eg: array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or as an array of key-value pairs, where the key is to be used for the
336
+	 * select input's name, and the value will be the text shown to the user.  Optionally you can also include an additional key of "class" which will add a specific class to the option for that value.
337
+	 * @param  string  $default    default value
338
+	 * @param  string  $parameters extra paramaters
339
+	 * @param  string  $class      css class
340
+	 * @param  boolean $autosize   whether to autosize the select or not
341
+	 * @return string              html string for the select input
342
+	 */
343
+	public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
344
+	{
345
+		// if $values was submitted in the wrong format, convert it over
346
+		if (!empty($values) && (!array_key_exists(0, $values) || !is_array($values[0]))) {
347
+			$converted_values = array();
348
+			foreach ($values as $id => $text) {
349
+				$converted_values[] = array('id' => $id,'text' => $text);
350
+			}
351
+			$values = $converted_values;
352
+		}
353
+
354
+		$field = '<select id="' . EEH_Formatter::ee_tep_output_string($name) . '" name="' . EEH_Formatter::ee_tep_output_string($name) . '"';
355
+		// Debug
356
+		// EEH_Debug_Tools::printr( $values, '$values  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
357
+		if (EEH_Formatter::ee_tep_not_null($parameters)) {
358
+			$field .= ' ' . $parameters;
359
+		}
360
+		if ($autosize) {
361
+			$size = 'med';
362
+			for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
363
+				if ($values[ $ii ]['text']) {
364
+					if (strlen($values[ $ii ]['text']) > 5) {
365
+						$size = 'wide';
366
+					}
367
+				}
368
+			}
369
+		} else {
370
+			$size = '';
371
+		}
372
+
373
+		$field .= ' class="' . $class . ' ' . $size . '">';
374
+
375
+		if (empty($default) && isset($GLOBALS[ $name ])) {
376
+			$default = stripslashes($GLOBALS[ $name ]);
377
+		}
378
+
379
+
380
+		for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
381
+			$field .= '<option value="' . $values[ $i ]['id'] . '"';
382
+			if ($default == $values[ $i ]['id']) {
383
+				$field .= ' selected = "selected"';
384
+			}
385
+			if (isset($values[ $i ]['class'])) {
386
+				$field .= ' class="' . $values[ $i ]['class'] . '"';
387
+			}
388
+			$field .= '>' . $values[ $i ]['text'] . '</option>';
389
+		}
390
+		$field .= '</select>';
391
+
392
+		return $field;
393
+	}
394
+
395
+
396
+
397
+
398
+
399
+
400
+	/**
401
+	 * generate_question_groups_html
402
+	 *
403
+	 * @param string $question_groups
404
+	 * @return string HTML
405
+	 */
406
+	public static function generate_question_groups_html($question_groups = array(), $group_wrapper = 'fieldset')
407
+	{
408
+
409
+		$html = '';
410
+		$before_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
411
+		$after_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
412
+
413
+		if (! empty($question_groups)) {
414
+			// EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
415
+			// loop thru question groups
416
+			foreach ($question_groups as $QSG) {
417
+				// check that questions exist
418
+				if (! empty($QSG['QSG_questions'])) {
419
+					// use fieldsets
420
+					$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG['QSG_identifier'] . '">';
421
+					// group_name
422
+					$html .= $QSG['QSG_show_group_name'] ? "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . self::prep_answer($QSG['QSG_name']) . '</h5>' : '';
423
+					// group_desc
424
+					$html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc']) ? '<div class="espresso-question-group-desc-pg">' . self::prep_answer($QSG['QSG_desc']) . '</div>' : '';
425
+
426
+					$html .= $before_question_group_questions;
427
+					// loop thru questions
428
+					foreach ($QSG['QSG_questions'] as $question) {
429 429
 //                      EEH_Debug_Tools::printr( $question, '$question  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
430
-                        $QFI = new EE_Question_Form_Input(
431
-                            $question['qst_obj'],
432
-                            $question['ans_obj'],
433
-                            $question
434
-                        );
435
-                        $html .= self::generate_form_input($QFI);
436
-                    }
437
-                    $html .= $after_question_group_questions;
438
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
439
-                }
440
-            }
441
-        }
442
-
443
-        return $html;
444
-    }
445
-
446
-
447
-
448
-    /**
449
-     * generate_question_groups_html
450
-     *
451
-     * @param array         $question_groups
452
-     * @param array        $q_meta
453
-     * @param bool         $from_admin
454
-     * @param string       $group_wrapper
455
-     * @return string HTML
456
-     */
457
-    public static function generate_question_groups_html2($question_groups = array(), $q_meta = array(), $from_admin = false, $group_wrapper = 'fieldset')
458
-    {
459
-
460
-        $html = '';
461
-        $before_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
462
-        $after_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
463
-
464
-        $default_q_meta = array(
465
-                'att_nmbr' => 1,
466
-                'ticket_id' => '',
467
-                'input_name' => '',
468
-                'input_id' => '',
469
-                'input_class' => ''
470
-        );
471
-        $q_meta = array_merge($default_q_meta, $q_meta);
472
-        // EEH_Debug_Tools::printr( $q_meta, '$q_meta  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
473
-
474
-        if (! empty($question_groups)) {
430
+						$QFI = new EE_Question_Form_Input(
431
+							$question['qst_obj'],
432
+							$question['ans_obj'],
433
+							$question
434
+						);
435
+						$html .= self::generate_form_input($QFI);
436
+					}
437
+					$html .= $after_question_group_questions;
438
+					$html .= "\n\t" . '</' . $group_wrapper . '>';
439
+				}
440
+			}
441
+		}
442
+
443
+		return $html;
444
+	}
445
+
446
+
447
+
448
+	/**
449
+	 * generate_question_groups_html
450
+	 *
451
+	 * @param array         $question_groups
452
+	 * @param array        $q_meta
453
+	 * @param bool         $from_admin
454
+	 * @param string       $group_wrapper
455
+	 * @return string HTML
456
+	 */
457
+	public static function generate_question_groups_html2($question_groups = array(), $q_meta = array(), $from_admin = false, $group_wrapper = 'fieldset')
458
+	{
459
+
460
+		$html = '';
461
+		$before_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
462
+		$after_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
463
+
464
+		$default_q_meta = array(
465
+				'att_nmbr' => 1,
466
+				'ticket_id' => '',
467
+				'input_name' => '',
468
+				'input_id' => '',
469
+				'input_class' => ''
470
+		);
471
+		$q_meta = array_merge($default_q_meta, $q_meta);
472
+		// EEH_Debug_Tools::printr( $q_meta, '$q_meta  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
473
+
474
+		if (! empty($question_groups)) {
475 475
 //          EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
476
-            // loop thru question groups
477
-            foreach ($question_groups as $QSG) {
478
-                if ($QSG instanceof EE_Question_Group) {
479
-                    // check that questions exist
480
-
481
-                    $where = array( 'QST_deleted' => 0 );
482
-                    if (! $from_admin) {
483
-                        $where['QST_admin_only'] = 0;
484
-                    }
485
-                    $questions = $QSG->questions(array( $where, 'order_by' => array( 'Question_Group_Question.QGQ_order' => 'ASC' )));
486
-                    if (! empty($questions)) {
487
-                        // use fieldsets
488
-                        $html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG->get('QSG_identifier') . '">';
489
-                        // group_name
490
-                        if ($QSG->show_group_name()) {
491
-                            $html .=  "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . $QSG->get_pretty('QSG_name') . '</h5>';
492
-                        }
493
-                        // group_desc
494
-                        if ($QSG->show_group_desc()) {
495
-                            $html .=  '<div class="espresso-question-group-desc-pg">' . $QSG->get_pretty('QSG_desc') . '</div>';
496
-                        }
497
-
498
-                        $html .= $before_question_group_questions;
499
-                        // loop thru questions
500
-                        foreach ($questions as $QST) {
501
-                            $qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
502
-
503
-                            $answer = null;
504
-
505
-                            if (isset($_GET['qstn']) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
506
-                                // check for answer in $_GET in case we are reprocessing a form after an error
507
-                                if (isset($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ])) {
508
-                                    $answer = is_array($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ]) ? $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] : sanitize_text_field($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ]);
509
-                                }
510
-                            } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
511
-                                // attendee data from the session
512
-                                $answer = isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
513
-                            }
514
-
515
-
516
-
517
-                            $QFI = new EE_Question_Form_Input(
518
-                                $QST,
519
-                                EE_Answer::new_instance(array(
520
-                                            'ANS_ID' => 0,
521
-                                            'QST_ID' => 0,
522
-                                            'REG_ID' => 0,
523
-                                            'ANS_value' => $answer
524
-                                    )),
525
-                                $q_meta
526
-                            );
527
-                            // EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
528
-                            $html .= self::generate_form_input($QFI);
529
-                        }
530
-                        $html .= $after_question_group_questions;
531
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
532
-                    }
533
-                }
534
-            }
535
-        }
536
-        return $html;
537
-    }
538
-
539
-
540
-
541
-
542
-
543
-
544
-    /**
545
-     * generate_form_input
546
-     *
547
-     * @param EE_Question_Form_Input $QFI
548
-     * @return string HTML
549
-     */
550
-    public static function generate_form_input(EE_Question_Form_Input $QFI)
551
-    {
552
-        if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
553
-            return '';
554
-        }
555
-
556
-        $QFI = self::_load_system_dropdowns($QFI);
557
-        $QFI = self::_load_specialized_dropdowns($QFI);
558
-
559
-        // we also need to verify
560
-
561
-        $display_text = $QFI->get('QST_display_text');
562
-        $input_name = $QFI->get('QST_input_name');
563
-        $answer = EE_Registry::instance()->REQ->is_set($input_name) ? EE_Registry::instance()->REQ->get($input_name) : $QFI->get('ANS_value');
564
-        $input_id = $QFI->get('QST_input_id');
565
-        $input_class = $QFI->get('QST_input_class');
476
+			// loop thru question groups
477
+			foreach ($question_groups as $QSG) {
478
+				if ($QSG instanceof EE_Question_Group) {
479
+					// check that questions exist
480
+
481
+					$where = array( 'QST_deleted' => 0 );
482
+					if (! $from_admin) {
483
+						$where['QST_admin_only'] = 0;
484
+					}
485
+					$questions = $QSG->questions(array( $where, 'order_by' => array( 'Question_Group_Question.QGQ_order' => 'ASC' )));
486
+					if (! empty($questions)) {
487
+						// use fieldsets
488
+						$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG->get('QSG_identifier') . '">';
489
+						// group_name
490
+						if ($QSG->show_group_name()) {
491
+							$html .=  "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . $QSG->get_pretty('QSG_name') . '</h5>';
492
+						}
493
+						// group_desc
494
+						if ($QSG->show_group_desc()) {
495
+							$html .=  '<div class="espresso-question-group-desc-pg">' . $QSG->get_pretty('QSG_desc') . '</div>';
496
+						}
497
+
498
+						$html .= $before_question_group_questions;
499
+						// loop thru questions
500
+						foreach ($questions as $QST) {
501
+							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
502
+
503
+							$answer = null;
504
+
505
+							if (isset($_GET['qstn']) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
506
+								// check for answer in $_GET in case we are reprocessing a form after an error
507
+								if (isset($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ])) {
508
+									$answer = is_array($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ]) ? $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] : sanitize_text_field($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ]);
509
+								}
510
+							} elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
511
+								// attendee data from the session
512
+								$answer = isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
513
+							}
514
+
515
+
516
+
517
+							$QFI = new EE_Question_Form_Input(
518
+								$QST,
519
+								EE_Answer::new_instance(array(
520
+											'ANS_ID' => 0,
521
+											'QST_ID' => 0,
522
+											'REG_ID' => 0,
523
+											'ANS_value' => $answer
524
+									)),
525
+								$q_meta
526
+							);
527
+							// EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
528
+							$html .= self::generate_form_input($QFI);
529
+						}
530
+						$html .= $after_question_group_questions;
531
+						$html .= "\n\t" . '</' . $group_wrapper . '>';
532
+					}
533
+				}
534
+			}
535
+		}
536
+		return $html;
537
+	}
538
+
539
+
540
+
541
+
542
+
543
+
544
+	/**
545
+	 * generate_form_input
546
+	 *
547
+	 * @param EE_Question_Form_Input $QFI
548
+	 * @return string HTML
549
+	 */
550
+	public static function generate_form_input(EE_Question_Form_Input $QFI)
551
+	{
552
+		if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
553
+			return '';
554
+		}
555
+
556
+		$QFI = self::_load_system_dropdowns($QFI);
557
+		$QFI = self::_load_specialized_dropdowns($QFI);
558
+
559
+		// we also need to verify
560
+
561
+		$display_text = $QFI->get('QST_display_text');
562
+		$input_name = $QFI->get('QST_input_name');
563
+		$answer = EE_Registry::instance()->REQ->is_set($input_name) ? EE_Registry::instance()->REQ->get($input_name) : $QFI->get('ANS_value');
564
+		$input_id = $QFI->get('QST_input_id');
565
+		$input_class = $QFI->get('QST_input_class');
566 566
 //      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
567
-        $disabled = $QFI->get('QST_disabled') ? true : false;
568
-        $required_label = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
569
-        $QST_required = $QFI->get('QST_required');
570
-        $required = $QST_required ? array( 'label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required ) : array();
571
-        $use_html_entities = $QFI->get_meta('htmlentities');
572
-        $required_text = $QFI->get('QST_required_text') != '' ? $QFI->get('QST_required_text') : __('This field is required', 'event_espresso');
573
-        $required_text = $QST_required ? "\n\t\t\t" . '<div class="required-text hidden">' . self::prep_answer($required_text, $use_html_entities) . '</div>' : '';
574
-        $label_class = 'espresso-form-input-lbl';
575
-        $QST_options = $QFI->options(true, $answer);
576
-        $options = is_array($QST_options) ? self::prep_answer_options($QST_options) : array();
577
-        $system_ID = $QFI->get('QST_system');
578
-        $label_b4 = $QFI->get_meta('label_b4');
579
-        $use_desc_4_label = $QFI->get_meta('use_desc_4_label');
580
-
581
-
582
-        switch ($QFI->get('QST_type')) {
583
-            case 'TEXTAREA':
584
-                return EEH_Form_Fields::textarea($display_text, $answer, $input_name, $input_id, $input_class, array(), $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities);
585
-                break;
586
-
587
-            case 'DROPDOWN':
588
-                return EEH_Form_Fields::select($display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities, true);
589
-                break;
590
-
591
-
592
-            case 'RADIO_BTN':
593
-                return EEH_Form_Fields::radio($display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities, $label_b4, $use_desc_4_label);
594
-                break;
595
-
596
-            case 'CHECKBOX':
597
-                return EEH_Form_Fields::checkbox($display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $label_b4, $system_ID, $use_html_entities);
598
-                break;
599
-
600
-            case 'DATE':
601
-                return EEH_Form_Fields::datepicker($display_text, $answer, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities);
602
-                break;
603
-
604
-            case 'TEXT':
605
-            default:
606
-                return EEH_Form_Fields::text($display_text, $answer, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities);
607
-                break;
608
-        }
609
-    }
610
-
611
-
612
-
613
-
614
-
615
-
616
-    /**
617
-     * generates HTML for a form text input
618
-     *
619
-     * @param string $question  label content
620
-     * @param string $answer        form input value attribute
621
-     * @param string $name          form input name attribute
622
-     * @param string $id                form input css id attribute
623
-     * @param string $class             form input css class attribute
624
-     * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
625
-     * @param string $label_class   css class attribute for the label
626
-     * @param string $disabled      disabled="disabled" or null
627
-     * @return string HTML
628
-     */
629
-    public static function text($question = false, $answer = null, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
630
-    {
631
-        // need these
632
-        if (! $question || ! $name) {
633
-            return null;
634
-        }
635
-        // prep the answer
636
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
637
-        // prep the required array
638
-        $required = self::prep_required($required);
639
-        // set disabled tag
640
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
641
-        // ya gots ta have style man!!!
642
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
643
-        $class = empty($class) ? $txt_class : $class;
644
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
645
-        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
646
-
647
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
648
-        // filter label but ensure required text comes before it
649
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
650
-
651
-        $input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
652
-
653
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
654
-        return  $label_html . $input_html;
655
-    }
656
-
657
-
658
-
659
-
660
-
661
-    /**
662
-     * generates HTML for a form textarea
663
-     *
664
-     * @param string $question      label content
665
-     * @param string $answer        form input value attribute
666
-     * @param string $name          form input name attribute
667
-     * @param string $id                form input css id attribute
668
-     * @param string $class             form input css class attribute
669
-     * @param array $dimensions array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
670
-     * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
671
-     * @param string $label_class   css class attribute for the label
672
-     * @param string $disabled      disabled="disabled" or null
673
-     * @return string HTML
674
-     */
675
-    public static function textarea($question = false, $answer = null, $name = false, $id = '', $class = '', $dimensions = false, $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
676
-    {
677
-        // need these
678
-        if (! $question || ! $name) {
679
-            return null;
680
-        }
681
-        // prep the answer
682
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
683
-        // prep the required array
684
-        $required = self::prep_required($required);
685
-        // make sure $dimensions is an array
686
-        $dimensions = is_array($dimensions) ? $dimensions : array();
687
-        // and set some defaults
688
-        $dimensions = array_merge(array( 'rows' => 3, 'cols' => 40 ), $dimensions);
689
-        // set disabled tag
690
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
691
-        // ya gots ta have style man!!!
692
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
693
-        $class = empty($class) ? $txt_class : $class;
694
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
695
-        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
696
-
697
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
698
-        // filter label but ensure required text comes before it
699
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
700
-
701
-        $input_html = "\n\t\t\t" . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>' . $answer . '</textarea>';
702
-
703
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
704
-        return  $label_html . $input_html;
705
-    }
706
-
707
-
708
-
709
-
710
-
711
-
712
-    /**
713
-     * generates HTML for a form select input
714
-     *
715
-     * @param string $question      label content
716
-     * @param string $answer        form input value attribute
717
-     * @param array $options            array of answer options where array key = option value and array value = option display text
718
-     * @param string $name          form input name attribute
719
-     * @param string $id                form input css id attribute
720
-     * @param string $class             form input css class attribute
721
-     * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
722
-     * @param string $label_class   css class attribute for the label
723
-     * @param string $disabled      disabled="disabled" or null
724
-     * @return string HTML
725
-     */
726
-    public static function select($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true, $add_please_select_option = false)
727
-    {
728
-
729
-        // need these
730
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
731
-            return null;
732
-        }
733
-        // prep the answer
734
-        $answer = is_array($answer) ? self::prep_answer(array_shift($answer), $use_html_entities) : self::prep_answer($answer, $use_html_entities);
735
-        // prep the required array
736
-        $required = self::prep_required($required);
737
-        // set disabled tag
738
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
739
-        // ya gots ta have style man!!!
740
-        $txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
741
-        $class = empty($class) ? $txt_class : $class;
742
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
743
-        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
744
-
745
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
746
-        // filter label but ensure required text comes before it
747
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
748
-
749
-        $input_html = "\n\t\t\t" . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
750
-        // recursively count array elements, to determine total number of options
751
-        $only_option = count($options, 1) == 1 ? true : false;
752
-        if (! $only_option) {
753
-            // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
754
-            $selected = $answer === null ? ' selected="selected"' : '';
755
-            $input_html .= $add_please_select_option ? "\n\t\t\t\t" . '<option value=""' . $selected . '>' . __(' - please select - ', 'event_espresso') . '</option>' : '';
756
-        }
757
-        foreach ($options as $key => $value) {
758
-            // if value is an array, then create option groups, else create regular ol' options
759
-            $input_html .= is_array($value) ? self::_generate_select_option_group($key, $value, $answer, $use_html_entities) : self::_generate_select_option($value->value(), $value->desc(), $answer, $only_option, $use_html_entities);
760
-        }
761
-
762
-        $input_html .= "\n\t\t\t" . '</select>';
763
-
764
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID);
765
-
766
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
767
-        return  $label_html . $input_html;
768
-    }
769
-
770
-
771
-
772
-    /**
773
-     *  _generate_select_option_group
774
-     *
775
-     *  if  $value for a select box is an array, then the key will be used as the optgroup label
776
-     *  and the value array will be looped thru and the elements sent to _generate_select_option
777
-     *
778
-     * @param mixed $opt_group
779
-     * @param mixed $QSOs
780
-     * @param mixed $answer
781
-     * @param boolean $use_html_entities
782
-     * @return string
783
-     */
784
-    private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
785
-    {
786
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
787
-        foreach ($QSOs as $QSO) {
788
-            $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
789
-        }
790
-        $html .= "\n\t\t\t\t" . '</optgroup>';
791
-        return $html;
792
-    }
793
-
794
-
795
-
796
-    /**
797
-     *  _generate_select_option
798
-     * @param mixed $key
799
-     * @param mixed $value
800
-     * @param mixed $answer
801
-     * @param int $only_option
802
-     * @param boolean $use_html_entities
803
-     * @return string
804
-     */
805
-    private static function _generate_select_option($key, $value, $answer, $only_option = false, $use_html_entities = true)
806
-    {
807
-        $key = self::prep_answer($key, $use_html_entities);
808
-        $value = self::prep_answer($value, $use_html_entities);
809
-        $value = ! empty($value) ? $value : $key;
810
-        $selected = ( $answer == $key || $only_option ) ? ' selected="selected"' : '';
811
-        return "\n\t\t\t\t" . '<option value="' . self::prep_option_value($key) . '"' . $selected . '> ' . $value . '&nbsp;&nbsp;&nbsp;</option>';
812
-    }
813
-
814
-
815
-
816
-    /**
817
-     * generates HTML for form radio button inputs
818
-     *
819
-     * @param bool|string $question    label content
820
-     * @param string      $answer      form input value attribute
821
-     * @param array|bool  $options     array of answer options where array key = option value and array value = option display text
822
-     * @param bool|string $name        form input name attribute
823
-     * @param string      $id          form input css id attribute
824
-     * @param string      $class       form input css class attribute
825
-     * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
826
-     * @param string      $required_text
827
-     * @param string      $label_class css class attribute for the label
828
-     * @param bool|string $disabled    disabled="disabled" or null
829
-     * @param bool        $system_ID
830
-     * @param bool        $use_html_entities
831
-     * @param bool        $label_b4
832
-     * @param bool        $use_desc_4_label
833
-     * @return string HTML
834
-     */
835
-    public static function radio($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true, $label_b4 = false, $use_desc_4_label = false)
836
-    {
837
-        // need these
838
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
839
-            return null;
840
-        }
841
-        // prep the answer
842
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
843
-        // prep the required array
844
-        $required = self::prep_required($required);
845
-        // set disabled tag
846
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
847
-        // ya gots ta have style man!!!
848
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
849
-        $class = ! empty($class) ? $class : 'espresso-radio-btn-inp';
850
-        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
851
-
852
-        $label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label> ';
853
-        // filter label but ensure required text comes before it
854
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
855
-
856
-        $input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
857
-
858
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
859
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
860
-
861
-        foreach ($options as $OPT) {
862
-            if ($OPT instanceof EE_Question_Option) {
863
-                $value = self::prep_option_value($OPT->value());
864
-                $label = $use_desc_4_label ? $OPT->desc() : $OPT->value();
865
-                $size = $use_desc_4_label ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc()) : self::get_label_size_class($OPT->value());
866
-                $desc = $OPT->desc();// no self::prep_answer
867
-                $answer = is_numeric($value) && empty($answer) ? 0 : $answer;
868
-                $checked = (string) $value == (string) $answer ? ' checked="checked"' : '';
869
-                $opt = '-' . sanitize_key($value);
870
-
871
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
872
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
873
-                $input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
874
-                $input_html .= "\n\t\t\t\t\t\t" . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
875
-                $input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span class="espresso-radio-btn-desc">' . $label . '</span>' : '';
876
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
877
-                $input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
878
-                $input_html .= "\n\t\t\t\t" . '</li>';
879
-            }
880
-        }
881
-
882
-        $input_html .= "\n\t\t\t" . '</ul>';
883
-
884
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
885
-        return  $label_html . $input_html;
886
-    }
887
-
888
-
889
-
890
-
891
-
892
-
893
-    /**
894
-     * generates HTML for form checkbox inputs
895
-     *
896
-     * @param string $question      label content
897
-     * @param string $answer        form input value attribute
898
-     * @param array $options            array of options where array key = option value and array value = option display text
899
-     * @param string $name          form input name attribute
900
-     * @param string $id                form input css id attribute
901
-     * @param string $class             form input css class attribute
902
-     * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
903
-     * @param string $label_class   css class attribute for the label
904
-     * @param string $disabled      disabled="disabled" or null
905
-     * @return string HTML
906
-     */
907
-    public static function checkbox($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $label_b4 = false, $system_ID = false, $use_html_entities = true)
908
-    {
909
-        // need these
910
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
911
-            return null;
912
-        }
913
-        $answer = maybe_unserialize($answer);
914
-
915
-        // prep the answer(s)
916
-        $answer = is_array($answer) ? $answer : array( sanitize_key($answer) => $answer );
917
-
918
-        foreach ($answer as $key => $value) {
919
-            $key = self::prep_option_value($key);
920
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
921
-        }
922
-
923
-        // prep the required array
924
-        $required = self::prep_required($required);
925
-        // set disabled tag
926
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
927
-        // ya gots ta have style man!!!
928
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
929
-        $class = empty($class) ? 'espresso-radio-btn-inp' : $class;
930
-        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
931
-
932
-        $label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label> ';
933
-        // filter label but ensure required text comes before it
934
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
935
-
936
-        $input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
937
-
938
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
939
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
940
-
941
-        foreach ($options as $OPT) {
942
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
943
-            $size = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
944
-            $text = self::prep_answer($OPT->value());
945
-            $desc = $OPT->desc() ;
946
-            $opt = '-' . sanitize_key($value);
947
-
948
-            $checked = is_array($answer) && in_array($text, $answer) ? ' checked="checked"' : '';
949
-
950
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
951
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
952
-            $input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
953
-            $input_html .= "\n\t\t\t\t\t\t" . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
954
-            $input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
955
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
956
-            if (! empty($desc) && $desc != $text) {
957
-                $input_html .= "\n\t\t\t\t\t" . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">' . $desc . '</div>';
958
-            }
959
-            $input_html .= "\n\t\t\t\t" . '</li>';
960
-        }
961
-
962
-        $input_html .= "\n\t\t\t" . '</ul>';
963
-
964
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
965
-        return  $label_html . $input_html;
966
-    }
967
-
968
-
969
-
970
-
971
-
972
-
973
-    /**
974
-     * generates HTML for a form datepicker input
975
-     *
976
-     * @param string $question  label content
977
-     * @param string $answer        form input value attribute
978
-     * @param string $name          form input name attribute
979
-     * @param string $id                form input css id attribute
980
-     * @param string $class             form input css class attribute
981
-     * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
982
-     * @param string $label_class   css class attribute for the label
983
-     * @param string $disabled      disabled="disabled" or null
984
-     * @return string HTML
985
-     */
986
-    public static function datepicker($question = false, $answer = null, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
987
-    {
988
-        // need these
989
-        if (! $question || ! $name) {
990
-            return null;
991
-        }
992
-        // prep the answer
993
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
994
-        // prep the required array
995
-        $required = self::prep_required($required);
996
-        // set disabled tag
997
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
998
-        // ya gots ta have style man!!!
999
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1000
-        $class = empty($class) ? $txt_class : $class;
1001
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1002
-        $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1003
-
1004
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
1005
-        // filter label but ensure required text comes before it
1006
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1007
-
1008
-        $input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1009
-
1010
-        // enqueue scripts
1011
-        wp_register_style('espresso-ui-theme', EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', array(), EVENT_ESPRESSO_VERSION);
1012
-        wp_enqueue_style('espresso-ui-theme');
1013
-        wp_enqueue_script('jquery-ui-datepicker');
1014
-
1015
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1016
-        return  $label_html . $input_html;
1017
-    }
1018
-
1019
-
1020
-
1021
-    /**
1022
-     *  remove_label_keep_required_msg
1023
-     *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1024
-     *  @access public
1025
-     *  @return     string
1026
-     */
1027
-    public static function remove_label_keep_required_msg($label_html, $required_text)
1028
-    {
1029
-        return $required_text;
1030
-    }
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-    /**
1037
-     * Simply return sthe HTML for a hidden input of the given name and value.
1038
-     * @param string $name
1039
-     * @param string $value
1040
-     * @return string HTML
1041
-     */
1042
-    public static function hidden_input($name, $value, $id = '')
1043
-    {
1044
-        $id = ! empty($id) ? $id : $name;
1045
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' .  $value . '"/>';
1046
-    }
1047
-
1048
-
1049
-
1050
-
1051
-
1052
-    /**
1053
-     * prep_question
1054
-     * @param string $question
1055
-     * @return string
1056
-     */
1057
-    public static function prep_question($question)
1058
-    {
1059
-        return $question;
567
+		$disabled = $QFI->get('QST_disabled') ? true : false;
568
+		$required_label = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
569
+		$QST_required = $QFI->get('QST_required');
570
+		$required = $QST_required ? array( 'label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required ) : array();
571
+		$use_html_entities = $QFI->get_meta('htmlentities');
572
+		$required_text = $QFI->get('QST_required_text') != '' ? $QFI->get('QST_required_text') : __('This field is required', 'event_espresso');
573
+		$required_text = $QST_required ? "\n\t\t\t" . '<div class="required-text hidden">' . self::prep_answer($required_text, $use_html_entities) . '</div>' : '';
574
+		$label_class = 'espresso-form-input-lbl';
575
+		$QST_options = $QFI->options(true, $answer);
576
+		$options = is_array($QST_options) ? self::prep_answer_options($QST_options) : array();
577
+		$system_ID = $QFI->get('QST_system');
578
+		$label_b4 = $QFI->get_meta('label_b4');
579
+		$use_desc_4_label = $QFI->get_meta('use_desc_4_label');
580
+
581
+
582
+		switch ($QFI->get('QST_type')) {
583
+			case 'TEXTAREA':
584
+				return EEH_Form_Fields::textarea($display_text, $answer, $input_name, $input_id, $input_class, array(), $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities);
585
+				break;
586
+
587
+			case 'DROPDOWN':
588
+				return EEH_Form_Fields::select($display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities, true);
589
+				break;
590
+
591
+
592
+			case 'RADIO_BTN':
593
+				return EEH_Form_Fields::radio($display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities, $label_b4, $use_desc_4_label);
594
+				break;
595
+
596
+			case 'CHECKBOX':
597
+				return EEH_Form_Fields::checkbox($display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $label_b4, $system_ID, $use_html_entities);
598
+				break;
599
+
600
+			case 'DATE':
601
+				return EEH_Form_Fields::datepicker($display_text, $answer, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities);
602
+				break;
603
+
604
+			case 'TEXT':
605
+			default:
606
+				return EEH_Form_Fields::text($display_text, $answer, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities);
607
+				break;
608
+		}
609
+	}
610
+
611
+
612
+
613
+
614
+
615
+
616
+	/**
617
+	 * generates HTML for a form text input
618
+	 *
619
+	 * @param string $question  label content
620
+	 * @param string $answer        form input value attribute
621
+	 * @param string $name          form input name attribute
622
+	 * @param string $id                form input css id attribute
623
+	 * @param string $class             form input css class attribute
624
+	 * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
625
+	 * @param string $label_class   css class attribute for the label
626
+	 * @param string $disabled      disabled="disabled" or null
627
+	 * @return string HTML
628
+	 */
629
+	public static function text($question = false, $answer = null, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
630
+	{
631
+		// need these
632
+		if (! $question || ! $name) {
633
+			return null;
634
+		}
635
+		// prep the answer
636
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
637
+		// prep the required array
638
+		$required = self::prep_required($required);
639
+		// set disabled tag
640
+		$disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
641
+		// ya gots ta have style man!!!
642
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
643
+		$class = empty($class) ? $txt_class : $class;
644
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
645
+		$extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
646
+
647
+		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
648
+		// filter label but ensure required text comes before it
649
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
650
+
651
+		$input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
652
+
653
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
654
+		return  $label_html . $input_html;
655
+	}
656
+
657
+
658
+
659
+
660
+
661
+	/**
662
+	 * generates HTML for a form textarea
663
+	 *
664
+	 * @param string $question      label content
665
+	 * @param string $answer        form input value attribute
666
+	 * @param string $name          form input name attribute
667
+	 * @param string $id                form input css id attribute
668
+	 * @param string $class             form input css class attribute
669
+	 * @param array $dimensions array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
670
+	 * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
671
+	 * @param string $label_class   css class attribute for the label
672
+	 * @param string $disabled      disabled="disabled" or null
673
+	 * @return string HTML
674
+	 */
675
+	public static function textarea($question = false, $answer = null, $name = false, $id = '', $class = '', $dimensions = false, $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
676
+	{
677
+		// need these
678
+		if (! $question || ! $name) {
679
+			return null;
680
+		}
681
+		// prep the answer
682
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
683
+		// prep the required array
684
+		$required = self::prep_required($required);
685
+		// make sure $dimensions is an array
686
+		$dimensions = is_array($dimensions) ? $dimensions : array();
687
+		// and set some defaults
688
+		$dimensions = array_merge(array( 'rows' => 3, 'cols' => 40 ), $dimensions);
689
+		// set disabled tag
690
+		$disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
691
+		// ya gots ta have style man!!!
692
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
693
+		$class = empty($class) ? $txt_class : $class;
694
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
695
+		$extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
696
+
697
+		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
698
+		// filter label but ensure required text comes before it
699
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
700
+
701
+		$input_html = "\n\t\t\t" . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>' . $answer . '</textarea>';
702
+
703
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
704
+		return  $label_html . $input_html;
705
+	}
706
+
707
+
708
+
709
+
710
+
711
+
712
+	/**
713
+	 * generates HTML for a form select input
714
+	 *
715
+	 * @param string $question      label content
716
+	 * @param string $answer        form input value attribute
717
+	 * @param array $options            array of answer options where array key = option value and array value = option display text
718
+	 * @param string $name          form input name attribute
719
+	 * @param string $id                form input css id attribute
720
+	 * @param string $class             form input css class attribute
721
+	 * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
722
+	 * @param string $label_class   css class attribute for the label
723
+	 * @param string $disabled      disabled="disabled" or null
724
+	 * @return string HTML
725
+	 */
726
+	public static function select($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true, $add_please_select_option = false)
727
+	{
728
+
729
+		// need these
730
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
731
+			return null;
732
+		}
733
+		// prep the answer
734
+		$answer = is_array($answer) ? self::prep_answer(array_shift($answer), $use_html_entities) : self::prep_answer($answer, $use_html_entities);
735
+		// prep the required array
736
+		$required = self::prep_required($required);
737
+		// set disabled tag
738
+		$disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
739
+		// ya gots ta have style man!!!
740
+		$txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
741
+		$class = empty($class) ? $txt_class : $class;
742
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
743
+		$extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
744
+
745
+		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
746
+		// filter label but ensure required text comes before it
747
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
748
+
749
+		$input_html = "\n\t\t\t" . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
750
+		// recursively count array elements, to determine total number of options
751
+		$only_option = count($options, 1) == 1 ? true : false;
752
+		if (! $only_option) {
753
+			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
754
+			$selected = $answer === null ? ' selected="selected"' : '';
755
+			$input_html .= $add_please_select_option ? "\n\t\t\t\t" . '<option value=""' . $selected . '>' . __(' - please select - ', 'event_espresso') . '</option>' : '';
756
+		}
757
+		foreach ($options as $key => $value) {
758
+			// if value is an array, then create option groups, else create regular ol' options
759
+			$input_html .= is_array($value) ? self::_generate_select_option_group($key, $value, $answer, $use_html_entities) : self::_generate_select_option($value->value(), $value->desc(), $answer, $only_option, $use_html_entities);
760
+		}
761
+
762
+		$input_html .= "\n\t\t\t" . '</select>';
763
+
764
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID);
765
+
766
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
767
+		return  $label_html . $input_html;
768
+	}
769
+
770
+
771
+
772
+	/**
773
+	 *  _generate_select_option_group
774
+	 *
775
+	 *  if  $value for a select box is an array, then the key will be used as the optgroup label
776
+	 *  and the value array will be looped thru and the elements sent to _generate_select_option
777
+	 *
778
+	 * @param mixed $opt_group
779
+	 * @param mixed $QSOs
780
+	 * @param mixed $answer
781
+	 * @param boolean $use_html_entities
782
+	 * @return string
783
+	 */
784
+	private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
785
+	{
786
+		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
787
+		foreach ($QSOs as $QSO) {
788
+			$html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
789
+		}
790
+		$html .= "\n\t\t\t\t" . '</optgroup>';
791
+		return $html;
792
+	}
793
+
794
+
795
+
796
+	/**
797
+	 *  _generate_select_option
798
+	 * @param mixed $key
799
+	 * @param mixed $value
800
+	 * @param mixed $answer
801
+	 * @param int $only_option
802
+	 * @param boolean $use_html_entities
803
+	 * @return string
804
+	 */
805
+	private static function _generate_select_option($key, $value, $answer, $only_option = false, $use_html_entities = true)
806
+	{
807
+		$key = self::prep_answer($key, $use_html_entities);
808
+		$value = self::prep_answer($value, $use_html_entities);
809
+		$value = ! empty($value) ? $value : $key;
810
+		$selected = ( $answer == $key || $only_option ) ? ' selected="selected"' : '';
811
+		return "\n\t\t\t\t" . '<option value="' . self::prep_option_value($key) . '"' . $selected . '> ' . $value . '&nbsp;&nbsp;&nbsp;</option>';
812
+	}
813
+
814
+
815
+
816
+	/**
817
+	 * generates HTML for form radio button inputs
818
+	 *
819
+	 * @param bool|string $question    label content
820
+	 * @param string      $answer      form input value attribute
821
+	 * @param array|bool  $options     array of answer options where array key = option value and array value = option display text
822
+	 * @param bool|string $name        form input name attribute
823
+	 * @param string      $id          form input css id attribute
824
+	 * @param string      $class       form input css class attribute
825
+	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
826
+	 * @param string      $required_text
827
+	 * @param string      $label_class css class attribute for the label
828
+	 * @param bool|string $disabled    disabled="disabled" or null
829
+	 * @param bool        $system_ID
830
+	 * @param bool        $use_html_entities
831
+	 * @param bool        $label_b4
832
+	 * @param bool        $use_desc_4_label
833
+	 * @return string HTML
834
+	 */
835
+	public static function radio($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true, $label_b4 = false, $use_desc_4_label = false)
836
+	{
837
+		// need these
838
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
839
+			return null;
840
+		}
841
+		// prep the answer
842
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
843
+		// prep the required array
844
+		$required = self::prep_required($required);
845
+		// set disabled tag
846
+		$disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
847
+		// ya gots ta have style man!!!
848
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
849
+		$class = ! empty($class) ? $class : 'espresso-radio-btn-inp';
850
+		$extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
851
+
852
+		$label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label> ';
853
+		// filter label but ensure required text comes before it
854
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
855
+
856
+		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
857
+
858
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
859
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
860
+
861
+		foreach ($options as $OPT) {
862
+			if ($OPT instanceof EE_Question_Option) {
863
+				$value = self::prep_option_value($OPT->value());
864
+				$label = $use_desc_4_label ? $OPT->desc() : $OPT->value();
865
+				$size = $use_desc_4_label ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc()) : self::get_label_size_class($OPT->value());
866
+				$desc = $OPT->desc();// no self::prep_answer
867
+				$answer = is_numeric($value) && empty($answer) ? 0 : $answer;
868
+				$checked = (string) $value == (string) $answer ? ' checked="checked"' : '';
869
+				$opt = '-' . sanitize_key($value);
870
+
871
+				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
872
+				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
873
+				$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
874
+				$input_html .= "\n\t\t\t\t\t\t" . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
875
+				$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span class="espresso-radio-btn-desc">' . $label . '</span>' : '';
876
+				$input_html .= "\n\t\t\t\t\t" . '</label>';
877
+				$input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
878
+				$input_html .= "\n\t\t\t\t" . '</li>';
879
+			}
880
+		}
881
+
882
+		$input_html .= "\n\t\t\t" . '</ul>';
883
+
884
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
885
+		return  $label_html . $input_html;
886
+	}
887
+
888
+
889
+
890
+
891
+
892
+
893
+	/**
894
+	 * generates HTML for form checkbox inputs
895
+	 *
896
+	 * @param string $question      label content
897
+	 * @param string $answer        form input value attribute
898
+	 * @param array $options            array of options where array key = option value and array value = option display text
899
+	 * @param string $name          form input name attribute
900
+	 * @param string $id                form input css id attribute
901
+	 * @param string $class             form input css class attribute
902
+	 * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
903
+	 * @param string $label_class   css class attribute for the label
904
+	 * @param string $disabled      disabled="disabled" or null
905
+	 * @return string HTML
906
+	 */
907
+	public static function checkbox($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $label_b4 = false, $system_ID = false, $use_html_entities = true)
908
+	{
909
+		// need these
910
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
911
+			return null;
912
+		}
913
+		$answer = maybe_unserialize($answer);
914
+
915
+		// prep the answer(s)
916
+		$answer = is_array($answer) ? $answer : array( sanitize_key($answer) => $answer );
917
+
918
+		foreach ($answer as $key => $value) {
919
+			$key = self::prep_option_value($key);
920
+			$answer[ $key ] = self::prep_answer($value, $use_html_entities);
921
+		}
922
+
923
+		// prep the required array
924
+		$required = self::prep_required($required);
925
+		// set disabled tag
926
+		$disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
927
+		// ya gots ta have style man!!!
928
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
929
+		$class = empty($class) ? 'espresso-radio-btn-inp' : $class;
930
+		$extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
931
+
932
+		$label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label> ';
933
+		// filter label but ensure required text comes before it
934
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
935
+
936
+		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
937
+
938
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
939
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
940
+
941
+		foreach ($options as $OPT) {
942
+			$value = $OPT->value();// self::prep_option_value( $OPT->value() );
943
+			$size = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
944
+			$text = self::prep_answer($OPT->value());
945
+			$desc = $OPT->desc() ;
946
+			$opt = '-' . sanitize_key($value);
947
+
948
+			$checked = is_array($answer) && in_array($text, $answer) ? ' checked="checked"' : '';
949
+
950
+			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
951
+			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
952
+			$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
953
+			$input_html .= "\n\t\t\t\t\t\t" . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
954
+			$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
955
+			$input_html .= "\n\t\t\t\t\t" . '</label>';
956
+			if (! empty($desc) && $desc != $text) {
957
+				$input_html .= "\n\t\t\t\t\t" . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">' . $desc . '</div>';
958
+			}
959
+			$input_html .= "\n\t\t\t\t" . '</li>';
960
+		}
961
+
962
+		$input_html .= "\n\t\t\t" . '</ul>';
963
+
964
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
965
+		return  $label_html . $input_html;
966
+	}
967
+
968
+
969
+
970
+
971
+
972
+
973
+	/**
974
+	 * generates HTML for a form datepicker input
975
+	 *
976
+	 * @param string $question  label content
977
+	 * @param string $answer        form input value attribute
978
+	 * @param string $name          form input name attribute
979
+	 * @param string $id                form input css id attribute
980
+	 * @param string $class             form input css class attribute
981
+	 * @param array $required       'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
982
+	 * @param string $label_class   css class attribute for the label
983
+	 * @param string $disabled      disabled="disabled" or null
984
+	 * @return string HTML
985
+	 */
986
+	public static function datepicker($question = false, $answer = null, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
987
+	{
988
+		// need these
989
+		if (! $question || ! $name) {
990
+			return null;
991
+		}
992
+		// prep the answer
993
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
994
+		// prep the required array
995
+		$required = self::prep_required($required);
996
+		// set disabled tag
997
+		$disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
998
+		// ya gots ta have style man!!!
999
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1000
+		$class = empty($class) ? $txt_class : $class;
1001
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1002
+		$extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1003
+
1004
+		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
1005
+		// filter label but ensure required text comes before it
1006
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1007
+
1008
+		$input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1009
+
1010
+		// enqueue scripts
1011
+		wp_register_style('espresso-ui-theme', EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', array(), EVENT_ESPRESSO_VERSION);
1012
+		wp_enqueue_style('espresso-ui-theme');
1013
+		wp_enqueue_script('jquery-ui-datepicker');
1014
+
1015
+		$input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1016
+		return  $label_html . $input_html;
1017
+	}
1018
+
1019
+
1020
+
1021
+	/**
1022
+	 *  remove_label_keep_required_msg
1023
+	 *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1024
+	 *  @access public
1025
+	 *  @return     string
1026
+	 */
1027
+	public static function remove_label_keep_required_msg($label_html, $required_text)
1028
+	{
1029
+		return $required_text;
1030
+	}
1031
+
1032
+
1033
+
1034
+
1035
+
1036
+	/**
1037
+	 * Simply return sthe HTML for a hidden input of the given name and value.
1038
+	 * @param string $name
1039
+	 * @param string $value
1040
+	 * @return string HTML
1041
+	 */
1042
+	public static function hidden_input($name, $value, $id = '')
1043
+	{
1044
+		$id = ! empty($id) ? $id : $name;
1045
+		return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' .  $value . '"/>';
1046
+	}
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+	/**
1053
+	 * prep_question
1054
+	 * @param string $question
1055
+	 * @return string
1056
+	 */
1057
+	public static function prep_question($question)
1058
+	{
1059
+		return $question;
1060 1060
 //      $link = '';
1061 1061
 //      // does this label have a help link attached ?
1062 1062
 //      if ( strpos( $question, '<a ' ) !== FALSE ) {
@@ -1068,449 +1068,449 @@  discard block
 block discarded – undo
1068 1068
 //          $link = '<a ' . $link;
1069 1069
 //      }
1070 1070
 //      return htmlspecialchars( trim( stripslashes( str_replace( '&#039;', "'", $question ))), ENT_QUOTES, 'UTF-8' ) . ' ' . $link;
1071
-    }
1072
-
1073
-
1074
-
1075
-
1076
-    /**
1077
-     *  prep_answer
1078
-     * @param mixed $answer
1079
-     * @return string
1080
-     */
1081
-    public static function prep_answer($answer, $use_html_entities = true)
1082
-    {
1083
-        // make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired, we want "0".
1084
-        if (is_bool($answer)) {
1085
-            $answer = $answer ? 1 : 0;
1086
-        }
1087
-        $answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1088
-        return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1089
-    }
1090
-
1091
-
1092
-
1093
-    /**
1094
-     *  prep_answer_options
1095
-     *  @param array $QSOs  array of EE_Question_Option objects
1096
-     *  @return array
1097
-     */
1098
-    public static function prep_answer_options($QSOs = array())
1099
-    {
1100
-        $prepped_answer_options = array();
1101
-        if (is_array($QSOs) && ! empty($QSOs)) {
1102
-            foreach ($QSOs as $key => $QSO) {
1103
-                if (! $QSO instanceof EE_Question_Option) {
1104
-                    $QSO = EE_Question_Option::new_instance(array(
1105
-                        'QSO_value' => is_array($QSO) && isset($QSO['id']) ? (string) $QSO['id'] : (string) $key,
1106
-                        'QSO_desc' => is_array($QSO) && isset($QSO['text']) ? (string) $QSO['text'] : (string) $QSO
1107
-                    ));
1108
-                }
1109
-                if ($QSO->opt_group()) {
1110
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1111
-                } else {
1112
-                    $prepped_answer_options[] = $QSO;
1113
-                }
1114
-            }
1115
-        }
1071
+	}
1072
+
1073
+
1074
+
1075
+
1076
+	/**
1077
+	 *  prep_answer
1078
+	 * @param mixed $answer
1079
+	 * @return string
1080
+	 */
1081
+	public static function prep_answer($answer, $use_html_entities = true)
1082
+	{
1083
+		// make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired, we want "0".
1084
+		if (is_bool($answer)) {
1085
+			$answer = $answer ? 1 : 0;
1086
+		}
1087
+		$answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1088
+		return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1089
+	}
1090
+
1091
+
1092
+
1093
+	/**
1094
+	 *  prep_answer_options
1095
+	 *  @param array $QSOs  array of EE_Question_Option objects
1096
+	 *  @return array
1097
+	 */
1098
+	public static function prep_answer_options($QSOs = array())
1099
+	{
1100
+		$prepped_answer_options = array();
1101
+		if (is_array($QSOs) && ! empty($QSOs)) {
1102
+			foreach ($QSOs as $key => $QSO) {
1103
+				if (! $QSO instanceof EE_Question_Option) {
1104
+					$QSO = EE_Question_Option::new_instance(array(
1105
+						'QSO_value' => is_array($QSO) && isset($QSO['id']) ? (string) $QSO['id'] : (string) $key,
1106
+						'QSO_desc' => is_array($QSO) && isset($QSO['text']) ? (string) $QSO['text'] : (string) $QSO
1107
+					));
1108
+				}
1109
+				if ($QSO->opt_group()) {
1110
+					$prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1111
+				} else {
1112
+					$prepped_answer_options[] = $QSO;
1113
+				}
1114
+			}
1115
+		}
1116 1116
 //      d( $prepped_answer_options );
1117
-        return $prepped_answer_options;
1118
-    }
1119
-
1120
-
1121
-    /**
1122
-     *  prep_option_value
1123
-     * @param string $option_value
1124
-     * @return string
1125
-     */
1126
-    public static function prep_option_value($option_value)
1127
-    {
1128
-        return esc_attr(trim(stripslashes($option_value)));
1129
-    }
1130
-
1131
-
1132
-
1133
-
1134
-    /**
1135
-     *  prep_required
1136
-     * @param string|array  $required
1137
-     * @return array
1138
-     */
1139
-    public static function prep_required($required = array())
1140
-    {
1141
-        // make sure required is an array
1142
-        $required = is_array($required) ? $required : array();
1143
-        // and set some defaults
1144
-        $required = array_merge(array( 'label' => '', 'class' => '', 'msg' => '' ), $required);
1145
-        return $required;
1146
-    }
1147
-
1148
-
1149
-
1150
-    /**
1151
-     *  get_label_size_class
1152
-     * @param string    $value
1153
-     * @return string
1154
-     */
1155
-    public static function get_label_size_class($value = false)
1156
-    {
1157
-        if ($value === false || $value == '') {
1158
-            return ' class="medium-lbl"';
1159
-        }
1160
-            // determine length of option value
1161
-            $val_size = strlen($value);
1162
-        switch ($val_size) {
1163
-            case $val_size < 3:
1164
-                $size =  ' class="nano-lbl"';
1165
-                break;
1166
-            case $val_size < 6:
1167
-                $size =  ' class="micro-lbl"';
1168
-                break;
1169
-            case $val_size < 12:
1170
-                $size =  ' class="tiny-lbl"';
1171
-                break;
1172
-            case $val_size < 25:
1173
-                $size =  ' class="small-lbl"';
1174
-                break;
1175
-            case $val_size > 100:
1176
-                $size =  ' class="big-lbl"';
1177
-                break;
1178
-            default:
1179
-                $size =  ' class="medium-lbl"';
1180
-                break;
1181
-        }
1182
-        return $size;
1183
-    }
1184
-
1185
-
1186
-
1187
-
1188
-    /**
1189
-     *  _load_system_dropdowns
1190
-     * @param array     $QFI
1191
-     * @return array
1192
-     */
1193
-    private static function _load_system_dropdowns($QFI)
1194
-    {
1195
-        $QST_system = $QFI->get('QST_system');
1196
-        switch ($QST_system) {
1197
-            case 'state':
1198
-                $QFI = self::generate_state_dropdown($QFI);
1199
-                break;
1200
-            case 'country':
1201
-                $QFI = self::generate_country_dropdown($QFI);
1202
-                break;
1203
-            case 'admin-state':
1204
-                $QFI = self::generate_state_dropdown($QFI, true);
1205
-                break;
1206
-            case 'admin-country':
1207
-                $QFI = self::generate_country_dropdown($QFI, true);
1208
-                break;
1209
-        }
1210
-        return $QFI;
1211
-    }
1212
-
1213
-
1214
-
1215
-    /**
1216
-     * This preps dropdowns that are specialized.
1217
-     *
1218
-     * @since  4.6.0
1219
-     *
1220
-     * @param EE_Question_Form_Input $QFI
1221
-     *
1222
-     * @return EE_Question_Form_Input
1223
-     */
1224
-    protected static function _load_specialized_dropdowns($QFI)
1225
-    {
1226
-        switch ($QFI->get('QST_type')) {
1227
-            case 'STATE':
1228
-                $QFI = self::generate_state_dropdown($QFI);
1229
-                break;
1230
-            case 'COUNTRY':
1231
-                $QFI = self::generate_country_dropdown($QFI);
1232
-                break;
1233
-        }
1234
-        return $QFI;
1235
-    }
1236
-
1237
-
1238
-
1239
-    /**
1240
-     *    generate_state_dropdown
1241
-     * @param array $QST
1242
-     * @param bool  $get_all
1243
-     * @return array
1244
-     */
1245
-    public static function generate_state_dropdown($QST, $get_all = false)
1246
-    {
1247
-        $states = $get_all
1248
-            ? EEM_State::instance()->get_all_states()
1249
-            : EEM_State::instance()->get_all_states_of_active_countries();
1250
-        if (! empty($states) && count($states) != count($QST->options())) {
1251
-            $QST->set('QST_type', 'DROPDOWN');
1252
-            // if multiple countries, we'll create option groups within the dropdown
1253
-            foreach ($states as $state) {
1254
-                if ($state instanceof EE_State) {
1255
-                    $QSO = EE_Question_Option::new_instance(array (
1256
-                        'QSO_value' => $state->ID(),
1257
-                        'QSO_desc' => $state->name(),
1258
-                        'QST_ID' => $QST->get('QST_ID'),
1259
-                        'QSO_deleted' => false
1260
-                    ));
1261
-                    // set option group
1262
-                    $QSO->set_opt_group($state->country()->name());
1263
-                    // add option to question
1264
-                    $QST->add_temp_option($QSO);
1265
-                }
1266
-            }
1267
-        }
1268
-        return $QST;
1269
-    }
1270
-
1271
-
1272
-
1273
-    /**
1274
-     *    generate_country_dropdown
1275
-     * @param      $QST
1276
-     * @param bool $get_all
1277
-     * @internal param array $question
1278
-     * @return array
1279
-     */
1280
-    public static function generate_country_dropdown($QST, $get_all = false)
1281
-    {
1282
-        $countries = $get_all ? EEM_Country::instance()->get_all_countries() : EEM_Country::instance()->get_all_active_countries();
1283
-        if ($countries && count($countries) != count($QST->options())) {
1284
-            $QST->set('QST_type', 'DROPDOWN');
1285
-            // now add countries
1286
-            foreach ($countries as $country) {
1287
-                if ($country instanceof EE_Country) {
1288
-                    $QSO = EE_Question_Option::new_instance(array (
1289
-                        'QSO_value' => $country->ID(),
1290
-                        'QSO_desc' => $country->name(),
1291
-                        'QST_ID' => $QST->get('QST_ID'),
1292
-                        'QSO_deleted' => false
1293
-                    ));
1294
-                    $QST->add_temp_option($QSO);
1295
-                }
1296
-            }
1297
-        }
1298
-        return $QST;
1299
-    }
1300
-
1301
-
1302
-
1303
-
1304
-
1305
-    /**
1306
-     *  generates options for a month dropdown selector with numbers from 01 to 12
1307
-     *  @return array()
1308
-     */
1309
-    public static function two_digit_months_dropdown_options()
1310
-    {
1311
-        $options = array();
1312
-        for ($x = 1; $x <= 12; $x++) {
1313
-            $mm = str_pad($x, 2, '0', STR_PAD_LEFT);
1314
-            $options[ (string) $mm ] = (string) $mm;
1315
-        }
1316
-        return EEH_Form_Fields::prep_answer_options($options);
1317
-    }
1318
-
1319
-
1320
-
1321
-
1322
-
1323
-    /**
1324
-     *  generates a year dropdown selector with numbers for the next ten years
1325
-     *  @return object
1326
-     */
1327
-    public static function next_decade_two_digit_year_dropdown_options()
1328
-    {
1329
-        $options = array();
1330
-        $current_year = date('y');
1331
-        $next_decade = $current_year + 10;
1332
-        for ($x = $current_year; $x <= $next_decade; $x++) {
1333
-            $yy = str_pad($x, 2, '0', STR_PAD_LEFT);
1334
-            $options[ (string) $yy ] = (string) $yy;
1335
-        }
1336
-        return EEH_Form_Fields::prep_answer_options($options);
1337
-    }
1338
-
1339
-
1340
-
1341
-
1342
-
1343
-    /**
1344
-     * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for list table filter.
1345
-     * @param  string  $cur_date     any currently selected date can be entered here.
1346
-     * @param  string  $status       Registration status
1347
-     * @param  integer $evt_category Event Category ID if the Event Category filter is selected
1348
-     * @return string                html
1349
-     */
1350
-    public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1351
-    {
1352
-        $_where = array();
1353
-        if (!empty($status)) {
1354
-            $_where['STS_ID'] = $status;
1355
-        }
1356
-
1357
-        if ($evt_category > 0) {
1358
-            $_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1359
-        }
1360
-
1361
-        $regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1362
-
1363
-        // setup vals for select input helper
1364
-        $options = array(
1365
-            0 => array(
1366
-                'text' => __('Select a Month/Year', 'event_espresso'),
1367
-                'id' => ''
1368
-                )
1369
-            );
1370
-
1371
-        foreach ($regdtts as $regdtt) {
1372
-            $date = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1373
-            $options[] = array(
1374
-                'text' => $date,
1375
-                'id' => $date
1376
-                );
1377
-        }
1378
-
1379
-        return self::select_input('month_range', $options, $cur_date, '', 'wide');
1380
-    }
1381
-
1382
-
1383
-
1384
-    /**
1385
-     * generates a month/year dropdown selector for all events matching the given criteria
1386
-     * Typically used for list table filter
1387
-     * @param  string $cur_date          any currently selected date can be entered here.
1388
-     * @param  string $status            "view" (i.e. all, today, month, draft)
1389
-     * @param  int    $evt_category      category event belongs to
1390
-     * @param  string $evt_active_status "upcoming", "expired", "active", or "inactive"
1391
-     * @return string                    html
1392
-     */
1393
-    public static function generate_event_months_dropdown($cur_date = '', $status = '', $evt_category = '', $evt_active_status = '')
1394
-    {
1395
-        // determine what post_status our condition will have for the query.
1396
-        // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1397
-        switch ($status) {
1398
-            case 'month':
1399
-            case 'today':
1400
-            case null:
1401
-            case 'all':
1402
-                $where['Event.status'] = array( 'NOT IN', array('trash') );
1403
-                break;
1404
-
1405
-            case 'draft':
1406
-                $where['Event.status'] = array( 'IN', array('draft', 'auto-draft') );
1407
-
1408
-            default:
1409
-                $where['Event.status'] = $status;
1410
-        }
1411
-
1412
-        // phpcs:enable
1413
-
1414
-        // categories?
1415
-
1117
+		return $prepped_answer_options;
1118
+	}
1119
+
1120
+
1121
+	/**
1122
+	 *  prep_option_value
1123
+	 * @param string $option_value
1124
+	 * @return string
1125
+	 */
1126
+	public static function prep_option_value($option_value)
1127
+	{
1128
+		return esc_attr(trim(stripslashes($option_value)));
1129
+	}
1130
+
1131
+
1132
+
1133
+
1134
+	/**
1135
+	 *  prep_required
1136
+	 * @param string|array  $required
1137
+	 * @return array
1138
+	 */
1139
+	public static function prep_required($required = array())
1140
+	{
1141
+		// make sure required is an array
1142
+		$required = is_array($required) ? $required : array();
1143
+		// and set some defaults
1144
+		$required = array_merge(array( 'label' => '', 'class' => '', 'msg' => '' ), $required);
1145
+		return $required;
1146
+	}
1147
+
1148
+
1149
+
1150
+	/**
1151
+	 *  get_label_size_class
1152
+	 * @param string    $value
1153
+	 * @return string
1154
+	 */
1155
+	public static function get_label_size_class($value = false)
1156
+	{
1157
+		if ($value === false || $value == '') {
1158
+			return ' class="medium-lbl"';
1159
+		}
1160
+			// determine length of option value
1161
+			$val_size = strlen($value);
1162
+		switch ($val_size) {
1163
+			case $val_size < 3:
1164
+				$size =  ' class="nano-lbl"';
1165
+				break;
1166
+			case $val_size < 6:
1167
+				$size =  ' class="micro-lbl"';
1168
+				break;
1169
+			case $val_size < 12:
1170
+				$size =  ' class="tiny-lbl"';
1171
+				break;
1172
+			case $val_size < 25:
1173
+				$size =  ' class="small-lbl"';
1174
+				break;
1175
+			case $val_size > 100:
1176
+				$size =  ' class="big-lbl"';
1177
+				break;
1178
+			default:
1179
+				$size =  ' class="medium-lbl"';
1180
+				break;
1181
+		}
1182
+		return $size;
1183
+	}
1184
+
1185
+
1186
+
1187
+
1188
+	/**
1189
+	 *  _load_system_dropdowns
1190
+	 * @param array     $QFI
1191
+	 * @return array
1192
+	 */
1193
+	private static function _load_system_dropdowns($QFI)
1194
+	{
1195
+		$QST_system = $QFI->get('QST_system');
1196
+		switch ($QST_system) {
1197
+			case 'state':
1198
+				$QFI = self::generate_state_dropdown($QFI);
1199
+				break;
1200
+			case 'country':
1201
+				$QFI = self::generate_country_dropdown($QFI);
1202
+				break;
1203
+			case 'admin-state':
1204
+				$QFI = self::generate_state_dropdown($QFI, true);
1205
+				break;
1206
+			case 'admin-country':
1207
+				$QFI = self::generate_country_dropdown($QFI, true);
1208
+				break;
1209
+		}
1210
+		return $QFI;
1211
+	}
1212
+
1213
+
1214
+
1215
+	/**
1216
+	 * This preps dropdowns that are specialized.
1217
+	 *
1218
+	 * @since  4.6.0
1219
+	 *
1220
+	 * @param EE_Question_Form_Input $QFI
1221
+	 *
1222
+	 * @return EE_Question_Form_Input
1223
+	 */
1224
+	protected static function _load_specialized_dropdowns($QFI)
1225
+	{
1226
+		switch ($QFI->get('QST_type')) {
1227
+			case 'STATE':
1228
+				$QFI = self::generate_state_dropdown($QFI);
1229
+				break;
1230
+			case 'COUNTRY':
1231
+				$QFI = self::generate_country_dropdown($QFI);
1232
+				break;
1233
+		}
1234
+		return $QFI;
1235
+	}
1236
+
1237
+
1238
+
1239
+	/**
1240
+	 *    generate_state_dropdown
1241
+	 * @param array $QST
1242
+	 * @param bool  $get_all
1243
+	 * @return array
1244
+	 */
1245
+	public static function generate_state_dropdown($QST, $get_all = false)
1246
+	{
1247
+		$states = $get_all
1248
+			? EEM_State::instance()->get_all_states()
1249
+			: EEM_State::instance()->get_all_states_of_active_countries();
1250
+		if (! empty($states) && count($states) != count($QST->options())) {
1251
+			$QST->set('QST_type', 'DROPDOWN');
1252
+			// if multiple countries, we'll create option groups within the dropdown
1253
+			foreach ($states as $state) {
1254
+				if ($state instanceof EE_State) {
1255
+					$QSO = EE_Question_Option::new_instance(array (
1256
+						'QSO_value' => $state->ID(),
1257
+						'QSO_desc' => $state->name(),
1258
+						'QST_ID' => $QST->get('QST_ID'),
1259
+						'QSO_deleted' => false
1260
+					));
1261
+					// set option group
1262
+					$QSO->set_opt_group($state->country()->name());
1263
+					// add option to question
1264
+					$QST->add_temp_option($QSO);
1265
+				}
1266
+			}
1267
+		}
1268
+		return $QST;
1269
+	}
1270
+
1271
+
1272
+
1273
+	/**
1274
+	 *    generate_country_dropdown
1275
+	 * @param      $QST
1276
+	 * @param bool $get_all
1277
+	 * @internal param array $question
1278
+	 * @return array
1279
+	 */
1280
+	public static function generate_country_dropdown($QST, $get_all = false)
1281
+	{
1282
+		$countries = $get_all ? EEM_Country::instance()->get_all_countries() : EEM_Country::instance()->get_all_active_countries();
1283
+		if ($countries && count($countries) != count($QST->options())) {
1284
+			$QST->set('QST_type', 'DROPDOWN');
1285
+			// now add countries
1286
+			foreach ($countries as $country) {
1287
+				if ($country instanceof EE_Country) {
1288
+					$QSO = EE_Question_Option::new_instance(array (
1289
+						'QSO_value' => $country->ID(),
1290
+						'QSO_desc' => $country->name(),
1291
+						'QST_ID' => $QST->get('QST_ID'),
1292
+						'QSO_deleted' => false
1293
+					));
1294
+					$QST->add_temp_option($QSO);
1295
+				}
1296
+			}
1297
+		}
1298
+		return $QST;
1299
+	}
1300
+
1301
+
1302
+
1303
+
1304
+
1305
+	/**
1306
+	 *  generates options for a month dropdown selector with numbers from 01 to 12
1307
+	 *  @return array()
1308
+	 */
1309
+	public static function two_digit_months_dropdown_options()
1310
+	{
1311
+		$options = array();
1312
+		for ($x = 1; $x <= 12; $x++) {
1313
+			$mm = str_pad($x, 2, '0', STR_PAD_LEFT);
1314
+			$options[ (string) $mm ] = (string) $mm;
1315
+		}
1316
+		return EEH_Form_Fields::prep_answer_options($options);
1317
+	}
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+	/**
1324
+	 *  generates a year dropdown selector with numbers for the next ten years
1325
+	 *  @return object
1326
+	 */
1327
+	public static function next_decade_two_digit_year_dropdown_options()
1328
+	{
1329
+		$options = array();
1330
+		$current_year = date('y');
1331
+		$next_decade = $current_year + 10;
1332
+		for ($x = $current_year; $x <= $next_decade; $x++) {
1333
+			$yy = str_pad($x, 2, '0', STR_PAD_LEFT);
1334
+			$options[ (string) $yy ] = (string) $yy;
1335
+		}
1336
+		return EEH_Form_Fields::prep_answer_options($options);
1337
+	}
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+	/**
1344
+	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for list table filter.
1345
+	 * @param  string  $cur_date     any currently selected date can be entered here.
1346
+	 * @param  string  $status       Registration status
1347
+	 * @param  integer $evt_category Event Category ID if the Event Category filter is selected
1348
+	 * @return string                html
1349
+	 */
1350
+	public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1351
+	{
1352
+		$_where = array();
1353
+		if (!empty($status)) {
1354
+			$_where['STS_ID'] = $status;
1355
+		}
1356
+
1357
+		if ($evt_category > 0) {
1358
+			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1359
+		}
1360
+
1361
+		$regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1362
+
1363
+		// setup vals for select input helper
1364
+		$options = array(
1365
+			0 => array(
1366
+				'text' => __('Select a Month/Year', 'event_espresso'),
1367
+				'id' => ''
1368
+				)
1369
+			);
1370
+
1371
+		foreach ($regdtts as $regdtt) {
1372
+			$date = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1373
+			$options[] = array(
1374
+				'text' => $date,
1375
+				'id' => $date
1376
+				);
1377
+		}
1378
+
1379
+		return self::select_input('month_range', $options, $cur_date, '', 'wide');
1380
+	}
1381
+
1382
+
1383
+
1384
+	/**
1385
+	 * generates a month/year dropdown selector for all events matching the given criteria
1386
+	 * Typically used for list table filter
1387
+	 * @param  string $cur_date          any currently selected date can be entered here.
1388
+	 * @param  string $status            "view" (i.e. all, today, month, draft)
1389
+	 * @param  int    $evt_category      category event belongs to
1390
+	 * @param  string $evt_active_status "upcoming", "expired", "active", or "inactive"
1391
+	 * @return string                    html
1392
+	 */
1393
+	public static function generate_event_months_dropdown($cur_date = '', $status = '', $evt_category = '', $evt_active_status = '')
1394
+	{
1395
+		// determine what post_status our condition will have for the query.
1396
+		// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1397
+		switch ($status) {
1398
+			case 'month':
1399
+			case 'today':
1400
+			case null:
1401
+			case 'all':
1402
+				$where['Event.status'] = array( 'NOT IN', array('trash') );
1403
+				break;
1404
+
1405
+			case 'draft':
1406
+				$where['Event.status'] = array( 'IN', array('draft', 'auto-draft') );
1407
+
1408
+			default:
1409
+				$where['Event.status'] = $status;
1410
+		}
1411
+
1412
+		// phpcs:enable
1413
+
1414
+		// categories?
1415
+
1416 1416
 
1417
-        if (!empty($evt_category)) {
1418
-            $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1419
-            $where['Event.Term_Taxonomy.term_id'] = $evt_category;
1420
-        }
1417
+		if (!empty($evt_category)) {
1418
+			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1419
+			$where['Event.Term_Taxonomy.term_id'] = $evt_category;
1420
+		}
1421 1421
 
1422 1422
 
1423 1423
 //      $where['DTT_is_primary'] = 1;
1424 1424
 
1425
-        $DTTS = EE_Registry::instance()->load_model('Datetime')->get_dtt_months_and_years($where, $evt_active_status);
1426
-
1427
-        // let's setup vals for select input helper
1428
-        $options = array(
1429
-            0 => array(
1430
-                'text' => __('Select a Month/Year', 'event_espresso'),
1431
-                'id' => ""
1432
-                )
1433
-            );
1434
-
1435
-
1436
-
1437
-        // translate month and date
1438
-        global $wp_locale;
1439
-
1440
-        foreach ($DTTS as $DTT) {
1441
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1442
-            $id = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1443
-            $options[] = array(
1444
-                'text' => $localized_date,
1445
-                'id' => $id
1446
-                );
1447
-        }
1448
-
1449
-
1450
-        return self::select_input('month_range', $options, $cur_date, '', 'wide');
1451
-    }
1452
-
1453
-
1454
-
1455
-    /**
1456
-     * generates the dropdown selector for event categories
1457
-     * typically used as a filter on list tables.
1458
-     * @param  integer $current_cat currently selected category
1459
-     * @return string               html for dropdown
1460
-     */
1461
-    public static function generate_event_category_dropdown($current_cat = -1)
1462
-    {
1463
-        $categories = EEM_Term::instance()->get_all_ee_categories(true);
1464
-        $options = array(
1465
-            '0' => array(
1466
-                'text' => __('All Categories', 'event_espresso'),
1467
-                'id' => -1
1468
-                )
1469
-            );
1470
-
1471
-        // setup categories for dropdown
1472
-        foreach ($categories as $category) {
1473
-            $options[] = array(
1474
-                'text' => $category->get('name'),
1475
-                'id' => $category->ID()
1476
-                );
1477
-        }
1478
-
1479
-        return self::select_input('EVT_CAT', $options, $current_cat);
1480
-    }
1481
-
1482
-
1483
-
1484
-    /**
1485
-     *    generate a submit button with or without it's own microform
1486
-     *    this is the only way to create buttons that are compatible across all themes
1487
-     *
1488
-     * @access    public
1489
-     * @param    string   $url              - the form action
1490
-     * @param    string   $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm" for the form
1491
-     * @param    string   $class            - css classes (separated by spaces if more than one)
1492
-     * @param    string   $text             - what appears on the button
1493
-     * @param    string   $nonce_action     - if using nonces
1494
-     * @param    bool|string $input_only       - whether to print form header and footer. TRUE returns the input without the form
1495
-     * @param    string   $extra_attributes - any extra attributes that need to be attached to the form input
1496
-     * @return    void
1497
-     */
1498
-    public static function submit_button($url = '', $ID = '', $class = '', $text = '', $nonce_action = '', $input_only = false, $extra_attributes = '')
1499
-    {
1500
-        $btn = '';
1501
-        if (empty($url) || empty($ID)) {
1502
-            return $btn;
1503
-        }
1504
-        $text = ! empty($text) ? $text : __('Submit', 'event_espresso');
1505
-        $btn .= '<input id="' . $ID . '-btn" class="' . $class . '" type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
1506
-        if (! $input_only) {
1507
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
1508
-            $btn_frm .= ! empty($nonce_action) ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false) : '';
1509
-            $btn_frm .= $btn;
1510
-            $btn_frm .= '</form>';
1511
-            $btn = $btn_frm;
1512
-            unset($btn_frm);
1513
-        }
1514
-        return $btn;
1515
-    }
1425
+		$DTTS = EE_Registry::instance()->load_model('Datetime')->get_dtt_months_and_years($where, $evt_active_status);
1426
+
1427
+		// let's setup vals for select input helper
1428
+		$options = array(
1429
+			0 => array(
1430
+				'text' => __('Select a Month/Year', 'event_espresso'),
1431
+				'id' => ""
1432
+				)
1433
+			);
1434
+
1435
+
1436
+
1437
+		// translate month and date
1438
+		global $wp_locale;
1439
+
1440
+		foreach ($DTTS as $DTT) {
1441
+			$localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1442
+			$id = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1443
+			$options[] = array(
1444
+				'text' => $localized_date,
1445
+				'id' => $id
1446
+				);
1447
+		}
1448
+
1449
+
1450
+		return self::select_input('month_range', $options, $cur_date, '', 'wide');
1451
+	}
1452
+
1453
+
1454
+
1455
+	/**
1456
+	 * generates the dropdown selector for event categories
1457
+	 * typically used as a filter on list tables.
1458
+	 * @param  integer $current_cat currently selected category
1459
+	 * @return string               html for dropdown
1460
+	 */
1461
+	public static function generate_event_category_dropdown($current_cat = -1)
1462
+	{
1463
+		$categories = EEM_Term::instance()->get_all_ee_categories(true);
1464
+		$options = array(
1465
+			'0' => array(
1466
+				'text' => __('All Categories', 'event_espresso'),
1467
+				'id' => -1
1468
+				)
1469
+			);
1470
+
1471
+		// setup categories for dropdown
1472
+		foreach ($categories as $category) {
1473
+			$options[] = array(
1474
+				'text' => $category->get('name'),
1475
+				'id' => $category->ID()
1476
+				);
1477
+		}
1478
+
1479
+		return self::select_input('EVT_CAT', $options, $current_cat);
1480
+	}
1481
+
1482
+
1483
+
1484
+	/**
1485
+	 *    generate a submit button with or without it's own microform
1486
+	 *    this is the only way to create buttons that are compatible across all themes
1487
+	 *
1488
+	 * @access    public
1489
+	 * @param    string   $url              - the form action
1490
+	 * @param    string   $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm" for the form
1491
+	 * @param    string   $class            - css classes (separated by spaces if more than one)
1492
+	 * @param    string   $text             - what appears on the button
1493
+	 * @param    string   $nonce_action     - if using nonces
1494
+	 * @param    bool|string $input_only       - whether to print form header and footer. TRUE returns the input without the form
1495
+	 * @param    string   $extra_attributes - any extra attributes that need to be attached to the form input
1496
+	 * @return    void
1497
+	 */
1498
+	public static function submit_button($url = '', $ID = '', $class = '', $text = '', $nonce_action = '', $input_only = false, $extra_attributes = '')
1499
+	{
1500
+		$btn = '';
1501
+		if (empty($url) || empty($ID)) {
1502
+			return $btn;
1503
+		}
1504
+		$text = ! empty($text) ? $text : __('Submit', 'event_espresso');
1505
+		$btn .= '<input id="' . $ID . '-btn" class="' . $class . '" type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
1506
+		if (! $input_only) {
1507
+			$btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
1508
+			$btn_frm .= ! empty($nonce_action) ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false) : '';
1509
+			$btn_frm .= $btn;
1510
+			$btn_frm .= '</form>';
1511
+			$btn = $btn_frm;
1512
+			unset($btn_frm);
1513
+		}
1514
+		return $btn;
1515
+	}
1516 1516
 }
Please login to merge, or discard this patch.
Spacing   +184 added lines, -184 removed lines patch added patch discarded remove patch
@@ -90,10 +90,10 @@  discard block
 block discarded – undo
90 90
             $required = isset($input_value['required']) && $input_value['required'] ? ' <span>*</span>: ' : ': ';
91 91
             // and the css class "required"
92 92
             $css_class = isset($input_value['css_class']) ? $input_value['css_class'] : '';
93
-            $styles = $input_value['required'] ? 'required ' . $css_class : $css_class;
93
+            $styles = $input_value['required'] ? 'required '.$css_class : $css_class;
94 94
 
95
-            $field_id = ($id) ? $id . '-' . $input_key : $input_key;
96
-            $tabindex = !empty($input_value['tabindex']) ? ' tabindex="' . $input_value['tabindex'] . '"' : '';
95
+            $field_id = ($id) ? $id.'-'.$input_key : $input_key;
96
+            $tabindex = ! empty($input_value['tabindex']) ? ' tabindex="'.$input_value['tabindex'].'"' : '';
97 97
 
98 98
             // rows or cols?
99 99
             $rows = isset($input_value['rows']) ? $input_value['rows'] : '10';
@@ -102,21 +102,21 @@  discard block
 block discarded – undo
102 102
             // any content?
103 103
             $append_content = $input_value['append_content'];
104 104
 
105
-            $output .= (!$close) ? '<ul>' : '';
105
+            $output .= ( ! $close) ? '<ul>' : '';
106 106
             $output .= '<li>';
107 107
 
108 108
             // what type of input are we dealing with ?
109 109
             switch ($input_value['input']) {
110 110
                 // text inputs
111 111
                 case 'text':
112
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
113
-                    $output .= "\n\t\t\t" . '<input id="' . $field_id . '" class="' . $styles . '" type="text" value="' . esc_textarea($input_value['value']) . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
112
+                    $output .= "\n\t\t\t".'<label for="'.$field_id.'">'.$input_value['label'].$required.'</label>';
113
+                    $output .= "\n\t\t\t".'<input id="'.$field_id.'" class="'.$styles.'" type="text" value="'.esc_textarea($input_value['value']).'" name="'.$input_value['name'].'"'.$tabindex.'>';
114 114
                     break;
115 115
 
116 116
                 // dropdowns
117 117
                 case 'select':
118
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
119
-                    $output .= "\n\t\t\t" . '<select id="' . $field_id . '" class="' . $styles . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
118
+                    $output .= "\n\t\t\t".'<label for="'.$field_id.'">'.$input_value['label'].$required.'</label>';
119
+                    $output .= "\n\t\t\t".'<select id="'.$field_id.'" class="'.$styles.'" name="'.$input_value['name'].'"'.$tabindex.'>';
120 120
 
121 121
                     if (is_array($input_value['options'])) {
122 122
                         $options = $input_value['options'];
@@ -127,27 +127,27 @@  discard block
 block discarded – undo
127 127
                     foreach ($options as $key => $value) {
128 128
                         $selected = isset($input_value['value']) && $input_value['value'] == $key ? 'selected=selected' : '';
129 129
                         // $key = str_replace( ' ', '_', sanitize_key( $value ));
130
-                        $output .= "\n\t\t\t\t" . '<option ' . $selected . ' value="' . $key . '">' . $value . '</option>';
130
+                        $output .= "\n\t\t\t\t".'<option '.$selected.' value="'.$key.'">'.$value.'</option>';
131 131
                     }
132
-                    $output .= "\n\t\t\t" . '</select>';
132
+                    $output .= "\n\t\t\t".'</select>';
133 133
 
134 134
                     break;
135 135
 
136 136
                 case 'textarea':
137
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
138
-                    $output .= "\n\t\t\t" . '<textarea id="' . $field_id . '" class="' . $styles . '" rows="' . $rows . '" cols="' . $cols . '" name="' . $input_value['name'] . '"' . $tabindex . '>' . esc_textarea($input_value['value']) . '</textarea>';
137
+                    $output .= "\n\t\t\t".'<label for="'.$field_id.'">'.$input_value['label'].$required.'</label>';
138
+                    $output .= "\n\t\t\t".'<textarea id="'.$field_id.'" class="'.$styles.'" rows="'.$rows.'" cols="'.$cols.'" name="'.$input_value['name'].'"'.$tabindex.'>'.esc_textarea($input_value['value']).'</textarea>';
139 139
                     break;
140 140
 
141 141
                 case 'hidden':
142 142
                     $close = false;
143 143
                     $output .= "</li></ul>";
144
-                    $output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="hidden" name="' . $input_value['name'] . '" value="' . $input_value['value'] . '">';
144
+                    $output .= "\n\t\t\t".'<input id="'.$field_id.'" type="hidden" name="'.$input_value['name'].'" value="'.$input_value['value'].'">';
145 145
                     break;
146 146
 
147 147
                 case 'checkbox':
148
-                    $checked = ( $input_value['value'] == 1 ) ? 'checked="checked"' : '';
149
-                    $output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
150
-                    $output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="checkbox" name="' . $input_value['name'] . '" value="1"' . $checked . $tabindex . ' />';
148
+                    $checked = ($input_value['value'] == 1) ? 'checked="checked"' : '';
149
+                    $output .= "\n\t\t\t".'<label for="'.$field_id.'">'.$input_value['label'].$required.'</label>';
150
+                    $output .= "\n\t\t\t".'<input id="'.$field_id.'" type="checkbox" name="'.$input_value['name'].'" value="1"'.$checked.$tabindex.' />';
151 151
                     break;
152 152
 
153 153
                 case 'wp_editor':
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
                     );
161 161
                     $output .= '</li>';
162 162
                     $output .= '</ul>';
163
-                    $output .= '<h4>' . $input_value['label'] . '</h4>';
163
+                    $output .= '<h4>'.$input_value['label'].'</h4>';
164 164
                     if ($append_content) {
165 165
                         $output .= $append_content;
166 166
                     }
@@ -232,17 +232,17 @@  discard block
 block discarded – undo
232 232
             $_fields = wp_parse_args($field_atts, $defaults);
233 233
             extract($_fields);
234 234
             // generate label
235
-            $label = empty($label) ? '' : '<label for="' . $id . '">' . $label . '</label>';
235
+            $label = empty($label) ? '' : '<label for="'.$id.'">'.$label.'</label>';
236 236
             // generate field name
237
-            $f_name = !empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
237
+            $f_name = ! empty($unique_id) ? $field_name.'['.$unique_id.']' : $field_name;
238 238
 
239 239
             // tabindex
240
-            $tabindex_str = !empty($tabindex) ? ' tabindex="' . $tabindex . '"' : '';
240
+            $tabindex_str = ! empty($tabindex) ? ' tabindex="'.$tabindex.'"' : '';
241 241
 
242 242
             // we determine what we're building based on the type
243 243
             switch ($type) {
244 244
                 case 'textarea':
245
-                        $fld = '<textarea id="' . $id . '" class="' . $class . '" rows="' . $dimensions[1] . '" cols="' . $dimensions[0] . '" name="' . $f_name . '"' . $tabindex_str . '>' . $value . '</textarea>';
245
+                        $fld = '<textarea id="'.$id.'" class="'.$class.'" rows="'.$dimensions[1].'" cols="'.$dimensions[0].'" name="'.$f_name.'"'.$tabindex_str.'>'.$value.'</textarea>';
246 246
                         $fld .= $extra_desc;
247 247
                     break;
248 248
 
@@ -250,16 +250,16 @@  discard block
 block discarded – undo
250 250
                         $c_input = '';
251 251
                     if (is_array($value)) {
252 252
                         foreach ($value as $key => $val) {
253
-                            $c_id = $field_name . '_' . $value;
254
-                            $c_class = isset($classes[ $key ]) ? ' class="' . $classes[ $key ] . '" ' : '';
255
-                            $c_label = isset($labels[ $key ]) ? '<label for="' . $c_id . '">' . $labels[ $key ] . '</label>' : '';
256
-                            $checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
257
-                            $c_input .= '<input name="' . $f_name . '[]" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
253
+                            $c_id = $field_name.'_'.$value;
254
+                            $c_class = isset($classes[$key]) ? ' class="'.$classes[$key].'" ' : '';
255
+                            $c_label = isset($labels[$key]) ? '<label for="'.$c_id.'">'.$labels[$key].'</label>' : '';
256
+                            $checked = ! empty($default) && $default == $val ? ' checked="checked" ' : '';
257
+                            $c_input .= '<input name="'.$f_name.'[]" type="checkbox" id="'.$c_id.'"'.$c_class.'value="'.$val.'"'.$checked.$tabindex_str.' />'."\n".$c_label;
258 258
                         }
259 259
                         $fld = $c_input;
260 260
                     } else {
261
-                        $checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
262
-                        $fld = '<input name="' . $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
261
+                        $checked = ! empty($default) && $default == $val ? 'checked="checked" ' : '';
262
+                        $fld = '<input name="'.$f_name.'" type="checkbox" id="'.$id.'" class="'.$class.'" value="'.$value.'"'.$checked.$tabindex_str.' />'."\n";
263 263
                     }
264 264
                     break;
265 265
 
@@ -267,28 +267,28 @@  discard block
 block discarded – undo
267 267
                         $c_input = '';
268 268
                     if (is_array($value)) {
269 269
                         foreach ($value as $key => $val) {
270
-                            $c_id = $field_name . '_' . $value;
271
-                            $c_class = isset($classes[ $key ]) ? 'class="' . $classes[ $key ] . '" ' : '';
272
-                            $c_label = isset($labels[ $key ]) ? '<label for="' . $c_id . '">' . $labels[ $key ] . '</label>' : '';
273
-                            $checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
274
-                            $c_input .= '<input name="' . $f_name . '" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
270
+                            $c_id = $field_name.'_'.$value;
271
+                            $c_class = isset($classes[$key]) ? 'class="'.$classes[$key].'" ' : '';
272
+                            $c_label = isset($labels[$key]) ? '<label for="'.$c_id.'">'.$labels[$key].'</label>' : '';
273
+                            $checked = ! empty($default) && $default == $val ? ' checked="checked" ' : '';
274
+                            $c_input .= '<input name="'.$f_name.'" type="checkbox" id="'.$c_id.'"'.$c_class.'value="'.$val.'"'.$checked.$tabindex_str.' />'."\n".$c_label;
275 275
                         }
276 276
                         $fld = $c_input;
277 277
                     } else {
278
-                        $checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
279
-                        $fld = '<input name="' . $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
278
+                        $checked = ! empty($default) && $default == $val ? 'checked="checked" ' : '';
279
+                        $fld = '<input name="'.$f_name.'" type="checkbox" id="'.$id.'" class="'.$class.'" value="'.$value.'"'.$checked.$tabindex_str.' />'."\n";
280 280
                     }
281 281
                     break;
282 282
 
283 283
                 case 'hidden':
284
-                        $fld = '<input name="' . $f_name . '" type="hidden" id="' . $id . '" class="' . $class . '" value="' . $value . '" />' . "\n";
284
+                        $fld = '<input name="'.$f_name.'" type="hidden" id="'.$id.'" class="'.$class.'" value="'.$value.'" />'."\n";
285 285
                     break;
286 286
 
287 287
                 case 'select':
288
-                        $fld = '<select name="' . $f_name . '" class="' . $class . '" id="' . $id . '"' . $tabindex_str . '>' . "\n";
288
+                        $fld = '<select name="'.$f_name.'" class="'.$class.'" id="'.$id.'"'.$tabindex_str.'>'."\n";
289 289
                     foreach ($value as $key => $val) {
290
-                        $checked = !empty($default) && $default == $val ? ' selected="selected"' : '';
291
-                        $fld .= "\t" . '<option value="' . $val . '"' . $checked . '>' . $labels[ $key ] . '</option>' . "\n";
290
+                        $checked = ! empty($default) && $default == $val ? ' selected="selected"' : '';
291
+                        $fld .= "\t".'<option value="'.$val.'"'.$checked.'>'.$labels[$key].'</option>'."\n";
292 292
                     }
293 293
                         $fld .= '</select>';
294 294
                     break;
@@ -309,11 +309,11 @@  discard block
 block discarded – undo
309 309
                     break;
310 310
 
311 311
                 default: // 'text fields'
312
-                        $fld = '<input name="' . $f_name . '" type="text" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $tabindex_str . ' />' . "\n";
312
+                        $fld = '<input name="'.$f_name.'" type="text" id="'.$id.'" class="'.$class.'" value="'.$value.'"'.$tabindex_str.' />'."\n";
313 313
                         $fld .= $extra_desc;
314 314
             }
315 315
 
316
-            $form_fields[ $field_name ] = array( 'label' => $label, 'field' => $fld );
316
+            $form_fields[$field_name] = array('label' => $label, 'field' => $fld);
317 317
         }
318 318
 
319 319
         return $form_fields;
@@ -343,25 +343,25 @@  discard block
 block discarded – undo
343 343
     public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
344 344
     {
345 345
         // if $values was submitted in the wrong format, convert it over
346
-        if (!empty($values) && (!array_key_exists(0, $values) || !is_array($values[0]))) {
346
+        if ( ! empty($values) && ( ! array_key_exists(0, $values) || ! is_array($values[0]))) {
347 347
             $converted_values = array();
348 348
             foreach ($values as $id => $text) {
349
-                $converted_values[] = array('id' => $id,'text' => $text);
349
+                $converted_values[] = array('id' => $id, 'text' => $text);
350 350
             }
351 351
             $values = $converted_values;
352 352
         }
353 353
 
354
-        $field = '<select id="' . EEH_Formatter::ee_tep_output_string($name) . '" name="' . EEH_Formatter::ee_tep_output_string($name) . '"';
354
+        $field = '<select id="'.EEH_Formatter::ee_tep_output_string($name).'" name="'.EEH_Formatter::ee_tep_output_string($name).'"';
355 355
         // Debug
356 356
         // EEH_Debug_Tools::printr( $values, '$values  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
357 357
         if (EEH_Formatter::ee_tep_not_null($parameters)) {
358
-            $field .= ' ' . $parameters;
358
+            $field .= ' '.$parameters;
359 359
         }
360 360
         if ($autosize) {
361 361
             $size = 'med';
362 362
             for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
363
-                if ($values[ $ii ]['text']) {
364
-                    if (strlen($values[ $ii ]['text']) > 5) {
363
+                if ($values[$ii]['text']) {
364
+                    if (strlen($values[$ii]['text']) > 5) {
365 365
                         $size = 'wide';
366 366
                     }
367 367
                 }
@@ -370,22 +370,22 @@  discard block
 block discarded – undo
370 370
             $size = '';
371 371
         }
372 372
 
373
-        $field .= ' class="' . $class . ' ' . $size . '">';
373
+        $field .= ' class="'.$class.' '.$size.'">';
374 374
 
375
-        if (empty($default) && isset($GLOBALS[ $name ])) {
376
-            $default = stripslashes($GLOBALS[ $name ]);
375
+        if (empty($default) && isset($GLOBALS[$name])) {
376
+            $default = stripslashes($GLOBALS[$name]);
377 377
         }
378 378
 
379 379
 
380 380
         for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
381
-            $field .= '<option value="' . $values[ $i ]['id'] . '"';
382
-            if ($default == $values[ $i ]['id']) {
381
+            $field .= '<option value="'.$values[$i]['id'].'"';
382
+            if ($default == $values[$i]['id']) {
383 383
                 $field .= ' selected = "selected"';
384 384
             }
385
-            if (isset($values[ $i ]['class'])) {
386
-                $field .= ' class="' . $values[ $i ]['class'] . '"';
385
+            if (isset($values[$i]['class'])) {
386
+                $field .= ' class="'.$values[$i]['class'].'"';
387 387
             }
388
-            $field .= '>' . $values[ $i ]['text'] . '</option>';
388
+            $field .= '>'.$values[$i]['text'].'</option>';
389 389
         }
390 390
         $field .= '</select>';
391 391
 
@@ -410,18 +410,18 @@  discard block
 block discarded – undo
410 410
         $before_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
411 411
         $after_question_group_questions = apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
412 412
 
413
-        if (! empty($question_groups)) {
413
+        if ( ! empty($question_groups)) {
414 414
             // EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
415 415
             // loop thru question groups
416 416
             foreach ($question_groups as $QSG) {
417 417
                 // check that questions exist
418
-                if (! empty($QSG['QSG_questions'])) {
418
+                if ( ! empty($QSG['QSG_questions'])) {
419 419
                     // use fieldsets
420
-                    $html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG['QSG_identifier'] . '">';
420
+                    $html .= "\n\t".'<'.$group_wrapper.' class="espresso-question-group-wrap" id="'.$QSG['QSG_identifier'].'">';
421 421
                     // group_name
422
-                    $html .= $QSG['QSG_show_group_name'] ? "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . self::prep_answer($QSG['QSG_name']) . '</h5>' : '';
422
+                    $html .= $QSG['QSG_show_group_name'] ? "\n\t\t".'<h5 class="espresso-question-group-title-h5 section-title">'.self::prep_answer($QSG['QSG_name']).'</h5>' : '';
423 423
                     // group_desc
424
-                    $html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc']) ? '<div class="espresso-question-group-desc-pg">' . self::prep_answer($QSG['QSG_desc']) . '</div>' : '';
424
+                    $html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc']) ? '<div class="espresso-question-group-desc-pg">'.self::prep_answer($QSG['QSG_desc']).'</div>' : '';
425 425
 
426 426
                     $html .= $before_question_group_questions;
427 427
                     // loop thru questions
@@ -435,7 +435,7 @@  discard block
 block discarded – undo
435 435
                         $html .= self::generate_form_input($QFI);
436 436
                     }
437 437
                     $html .= $after_question_group_questions;
438
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
438
+                    $html .= "\n\t".'</'.$group_wrapper.'>';
439 439
                 }
440 440
             }
441 441
         }
@@ -471,28 +471,28 @@  discard block
 block discarded – undo
471 471
         $q_meta = array_merge($default_q_meta, $q_meta);
472 472
         // EEH_Debug_Tools::printr( $q_meta, '$q_meta  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
473 473
 
474
-        if (! empty($question_groups)) {
474
+        if ( ! empty($question_groups)) {
475 475
 //          EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
476 476
             // loop thru question groups
477 477
             foreach ($question_groups as $QSG) {
478 478
                 if ($QSG instanceof EE_Question_Group) {
479 479
                     // check that questions exist
480 480
 
481
-                    $where = array( 'QST_deleted' => 0 );
482
-                    if (! $from_admin) {
481
+                    $where = array('QST_deleted' => 0);
482
+                    if ( ! $from_admin) {
483 483
                         $where['QST_admin_only'] = 0;
484 484
                     }
485
-                    $questions = $QSG->questions(array( $where, 'order_by' => array( 'Question_Group_Question.QGQ_order' => 'ASC' )));
486
-                    if (! empty($questions)) {
485
+                    $questions = $QSG->questions(array($where, 'order_by' => array('Question_Group_Question.QGQ_order' => 'ASC')));
486
+                    if ( ! empty($questions)) {
487 487
                         // use fieldsets
488
-                        $html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG->get('QSG_identifier') . '">';
488
+                        $html .= "\n\t".'<'.$group_wrapper.' class="espresso-question-group-wrap" id="'.$QSG->get('QSG_identifier').'">';
489 489
                         // group_name
490 490
                         if ($QSG->show_group_name()) {
491
-                            $html .=  "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . $QSG->get_pretty('QSG_name') . '</h5>';
491
+                            $html .= "\n\t\t".'<h5 class="espresso-question-group-title-h5 section-title">'.$QSG->get_pretty('QSG_name').'</h5>';
492 492
                         }
493 493
                         // group_desc
494 494
                         if ($QSG->show_group_desc()) {
495
-                            $html .=  '<div class="espresso-question-group-desc-pg">' . $QSG->get_pretty('QSG_desc') . '</div>';
495
+                            $html .= '<div class="espresso-question-group-desc-pg">'.$QSG->get_pretty('QSG_desc').'</div>';
496 496
                         }
497 497
 
498 498
                         $html .= $before_question_group_questions;
@@ -504,12 +504,12 @@  discard block
 block discarded – undo
504 504
 
505 505
                             if (isset($_GET['qstn']) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
506 506
                                 // check for answer in $_GET in case we are reprocessing a form after an error
507
-                                if (isset($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ])) {
508
-                                    $answer = is_array($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ]) ? $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] : sanitize_text_field($_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ]);
507
+                                if (isset($_GET['qstn'][$q_meta['input_id']][$qstn_id])) {
508
+                                    $answer = is_array($_GET['qstn'][$q_meta['input_id']][$qstn_id]) ? $_GET['qstn'][$q_meta['input_id']][$qstn_id] : sanitize_text_field($_GET['qstn'][$q_meta['input_id']][$qstn_id]);
509 509
                                 }
510 510
                             } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
511 511
                                 // attendee data from the session
512
-                                $answer = isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
512
+                                $answer = isset($q_meta['attendee'][$qstn_id]) ? $q_meta['attendee'][$qstn_id] : null;
513 513
                             }
514 514
 
515 515
 
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
                             $html .= self::generate_form_input($QFI);
529 529
                         }
530 530
                         $html .= $after_question_group_questions;
531
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
531
+                        $html .= "\n\t".'</'.$group_wrapper.'>';
532 532
                     }
533 533
                 }
534 534
             }
@@ -567,10 +567,10 @@  discard block
 block discarded – undo
567 567
         $disabled = $QFI->get('QST_disabled') ? true : false;
568 568
         $required_label = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
569 569
         $QST_required = $QFI->get('QST_required');
570
-        $required = $QST_required ? array( 'label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required ) : array();
570
+        $required = $QST_required ? array('label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required) : array();
571 571
         $use_html_entities = $QFI->get_meta('htmlentities');
572 572
         $required_text = $QFI->get('QST_required_text') != '' ? $QFI->get('QST_required_text') : __('This field is required', 'event_espresso');
573
-        $required_text = $QST_required ? "\n\t\t\t" . '<div class="required-text hidden">' . self::prep_answer($required_text, $use_html_entities) . '</div>' : '';
573
+        $required_text = $QST_required ? "\n\t\t\t".'<div class="required-text hidden">'.self::prep_answer($required_text, $use_html_entities).'</div>' : '';
574 574
         $label_class = 'espresso-form-input-lbl';
575 575
         $QST_options = $QFI->options(true, $answer);
576 576
         $options = is_array($QST_options) ? self::prep_answer_options($QST_options) : array();
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
     public static function text($question = false, $answer = null, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
630 630
     {
631 631
         // need these
632
-        if (! $question || ! $name) {
632
+        if ( ! $question || ! $name) {
633 633
             return null;
634 634
         }
635 635
         // prep the answer
@@ -637,21 +637,21 @@  discard block
 block discarded – undo
637 637
         // prep the required array
638 638
         $required = self::prep_required($required);
639 639
         // set disabled tag
640
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
640
+        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
641 641
         // ya gots ta have style man!!!
642 642
         $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
643 643
         $class = empty($class) ? $txt_class : $class;
644
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
644
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
645 645
         $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
646 646
 
647
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
647
+        $label_html = $required_text."\n\t\t\t".'<label for="'.$name.'" class="'.$label_class.'">'.self::prep_question($question).$required['label'].'</label><br/>';
648 648
         // filter label but ensure required text comes before it
649 649
         $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
650 650
 
651
-        $input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
651
+        $input_html = "\n\t\t\t".'<input type="text" name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" value="'.esc_attr($answer).'"  title="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
652 652
 
653
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
654
-        return  $label_html . $input_html;
653
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
654
+        return  $label_html.$input_html;
655 655
     }
656 656
 
657 657
 
@@ -675,7 +675,7 @@  discard block
 block discarded – undo
675 675
     public static function textarea($question = false, $answer = null, $name = false, $id = '', $class = '', $dimensions = false, $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
676 676
     {
677 677
         // need these
678
-        if (! $question || ! $name) {
678
+        if ( ! $question || ! $name) {
679 679
             return null;
680 680
         }
681 681
         // prep the answer
@@ -685,23 +685,23 @@  discard block
 block discarded – undo
685 685
         // make sure $dimensions is an array
686 686
         $dimensions = is_array($dimensions) ? $dimensions : array();
687 687
         // and set some defaults
688
-        $dimensions = array_merge(array( 'rows' => 3, 'cols' => 40 ), $dimensions);
688
+        $dimensions = array_merge(array('rows' => 3, 'cols' => 40), $dimensions);
689 689
         // set disabled tag
690
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
690
+        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
691 691
         // ya gots ta have style man!!!
692 692
         $txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
693 693
         $class = empty($class) ? $txt_class : $class;
694
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
694
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
695 695
         $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
696 696
 
697
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
697
+        $label_html = $required_text."\n\t\t\t".'<label for="'.$name.'" class="'.$label_class.'">'.self::prep_question($question).$required['label'].'</label><br/>';
698 698
         // filter label but ensure required text comes before it
699 699
         $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
700 700
 
701
-        $input_html = "\n\t\t\t" . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>' . $answer . '</textarea>';
701
+        $input_html = "\n\t\t\t".'<textarea name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" rows="'.$dimensions['rows'].'" cols="'.$dimensions['cols'].'"  title="'.$required['msg'].'" '.$disabled.' '.$extra.'>'.$answer.'</textarea>';
702 702
 
703
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
704
-        return  $label_html . $input_html;
703
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
704
+        return  $label_html.$input_html;
705 705
     }
706 706
 
707 707
 
@@ -727,7 +727,7 @@  discard block
 block discarded – undo
727 727
     {
728 728
 
729 729
         // need these
730
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
730
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
731 731
             return null;
732 732
         }
733 733
         // prep the answer
@@ -735,36 +735,36 @@  discard block
 block discarded – undo
735 735
         // prep the required array
736 736
         $required = self::prep_required($required);
737 737
         // set disabled tag
738
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
738
+        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
739 739
         // ya gots ta have style man!!!
740 740
         $txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
741 741
         $class = empty($class) ? $txt_class : $class;
742
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
742
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
743 743
         $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
744 744
 
745
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
745
+        $label_html = $required_text."\n\t\t\t".'<label for="'.$name.'" class="'.$label_class.'">'.self::prep_question($question).$required['label'].'</label><br/>';
746 746
         // filter label but ensure required text comes before it
747 747
         $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
748 748
 
749
-        $input_html = "\n\t\t\t" . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
749
+        $input_html = "\n\t\t\t".'<select name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" title="'.esc_attr($required['msg']).'"'.$disabled.' '.$extra.'>';
750 750
         // recursively count array elements, to determine total number of options
751 751
         $only_option = count($options, 1) == 1 ? true : false;
752
-        if (! $only_option) {
752
+        if ( ! $only_option) {
753 753
             // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
754 754
             $selected = $answer === null ? ' selected="selected"' : '';
755
-            $input_html .= $add_please_select_option ? "\n\t\t\t\t" . '<option value=""' . $selected . '>' . __(' - please select - ', 'event_espresso') . '</option>' : '';
755
+            $input_html .= $add_please_select_option ? "\n\t\t\t\t".'<option value=""'.$selected.'>'.__(' - please select - ', 'event_espresso').'</option>' : '';
756 756
         }
757 757
         foreach ($options as $key => $value) {
758 758
             // if value is an array, then create option groups, else create regular ol' options
759 759
             $input_html .= is_array($value) ? self::_generate_select_option_group($key, $value, $answer, $use_html_entities) : self::_generate_select_option($value->value(), $value->desc(), $answer, $only_option, $use_html_entities);
760 760
         }
761 761
 
762
-        $input_html .= "\n\t\t\t" . '</select>';
762
+        $input_html .= "\n\t\t\t".'</select>';
763 763
 
764
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID);
764
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID);
765 765
 
766
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
767
-        return  $label_html . $input_html;
766
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
767
+        return  $label_html.$input_html;
768 768
     }
769 769
 
770 770
 
@@ -783,11 +783,11 @@  discard block
 block discarded – undo
783 783
      */
784 784
     private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
785 785
     {
786
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
786
+        $html = "\n\t\t\t\t".'<optgroup label="'.self::prep_option_value($opt_group).'">';
787 787
         foreach ($QSOs as $QSO) {
788 788
             $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
789 789
         }
790
-        $html .= "\n\t\t\t\t" . '</optgroup>';
790
+        $html .= "\n\t\t\t\t".'</optgroup>';
791 791
         return $html;
792 792
     }
793 793
 
@@ -807,8 +807,8 @@  discard block
 block discarded – undo
807 807
         $key = self::prep_answer($key, $use_html_entities);
808 808
         $value = self::prep_answer($value, $use_html_entities);
809 809
         $value = ! empty($value) ? $value : $key;
810
-        $selected = ( $answer == $key || $only_option ) ? ' selected="selected"' : '';
811
-        return "\n\t\t\t\t" . '<option value="' . self::prep_option_value($key) . '"' . $selected . '> ' . $value . '&nbsp;&nbsp;&nbsp;</option>';
810
+        $selected = ($answer == $key || $only_option) ? ' selected="selected"' : '';
811
+        return "\n\t\t\t\t".'<option value="'.self::prep_option_value($key).'"'.$selected.'> '.$value.'&nbsp;&nbsp;&nbsp;</option>';
812 812
     }
813 813
 
814 814
 
@@ -835,7 +835,7 @@  discard block
 block discarded – undo
835 835
     public static function radio($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true, $label_b4 = false, $use_desc_4_label = false)
836 836
     {
837 837
         // need these
838
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
838
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
839 839
             return null;
840 840
         }
841 841
         // prep the answer
@@ -843,46 +843,46 @@  discard block
 block discarded – undo
843 843
         // prep the required array
844 844
         $required = self::prep_required($required);
845 845
         // set disabled tag
846
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
846
+        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
847 847
         // ya gots ta have style man!!!
848 848
         $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
849 849
         $class = ! empty($class) ? $class : 'espresso-radio-btn-inp';
850 850
         $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
851 851
 
852
-        $label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label> ';
852
+        $label_html = $required_text."\n\t\t\t".'<label class="'.$label_class.'">'.self::prep_question($question).$required['label'].'</label> ';
853 853
         // filter label but ensure required text comes before it
854 854
         $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
855 855
 
856
-        $input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
856
+        $input_html = "\n\t\t\t".'<ul id="'.$id.'-ul" class="espresso-radio-btn-options-ul '.$label_class.' '.$class.'-ul">';
857 857
 
858
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
859
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
858
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
859
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
860 860
 
861 861
         foreach ($options as $OPT) {
862 862
             if ($OPT instanceof EE_Question_Option) {
863 863
                 $value = self::prep_option_value($OPT->value());
864 864
                 $label = $use_desc_4_label ? $OPT->desc() : $OPT->value();
865
-                $size = $use_desc_4_label ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc()) : self::get_label_size_class($OPT->value());
866
-                $desc = $OPT->desc();// no self::prep_answer
865
+                $size = $use_desc_4_label ? self::get_label_size_class($OPT->value().' '.$OPT->desc()) : self::get_label_size_class($OPT->value());
866
+                $desc = $OPT->desc(); // no self::prep_answer
867 867
                 $answer = is_numeric($value) && empty($answer) ? 0 : $answer;
868 868
                 $checked = (string) $value == (string) $answer ? ' checked="checked"' : '';
869
-                $opt = '-' . sanitize_key($value);
870
-
871
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
872
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
873
-                $input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
874
-                $input_html .= "\n\t\t\t\t\t\t" . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
875
-                $input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span class="espresso-radio-btn-desc">' . $label . '</span>' : '';
876
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
877
-                $input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
878
-                $input_html .= "\n\t\t\t\t" . '</li>';
869
+                $opt = '-'.sanitize_key($value);
870
+
871
+                $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
872
+                $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-radio-btn-lbl">';
873
+                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$label.'</span>' : '';
874
+                $input_html .= "\n\t\t\t\t\t\t".'<input type="radio" name="'.$name.'" id="'.$id.$opt.'" class="'.$class.'" value="'.$value.'" title="'.esc_attr($required['msg']).'" '.$disabled.$checked.' '.$extra.'/>';
875
+                $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t".'<span class="espresso-radio-btn-desc">'.$label.'</span>' : '';
876
+                $input_html .= "\n\t\t\t\t\t".'</label>';
877
+                $input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">'.$desc.'</span>';
878
+                $input_html .= "\n\t\t\t\t".'</li>';
879 879
             }
880 880
         }
881 881
 
882
-        $input_html .= "\n\t\t\t" . '</ul>';
882
+        $input_html .= "\n\t\t\t".'</ul>';
883 883
 
884
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
885
-        return  $label_html . $input_html;
884
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
885
+        return  $label_html.$input_html;
886 886
     }
887 887
 
888 888
 
@@ -907,62 +907,62 @@  discard block
 block discarded – undo
907 907
     public static function checkbox($question = false, $answer = null, $options = false, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $label_b4 = false, $system_ID = false, $use_html_entities = true)
908 908
     {
909 909
         // need these
910
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
910
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
911 911
             return null;
912 912
         }
913 913
         $answer = maybe_unserialize($answer);
914 914
 
915 915
         // prep the answer(s)
916
-        $answer = is_array($answer) ? $answer : array( sanitize_key($answer) => $answer );
916
+        $answer = is_array($answer) ? $answer : array(sanitize_key($answer) => $answer);
917 917
 
918 918
         foreach ($answer as $key => $value) {
919 919
             $key = self::prep_option_value($key);
920
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
920
+            $answer[$key] = self::prep_answer($value, $use_html_entities);
921 921
         }
922 922
 
923 923
         // prep the required array
924 924
         $required = self::prep_required($required);
925 925
         // set disabled tag
926
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
926
+        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
927 927
         // ya gots ta have style man!!!
928 928
         $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
929 929
         $class = empty($class) ? 'espresso-radio-btn-inp' : $class;
930 930
         $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
931 931
 
932
-        $label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label> ';
932
+        $label_html = $required_text."\n\t\t\t".'<label class="'.$label_class.'">'.self::prep_question($question).$required['label'].'</label> ';
933 933
         // filter label but ensure required text comes before it
934 934
         $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
935 935
 
936
-        $input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
936
+        $input_html = "\n\t\t\t".'<ul id="'.$id.'-ul" class="espresso-checkbox-options-ul '.$label_class.' '.$class.'-ul">';
937 937
 
938
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
939
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
938
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
939
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
940 940
 
941 941
         foreach ($options as $OPT) {
942
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
943
-            $size = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
942
+            $value = $OPT->value(); // self::prep_option_value( $OPT->value() );
943
+            $size = self::get_label_size_class($OPT->value().' '.$OPT->desc());
944 944
             $text = self::prep_answer($OPT->value());
945
-            $desc = $OPT->desc() ;
946
-            $opt = '-' . sanitize_key($value);
945
+            $desc = $OPT->desc();
946
+            $opt = '-'.sanitize_key($value);
947 947
 
948 948
             $checked = is_array($answer) && in_array($text, $answer) ? ' checked="checked"' : '';
949 949
 
950
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
951
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
952
-            $input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
953
-            $input_html .= "\n\t\t\t\t\t\t" . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
954
-            $input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
955
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
956
-            if (! empty($desc) && $desc != $text) {
957
-                $input_html .= "\n\t\t\t\t\t" . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">' . $desc . '</div>';
950
+            $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
951
+            $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-checkbox-lbl">';
952
+            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>' : '';
953
+            $input_html .= "\n\t\t\t\t\t\t".'<input type="checkbox" name="'.$name.'['.$OPT->ID().']" id="'.$id.$opt.'" class="'.$class.'" value="'.$value.'" title="'.esc_attr($required['msg']).'" '.$disabled.$checked.' '.$extra.'/>';
954
+            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>' : '';
955
+            $input_html .= "\n\t\t\t\t\t".'</label>';
956
+            if ( ! empty($desc) && $desc != $text) {
957
+                $input_html .= "\n\t\t\t\t\t".' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'.$desc.'</div>';
958 958
             }
959
-            $input_html .= "\n\t\t\t\t" . '</li>';
959
+            $input_html .= "\n\t\t\t\t".'</li>';
960 960
         }
961 961
 
962
-        $input_html .= "\n\t\t\t" . '</ul>';
962
+        $input_html .= "\n\t\t\t".'</ul>';
963 963
 
964
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
965
-        return  $label_html . $input_html;
964
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
965
+        return  $label_html.$input_html;
966 966
     }
967 967
 
968 968
 
@@ -986,7 +986,7 @@  discard block
 block discarded – undo
986 986
     public static function datepicker($question = false, $answer = null, $name = false, $id = '', $class = '', $required = false, $required_text = '', $label_class = '', $disabled = false, $system_ID = false, $use_html_entities = true)
987 987
     {
988 988
         // need these
989
-        if (! $question || ! $name) {
989
+        if ( ! $question || ! $name) {
990 990
             return null;
991 991
         }
992 992
         // prep the answer
@@ -994,26 +994,26 @@  discard block
 block discarded – undo
994 994
         // prep the required array
995 995
         $required = self::prep_required($required);
996 996
         // set disabled tag
997
-        $disabled = $answer === null || ! $disabled  ? '' : ' disabled="disabled"';
997
+        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
998 998
         // ya gots ta have style man!!!
999 999
         $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1000 1000
         $class = empty($class) ? $txt_class : $class;
1001
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1001
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1002 1002
         $extra = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1003 1003
 
1004
-        $label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question($question) . $required['label'] . '</label><br/>';
1004
+        $label_html = $required_text."\n\t\t\t".'<label for="'.$name.'" class="'.$label_class.'">'.self::prep_question($question).$required['label'].'</label><br/>';
1005 1005
         // filter label but ensure required text comes before it
1006 1006
         $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1007 1007
 
1008
-        $input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1008
+        $input_html = "\n\t\t\t".'<input type="text" name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].' datepicker" value="'.$answer.'"  title="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
1009 1009
 
1010 1010
         // enqueue scripts
1011
-        wp_register_style('espresso-ui-theme', EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', array(), EVENT_ESPRESSO_VERSION);
1011
+        wp_register_style('espresso-ui-theme', EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', array(), EVENT_ESPRESSO_VERSION);
1012 1012
         wp_enqueue_style('espresso-ui-theme');
1013 1013
         wp_enqueue_script('jquery-ui-datepicker');
1014 1014
 
1015
-        $input_html =  apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1016
-        return  $label_html . $input_html;
1015
+        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1016
+        return  $label_html.$input_html;
1017 1017
     }
1018 1018
 
1019 1019
 
@@ -1042,7 +1042,7 @@  discard block
 block discarded – undo
1042 1042
     public static function hidden_input($name, $value, $id = '')
1043 1043
     {
1044 1044
         $id = ! empty($id) ? $id : $name;
1045
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' .  $value . '"/>';
1045
+        return '<input id="'.$id.'" type="hidden" name="'.$name.'" value="'.$value.'"/>';
1046 1046
     }
1047 1047
 
1048 1048
 
@@ -1100,14 +1100,14 @@  discard block
 block discarded – undo
1100 1100
         $prepped_answer_options = array();
1101 1101
         if (is_array($QSOs) && ! empty($QSOs)) {
1102 1102
             foreach ($QSOs as $key => $QSO) {
1103
-                if (! $QSO instanceof EE_Question_Option) {
1103
+                if ( ! $QSO instanceof EE_Question_Option) {
1104 1104
                     $QSO = EE_Question_Option::new_instance(array(
1105 1105
                         'QSO_value' => is_array($QSO) && isset($QSO['id']) ? (string) $QSO['id'] : (string) $key,
1106 1106
                         'QSO_desc' => is_array($QSO) && isset($QSO['text']) ? (string) $QSO['text'] : (string) $QSO
1107 1107
                     ));
1108 1108
                 }
1109 1109
                 if ($QSO->opt_group()) {
1110
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1110
+                    $prepped_answer_options[$QSO->opt_group()][] = $QSO;
1111 1111
                 } else {
1112 1112
                     $prepped_answer_options[] = $QSO;
1113 1113
                 }
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
         // make sure required is an array
1142 1142
         $required = is_array($required) ? $required : array();
1143 1143
         // and set some defaults
1144
-        $required = array_merge(array( 'label' => '', 'class' => '', 'msg' => '' ), $required);
1144
+        $required = array_merge(array('label' => '', 'class' => '', 'msg' => ''), $required);
1145 1145
         return $required;
1146 1146
     }
1147 1147
 
@@ -1161,22 +1161,22 @@  discard block
 block discarded – undo
1161 1161
             $val_size = strlen($value);
1162 1162
         switch ($val_size) {
1163 1163
             case $val_size < 3:
1164
-                $size =  ' class="nano-lbl"';
1164
+                $size = ' class="nano-lbl"';
1165 1165
                 break;
1166 1166
             case $val_size < 6:
1167
-                $size =  ' class="micro-lbl"';
1167
+                $size = ' class="micro-lbl"';
1168 1168
                 break;
1169 1169
             case $val_size < 12:
1170
-                $size =  ' class="tiny-lbl"';
1170
+                $size = ' class="tiny-lbl"';
1171 1171
                 break;
1172 1172
             case $val_size < 25:
1173
-                $size =  ' class="small-lbl"';
1173
+                $size = ' class="small-lbl"';
1174 1174
                 break;
1175 1175
             case $val_size > 100:
1176
-                $size =  ' class="big-lbl"';
1176
+                $size = ' class="big-lbl"';
1177 1177
                 break;
1178 1178
             default:
1179
-                $size =  ' class="medium-lbl"';
1179
+                $size = ' class="medium-lbl"';
1180 1180
                 break;
1181 1181
         }
1182 1182
         return $size;
@@ -1247,12 +1247,12 @@  discard block
 block discarded – undo
1247 1247
         $states = $get_all
1248 1248
             ? EEM_State::instance()->get_all_states()
1249 1249
             : EEM_State::instance()->get_all_states_of_active_countries();
1250
-        if (! empty($states) && count($states) != count($QST->options())) {
1250
+        if ( ! empty($states) && count($states) != count($QST->options())) {
1251 1251
             $QST->set('QST_type', 'DROPDOWN');
1252 1252
             // if multiple countries, we'll create option groups within the dropdown
1253 1253
             foreach ($states as $state) {
1254 1254
                 if ($state instanceof EE_State) {
1255
-                    $QSO = EE_Question_Option::new_instance(array (
1255
+                    $QSO = EE_Question_Option::new_instance(array(
1256 1256
                         'QSO_value' => $state->ID(),
1257 1257
                         'QSO_desc' => $state->name(),
1258 1258
                         'QST_ID' => $QST->get('QST_ID'),
@@ -1285,7 +1285,7 @@  discard block
 block discarded – undo
1285 1285
             // now add countries
1286 1286
             foreach ($countries as $country) {
1287 1287
                 if ($country instanceof EE_Country) {
1288
-                    $QSO = EE_Question_Option::new_instance(array (
1288
+                    $QSO = EE_Question_Option::new_instance(array(
1289 1289
                         'QSO_value' => $country->ID(),
1290 1290
                         'QSO_desc' => $country->name(),
1291 1291
                         'QST_ID' => $QST->get('QST_ID'),
@@ -1311,7 +1311,7 @@  discard block
 block discarded – undo
1311 1311
         $options = array();
1312 1312
         for ($x = 1; $x <= 12; $x++) {
1313 1313
             $mm = str_pad($x, 2, '0', STR_PAD_LEFT);
1314
-            $options[ (string) $mm ] = (string) $mm;
1314
+            $options[(string) $mm] = (string) $mm;
1315 1315
         }
1316 1316
         return EEH_Form_Fields::prep_answer_options($options);
1317 1317
     }
@@ -1331,7 +1331,7 @@  discard block
 block discarded – undo
1331 1331
         $next_decade = $current_year + 10;
1332 1332
         for ($x = $current_year; $x <= $next_decade; $x++) {
1333 1333
             $yy = str_pad($x, 2, '0', STR_PAD_LEFT);
1334
-            $options[ (string) $yy ] = (string) $yy;
1334
+            $options[(string) $yy] = (string) $yy;
1335 1335
         }
1336 1336
         return EEH_Form_Fields::prep_answer_options($options);
1337 1337
     }
@@ -1350,7 +1350,7 @@  discard block
 block discarded – undo
1350 1350
     public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1351 1351
     {
1352 1352
         $_where = array();
1353
-        if (!empty($status)) {
1353
+        if ( ! empty($status)) {
1354 1354
             $_where['STS_ID'] = $status;
1355 1355
         }
1356 1356
 
@@ -1369,7 +1369,7 @@  discard block
 block discarded – undo
1369 1369
             );
1370 1370
 
1371 1371
         foreach ($regdtts as $regdtt) {
1372
-            $date = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1372
+            $date = $regdtt->reg_month.' '.$regdtt->reg_year;
1373 1373
             $options[] = array(
1374 1374
                 'text' => $date,
1375 1375
                 'id' => $date
@@ -1399,11 +1399,11 @@  discard block
 block discarded – undo
1399 1399
             case 'today':
1400 1400
             case null:
1401 1401
             case 'all':
1402
-                $where['Event.status'] = array( 'NOT IN', array('trash') );
1402
+                $where['Event.status'] = array('NOT IN', array('trash'));
1403 1403
                 break;
1404 1404
 
1405 1405
             case 'draft':
1406
-                $where['Event.status'] = array( 'IN', array('draft', 'auto-draft') );
1406
+                $where['Event.status'] = array('IN', array('draft', 'auto-draft'));
1407 1407
 
1408 1408
             default:
1409 1409
                 $where['Event.status'] = $status;
@@ -1414,7 +1414,7 @@  discard block
 block discarded – undo
1414 1414
         // categories?
1415 1415
 
1416 1416
 
1417
-        if (!empty($evt_category)) {
1417
+        if ( ! empty($evt_category)) {
1418 1418
             $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1419 1419
             $where['Event.Term_Taxonomy.term_id'] = $evt_category;
1420 1420
         }
@@ -1438,8 +1438,8 @@  discard block
 block discarded – undo
1438 1438
         global $wp_locale;
1439 1439
 
1440 1440
         foreach ($DTTS as $DTT) {
1441
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1442
-            $id = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1441
+            $localized_date = $wp_locale->get_month($DTT->dtt_month_num).' '.$DTT->dtt_year;
1442
+            $id = $DTT->dtt_month.' '.$DTT->dtt_year;
1443 1443
             $options[] = array(
1444 1444
                 'text' => $localized_date,
1445 1445
                 'id' => $id
@@ -1502,10 +1502,10 @@  discard block
 block discarded – undo
1502 1502
             return $btn;
1503 1503
         }
1504 1504
         $text = ! empty($text) ? $text : __('Submit', 'event_espresso');
1505
-        $btn .= '<input id="' . $ID . '-btn" class="' . $class . '" type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
1506
-        if (! $input_only) {
1507
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
1508
-            $btn_frm .= ! empty($nonce_action) ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false) : '';
1505
+        $btn .= '<input id="'.$ID.'-btn" class="'.$class.'" type="submit" value="'.$text.'" '.$extra_attributes.'/>';
1506
+        if ( ! $input_only) {
1507
+            $btn_frm = '<form id="'.$ID.'-frm" method="POST" action="'.$url.'">';
1508
+            $btn_frm .= ! empty($nonce_action) ? wp_nonce_field($nonce_action, $nonce_action.'_nonce', true, false) : '';
1509 1509
             $btn_frm .= $btn;
1510 1510
             $btn_frm .= '</form>';
1511 1511
             $btn = $btn_frm;
Please login to merge, or discard this patch.
core/db_classes/EE_Import.class.php 1 patch
Indentation   +954 added lines, -954 removed lines patch added patch discarded remove patch
@@ -14,91 +14,91 @@  discard block
 block discarded – undo
14 14
 class EE_Import implements ResettableInterface
15 15
 {
16 16
 
17
-    const do_insert = 'insert';
18
-    const do_update = 'update';
19
-    const do_nothing = 'nothing';
20
-
21
-
22
-    // instance of the EE_Import object
23
-    private static $_instance;
24
-
25
-    private static $_csv_array = array();
26
-
27
-    /**
28
-     *
29
-     * @var array of model names
30
-     */
31
-    private static $_model_list = array();
32
-
33
-    private static $_columns_to_save = array();
34
-
35
-    protected $_total_inserts = 0;
36
-    protected $_total_updates = 0;
37
-    protected $_total_insert_errors = 0;
38
-    protected $_total_update_errors = 0;
39
-
40
-
41
-    /**
42
-     *        private constructor to prevent direct creation
43
-     *
44
-     * @Constructor
45
-     * @access private
46
-     * @return void
47
-     */
48
-    private function __construct()
49
-    {
50
-        $this->_total_inserts = 0;
51
-        $this->_total_updates = 0;
52
-        $this->_total_insert_errors = 0;
53
-        $this->_total_update_errors = 0;
54
-    }
55
-
56
-
57
-    /**
58
-     *    @ singleton method used to instantiate class object
59
-     *    @ access public
60
-     *
61
-     * @return EE_Import
62
-     */
63
-    public static function instance()
64
-    {
65
-        // check if class object is instantiated
66
-        if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
67
-            self::$_instance = new self();
68
-        }
69
-        return self::$_instance;
70
-    }
71
-
72
-    /**
73
-     * Resets the importer
74
-     *
75
-     * @return EE_Import
76
-     */
77
-    public static function reset()
78
-    {
79
-        self::$_instance = null;
80
-        return self::instance();
81
-    }
82
-
83
-
84
-    /**
85
-     *    @ generates HTML for a file upload input and form
86
-     *    @ access    public
87
-     *
88
-     * @param    string $title  - heading for the form
89
-     * @param    string $intro  - additional text explaing what to do
90
-     * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91
-     * @param    string $action - EE Admin page route array "action" that form will direct to
92
-     * @param    string $type   - type of file to import
93
-     *                          @ return    string
94
-     */
95
-    public function upload_form($title, $intro, $form_url, $action, $type)
96
-    {
97
-
98
-        $form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url);
99
-
100
-        ob_start();
101
-        ?>
17
+	const do_insert = 'insert';
18
+	const do_update = 'update';
19
+	const do_nothing = 'nothing';
20
+
21
+
22
+	// instance of the EE_Import object
23
+	private static $_instance;
24
+
25
+	private static $_csv_array = array();
26
+
27
+	/**
28
+	 *
29
+	 * @var array of model names
30
+	 */
31
+	private static $_model_list = array();
32
+
33
+	private static $_columns_to_save = array();
34
+
35
+	protected $_total_inserts = 0;
36
+	protected $_total_updates = 0;
37
+	protected $_total_insert_errors = 0;
38
+	protected $_total_update_errors = 0;
39
+
40
+
41
+	/**
42
+	 *        private constructor to prevent direct creation
43
+	 *
44
+	 * @Constructor
45
+	 * @access private
46
+	 * @return void
47
+	 */
48
+	private function __construct()
49
+	{
50
+		$this->_total_inserts = 0;
51
+		$this->_total_updates = 0;
52
+		$this->_total_insert_errors = 0;
53
+		$this->_total_update_errors = 0;
54
+	}
55
+
56
+
57
+	/**
58
+	 *    @ singleton method used to instantiate class object
59
+	 *    @ access public
60
+	 *
61
+	 * @return EE_Import
62
+	 */
63
+	public static function instance()
64
+	{
65
+		// check if class object is instantiated
66
+		if (self::$_instance === null or ! is_object(self::$_instance) or ! (self::$_instance instanceof EE_Import)) {
67
+			self::$_instance = new self();
68
+		}
69
+		return self::$_instance;
70
+	}
71
+
72
+	/**
73
+	 * Resets the importer
74
+	 *
75
+	 * @return EE_Import
76
+	 */
77
+	public static function reset()
78
+	{
79
+		self::$_instance = null;
80
+		return self::instance();
81
+	}
82
+
83
+
84
+	/**
85
+	 *    @ generates HTML for a file upload input and form
86
+	 *    @ access    public
87
+	 *
88
+	 * @param    string $title  - heading for the form
89
+	 * @param    string $intro  - additional text explaing what to do
90
+	 * @param    string $page   - EE Admin page to direct form to - in the form "espresso_{pageslug}"
91
+	 * @param    string $action - EE Admin page route array "action" that form will direct to
92
+	 * @param    string $type   - type of file to import
93
+	 *                          @ return    string
94
+	 */
95
+	public function upload_form($title, $intro, $form_url, $action, $type)
96
+	{
97
+
98
+		$form_url = EE_Admin_Page::add_query_args_and_nonce(array('action' => $action), $form_url);
99
+
100
+		ob_start();
101
+		?>
102 102
         <div class="ee-upload-form-dv">
103 103
             <h3><?php echo $title; ?></h3>
104 104
             <p><?php echo $intro; ?></p>
@@ -114,878 +114,878 @@  discard block
 block discarded – undo
114 114
                 <b><?php _e('Attention', 'event_espresso'); ?></b><br/>
115 115
                 <?php echo sprintf(__('Accepts .%s file types only.', 'event_espresso'), $type); ?>
116 116
                 <?php echo __(
117
-                    'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
118
-                    'event_espresso'
119
-                ); ?>
117
+					'Please only import CSV files exported from Event Espresso, or compatible 3rd-party software.',
118
+					'event_espresso'
119
+				); ?>
120 120
             </p>
121 121
 
122 122
         </div>
123 123
 
124 124
         <?php
125
-        $uploader = ob_get_clean();
126
-        return $uploader;
127
-    }
128
-
129
-
130
-    /**
131
-     * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132
-     * @access public
133
-     * @return boolean success
134
-     */
135
-    public function import()
136
-    {
137
-
138
-        require_once(EE_CLASSES . 'EE_CSV.class.php');
139
-        $this->EE_CSV = EE_CSV::instance();
140
-
141
-        if (isset($_REQUEST['import'])) {
142
-            if (isset($_POST['csv_submitted'])) {
143
-                switch ($_FILES['file']['error'][0]) {
144
-                    case UPLOAD_ERR_OK:
145
-                        $error_msg = false;
146
-                        break;
147
-                    case UPLOAD_ERR_INI_SIZE:
148
-                        $error_msg = __(
149
-                            "'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
150
-                            "event_espresso"
151
-                        );
152
-                        break;
153
-                    case UPLOAD_ERR_FORM_SIZE:
154
-                        $error_msg = __(
155
-                            'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
156
-                            "event_espresso"
157
-                        );
158
-                        break;
159
-                    case UPLOAD_ERR_PARTIAL:
160
-                        $error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
161
-                        break;
162
-                    case UPLOAD_ERR_NO_FILE:
163
-                        $error_msg = __('No file was uploaded.', "event_espresso");
164
-                        break;
165
-                    case UPLOAD_ERR_NO_TMP_DIR:
166
-                        $error_msg = __('Missing a temporary folder.', "event_espresso");
167
-                        break;
168
-                    case UPLOAD_ERR_CANT_WRITE:
169
-                        $error_msg = __('Failed to write file to disk.', "event_espresso");
170
-                        break;
171
-                    case UPLOAD_ERR_EXTENSION:
172
-                        $error_msg = __('File upload stopped by extension.', "event_espresso");
173
-                        break;
174
-                    default:
175
-                        $error_msg = __(
176
-                            'An unknown error occurred and the file could not be uploaded',
177
-                            "event_espresso"
178
-                        );
179
-                        break;
180
-                }
181
-
182
-                if (! $error_msg) {
183
-                    $filename = $_FILES['file']['name'][0];
184
-                    $file_ext = substr(strrchr($filename, '.'), 1);
185
-                    $file_type = $_FILES['file']['type'][0];
186
-                    $temp_file = $_FILES['file']['tmp_name'][0];
187
-                    $filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
188
-
189
-                    if ($file_ext == 'csv') {
190
-                        $max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
191
-                        if ($filesize < $max_upload || true) {
192
-                            $wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir());
193
-                            $path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
194
-
195
-                            if (move_uploaded_file($temp_file, $path_to_file)) {
196
-                                // convert csv to array
197
-                                $this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
198
-
199
-                                // was data successfully stored in an array?
200
-                                if (is_array($this->csv_array)) {
201
-                                    $import_what = str_replace('csv_import_', '', $_REQUEST['action']);
202
-                                    $import_what = str_replace('_', ' ', ucwords($import_what));
203
-                                    $processed_data = $this->csv_array;
204
-                                    $this->columns_to_save = false;
205
-
206
-                                    // if any imports require funcky processing, we'll catch them in the switch
207
-                                    switch ($_REQUEST['action']) {
208
-                                        case "import_events":
209
-                                        case "event_list":
210
-                                            $import_what = 'Event Details';
211
-                                            break;
212
-
213
-                                        case 'groupon_import_csv':
214
-                                            $import_what = 'Groupon Codes';
215
-                                            $processed_data = $this->process_groupon_codes();
216
-                                            break;
217
-                                    }
218
-                                    // save processed codes to db
219
-                                    if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
220
-                                        return true;
221
-                                    }
222
-                                } else {
223
-                                    // no array? must be an error
224
-                                    EE_Error::add_error(
225
-                                        sprintf(__("No file seems to have been uploaded", "event_espresso")),
226
-                                        __FILE__,
227
-                                        __FUNCTION__,
228
-                                        __LINE__
229
-                                    );
230
-                                    return false;
231
-                                }
232
-                            } else {
233
-                                EE_Error::add_error(
234
-                                    sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
235
-                                    __FILE__,
236
-                                    __FUNCTION__,
237
-                                    __LINE__
238
-                                );
239
-                                return false;
240
-                            }
241
-                        } else {
242
-                            EE_Error::add_error(
243
-                                sprintf(
244
-                                    __(
245
-                                        "%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
246
-                                        "event_espresso"
247
-                                    ),
248
-                                    $filename,
249
-                                    $max_upload
250
-                                ),
251
-                                __FILE__,
252
-                                __FUNCTION__,
253
-                                __LINE__
254
-                            );
255
-                            return false;
256
-                        }
257
-                    } else {
258
-                        EE_Error::add_error(
259
-                            sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
260
-                            __FILE__,
261
-                            __FUNCTION__,
262
-                            __LINE__
263
-                        );
264
-                        return false;
265
-                    }
266
-                } else {
267
-                    EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
268
-                    return false;
269
-                }
270
-            }
271
-        }
272
-        return;
273
-    }
274
-
275
-
276
-    /**
277
-     *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
278
-     *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
279
-     *    next level being numeric indexes adn each value representing a model object, and the last layer down
280
-     *    being keys of model fields and their proposed values.
281
-     *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
282
-     *    If the CSV data says (in the metadata row) that it's from the SAME database,
283
-     *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
284
-     *    IDs DON'T exist in the database, they're treated as temporary IDs,
285
-     *    which can used elsewhere to refer to the same object. Once an item
286
-     *    with a temporary ID gets inserted, we record its mapping from temporary
287
-     *    ID to real ID, and use the real ID in place of the temporary ID
288
-     *    when that temporary ID was used as a foreign key.
289
-     *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
290
-     *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
291
-     *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
292
-     *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
293
-     *    An important exception are non-auto-increment primary keys. If one entry in the
294
-     *    CSV file has the same ID as one in the DB, we assume they are meant to be
295
-     *    the same item, and instead update the item in the DB with that same ID.
296
-     *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
297
-     *    time you import a CSV from a different site, we remember their mappings, and
298
-     * will try to update the item in the DB instead of inserting another item (eg
299
-     * if we previously imported an event with temporary ID 1, and then it got a
300
-     * real ID of 123, we remember that. So the next time we import an event with
301
-     * temporary ID, from the same site, we know that it's real ID is 123, and will
302
-     * update that event, instead of adding a new event).
303
-     *
304
-     * @access public
305
-     * @param array $csv_data_array - the array containing the csv data produced from
306
-     *                              EE_CSV::import_csv_to_model_data_array()
307
-     * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
-     *                              fields they will be saved to
309
-     * @return TRUE on success, FALSE on fail
310
-     * @throws \EE_Error
311
-     */
312
-    public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
313
-    {
314
-        $success = false;
315
-        $error = false;
316
-        // whther to treat this import as if it's data froma different database or not
317
-        // ie, if it IS from a different database, ignore foreign keys whihf
318
-        $export_from_site_a_to_b = true;
319
-        // first level of array is not table information but a table name was passed to the function
320
-        // array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
321
-        if ($model_name) {
322
-            $csv_data_array = array($csv_data_array);
323
-        }
324
-        // begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325
-        $old_site_url = 'none-specified';
326
-        // hanlde metadata
327
-        if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
-            $csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
329
-            // ok so its metadata, dont try to save it to ehte db obviously...
330
-            if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331
-                EE_Error::add_attention(
332
-                    sprintf(
333
-                        __(
334
-                            "CSV Data appears to be from the same database, so attempting to update data",
335
-                            "event_espresso"
336
-                        )
337
-                    )
338
-                );
339
-                $export_from_site_a_to_b = false;
340
-            } else {
341
-                $old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
342
-                EE_Error::add_attention(
343
-                    sprintf(
344
-                        __(
345
-                            "CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
346
-                            "event_espresso"
347
-                        ),
348
-                        $old_site_url,
349
-                        site_url()
350
-                    )
351
-                );
352
-            };
353
-            unset($csv_data_array[ EE_CSV::metadata_header ]);
354
-        }
355
-        /**
356
-         * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357
-         * the value will be the newly-inserted ID.
358
-         * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359
-         */
360
-        $old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
361
-        if ($old_db_to_new_db_mapping) {
362
-            EE_Error::add_attention(
363
-                sprintf(
364
-                    __(
365
-                        "We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
366
-                        "event_espresso"
367
-                    ),
368
-                    $old_site_url,
369
-                    site_url()
370
-                )
371
-            );
372
-        }
373
-        $old_db_to_new_db_mapping = $this->save_data_rows_to_db(
374
-            $csv_data_array,
375
-            $export_from_site_a_to_b,
376
-            $old_db_to_new_db_mapping
377
-        );
378
-
379
-        // save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
-        update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381
-
382
-        if ($this->_total_updates > 0) {
383
-            EE_Error::add_success(
384
-                sprintf(
385
-                    __("%s existing records in the database were updated.", "event_espresso"),
386
-                    $this->_total_updates
387
-                )
388
-            );
389
-            $success = true;
390
-        }
391
-        if ($this->_total_inserts > 0) {
392
-            EE_Error::add_success(
393
-                sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
394
-            );
395
-            $success = true;
396
-        }
397
-
398
-        if ($this->_total_update_errors > 0) {
399
-            EE_Error::add_error(
400
-                sprintf(
401
-                    __(
402
-                        "'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
403
-                        "event_espresso"
404
-                    ),
405
-                    $this->_total_update_errors
406
-                ),
407
-                __FILE__,
408
-                __FUNCTION__,
409
-                __LINE__
410
-            );
411
-            $error = true;
412
-        }
413
-        if ($this->_total_insert_errors > 0) {
414
-            EE_Error::add_error(
415
-                sprintf(
416
-                    __(
417
-                        "One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
418
-                        "event_espresso"
419
-                    ),
420
-                    $this->_total_insert_errors
421
-                ),
422
-                __FILE__,
423
-                __FUNCTION__,
424
-                __LINE__
425
-            );
426
-            $error = true;
427
-        }
428
-
429
-        // lastly, we need to update the datetime and ticket sold amounts
430
-        // as those may have been affected by this
431
-        EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
432
-
433
-        // if there was at least one success and absolutely no errors
434
-        if ($success && ! $error) {
435
-            return true;
436
-        } else {
437
-            return false;
438
-        }
439
-    }
440
-
441
-
442
-    /**
443
-     * Processes the array of data, given the knowledge that it's from the same database or a different one,
444
-     * and the mapping from temporary IDs to real IDs.
445
-     * If the data is from a different database, we treat the primary keys and their corresponding
446
-     * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
447
-     * in the real target database. As items are inserted, their temporary primary keys
448
-     * are mapped to the real IDs in the target database. Also, before doing any update or
449
-     * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
450
-     * An exception: string primary keys are treated as real IDs, or else we'd need to
451
-     * dynamically generate new string primary keys which would be very awkard for the country table etc.
452
-     * Also, models with no primary key are strange too. We combine use their primar key INDEX (a
453
-     * combination of fields) to create a unique string identifying the row and store
454
-     * those in the mapping.
455
-     *
456
-     * If the data is from the same database, we usually treat primary keys as real IDs.
457
-     * An exception is if there is nothing in the database for that ID. If that's the case,
458
-     * we need to insert a new row for that ID, and then map from the non-existent ID
459
-     * to the newly-inserted real ID.
460
-     *
461
-     * @param type $csv_data_array
462
-     * @param type $export_from_site_a_to_b
463
-     * @param type $old_db_to_new_db_mapping
464
-     * @return array updated $old_db_to_new_db_mapping
465
-     */
466
-    public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping)
467
-    {
468
-        foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
469
-            // now check that assumption was correct. If
470
-            if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
471
-                $model_name = $model_name_in_csv_data;
472
-            } else {
473
-                // no table info in the array and no table name passed to the function?? FAIL
474
-                EE_Error::add_error(
475
-                    __(
476
-                        'No table information was specified and/or found, therefore the import could not be completed',
477
-                        'event_espresso'
478
-                    ),
479
-                    __FILE__,
480
-                    __FUNCTION__,
481
-                    __LINE__
482
-                );
483
-                return false;
484
-            }
485
-            /* @var $model EEM_Base */
486
-            $model = EE_Registry::instance()->load_model($model_name);
487
-
488
-            // so without further ado, scanning all the data provided for primary keys and their inital values
489
-            foreach ($model_data_from_import as $model_object_data) {
490
-                // before we do ANYTHING, make sure the csv row wasn't just completely blank
491
-                $row_is_completely_empty = true;
492
-                foreach ($model_object_data as $field) {
493
-                    if ($field) {
494
-                        $row_is_completely_empty = false;
495
-                    }
496
-                }
497
-                if ($row_is_completely_empty) {
498
-                    continue;
499
-                }
500
-                // find the PK in the row of data (or a combined key if
501
-                // there is no primary key)
502
-                if ($model->has_primary_key_field()) {
503
-                    $id_in_csv = $model_object_data[ $model->primary_key_name() ];
504
-                } else {
505
-                    $id_in_csv = $model->get_index_primary_key_string($model_object_data);
506
-                }
507
-
508
-
509
-                $model_object_data = $this->_replace_temp_ids_with_mappings(
510
-                    $model_object_data,
511
-                    $model,
512
-                    $old_db_to_new_db_mapping,
513
-                    $export_from_site_a_to_b
514
-                );
515
-                // now we need to decide if we're going to add a new model object given the $model_object_data,
516
-                // or just update.
517
-                if ($export_from_site_a_to_b) {
518
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
519
-                        $id_in_csv,
520
-                        $model_object_data,
521
-                        $model,
522
-                        $old_db_to_new_db_mapping
523
-                    );
524
-                } else {// this is just a re-import
525
-                    $what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
526
-                        $id_in_csv,
527
-                        $model_object_data,
528
-                        $model,
529
-                        $old_db_to_new_db_mapping
530
-                    );
531
-                }
532
-                if ($what_to_do == self::do_nothing) {
533
-                    continue;
534
-                }
535
-
536
-                // double-check we actually want to insert, if that's what we're planning
537
-                // based on whether this item would be unique in the DB or not
538
-                if ($what_to_do == self::do_insert) {
539
-                    // we're supposed to be inserting. But wait, will this thing
540
-                    // be acceptable if inserted?
541
-                    $conflicting = $model->get_one_conflicting($model_object_data, false);
542
-                    if ($conflicting) {
543
-                        // ok, this item would conflict if inserted. Just update the item that it conflicts with.
544
-                        $what_to_do = self::do_update;
545
-                        // and if this model has a primary key, remember its mapping
546
-                        if ($model->has_primary_key_field()) {
547
-                            $old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
-                            $model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
549
-                        } else {
550
-                            // we want to update this conflicting item, instead of inserting a conflicting item
551
-                            // so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552
-                            // for the WHERE conditions in the update). At the time of this comment, there were no models like this
553
-                            foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
-                                $model_object_data[ $key_field->get_name() ] = $conflicting->get(
555
-                                    $key_field->get_name()
556
-                                );
557
-                            }
558
-                        }
559
-                    }
560
-                }
561
-                if ($what_to_do == self::do_insert) {
562
-                    $old_db_to_new_db_mapping = $this->_insert_from_data_array(
563
-                        $id_in_csv,
564
-                        $model_object_data,
565
-                        $model,
566
-                        $old_db_to_new_db_mapping
567
-                    );
568
-                } elseif ($what_to_do == self::do_update) {
569
-                    $old_db_to_new_db_mapping = $this->_update_from_data_array(
570
-                        $id_in_csv,
571
-                        $model_object_data,
572
-                        $model,
573
-                        $old_db_to_new_db_mapping
574
-                    );
575
-                } else {
576
-                    throw new EE_Error(
577
-                        sprintf(
578
-                            __(
579
-                                'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
580
-                                'event_espresso'
581
-                            ),
582
-                            $what_to_do
583
-                        )
584
-                    );
585
-                }
586
-            }
587
-        }
588
-        return $old_db_to_new_db_mapping;
589
-    }
590
-
591
-
592
-    /**
593
-     * Decides whether or not to insert, given that this data is from another database.
594
-     * So, if the primary key of this $model_object_data already exists in the database,
595
-     * it's just a coincidence and we should still insert. The only time we should
596
-     * update is when we know what it maps to, or there's something that would
597
-     * conflict (and we should instead just update that conflicting thing)
598
-     *
599
-     * @param string   $id_in_csv
600
-     * @param array    $model_object_data        by reference so it can be modified
601
-     * @param EEM_Base $model
602
-     * @param array    $old_db_to_new_db_mapping by reference so it can be modified
603
-     * @return string one of the consts on this class that starts with do_*
604
-     */
605
-    protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
606
-        $id_in_csv,
607
-        $model_object_data,
608
-        $model,
609
-        $old_db_to_new_db_mapping
610
-    ) {
611
-        $model_name = $model->get_this_model_name();
612
-        // if it's a site-to-site export-and-import, see if this modelobject's id
613
-        // in the old data that we know of
614
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
615
-            return self::do_update;
616
-        } else {
617
-            return self::do_insert;
618
-        }
619
-    }
620
-
621
-    /**
622
-     * If this thing basically already exists in the database, we want to update it;
623
-     * otherwise insert it (ie, someone tweaked the CSV file, or the item was
624
-     * deleted in the database so it should be re-inserted)
625
-     *
626
-     * @param type     $id_in_csv
627
-     * @param type     $model_object_data
628
-     * @param EEM_Base $model
629
-     * @param type     $old_db_to_new_db_mapping
630
-     * @return
631
-     */
632
-    protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
633
-        $id_in_csv,
634
-        $model_object_data,
635
-        $model
636
-    ) {
637
-        // in this case, check if this thing ACTUALLY exists in the database
638
-        if ($model->get_one_conflicting($model_object_data)) {
639
-            return self::do_update;
640
-        } else {
641
-            return self::do_insert;
642
-        }
643
-    }
644
-
645
-    /**
646
-     * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
647
-     * with their mapped real IDs. Eg, if importing from site A to B, the mapping
648
-     * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
649
-     * So this function searches for any event temp Ids called "my_event_id" and
650
-     * replaces them with 123.
651
-     * Also, if there is no temp ID for the INT foreign keys from another database,
652
-     * replaces them with 0 or the field's default.
653
-     *
654
-     * @param type     $model_object_data
655
-     * @param EEM_Base $model
656
-     * @param type     $old_db_to_new_db_mapping
657
-     * @param boolean  $export_from_site_a_to_b
658
-     * @return array updated model object data with temp IDs removed
659
-     */
660
-    protected function _replace_temp_ids_with_mappings(
661
-        $model_object_data,
662
-        $model,
663
-        $old_db_to_new_db_mapping,
664
-        $export_from_site_a_to_b
665
-    ) {
666
-        // if this model object's primary key is in the mapping, replace it
667
-        if (
668
-            $model->has_primary_key_field() &&
669
-            $model->get_primary_key_field()->is_auto_increment() &&
670
-            isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
671
-            isset(
672
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
673
-            )
674
-        ) {
675
-            $model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
676
-            ) ][ $model_object_data[ $model->primary_key_name() ] ];
677
-        }
678
-
679
-        try {
680
-            $model_name_field = $model->get_field_containing_related_model_name();
681
-            $models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
682
-        } catch (EE_Error $e) {
683
-            $model_name_field = null;
684
-            $models_pointed_to_by_model_name_field = array();
685
-        }
686
-        foreach ($model->field_settings(true) as $field_obj) {
687
-            if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
688
-                $models_pointed_to = $field_obj->get_model_names_pointed_to();
689
-                $found_a_mapping = false;
690
-                foreach ($models_pointed_to as $model_pointed_to_by_fk) {
691
-                    if ($model_name_field) {
692
-                        $value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
693
-                        if ($value_of_model_name_field == $model_pointed_to_by_fk) {
694
-                            $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
695
-                                $model_object_data[ $field_obj->get_name() ],
696
-                                $model_pointed_to_by_fk,
697
-                                $old_db_to_new_db_mapping,
698
-                                $export_from_site_a_to_b
699
-                            );
700
-                            $found_a_mapping = true;
701
-                            break;
702
-                        }
703
-                    } else {
704
-                        $model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
705
-                            $model_object_data[ $field_obj->get_name() ],
706
-                            $model_pointed_to_by_fk,
707
-                            $old_db_to_new_db_mapping,
708
-                            $export_from_site_a_to_b
709
-                        );
710
-                        $found_a_mapping = true;
711
-                    }
712
-                    // once we've found a mapping for this field no need to continue
713
-                    if ($found_a_mapping) {
714
-                        break;
715
-                    }
716
-                }
717
-            } else {
718
-                // it's a string foreign key (which we leave alone, because those are things
719
-                // like country names, which we'd really rather not make 2 USAs etc (we'd actually
720
-                // prefer to just update one)
721
-                // or it's just a regular value that ought to be replaced
722
-            }
723
-        }
724
-        //
725
-        if ($model instanceof EEM_Term_Taxonomy) {
726
-            $model_object_data = $this->_handle_split_term_ids($model_object_data);
727
-        }
728
-        return $model_object_data;
729
-    }
730
-
731
-    /**
732
-     * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
733
-     * this term-taxonomy refers to may be out-of-date so we need to update it.
734
-     * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
735
-     *
736
-     * @param type $model_object_data
737
-     * @return array new model object data
738
-     */
739
-    protected function _handle_split_term_ids($model_object_data)
740
-    {
741
-        if (
742
-            isset($model_object_data['term_id'])
743
-            && isset($model_object_data['taxonomy'])
744
-            && apply_filters(
745
-                'FHEE__EE_Import__handle_split_term_ids__function_exists',
746
-                function_exists('wp_get_split_term'),
747
-                $model_object_data
748
-            )
749
-        ) {
750
-            $new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
751
-            if ($new_term_id) {
752
-                $model_object_data['term_id'] = $new_term_id;
753
-            }
754
-        }
755
-        return $model_object_data;
756
-    }
757
-
758
-    /**
759
-     * Given the object's ID and its model's name, find it int he mapping data,
760
-     * bearing in mind where it came from
761
-     *
762
-     * @param type   $object_id
763
-     * @param string $model_name
764
-     * @param array  $old_db_to_new_db_mapping
765
-     * @param type   $export_from_site_a_to_b
766
-     * @return int
767
-     */
768
-    protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
769
-    {
770
-        if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
771
-            return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
772
-        } elseif ($object_id == '0' || $object_id == '') {
773
-            // leave as-is
774
-            return $object_id;
775
-        } elseif ($export_from_site_a_to_b) {
776
-            // we couldn't find a mapping for this, and it's from a different site,
777
-            // so blank it out
778
-            return null;
779
-        } elseif (! $export_from_site_a_to_b) {
780
-            // we coudln't find a mapping for this, but it's from thsi DB anyway
781
-            // so let's just leave it as-is
782
-            return $object_id;
783
-        }
784
-    }
785
-
786
-    /**
787
-     *
788
-     * @param type     $id_in_csv
789
-     * @param type     $model_object_data
790
-     * @param EEM_Base $model
791
-     * @param type     $old_db_to_new_db_mapping
792
-     * @return array updated $old_db_to_new_db_mapping
793
-     */
794
-    protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
795
-    {
796
-        // remove the primary key, if there is one (we don't want it for inserts OR updates)
797
-        // we'll put it back in if we need it
798
-        if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
799
-            $effective_id = $model_object_data[ $model->primary_key_name() ];
800
-            unset($model_object_data[ $model->primary_key_name() ]);
801
-        } else {
802
-            $effective_id = $model->get_index_primary_key_string($model_object_data);
803
-        }
804
-        // the model takes care of validating the CSV's input
805
-        try {
806
-            $new_id = $model->insert($model_object_data);
807
-            if ($new_id) {
808
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
809
-                $this->_total_inserts++;
810
-                EE_Error::add_success(
811
-                    sprintf(
812
-                        __("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
813
-                        $model->get_this_model_name(),
814
-                        $new_id,
815
-                        implode(",", $model_object_data)
816
-                    )
817
-                );
818
-            } else {
819
-                $this->_total_insert_errors++;
820
-                // put the ID used back in there for the error message
821
-                if ($model->has_primary_key_field()) {
822
-                    $model_object_data[ $model->primary_key_name() ] = $effective_id;
823
-                }
824
-                EE_Error::add_error(
825
-                    sprintf(
826
-                        __("Could not insert new %s with the csv data: %s", "event_espresso"),
827
-                        $model->get_this_model_name(),
828
-                        http_build_query($model_object_data)
829
-                    ),
830
-                    __FILE__,
831
-                    __FUNCTION__,
832
-                    __LINE__
833
-                );
834
-            }
835
-        } catch (EE_Error $e) {
836
-            $this->_total_insert_errors++;
837
-            if ($model->has_primary_key_field()) {
838
-                $model_object_data[ $model->primary_key_name() ] = $effective_id;
839
-            }
840
-            EE_Error::add_error(
841
-                sprintf(
842
-                    __("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
843
-                    $model->get_this_model_name(),
844
-                    implode(",", $model_object_data),
845
-                    $e->getMessage()
846
-                ),
847
-                __FILE__,
848
-                __FUNCTION__,
849
-                __LINE__
850
-            );
851
-        }
852
-        return $old_db_to_new_db_mapping;
853
-    }
854
-
855
-    /**
856
-     * Given the model object data, finds the row to update and updates it
857
-     *
858
-     * @param string|int $id_in_csv
859
-     * @param array      $model_object_data
860
-     * @param EEM_Base   $model
861
-     * @param array      $old_db_to_new_db_mapping
862
-     * @return array updated $old_db_to_new_db_mapping
863
-     */
864
-    protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
865
-    {
866
-        try {
867
-            // let's keep two copies of the model object data:
868
-            // one for performing an update, one for everthing else
869
-            $model_object_data_for_update = $model_object_data;
870
-            if ($model->has_primary_key_field()) {
871
-                $conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
872
-                // remove the primary key because we shouldn't use it for updating
873
-                unset($model_object_data_for_update[ $model->primary_key_name() ]);
874
-            } elseif ($model->get_combined_primary_key_fields() > 1) {
875
-                $conditions = array();
876
-                foreach ($model->get_combined_primary_key_fields() as $key_field) {
877
-                    $conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
878
-                }
879
-            } else {
880
-                $model->primary_key_name(
881
-                );// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
882
-            }
883
-
884
-            $success = $model->update($model_object_data_for_update, array($conditions));
885
-            if ($success) {
886
-                $this->_total_updates++;
887
-                EE_Error::add_success(
888
-                    sprintf(
889
-                        __("Successfully updated %s with csv data %s", "event_espresso"),
890
-                        $model->get_this_model_name(),
891
-                        implode(",", $model_object_data_for_update)
892
-                    )
893
-                );
894
-                // we should still record the mapping even though it was an update
895
-                // because if we were going to insert somethign but it was going to conflict
896
-                // we would have last-minute decided to update. So we'd like to know what we updated
897
-                // and so we record what record ended up being updated using the mapping
898
-                if ($model->has_primary_key_field()) {
899
-                    $new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
900
-                } else {
901
-                    // no primary key just a combined key
902
-                    $new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
903
-                }
904
-                $old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
905
-            } else {
906
-                $matched_items = $model->get_all(array($conditions));
907
-                if (! $matched_items) {
908
-                    // no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
909
-                    $this->_total_update_errors++;
910
-                    EE_Error::add_error(
911
-                        sprintf(
912
-                            __(
913
-                                "Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
914
-                                "event_espresso"
915
-                            ),
916
-                            $model->get_this_model_name(),
917
-                            http_build_query($model_object_data),
918
-                            http_build_query($conditions)
919
-                        ),
920
-                        __FILE__,
921
-                        __FUNCTION__,
922
-                        __LINE__
923
-                    );
924
-                } else {
925
-                    $this->_total_updates++;
926
-                    EE_Error::add_success(
927
-                        sprintf(
928
-                            __(
929
-                                "%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
930
-                                "event_espresso"
931
-                            ),
932
-                            $model->get_this_model_name(),
933
-                            implode(",", $model_object_data)
934
-                        )
935
-                    );
936
-                }
937
-            }
938
-        } catch (EE_Error $e) {
939
-            $this->_total_update_errors++;
940
-            $basic_message = sprintf(
941
-                __("Could not update %s with the csv data: %s because %s", "event_espresso"),
942
-                $model->get_this_model_name(),
943
-                implode(",", $model_object_data),
944
-                $e->getMessage()
945
-            );
946
-            $debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
947
-            EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
948
-        }
949
-        return $old_db_to_new_db_mapping;
950
-    }
951
-
952
-    /**
953
-     * Gets the number of inserts performed since importer was instantiated or reset
954
-     *
955
-     * @return int
956
-     */
957
-    public function get_total_inserts()
958
-    {
959
-        return $this->_total_inserts;
960
-    }
961
-
962
-    /**
963
-     *  Gets the number of insert errors since importer was instantiated or reset
964
-     *
965
-     * @return int
966
-     */
967
-    public function get_total_insert_errors()
968
-    {
969
-        return $this->_total_insert_errors;
970
-    }
971
-
972
-    /**
973
-     *  Gets the number of updates performed since importer was instantiated or reset
974
-     *
975
-     * @return int
976
-     */
977
-    public function get_total_updates()
978
-    {
979
-        return $this->_total_updates;
980
-    }
981
-
982
-    /**
983
-     *  Gets the number of update errors since importer was instantiated or reset
984
-     *
985
-     * @return int
986
-     */
987
-    public function get_total_update_errors()
988
-    {
989
-        return $this->_total_update_errors;
990
-    }
125
+		$uploader = ob_get_clean();
126
+		return $uploader;
127
+	}
128
+
129
+
130
+	/**
131
+	 * @Import Event Espresso data - some code "borrowed" from event espresso csv_import.php
132
+	 * @access public
133
+	 * @return boolean success
134
+	 */
135
+	public function import()
136
+	{
137
+
138
+		require_once(EE_CLASSES . 'EE_CSV.class.php');
139
+		$this->EE_CSV = EE_CSV::instance();
140
+
141
+		if (isset($_REQUEST['import'])) {
142
+			if (isset($_POST['csv_submitted'])) {
143
+				switch ($_FILES['file']['error'][0]) {
144
+					case UPLOAD_ERR_OK:
145
+						$error_msg = false;
146
+						break;
147
+					case UPLOAD_ERR_INI_SIZE:
148
+						$error_msg = __(
149
+							"'The uploaded file exceeds the upload_max_filesize directive in php.ini.'",
150
+							"event_espresso"
151
+						);
152
+						break;
153
+					case UPLOAD_ERR_FORM_SIZE:
154
+						$error_msg = __(
155
+							'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
156
+							"event_espresso"
157
+						);
158
+						break;
159
+					case UPLOAD_ERR_PARTIAL:
160
+						$error_msg = __('The uploaded file was only partially uploaded.', "event_espresso");
161
+						break;
162
+					case UPLOAD_ERR_NO_FILE:
163
+						$error_msg = __('No file was uploaded.', "event_espresso");
164
+						break;
165
+					case UPLOAD_ERR_NO_TMP_DIR:
166
+						$error_msg = __('Missing a temporary folder.', "event_espresso");
167
+						break;
168
+					case UPLOAD_ERR_CANT_WRITE:
169
+						$error_msg = __('Failed to write file to disk.', "event_espresso");
170
+						break;
171
+					case UPLOAD_ERR_EXTENSION:
172
+						$error_msg = __('File upload stopped by extension.', "event_espresso");
173
+						break;
174
+					default:
175
+						$error_msg = __(
176
+							'An unknown error occurred and the file could not be uploaded',
177
+							"event_espresso"
178
+						);
179
+						break;
180
+				}
181
+
182
+				if (! $error_msg) {
183
+					$filename = $_FILES['file']['name'][0];
184
+					$file_ext = substr(strrchr($filename, '.'), 1);
185
+					$file_type = $_FILES['file']['type'][0];
186
+					$temp_file = $_FILES['file']['tmp_name'][0];
187
+					$filesize = $_FILES['file']['size'][0] / 1024;// convert from bytes to KB
188
+
189
+					if ($file_ext == 'csv') {
190
+						$max_upload = $this->EE_CSV->get_max_upload_size();// max upload size in KB
191
+						if ($filesize < $max_upload || true) {
192
+							$wp_upload_dir = str_replace(array('\\', '/'), '/', wp_upload_dir());
193
+							$path_to_file = $wp_upload_dir['basedir'] . '/espresso/' . $filename;
194
+
195
+							if (move_uploaded_file($temp_file, $path_to_file)) {
196
+								// convert csv to array
197
+								$this->csv_array = $this->EE_CSV->import_csv_to_model_data_array($path_to_file);
198
+
199
+								// was data successfully stored in an array?
200
+								if (is_array($this->csv_array)) {
201
+									$import_what = str_replace('csv_import_', '', $_REQUEST['action']);
202
+									$import_what = str_replace('_', ' ', ucwords($import_what));
203
+									$processed_data = $this->csv_array;
204
+									$this->columns_to_save = false;
205
+
206
+									// if any imports require funcky processing, we'll catch them in the switch
207
+									switch ($_REQUEST['action']) {
208
+										case "import_events":
209
+										case "event_list":
210
+											$import_what = 'Event Details';
211
+											break;
212
+
213
+										case 'groupon_import_csv':
214
+											$import_what = 'Groupon Codes';
215
+											$processed_data = $this->process_groupon_codes();
216
+											break;
217
+									}
218
+									// save processed codes to db
219
+									if ($this->save_csv_data_array_to_db($processed_data, $this->columns_to_save)) {
220
+										return true;
221
+									}
222
+								} else {
223
+									// no array? must be an error
224
+									EE_Error::add_error(
225
+										sprintf(__("No file seems to have been uploaded", "event_espresso")),
226
+										__FILE__,
227
+										__FUNCTION__,
228
+										__LINE__
229
+									);
230
+									return false;
231
+								}
232
+							} else {
233
+								EE_Error::add_error(
234
+									sprintf(__("%s was not successfully uploaded", "event_espresso"), $filename),
235
+									__FILE__,
236
+									__FUNCTION__,
237
+									__LINE__
238
+								);
239
+								return false;
240
+							}
241
+						} else {
242
+							EE_Error::add_error(
243
+								sprintf(
244
+									__(
245
+										"%s was too large of a file and could not be uploaded. The max filesize is %s' KB.",
246
+										"event_espresso"
247
+									),
248
+									$filename,
249
+									$max_upload
250
+								),
251
+								__FILE__,
252
+								__FUNCTION__,
253
+								__LINE__
254
+							);
255
+							return false;
256
+						}
257
+					} else {
258
+						EE_Error::add_error(
259
+							sprintf(__("%s  had an invalid file extension, not uploaded", "event_espresso"), $filename),
260
+							__FILE__,
261
+							__FUNCTION__,
262
+							__LINE__
263
+						);
264
+						return false;
265
+					}
266
+				} else {
267
+					EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
268
+					return false;
269
+				}
270
+			}
271
+		}
272
+		return;
273
+	}
274
+
275
+
276
+	/**
277
+	 *    Given an array of data (usually from a CSV import) attempts to save that data to the db.
278
+	 *    If $model_name ISN'T provided, assumes that this is a 3d array, with toplevel keys being model names,
279
+	 *    next level being numeric indexes adn each value representing a model object, and the last layer down
280
+	 *    being keys of model fields and their proposed values.
281
+	 *    If $model_name IS provided, assumes a 2d array of the bottom two layers previously mentioned.
282
+	 *    If the CSV data says (in the metadata row) that it's from the SAME database,
283
+	 *    we treat the IDs in the CSV as the normal IDs, and try to update those records. However, if those
284
+	 *    IDs DON'T exist in the database, they're treated as temporary IDs,
285
+	 *    which can used elsewhere to refer to the same object. Once an item
286
+	 *    with a temporary ID gets inserted, we record its mapping from temporary
287
+	 *    ID to real ID, and use the real ID in place of the temporary ID
288
+	 *    when that temporary ID was used as a foreign key.
289
+	 *    If the CSV data says (in the metadata again) that it's from a DIFFERENT database,
290
+	 *    we treat all the IDs in the CSV as temporary ID- eg, if the CSV specifies an event with
291
+	 *    ID 1, and the database already has an event with ID 1, we assume that's just a coincidence,
292
+	 *    and insert a new event, and map it's temporary ID of 1 over to its new real ID.
293
+	 *    An important exception are non-auto-increment primary keys. If one entry in the
294
+	 *    CSV file has the same ID as one in the DB, we assume they are meant to be
295
+	 *    the same item, and instead update the item in the DB with that same ID.
296
+	 *    Also note, we remember the mappings permanently. So the 2nd, 3rd, and 10000th
297
+	 *    time you import a CSV from a different site, we remember their mappings, and
298
+	 * will try to update the item in the DB instead of inserting another item (eg
299
+	 * if we previously imported an event with temporary ID 1, and then it got a
300
+	 * real ID of 123, we remember that. So the next time we import an event with
301
+	 * temporary ID, from the same site, we know that it's real ID is 123, and will
302
+	 * update that event, instead of adding a new event).
303
+	 *
304
+	 * @access public
305
+	 * @param array $csv_data_array - the array containing the csv data produced from
306
+	 *                              EE_CSV::import_csv_to_model_data_array()
307
+	 * @param array $fields_to_save - an array containing the csv column names as keys with the corresponding db table
308
+	 *                              fields they will be saved to
309
+	 * @return TRUE on success, FALSE on fail
310
+	 * @throws \EE_Error
311
+	 */
312
+	public function save_csv_data_array_to_db($csv_data_array, $model_name = false)
313
+	{
314
+		$success = false;
315
+		$error = false;
316
+		// whther to treat this import as if it's data froma different database or not
317
+		// ie, if it IS from a different database, ignore foreign keys whihf
318
+		$export_from_site_a_to_b = true;
319
+		// first level of array is not table information but a table name was passed to the function
320
+		// array is only two levels deep, so let's fix that by adding a level, else the next steps will fail
321
+		if ($model_name) {
322
+			$csv_data_array = array($csv_data_array);
323
+		}
324
+		// begin looking through the $csv_data_array, expecting the toplevel key to be the model's name...
325
+		$old_site_url = 'none-specified';
326
+		// hanlde metadata
327
+		if (isset($csv_data_array[ EE_CSV::metadata_header ])) {
328
+			$csv_metadata = array_shift($csv_data_array[ EE_CSV::metadata_header ]);
329
+			// ok so its metadata, dont try to save it to ehte db obviously...
330
+			if (isset($csv_metadata['site_url']) && $csv_metadata['site_url'] == site_url()) {
331
+				EE_Error::add_attention(
332
+					sprintf(
333
+						__(
334
+							"CSV Data appears to be from the same database, so attempting to update data",
335
+							"event_espresso"
336
+						)
337
+					)
338
+				);
339
+				$export_from_site_a_to_b = false;
340
+			} else {
341
+				$old_site_url = isset($csv_metadata['site_url']) ? $csv_metadata['site_url'] : $old_site_url;
342
+				EE_Error::add_attention(
343
+					sprintf(
344
+						__(
345
+							"CSV Data appears to be from a different database (%s instead of %s), so we assume IDs in the CSV data DO NOT correspond to IDs in this database",
346
+							"event_espresso"
347
+						),
348
+						$old_site_url,
349
+						site_url()
350
+					)
351
+				);
352
+			};
353
+			unset($csv_data_array[ EE_CSV::metadata_header ]);
354
+		}
355
+		/**
356
+		 * @var $old_db_to_new_db_mapping 2d array: toplevel keys being model names, bottom-level keys being the original key, and
357
+		 * the value will be the newly-inserted ID.
358
+		 * If we have already imported data from the same website via CSV, it shoudl be kept in this wp option
359
+		 */
360
+		$old_db_to_new_db_mapping = get_option('ee_id_mapping_from' . sanitize_title($old_site_url), array());
361
+		if ($old_db_to_new_db_mapping) {
362
+			EE_Error::add_attention(
363
+				sprintf(
364
+					__(
365
+						"We noticed you have imported data via CSV from %s before. Because of this, IDs in your CSV have been mapped to their new IDs in %s",
366
+						"event_espresso"
367
+					),
368
+					$old_site_url,
369
+					site_url()
370
+				)
371
+			);
372
+		}
373
+		$old_db_to_new_db_mapping = $this->save_data_rows_to_db(
374
+			$csv_data_array,
375
+			$export_from_site_a_to_b,
376
+			$old_db_to_new_db_mapping
377
+		);
378
+
379
+		// save the mapping from old db to new db in case they try re-importing the same data from the same website again
380
+		update_option('ee_id_mapping_from' . sanitize_title($old_site_url), $old_db_to_new_db_mapping);
381
+
382
+		if ($this->_total_updates > 0) {
383
+			EE_Error::add_success(
384
+				sprintf(
385
+					__("%s existing records in the database were updated.", "event_espresso"),
386
+					$this->_total_updates
387
+				)
388
+			);
389
+			$success = true;
390
+		}
391
+		if ($this->_total_inserts > 0) {
392
+			EE_Error::add_success(
393
+				sprintf(__("%s new records were added to the database.", "event_espresso"), $this->_total_inserts)
394
+			);
395
+			$success = true;
396
+		}
397
+
398
+		if ($this->_total_update_errors > 0) {
399
+			EE_Error::add_error(
400
+				sprintf(
401
+					__(
402
+						"'One or more errors occurred, and a total of %s existing records in the database were <strong>not</strong> updated.'",
403
+						"event_espresso"
404
+					),
405
+					$this->_total_update_errors
406
+				),
407
+				__FILE__,
408
+				__FUNCTION__,
409
+				__LINE__
410
+			);
411
+			$error = true;
412
+		}
413
+		if ($this->_total_insert_errors > 0) {
414
+			EE_Error::add_error(
415
+				sprintf(
416
+					__(
417
+						"One or more errors occurred, and a total of %s new records were <strong>not</strong> added to the database.'",
418
+						"event_espresso"
419
+					),
420
+					$this->_total_insert_errors
421
+				),
422
+				__FILE__,
423
+				__FUNCTION__,
424
+				__LINE__
425
+			);
426
+			$error = true;
427
+		}
428
+
429
+		// lastly, we need to update the datetime and ticket sold amounts
430
+		// as those may have been affected by this
431
+		EEM_Ticket::instance()->update_tickets_sold(EEM_Ticket::instance()->get_all());
432
+
433
+		// if there was at least one success and absolutely no errors
434
+		if ($success && ! $error) {
435
+			return true;
436
+		} else {
437
+			return false;
438
+		}
439
+	}
440
+
441
+
442
+	/**
443
+	 * Processes the array of data, given the knowledge that it's from the same database or a different one,
444
+	 * and the mapping from temporary IDs to real IDs.
445
+	 * If the data is from a different database, we treat the primary keys and their corresponding
446
+	 * foreign keys as "temp Ids", basically identifiers that get mapped to real primary keys
447
+	 * in the real target database. As items are inserted, their temporary primary keys
448
+	 * are mapped to the real IDs in the target database. Also, before doing any update or
449
+	 * insert, we replace all the temp ID which are foreign keys with their mapped real IDs.
450
+	 * An exception: string primary keys are treated as real IDs, or else we'd need to
451
+	 * dynamically generate new string primary keys which would be very awkard for the country table etc.
452
+	 * Also, models with no primary key are strange too. We combine use their primar key INDEX (a
453
+	 * combination of fields) to create a unique string identifying the row and store
454
+	 * those in the mapping.
455
+	 *
456
+	 * If the data is from the same database, we usually treat primary keys as real IDs.
457
+	 * An exception is if there is nothing in the database for that ID. If that's the case,
458
+	 * we need to insert a new row for that ID, and then map from the non-existent ID
459
+	 * to the newly-inserted real ID.
460
+	 *
461
+	 * @param type $csv_data_array
462
+	 * @param type $export_from_site_a_to_b
463
+	 * @param type $old_db_to_new_db_mapping
464
+	 * @return array updated $old_db_to_new_db_mapping
465
+	 */
466
+	public function save_data_rows_to_db($csv_data_array, $export_from_site_a_to_b, $old_db_to_new_db_mapping)
467
+	{
468
+		foreach ($csv_data_array as $model_name_in_csv_data => $model_data_from_import) {
469
+			// now check that assumption was correct. If
470
+			if (EE_Registry::instance()->is_model_name($model_name_in_csv_data)) {
471
+				$model_name = $model_name_in_csv_data;
472
+			} else {
473
+				// no table info in the array and no table name passed to the function?? FAIL
474
+				EE_Error::add_error(
475
+					__(
476
+						'No table information was specified and/or found, therefore the import could not be completed',
477
+						'event_espresso'
478
+					),
479
+					__FILE__,
480
+					__FUNCTION__,
481
+					__LINE__
482
+				);
483
+				return false;
484
+			}
485
+			/* @var $model EEM_Base */
486
+			$model = EE_Registry::instance()->load_model($model_name);
487
+
488
+			// so without further ado, scanning all the data provided for primary keys and their inital values
489
+			foreach ($model_data_from_import as $model_object_data) {
490
+				// before we do ANYTHING, make sure the csv row wasn't just completely blank
491
+				$row_is_completely_empty = true;
492
+				foreach ($model_object_data as $field) {
493
+					if ($field) {
494
+						$row_is_completely_empty = false;
495
+					}
496
+				}
497
+				if ($row_is_completely_empty) {
498
+					continue;
499
+				}
500
+				// find the PK in the row of data (or a combined key if
501
+				// there is no primary key)
502
+				if ($model->has_primary_key_field()) {
503
+					$id_in_csv = $model_object_data[ $model->primary_key_name() ];
504
+				} else {
505
+					$id_in_csv = $model->get_index_primary_key_string($model_object_data);
506
+				}
507
+
508
+
509
+				$model_object_data = $this->_replace_temp_ids_with_mappings(
510
+					$model_object_data,
511
+					$model,
512
+					$old_db_to_new_db_mapping,
513
+					$export_from_site_a_to_b
514
+				);
515
+				// now we need to decide if we're going to add a new model object given the $model_object_data,
516
+				// or just update.
517
+				if ($export_from_site_a_to_b) {
518
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_other_db(
519
+						$id_in_csv,
520
+						$model_object_data,
521
+						$model,
522
+						$old_db_to_new_db_mapping
523
+					);
524
+				} else {// this is just a re-import
525
+					$what_to_do = $this->_decide_whether_to_insert_or_update_given_data_from_same_db(
526
+						$id_in_csv,
527
+						$model_object_data,
528
+						$model,
529
+						$old_db_to_new_db_mapping
530
+					);
531
+				}
532
+				if ($what_to_do == self::do_nothing) {
533
+					continue;
534
+				}
535
+
536
+				// double-check we actually want to insert, if that's what we're planning
537
+				// based on whether this item would be unique in the DB or not
538
+				if ($what_to_do == self::do_insert) {
539
+					// we're supposed to be inserting. But wait, will this thing
540
+					// be acceptable if inserted?
541
+					$conflicting = $model->get_one_conflicting($model_object_data, false);
542
+					if ($conflicting) {
543
+						// ok, this item would conflict if inserted. Just update the item that it conflicts with.
544
+						$what_to_do = self::do_update;
545
+						// and if this model has a primary key, remember its mapping
546
+						if ($model->has_primary_key_field()) {
547
+							$old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ] = $conflicting->ID();
548
+							$model_object_data[ $model->primary_key_name() ] = $conflicting->ID();
549
+						} else {
550
+							// we want to update this conflicting item, instead of inserting a conflicting item
551
+							// so we need to make sure they match entirely (its possible that they only conflicted on one field, but we need them to match on other fields
552
+							// for the WHERE conditions in the update). At the time of this comment, there were no models like this
553
+							foreach ($model->get_combined_primary_key_fields() as $key_field) {
554
+								$model_object_data[ $key_field->get_name() ] = $conflicting->get(
555
+									$key_field->get_name()
556
+								);
557
+							}
558
+						}
559
+					}
560
+				}
561
+				if ($what_to_do == self::do_insert) {
562
+					$old_db_to_new_db_mapping = $this->_insert_from_data_array(
563
+						$id_in_csv,
564
+						$model_object_data,
565
+						$model,
566
+						$old_db_to_new_db_mapping
567
+					);
568
+				} elseif ($what_to_do == self::do_update) {
569
+					$old_db_to_new_db_mapping = $this->_update_from_data_array(
570
+						$id_in_csv,
571
+						$model_object_data,
572
+						$model,
573
+						$old_db_to_new_db_mapping
574
+					);
575
+				} else {
576
+					throw new EE_Error(
577
+						sprintf(
578
+							__(
579
+								'Programming error. We shoudl be inserting or updating, but instead we are being told to "%s", whifh is invalid',
580
+								'event_espresso'
581
+							),
582
+							$what_to_do
583
+						)
584
+					);
585
+				}
586
+			}
587
+		}
588
+		return $old_db_to_new_db_mapping;
589
+	}
590
+
591
+
592
+	/**
593
+	 * Decides whether or not to insert, given that this data is from another database.
594
+	 * So, if the primary key of this $model_object_data already exists in the database,
595
+	 * it's just a coincidence and we should still insert. The only time we should
596
+	 * update is when we know what it maps to, or there's something that would
597
+	 * conflict (and we should instead just update that conflicting thing)
598
+	 *
599
+	 * @param string   $id_in_csv
600
+	 * @param array    $model_object_data        by reference so it can be modified
601
+	 * @param EEM_Base $model
602
+	 * @param array    $old_db_to_new_db_mapping by reference so it can be modified
603
+	 * @return string one of the consts on this class that starts with do_*
604
+	 */
605
+	protected function _decide_whether_to_insert_or_update_given_data_from_other_db(
606
+		$id_in_csv,
607
+		$model_object_data,
608
+		$model,
609
+		$old_db_to_new_db_mapping
610
+	) {
611
+		$model_name = $model->get_this_model_name();
612
+		// if it's a site-to-site export-and-import, see if this modelobject's id
613
+		// in the old data that we know of
614
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $id_in_csv ])) {
615
+			return self::do_update;
616
+		} else {
617
+			return self::do_insert;
618
+		}
619
+	}
620
+
621
+	/**
622
+	 * If this thing basically already exists in the database, we want to update it;
623
+	 * otherwise insert it (ie, someone tweaked the CSV file, or the item was
624
+	 * deleted in the database so it should be re-inserted)
625
+	 *
626
+	 * @param type     $id_in_csv
627
+	 * @param type     $model_object_data
628
+	 * @param EEM_Base $model
629
+	 * @param type     $old_db_to_new_db_mapping
630
+	 * @return
631
+	 */
632
+	protected function _decide_whether_to_insert_or_update_given_data_from_same_db(
633
+		$id_in_csv,
634
+		$model_object_data,
635
+		$model
636
+	) {
637
+		// in this case, check if this thing ACTUALLY exists in the database
638
+		if ($model->get_one_conflicting($model_object_data)) {
639
+			return self::do_update;
640
+		} else {
641
+			return self::do_insert;
642
+		}
643
+	}
644
+
645
+	/**
646
+	 * Using the $old_db_to_new_db_mapping array, replaces all the temporary IDs
647
+	 * with their mapped real IDs. Eg, if importing from site A to B, the mapping
648
+	 * file may indicate that the ID "my_event_id" maps to an actual event ID of 123.
649
+	 * So this function searches for any event temp Ids called "my_event_id" and
650
+	 * replaces them with 123.
651
+	 * Also, if there is no temp ID for the INT foreign keys from another database,
652
+	 * replaces them with 0 or the field's default.
653
+	 *
654
+	 * @param type     $model_object_data
655
+	 * @param EEM_Base $model
656
+	 * @param type     $old_db_to_new_db_mapping
657
+	 * @param boolean  $export_from_site_a_to_b
658
+	 * @return array updated model object data with temp IDs removed
659
+	 */
660
+	protected function _replace_temp_ids_with_mappings(
661
+		$model_object_data,
662
+		$model,
663
+		$old_db_to_new_db_mapping,
664
+		$export_from_site_a_to_b
665
+	) {
666
+		// if this model object's primary key is in the mapping, replace it
667
+		if (
668
+			$model->has_primary_key_field() &&
669
+			$model->get_primary_key_field()->is_auto_increment() &&
670
+			isset($old_db_to_new_db_mapping[ $model->get_this_model_name() ]) &&
671
+			isset(
672
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $model_object_data[ $model->primary_key_name() ] ]
673
+			)
674
+		) {
675
+			$model_object_data[ $model->primary_key_name() ] = $old_db_to_new_db_mapping[ $model->get_this_model_name(
676
+			) ][ $model_object_data[ $model->primary_key_name() ] ];
677
+		}
678
+
679
+		try {
680
+			$model_name_field = $model->get_field_containing_related_model_name();
681
+			$models_pointed_to_by_model_name_field = $model_name_field->get_model_names_pointed_to();
682
+		} catch (EE_Error $e) {
683
+			$model_name_field = null;
684
+			$models_pointed_to_by_model_name_field = array();
685
+		}
686
+		foreach ($model->field_settings(true) as $field_obj) {
687
+			if ($field_obj instanceof EE_Foreign_Key_Int_Field) {
688
+				$models_pointed_to = $field_obj->get_model_names_pointed_to();
689
+				$found_a_mapping = false;
690
+				foreach ($models_pointed_to as $model_pointed_to_by_fk) {
691
+					if ($model_name_field) {
692
+						$value_of_model_name_field = $model_object_data[ $model_name_field->get_name() ];
693
+						if ($value_of_model_name_field == $model_pointed_to_by_fk) {
694
+							$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
695
+								$model_object_data[ $field_obj->get_name() ],
696
+								$model_pointed_to_by_fk,
697
+								$old_db_to_new_db_mapping,
698
+								$export_from_site_a_to_b
699
+							);
700
+							$found_a_mapping = true;
701
+							break;
702
+						}
703
+					} else {
704
+						$model_object_data[ $field_obj->get_name() ] = $this->_find_mapping_in(
705
+							$model_object_data[ $field_obj->get_name() ],
706
+							$model_pointed_to_by_fk,
707
+							$old_db_to_new_db_mapping,
708
+							$export_from_site_a_to_b
709
+						);
710
+						$found_a_mapping = true;
711
+					}
712
+					// once we've found a mapping for this field no need to continue
713
+					if ($found_a_mapping) {
714
+						break;
715
+					}
716
+				}
717
+			} else {
718
+				// it's a string foreign key (which we leave alone, because those are things
719
+				// like country names, which we'd really rather not make 2 USAs etc (we'd actually
720
+				// prefer to just update one)
721
+				// or it's just a regular value that ought to be replaced
722
+			}
723
+		}
724
+		//
725
+		if ($model instanceof EEM_Term_Taxonomy) {
726
+			$model_object_data = $this->_handle_split_term_ids($model_object_data);
727
+		}
728
+		return $model_object_data;
729
+	}
730
+
731
+	/**
732
+	 * If the data was exported PRE-4.2, but then imported POST-4.2, then the term_id
733
+	 * this term-taxonomy refers to may be out-of-date so we need to update it.
734
+	 * see https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/
735
+	 *
736
+	 * @param type $model_object_data
737
+	 * @return array new model object data
738
+	 */
739
+	protected function _handle_split_term_ids($model_object_data)
740
+	{
741
+		if (
742
+			isset($model_object_data['term_id'])
743
+			&& isset($model_object_data['taxonomy'])
744
+			&& apply_filters(
745
+				'FHEE__EE_Import__handle_split_term_ids__function_exists',
746
+				function_exists('wp_get_split_term'),
747
+				$model_object_data
748
+			)
749
+		) {
750
+			$new_term_id = wp_get_split_term($model_object_data['term_id'], $model_object_data['taxonomy']);
751
+			if ($new_term_id) {
752
+				$model_object_data['term_id'] = $new_term_id;
753
+			}
754
+		}
755
+		return $model_object_data;
756
+	}
757
+
758
+	/**
759
+	 * Given the object's ID and its model's name, find it int he mapping data,
760
+	 * bearing in mind where it came from
761
+	 *
762
+	 * @param type   $object_id
763
+	 * @param string $model_name
764
+	 * @param array  $old_db_to_new_db_mapping
765
+	 * @param type   $export_from_site_a_to_b
766
+	 * @return int
767
+	 */
768
+	protected function _find_mapping_in($object_id, $model_name, $old_db_to_new_db_mapping, $export_from_site_a_to_b)
769
+	{
770
+		if (isset($old_db_to_new_db_mapping[ $model_name ][ $object_id ])) {
771
+			return $old_db_to_new_db_mapping[ $model_name ][ $object_id ];
772
+		} elseif ($object_id == '0' || $object_id == '') {
773
+			// leave as-is
774
+			return $object_id;
775
+		} elseif ($export_from_site_a_to_b) {
776
+			// we couldn't find a mapping for this, and it's from a different site,
777
+			// so blank it out
778
+			return null;
779
+		} elseif (! $export_from_site_a_to_b) {
780
+			// we coudln't find a mapping for this, but it's from thsi DB anyway
781
+			// so let's just leave it as-is
782
+			return $object_id;
783
+		}
784
+	}
785
+
786
+	/**
787
+	 *
788
+	 * @param type     $id_in_csv
789
+	 * @param type     $model_object_data
790
+	 * @param EEM_Base $model
791
+	 * @param type     $old_db_to_new_db_mapping
792
+	 * @return array updated $old_db_to_new_db_mapping
793
+	 */
794
+	protected function _insert_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
795
+	{
796
+		// remove the primary key, if there is one (we don't want it for inserts OR updates)
797
+		// we'll put it back in if we need it
798
+		if ($model->has_primary_key_field() && $model->get_primary_key_field()->is_auto_increment()) {
799
+			$effective_id = $model_object_data[ $model->primary_key_name() ];
800
+			unset($model_object_data[ $model->primary_key_name() ]);
801
+		} else {
802
+			$effective_id = $model->get_index_primary_key_string($model_object_data);
803
+		}
804
+		// the model takes care of validating the CSV's input
805
+		try {
806
+			$new_id = $model->insert($model_object_data);
807
+			if ($new_id) {
808
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_id;
809
+				$this->_total_inserts++;
810
+				EE_Error::add_success(
811
+					sprintf(
812
+						__("Successfully added new %s (with id %s) with csv data %s", "event_espresso"),
813
+						$model->get_this_model_name(),
814
+						$new_id,
815
+						implode(",", $model_object_data)
816
+					)
817
+				);
818
+			} else {
819
+				$this->_total_insert_errors++;
820
+				// put the ID used back in there for the error message
821
+				if ($model->has_primary_key_field()) {
822
+					$model_object_data[ $model->primary_key_name() ] = $effective_id;
823
+				}
824
+				EE_Error::add_error(
825
+					sprintf(
826
+						__("Could not insert new %s with the csv data: %s", "event_espresso"),
827
+						$model->get_this_model_name(),
828
+						http_build_query($model_object_data)
829
+					),
830
+					__FILE__,
831
+					__FUNCTION__,
832
+					__LINE__
833
+				);
834
+			}
835
+		} catch (EE_Error $e) {
836
+			$this->_total_insert_errors++;
837
+			if ($model->has_primary_key_field()) {
838
+				$model_object_data[ $model->primary_key_name() ] = $effective_id;
839
+			}
840
+			EE_Error::add_error(
841
+				sprintf(
842
+					__("Could not insert new %s with the csv data: %s because %s", "event_espresso"),
843
+					$model->get_this_model_name(),
844
+					implode(",", $model_object_data),
845
+					$e->getMessage()
846
+				),
847
+				__FILE__,
848
+				__FUNCTION__,
849
+				__LINE__
850
+			);
851
+		}
852
+		return $old_db_to_new_db_mapping;
853
+	}
854
+
855
+	/**
856
+	 * Given the model object data, finds the row to update and updates it
857
+	 *
858
+	 * @param string|int $id_in_csv
859
+	 * @param array      $model_object_data
860
+	 * @param EEM_Base   $model
861
+	 * @param array      $old_db_to_new_db_mapping
862
+	 * @return array updated $old_db_to_new_db_mapping
863
+	 */
864
+	protected function _update_from_data_array($id_in_csv, $model_object_data, $model, $old_db_to_new_db_mapping)
865
+	{
866
+		try {
867
+			// let's keep two copies of the model object data:
868
+			// one for performing an update, one for everthing else
869
+			$model_object_data_for_update = $model_object_data;
870
+			if ($model->has_primary_key_field()) {
871
+				$conditions = array($model->primary_key_name() => $model_object_data[ $model->primary_key_name() ]);
872
+				// remove the primary key because we shouldn't use it for updating
873
+				unset($model_object_data_for_update[ $model->primary_key_name() ]);
874
+			} elseif ($model->get_combined_primary_key_fields() > 1) {
875
+				$conditions = array();
876
+				foreach ($model->get_combined_primary_key_fields() as $key_field) {
877
+					$conditions[ $key_field->get_name() ] = $model_object_data[ $key_field->get_name() ];
878
+				}
879
+			} else {
880
+				$model->primary_key_name(
881
+				);// this shoudl just throw an exception, explaining that we dont have a primary key (or a combine dkey)
882
+			}
883
+
884
+			$success = $model->update($model_object_data_for_update, array($conditions));
885
+			if ($success) {
886
+				$this->_total_updates++;
887
+				EE_Error::add_success(
888
+					sprintf(
889
+						__("Successfully updated %s with csv data %s", "event_espresso"),
890
+						$model->get_this_model_name(),
891
+						implode(",", $model_object_data_for_update)
892
+					)
893
+				);
894
+				// we should still record the mapping even though it was an update
895
+				// because if we were going to insert somethign but it was going to conflict
896
+				// we would have last-minute decided to update. So we'd like to know what we updated
897
+				// and so we record what record ended up being updated using the mapping
898
+				if ($model->has_primary_key_field()) {
899
+					$new_key_for_mapping = $model_object_data[ $model->primary_key_name() ];
900
+				} else {
901
+					// no primary key just a combined key
902
+					$new_key_for_mapping = $model->get_index_primary_key_string($model_object_data);
903
+				}
904
+				$old_db_to_new_db_mapping[ $model->get_this_model_name() ][ $id_in_csv ] = $new_key_for_mapping;
905
+			} else {
906
+				$matched_items = $model->get_all(array($conditions));
907
+				if (! $matched_items) {
908
+					// no items were matched (so we shouldn't have updated)... but then we should have inserted? what the heck?
909
+					$this->_total_update_errors++;
910
+					EE_Error::add_error(
911
+						sprintf(
912
+							__(
913
+								"Could not update %s with the csv data: '%s' for an unknown reason (using WHERE conditions %s)",
914
+								"event_espresso"
915
+							),
916
+							$model->get_this_model_name(),
917
+							http_build_query($model_object_data),
918
+							http_build_query($conditions)
919
+						),
920
+						__FILE__,
921
+						__FUNCTION__,
922
+						__LINE__
923
+					);
924
+				} else {
925
+					$this->_total_updates++;
926
+					EE_Error::add_success(
927
+						sprintf(
928
+							__(
929
+								"%s with csv data '%s' was found in the database and didn't need updating because all the data is identical.",
930
+								"event_espresso"
931
+							),
932
+							$model->get_this_model_name(),
933
+							implode(",", $model_object_data)
934
+						)
935
+					);
936
+				}
937
+			}
938
+		} catch (EE_Error $e) {
939
+			$this->_total_update_errors++;
940
+			$basic_message = sprintf(
941
+				__("Could not update %s with the csv data: %s because %s", "event_espresso"),
942
+				$model->get_this_model_name(),
943
+				implode(",", $model_object_data),
944
+				$e->getMessage()
945
+			);
946
+			$debug_message = $basic_message . ' Stack trace: ' . $e->getTraceAsString();
947
+			EE_Error::add_error("$basic_message | $debug_message", __FILE__, __FUNCTION__, __LINE__);
948
+		}
949
+		return $old_db_to_new_db_mapping;
950
+	}
951
+
952
+	/**
953
+	 * Gets the number of inserts performed since importer was instantiated or reset
954
+	 *
955
+	 * @return int
956
+	 */
957
+	public function get_total_inserts()
958
+	{
959
+		return $this->_total_inserts;
960
+	}
961
+
962
+	/**
963
+	 *  Gets the number of insert errors since importer was instantiated or reset
964
+	 *
965
+	 * @return int
966
+	 */
967
+	public function get_total_insert_errors()
968
+	{
969
+		return $this->_total_insert_errors;
970
+	}
971
+
972
+	/**
973
+	 *  Gets the number of updates performed since importer was instantiated or reset
974
+	 *
975
+	 * @return int
976
+	 */
977
+	public function get_total_updates()
978
+	{
979
+		return $this->_total_updates;
980
+	}
981
+
982
+	/**
983
+	 *  Gets the number of update errors since importer was instantiated or reset
984
+	 *
985
+	 * @return int
986
+	 */
987
+	public function get_total_update_errors()
988
+	{
989
+		return $this->_total_update_errors;
990
+	}
991 991
 }
Please login to merge, or discard this patch.