Completed
Branch FET/11174/bot-detection-middle... (80970e)
by
unknown
131:55 queued 120:18
created
admin_pages/maintenance/Maintenance_Admin_Page.core.php 1 patch
Indentation   +827 added lines, -827 removed lines patch added patch discarded remove patch
@@ -29,843 +29,843 @@
 block discarded – undo
29 29
 {
30 30
 
31 31
 
32
-    /**
33
-     * @var EE_Datetime_Offset_Fix_Form
34
-     */
35
-    protected $datetime_fix_offset_form;
36
-
37
-
38
-
39
-    protected function _init_page_props()
40
-    {
41
-        $this->page_slug = EE_MAINTENANCE_PG_SLUG;
42
-        $this->page_label = EE_MAINTENANCE_LABEL;
43
-        $this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL;
44
-        $this->_admin_base_path = EE_MAINTENANCE_ADMIN;
45
-    }
46
-
47
-
48
-
49
-    protected function _ajax_hooks()
50
-    {
51
-        add_action('wp_ajax_migration_step', array($this, 'migration_step'));
52
-        add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran'));
53
-    }
54
-
55
-
56
-
57
-    protected function _define_page_props()
58
-    {
59
-        $this->_admin_page_title = EE_MAINTENANCE_LABEL;
60
-        $this->_labels = array(
61
-            'buttons' => array(
62
-                'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
63
-                'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
64
-            ),
65
-        );
66
-    }
67
-
68
-
69
-
70
-    protected function _set_page_routes()
71
-    {
72
-        $this->_page_routes = array(
73
-            'default'                             => array(
74
-                'func'       => '_maintenance',
75
-                'capability' => 'manage_options',
76
-            ),
77
-            'change_maintenance_level'            => array(
78
-                'func'       => '_change_maintenance_level',
79
-                'capability' => 'manage_options',
80
-                'noheader'   => true,
81
-            ),
82
-            'system_status'                       => array(
83
-                'func'       => '_system_status',
84
-                'capability' => 'manage_options',
85
-            ),
86
-            'download_system_status' => array(
87
-                'func'       => '_download_system_status',
88
-                'capability' => 'manage_options',
89
-                'noheader'   => true,
90
-            ),
91
-            'send_migration_crash_report'         => array(
92
-                'func'       => '_send_migration_crash_report',
93
-                'capability' => 'manage_options',
94
-                'noheader'   => true,
95
-            ),
96
-            'confirm_migration_crash_report_sent' => array(
97
-                'func'       => '_confirm_migration_crash_report_sent',
98
-                'capability' => 'manage_options',
99
-            ),
100
-            'data_reset'                          => array(
101
-                'func'       => '_data_reset_and_delete',
102
-                'capability' => 'manage_options',
103
-            ),
104
-            'reset_db'                            => array(
105
-                'func'       => '_reset_db',
106
-                'capability' => 'manage_options',
107
-                'noheader'   => true,
108
-                'args'       => array('nuke_old_ee4_data' => true),
109
-            ),
110
-            'start_with_fresh_ee4_db'             => array(
111
-                'func'       => '_reset_db',
112
-                'capability' => 'manage_options',
113
-                'noheader'   => true,
114
-                'args'       => array('nuke_old_ee4_data' => false),
115
-            ),
116
-            'delete_db'                           => array(
117
-                'func'       => '_delete_db',
118
-                'capability' => 'manage_options',
119
-                'noheader'   => true,
120
-            ),
121
-            'rerun_migration_from_ee3'            => array(
122
-                'func'       => '_rerun_migration_from_ee3',
123
-                'capability' => 'manage_options',
124
-                'noheader'   => true,
125
-            ),
126
-            'reset_reservations'                  => array(
127
-                'func'       => '_reset_reservations',
128
-                'capability' => 'manage_options',
129
-                'noheader'   => true,
130
-            ),
131
-            'reset_capabilities'                  => array(
132
-                'func'       => '_reset_capabilities',
133
-                'capability' => 'manage_options',
134
-                'noheader'   => true,
135
-            ),
136
-            'reattempt_migration'                 => array(
137
-                'func'       => '_reattempt_migration',
138
-                'capability' => 'manage_options',
139
-                'noheader'   => true,
140
-            ),
141
-            'datetime_tools' => array(
142
-                'func' => '_datetime_tools',
143
-                'capability' => 'manage_options'
144
-            ),
145
-            'run_datetime_offset_fix' => array(
146
-                'func' => '_apply_datetime_offset',
147
-                'noheader' => true,
148
-                'headers_sent_route' => 'datetime_tools',
149
-                'capability' => 'manage_options'
150
-            )
151
-        );
152
-    }
153
-
154
-
155
-
156
-    protected function _set_page_config()
157
-    {
158
-        $this->_page_config = array(
159
-            'default'       => array(
160
-                'nav'           => array(
161
-                    'label' => esc_html__('Maintenance', 'event_espresso'),
162
-                    'order' => 10,
163
-                ),
164
-                'require_nonce' => false,
165
-            ),
166
-            'data_reset'    => array(
167
-                'nav'           => array(
168
-                    'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
169
-                    'order' => 20,
170
-                ),
171
-                'require_nonce' => false,
172
-            ),
173
-            'datetime_tools' => array(
174
-                'nav' => array(
175
-                    'label' => esc_html__('Datetime Utilities', 'event_espresso'),
176
-                    'order' => 25
177
-                ),
178
-                'require_nonce' => false,
179
-            ),
180
-            'system_status' => array(
181
-                'nav'           => array(
182
-                    'label' => esc_html__("System Information", "event_espresso"),
183
-                    'order' => 30,
184
-                ),
185
-                'require_nonce' => false,
186
-            ),
187
-        );
188
-    }
189
-
190
-
191
-
192
-    /**
193
-     * default maintenance page. If we're in maintenance mode level 2, then we need to show
194
-     * the migration scripts and all that UI.
195
-     */
196
-    public function _maintenance()
197
-    {
198
-        //it all depends if we're in maintenance model level 1 (frontend-only) or
199
-        //level 2 (everything except maintenance page)
200
-        try {
201
-            //get the current maintenance level and check if
202
-            //we are removed
203
-            $mm = EE_Maintenance_Mode::instance()->level();
204
-            $placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
205
-            if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
206
-                //we just took the site out of maintenance mode, so notify the user.
207
-                //unfortunately this message appears to be echoed on the NEXT page load...
208
-                //oh well, we should really be checking for this on addon deactivation anyways
209
-                EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required',
210
-                    'event_espresso'));
211
-                $this->_process_notices(array('page' => 'espresso_maintenance_settings'), false);
212
-            }
213
-            //in case an exception is thrown while trying to handle migrations
214
-            switch (EE_Maintenance_Mode::instance()->level()) {
215
-                case EE_Maintenance_Mode::level_0_not_in_maintenance:
216
-                case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
217
-                    $show_maintenance_switch = true;
218
-                    $show_backup_db_text = false;
219
-                    $show_migration_progress = false;
220
-                    $script_names = array();
221
-                    $addons_should_be_upgraded_first = false;
222
-                    break;
223
-                case EE_Maintenance_Mode::level_2_complete_maintenance:
224
-                    $show_maintenance_switch = false;
225
-                    $show_migration_progress = true;
226
-                    if (isset($this->_req_data['continue_migration'])) {
227
-                        $show_backup_db_text = false;
228
-                    } else {
229
-                        $show_backup_db_text = true;
230
-                    }
231
-                    $scripts_needing_to_run = EE_Data_Migration_Manager::instance()
232
-                                                                       ->check_for_applicable_data_migration_scripts();
233
-                    $addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating();
234
-                    $script_names = array();
235
-                    $current_script = null;
236
-                    foreach ($scripts_needing_to_run as $script) {
237
-                        if ($script instanceof EE_Data_Migration_Script_Base) {
238
-                            if ( ! $current_script) {
239
-                                $current_script = $script;
240
-                                $current_script->migration_page_hooks();
241
-                            }
242
-                            $script_names[] = $script->pretty_name();
243
-                        }
244
-                    }
245
-                    break;
246
-            }
247
-            $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
248
-            $exception_thrown = false;
249
-        } catch (EE_Error $e) {
250
-            EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
251
-            //now, just so we can display the page correctly, make a error migration script stage object
252
-            //and also put the error on it. It only persists for the duration of this request
253
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
254
-            $most_recent_migration->add_error($e->getMessage());
255
-            $exception_thrown = true;
256
-        }
257
-        $current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set();
258
-        $current_db_state = str_replace('.decaf', '', $current_db_state);
259
-        if ($exception_thrown
260
-            || ($most_recent_migration
261
-                && $most_recent_migration instanceof EE_Data_Migration_Script_Base
262
-                && $most_recent_migration->is_broken()
263
-            )
264
-        ) {
265
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
266
-            $this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267
-            $this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268
-                                                                                        'success' => '0',
269
-            ), EE_MAINTENANCE_ADMIN_URL);
270
-        } elseif ($addons_should_be_upgraded_first) {
271
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
272
-        } else {
273
-            if ($most_recent_migration
274
-                && $most_recent_migration instanceof EE_Data_Migration_Script_Base
275
-                && $most_recent_migration->can_continue()
276
-            ) {
277
-                $show_backup_db_text = false;
278
-                $show_continue_current_migration_script = true;
279
-                $show_most_recent_migration = true;
280
-            } elseif (isset($this->_req_data['continue_migration'])) {
281
-                $show_most_recent_migration = true;
282
-                $show_continue_current_migration_script = false;
283
-            } else {
284
-                $show_most_recent_migration = false;
285
-                $show_continue_current_migration_script = false;
286
-            }
287
-            if (isset($current_script)) {
288
-                $migrates_to = $current_script->migrates_to_version();
289
-                $plugin_slug = $migrates_to['slug'];
290
-                $new_version = $migrates_to['version'];
291
-                $this->_template_args = array_merge($this->_template_args, array(
292
-                    'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"),
293
-                        isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug),
294
-                    'next_db_state'    => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'),
295
-                        $new_version, $plugin_slug) : null,
296
-                ));
297
-            } else {
298
-                $this->_template_args['current_db_state'] = null;
299
-                $this->_template_args['next_db_state'] = null;
300
-            }
301
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
302
-            $this->_template_args = array_merge(
303
-                $this->_template_args,
304
-                array(
305
-                    'show_most_recent_migration'             => $show_most_recent_migration,
306
-                    //flag for showing the most recent migration's status and/or errors
307
-                    'show_migration_progress'                => $show_migration_progress,
308
-                    //flag for showing the option to run migrations and see their progress
309
-                    'show_backup_db_text'                    => $show_backup_db_text,
310
-                    //flag for showing text telling the user to backup their DB
311
-                    'show_maintenance_switch'                => $show_maintenance_switch,
312
-                    //flag for showing the option to change maintenance mode between levels 0 and 1
313
-                    'script_names'                           => $script_names,
314
-                    //array of names of scripts that have run
315
-                    'show_continue_current_migration_script' => $show_continue_current_migration_script,
316
-                    //flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
317
-                    'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
318
-                        EE_MAINTENANCE_ADMIN_URL),
319
-                    'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
320
-                        EE_MAINTENANCE_ADMIN_URL),
321
-                    'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'),
322
-                        EE_MAINTENANCE_ADMIN_URL),
323
-                    'ultimate_db_state'                      => sprintf(__("EE%s", 'event_espresso'),
324
-                        espresso_version()),
325
-                )
326
-            );
327
-            //make sure we have the form fields helper available. It usually is, but sometimes it isn't
328
-        }
329
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
330
-        //now render the migration options part, and put it in a variable
331
-        $migration_options_template_file = apply_filters(
332
-            'FHEE__ee_migration_page__migration_options_template',
333
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
334
-        );
335
-        $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
336
-        $this->_template_args['migration_options_html'] = $migration_options_html;
337
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338
-            $this->_template_args, true);
339
-        $this->display_admin_page_with_sidebar();
340
-    }
341
-
342
-
343
-
344
-    /**
345
-     * returns JSON and executes another step of the currently-executing data migration (called via ajax)
346
-     */
347
-    public function migration_step()
348
-    {
349
-        $this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request();
350
-        $this->_return_json();
351
-    }
352
-
353
-
354
-
355
-    /**
356
-     * Can be used by js when it notices a response with HTML in it in order
357
-     * to log the malformed response
358
-     */
359
-    public function add_error_to_migrations_ran()
360
-    {
361
-        EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']);
362
-        $this->_template_args['data'] = array('ok' => true);
363
-        $this->_return_json();
364
-    }
365
-
366
-
367
-
368
-    /**
369
-     * changes the maintenance level, provided there are still no migration scripts that should run
370
-     */
371
-    public function _change_maintenance_level()
372
-    {
373
-        $new_level = absint($this->_req_data['maintenance_mode_level']);
374
-        if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) {
375
-            EE_Maintenance_Mode::instance()->set_maintenance_level($new_level);
376
-            $success = true;
377
-        } else {
378
-            EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
379
-            $success = false;
380
-        }
381
-        $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
382
-    }
383
-
384
-
385
-
386
-    /**
387
-     * a tab with options for resetting and/or deleting EE data
388
-     *
389
-     * @throws \EE_Error
390
-     * @throws \DomainException
391
-     */
392
-    public function _data_reset_and_delete()
393
-    {
394
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
395
-        $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396
-            'reset_reservations',
397
-            'reset_reservations',
398
-            array(),
399
-            'button button-primary ee-confirm',
400
-            '',
401
-            false
402
-        );
403
-        $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
404
-            'reset_capabilities',
405
-            'reset_capabilities',
406
-            array(),
407
-            'button button-primary ee-confirm',
408
-            '',
409
-            false
410
-        );
411
-        $this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
412
-            array('action' => 'delete_db'),
413
-            EE_MAINTENANCE_ADMIN_URL
414
-        );
415
-        $this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
416
-            array('action' => 'reset_db'),
417
-            EE_MAINTENANCE_ADMIN_URL
418
-        );
419
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
420
-            $this->_template_path,
421
-            $this->_template_args,
422
-            true
423
-        );
424
-        $this->display_admin_page_with_sidebar();
425
-    }
426
-
427
-
428
-
429
-    protected function _reset_reservations()
430
-    {
431
-        if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432
-            EE_Error::add_success(
433
-                __(
434
-                    'Ticket and datetime reserved counts have been successfully reset.',
435
-                    'event_espresso'
436
-                )
437
-            );
438
-        } else {
439
-            EE_Error::add_success(
440
-                __(
441
-                    'Ticket and datetime reserved counts were correct and did not need resetting.',
442
-                    'event_espresso'
443
-                )
444
-            );
445
-        }
446
-        $this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true);
447
-    }
448
-
449
-
450
-
451
-    protected function _reset_capabilities()
452
-    {
453
-        EE_Registry::instance()->CAP->init_caps(true);
454
-        EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.',
455
-            'event_espresso'));
456
-        $this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true);
457
-    }
458
-
459
-
460
-
461
-    /**
462
-     * resets the DMSs so we can attempt to continue migrating after a fatal error
463
-     * (only a good idea when someone has somehow tried ot fix whatever caused
464
-     * the fatal error in teh first place)
465
-     */
466
-    protected function _reattempt_migration()
467
-    {
468
-        EE_Data_Migration_Manager::instance()->reattempt();
469
-        $this->_redirect_after_action(false, '', '', array('action' => 'default'), true);
470
-    }
471
-
472
-
473
-
474
-    /**
475
-     * shows the big ol' System Information page
476
-     */
477
-    public function _system_status()
478
-    {
479
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
480
-        $this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481
-        $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482
-            array(
483
-                'action' => 'download_system_status',
484
-            ),
485
-            EE_MAINTENANCE_ADMIN_URL
486
-        );
487
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
488
-            $this->_template_args, true);
489
-        $this->display_admin_page_with_sidebar();
490
-    }
491
-
492
-    /**
493
-     * Downloads an HTML file of the system status that can be easily stored or emailed
494
-     */
495
-    public function _download_system_status()
496
-    {
497
-        $status_info = EEM_System_Status::instance()->get_system_stati();
498
-        header( 'Content-Disposition: attachment' );
499
-        header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
500
-        echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
-        echo "<h1>System Information for " . site_url() . "</h1>";
502
-        echo EEH_Template::layout_array_as_table( $status_info );
503
-        die;
504
-    }
505
-
506
-
507
-
508
-    public function _send_migration_crash_report()
509
-    {
510
-        $from = $this->_req_data['from'];
511
-        $from_name = $this->_req_data['from_name'];
512
-        $body = $this->_req_data['body'];
513
-        try {
514
-            $success = wp_mail(EE_SUPPORT_EMAIL,
515
-                'Migration Crash Report',
516
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
517
-                array(
518
-                    "from:$from_name<$from>",
519
-                    //					'content-type:text/html charset=UTF-8'
520
-                ));
521
-        } catch (Exception $e) {
522
-            $success = false;
523
-        }
524
-        $this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"),
525
-            esc_html__("sent", "event_espresso"),
526
-            array('success' => $success, 'action' => 'confirm_migration_crash_report_sent'));
527
-    }
528
-
529
-
530
-
531
-    public function _confirm_migration_crash_report_sent()
532
-    {
533
-        try {
534
-            $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
535
-        } catch (EE_Error $e) {
536
-            EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
537
-            //now, just so we can display the page correctly, make a error migration script stage object
538
-            //and also put the error on it. It only persists for the duration of this request
539
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
540
-            $most_recent_migration->add_error($e->getMessage());
541
-        }
542
-        $success = $this->_req_data['success'] == '1' ? true : false;
543
-        $this->_template_args['success'] = $success;
544
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;
545
-        $this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
546
-            EE_MAINTENANCE_ADMIN_URL);
547
-        $this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
548
-            EE_MAINTENANCE_ADMIN_URL);
549
-        $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550
-            EE_MAINTENANCE_ADMIN_URL);
551
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
552
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553
-            $this->_template_args, true);
554
-        $this->display_admin_page_with_sidebar();
555
-    }
556
-
557
-
558
-
559
-    /**
560
-     * Resets the entire EE4 database.
561
-     * Currently basically only sets up ee4 database for a fresh install- doesn't
562
-     * actually clean out the old wp options, or cpts (although does erase old ee table data)
563
-     *
564
-     * @param boolean $nuke_old_ee4_data controls whether or not we
565
-     *                                   destroy the old ee4 data, or just try initializing ee4 default data
566
-     */
567
-    public function _reset_db($nuke_old_ee4_data = true)
568
-    {
569
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
570
-        if ($nuke_old_ee4_data) {
571
-            EEH_Activation::delete_all_espresso_cpt_data();
572
-            EEH_Activation::delete_all_espresso_tables_and_data(false);
573
-            EEH_Activation::remove_cron_tasks();
574
-        }
575
-        //make sure when we reset the registry's config that it
576
-        //switches to using the new singleton
577
-        EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
578
-        EE_System::instance()->initialize_db_if_no_migrations_required(true);
579
-        EE_System::instance()->redirect_to_about_ee();
580
-    }
581
-
582
-
583
-
584
-    /**
585
-     * Deletes ALL EE tables, Records, and Options from the database.
586
-     */
587
-    public function _delete_db()
588
-    {
589
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
590
-        EEH_Activation::delete_all_espresso_cpt_data();
591
-        EEH_Activation::delete_all_espresso_tables_and_data();
592
-        EEH_Activation::remove_cron_tasks();
593
-        EEH_Activation::deactivate_event_espresso();
594
-        wp_safe_redirect(admin_url('plugins.php'));
595
-        exit;
596
-    }
597
-
598
-
599
-
600
-    /**
601
-     * sets up EE4 to rerun the migrations from ee3 to ee4
602
-     */
603
-    public function _rerun_migration_from_ee3()
604
-    {
605
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
606
-        EEH_Activation::delete_all_espresso_cpt_data();
607
-        EEH_Activation::delete_all_espresso_tables_and_data(false);
608
-        //set the db state to something that will require migrations
609
-        update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
610
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
611
-        $this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso'));
612
-    }
613
-
614
-
615
-
616
-    //none of the below group are currently used for Gateway Settings
617
-    protected function _add_screen_options()
618
-    {
619
-    }
620
-
621
-
622
-
623
-    protected function _add_feature_pointers()
624
-    {
625
-    }
626
-
32
+	/**
33
+	 * @var EE_Datetime_Offset_Fix_Form
34
+	 */
35
+	protected $datetime_fix_offset_form;
36
+
37
+
38
+
39
+	protected function _init_page_props()
40
+	{
41
+		$this->page_slug = EE_MAINTENANCE_PG_SLUG;
42
+		$this->page_label = EE_MAINTENANCE_LABEL;
43
+		$this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL;
44
+		$this->_admin_base_path = EE_MAINTENANCE_ADMIN;
45
+	}
46
+
47
+
48
+
49
+	protected function _ajax_hooks()
50
+	{
51
+		add_action('wp_ajax_migration_step', array($this, 'migration_step'));
52
+		add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran'));
53
+	}
54
+
55
+
56
+
57
+	protected function _define_page_props()
58
+	{
59
+		$this->_admin_page_title = EE_MAINTENANCE_LABEL;
60
+		$this->_labels = array(
61
+			'buttons' => array(
62
+				'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
63
+				'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
64
+			),
65
+		);
66
+	}
67
+
68
+
69
+
70
+	protected function _set_page_routes()
71
+	{
72
+		$this->_page_routes = array(
73
+			'default'                             => array(
74
+				'func'       => '_maintenance',
75
+				'capability' => 'manage_options',
76
+			),
77
+			'change_maintenance_level'            => array(
78
+				'func'       => '_change_maintenance_level',
79
+				'capability' => 'manage_options',
80
+				'noheader'   => true,
81
+			),
82
+			'system_status'                       => array(
83
+				'func'       => '_system_status',
84
+				'capability' => 'manage_options',
85
+			),
86
+			'download_system_status' => array(
87
+				'func'       => '_download_system_status',
88
+				'capability' => 'manage_options',
89
+				'noheader'   => true,
90
+			),
91
+			'send_migration_crash_report'         => array(
92
+				'func'       => '_send_migration_crash_report',
93
+				'capability' => 'manage_options',
94
+				'noheader'   => true,
95
+			),
96
+			'confirm_migration_crash_report_sent' => array(
97
+				'func'       => '_confirm_migration_crash_report_sent',
98
+				'capability' => 'manage_options',
99
+			),
100
+			'data_reset'                          => array(
101
+				'func'       => '_data_reset_and_delete',
102
+				'capability' => 'manage_options',
103
+			),
104
+			'reset_db'                            => array(
105
+				'func'       => '_reset_db',
106
+				'capability' => 'manage_options',
107
+				'noheader'   => true,
108
+				'args'       => array('nuke_old_ee4_data' => true),
109
+			),
110
+			'start_with_fresh_ee4_db'             => array(
111
+				'func'       => '_reset_db',
112
+				'capability' => 'manage_options',
113
+				'noheader'   => true,
114
+				'args'       => array('nuke_old_ee4_data' => false),
115
+			),
116
+			'delete_db'                           => array(
117
+				'func'       => '_delete_db',
118
+				'capability' => 'manage_options',
119
+				'noheader'   => true,
120
+			),
121
+			'rerun_migration_from_ee3'            => array(
122
+				'func'       => '_rerun_migration_from_ee3',
123
+				'capability' => 'manage_options',
124
+				'noheader'   => true,
125
+			),
126
+			'reset_reservations'                  => array(
127
+				'func'       => '_reset_reservations',
128
+				'capability' => 'manage_options',
129
+				'noheader'   => true,
130
+			),
131
+			'reset_capabilities'                  => array(
132
+				'func'       => '_reset_capabilities',
133
+				'capability' => 'manage_options',
134
+				'noheader'   => true,
135
+			),
136
+			'reattempt_migration'                 => array(
137
+				'func'       => '_reattempt_migration',
138
+				'capability' => 'manage_options',
139
+				'noheader'   => true,
140
+			),
141
+			'datetime_tools' => array(
142
+				'func' => '_datetime_tools',
143
+				'capability' => 'manage_options'
144
+			),
145
+			'run_datetime_offset_fix' => array(
146
+				'func' => '_apply_datetime_offset',
147
+				'noheader' => true,
148
+				'headers_sent_route' => 'datetime_tools',
149
+				'capability' => 'manage_options'
150
+			)
151
+		);
152
+	}
153
+
154
+
155
+
156
+	protected function _set_page_config()
157
+	{
158
+		$this->_page_config = array(
159
+			'default'       => array(
160
+				'nav'           => array(
161
+					'label' => esc_html__('Maintenance', 'event_espresso'),
162
+					'order' => 10,
163
+				),
164
+				'require_nonce' => false,
165
+			),
166
+			'data_reset'    => array(
167
+				'nav'           => array(
168
+					'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
169
+					'order' => 20,
170
+				),
171
+				'require_nonce' => false,
172
+			),
173
+			'datetime_tools' => array(
174
+				'nav' => array(
175
+					'label' => esc_html__('Datetime Utilities', 'event_espresso'),
176
+					'order' => 25
177
+				),
178
+				'require_nonce' => false,
179
+			),
180
+			'system_status' => array(
181
+				'nav'           => array(
182
+					'label' => esc_html__("System Information", "event_espresso"),
183
+					'order' => 30,
184
+				),
185
+				'require_nonce' => false,
186
+			),
187
+		);
188
+	}
189
+
190
+
191
+
192
+	/**
193
+	 * default maintenance page. If we're in maintenance mode level 2, then we need to show
194
+	 * the migration scripts and all that UI.
195
+	 */
196
+	public function _maintenance()
197
+	{
198
+		//it all depends if we're in maintenance model level 1 (frontend-only) or
199
+		//level 2 (everything except maintenance page)
200
+		try {
201
+			//get the current maintenance level and check if
202
+			//we are removed
203
+			$mm = EE_Maintenance_Mode::instance()->level();
204
+			$placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
205
+			if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
206
+				//we just took the site out of maintenance mode, so notify the user.
207
+				//unfortunately this message appears to be echoed on the NEXT page load...
208
+				//oh well, we should really be checking for this on addon deactivation anyways
209
+				EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required',
210
+					'event_espresso'));
211
+				$this->_process_notices(array('page' => 'espresso_maintenance_settings'), false);
212
+			}
213
+			//in case an exception is thrown while trying to handle migrations
214
+			switch (EE_Maintenance_Mode::instance()->level()) {
215
+				case EE_Maintenance_Mode::level_0_not_in_maintenance:
216
+				case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
217
+					$show_maintenance_switch = true;
218
+					$show_backup_db_text = false;
219
+					$show_migration_progress = false;
220
+					$script_names = array();
221
+					$addons_should_be_upgraded_first = false;
222
+					break;
223
+				case EE_Maintenance_Mode::level_2_complete_maintenance:
224
+					$show_maintenance_switch = false;
225
+					$show_migration_progress = true;
226
+					if (isset($this->_req_data['continue_migration'])) {
227
+						$show_backup_db_text = false;
228
+					} else {
229
+						$show_backup_db_text = true;
230
+					}
231
+					$scripts_needing_to_run = EE_Data_Migration_Manager::instance()
232
+																	   ->check_for_applicable_data_migration_scripts();
233
+					$addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating();
234
+					$script_names = array();
235
+					$current_script = null;
236
+					foreach ($scripts_needing_to_run as $script) {
237
+						if ($script instanceof EE_Data_Migration_Script_Base) {
238
+							if ( ! $current_script) {
239
+								$current_script = $script;
240
+								$current_script->migration_page_hooks();
241
+							}
242
+							$script_names[] = $script->pretty_name();
243
+						}
244
+					}
245
+					break;
246
+			}
247
+			$most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
248
+			$exception_thrown = false;
249
+		} catch (EE_Error $e) {
250
+			EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
251
+			//now, just so we can display the page correctly, make a error migration script stage object
252
+			//and also put the error on it. It only persists for the duration of this request
253
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
254
+			$most_recent_migration->add_error($e->getMessage());
255
+			$exception_thrown = true;
256
+		}
257
+		$current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set();
258
+		$current_db_state = str_replace('.decaf', '', $current_db_state);
259
+		if ($exception_thrown
260
+			|| ($most_recent_migration
261
+				&& $most_recent_migration instanceof EE_Data_Migration_Script_Base
262
+				&& $most_recent_migration->is_broken()
263
+			)
264
+		) {
265
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
266
+			$this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267
+			$this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268
+																						'success' => '0',
269
+			), EE_MAINTENANCE_ADMIN_URL);
270
+		} elseif ($addons_should_be_upgraded_first) {
271
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
272
+		} else {
273
+			if ($most_recent_migration
274
+				&& $most_recent_migration instanceof EE_Data_Migration_Script_Base
275
+				&& $most_recent_migration->can_continue()
276
+			) {
277
+				$show_backup_db_text = false;
278
+				$show_continue_current_migration_script = true;
279
+				$show_most_recent_migration = true;
280
+			} elseif (isset($this->_req_data['continue_migration'])) {
281
+				$show_most_recent_migration = true;
282
+				$show_continue_current_migration_script = false;
283
+			} else {
284
+				$show_most_recent_migration = false;
285
+				$show_continue_current_migration_script = false;
286
+			}
287
+			if (isset($current_script)) {
288
+				$migrates_to = $current_script->migrates_to_version();
289
+				$plugin_slug = $migrates_to['slug'];
290
+				$new_version = $migrates_to['version'];
291
+				$this->_template_args = array_merge($this->_template_args, array(
292
+					'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"),
293
+						isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug),
294
+					'next_db_state'    => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'),
295
+						$new_version, $plugin_slug) : null,
296
+				));
297
+			} else {
298
+				$this->_template_args['current_db_state'] = null;
299
+				$this->_template_args['next_db_state'] = null;
300
+			}
301
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
302
+			$this->_template_args = array_merge(
303
+				$this->_template_args,
304
+				array(
305
+					'show_most_recent_migration'             => $show_most_recent_migration,
306
+					//flag for showing the most recent migration's status and/or errors
307
+					'show_migration_progress'                => $show_migration_progress,
308
+					//flag for showing the option to run migrations and see their progress
309
+					'show_backup_db_text'                    => $show_backup_db_text,
310
+					//flag for showing text telling the user to backup their DB
311
+					'show_maintenance_switch'                => $show_maintenance_switch,
312
+					//flag for showing the option to change maintenance mode between levels 0 and 1
313
+					'script_names'                           => $script_names,
314
+					//array of names of scripts that have run
315
+					'show_continue_current_migration_script' => $show_continue_current_migration_script,
316
+					//flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
317
+					'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
318
+						EE_MAINTENANCE_ADMIN_URL),
319
+					'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
320
+						EE_MAINTENANCE_ADMIN_URL),
321
+					'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'),
322
+						EE_MAINTENANCE_ADMIN_URL),
323
+					'ultimate_db_state'                      => sprintf(__("EE%s", 'event_espresso'),
324
+						espresso_version()),
325
+				)
326
+			);
327
+			//make sure we have the form fields helper available. It usually is, but sometimes it isn't
328
+		}
329
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
330
+		//now render the migration options part, and put it in a variable
331
+		$migration_options_template_file = apply_filters(
332
+			'FHEE__ee_migration_page__migration_options_template',
333
+			EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
334
+		);
335
+		$migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
336
+		$this->_template_args['migration_options_html'] = $migration_options_html;
337
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338
+			$this->_template_args, true);
339
+		$this->display_admin_page_with_sidebar();
340
+	}
341
+
342
+
343
+
344
+	/**
345
+	 * returns JSON and executes another step of the currently-executing data migration (called via ajax)
346
+	 */
347
+	public function migration_step()
348
+	{
349
+		$this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request();
350
+		$this->_return_json();
351
+	}
352
+
353
+
354
+
355
+	/**
356
+	 * Can be used by js when it notices a response with HTML in it in order
357
+	 * to log the malformed response
358
+	 */
359
+	public function add_error_to_migrations_ran()
360
+	{
361
+		EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']);
362
+		$this->_template_args['data'] = array('ok' => true);
363
+		$this->_return_json();
364
+	}
365
+
366
+
367
+
368
+	/**
369
+	 * changes the maintenance level, provided there are still no migration scripts that should run
370
+	 */
371
+	public function _change_maintenance_level()
372
+	{
373
+		$new_level = absint($this->_req_data['maintenance_mode_level']);
374
+		if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) {
375
+			EE_Maintenance_Mode::instance()->set_maintenance_level($new_level);
376
+			$success = true;
377
+		} else {
378
+			EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
379
+			$success = false;
380
+		}
381
+		$this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
382
+	}
383
+
384
+
385
+
386
+	/**
387
+	 * a tab with options for resetting and/or deleting EE data
388
+	 *
389
+	 * @throws \EE_Error
390
+	 * @throws \DomainException
391
+	 */
392
+	public function _data_reset_and_delete()
393
+	{
394
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
395
+		$this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396
+			'reset_reservations',
397
+			'reset_reservations',
398
+			array(),
399
+			'button button-primary ee-confirm',
400
+			'',
401
+			false
402
+		);
403
+		$this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
404
+			'reset_capabilities',
405
+			'reset_capabilities',
406
+			array(),
407
+			'button button-primary ee-confirm',
408
+			'',
409
+			false
410
+		);
411
+		$this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
412
+			array('action' => 'delete_db'),
413
+			EE_MAINTENANCE_ADMIN_URL
414
+		);
415
+		$this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
416
+			array('action' => 'reset_db'),
417
+			EE_MAINTENANCE_ADMIN_URL
418
+		);
419
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
420
+			$this->_template_path,
421
+			$this->_template_args,
422
+			true
423
+		);
424
+		$this->display_admin_page_with_sidebar();
425
+	}
426
+
427
+
428
+
429
+	protected function _reset_reservations()
430
+	{
431
+		if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432
+			EE_Error::add_success(
433
+				__(
434
+					'Ticket and datetime reserved counts have been successfully reset.',
435
+					'event_espresso'
436
+				)
437
+			);
438
+		} else {
439
+			EE_Error::add_success(
440
+				__(
441
+					'Ticket and datetime reserved counts were correct and did not need resetting.',
442
+					'event_espresso'
443
+				)
444
+			);
445
+		}
446
+		$this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true);
447
+	}
448
+
449
+
450
+
451
+	protected function _reset_capabilities()
452
+	{
453
+		EE_Registry::instance()->CAP->init_caps(true);
454
+		EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.',
455
+			'event_espresso'));
456
+		$this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true);
457
+	}
458
+
459
+
460
+
461
+	/**
462
+	 * resets the DMSs so we can attempt to continue migrating after a fatal error
463
+	 * (only a good idea when someone has somehow tried ot fix whatever caused
464
+	 * the fatal error in teh first place)
465
+	 */
466
+	protected function _reattempt_migration()
467
+	{
468
+		EE_Data_Migration_Manager::instance()->reattempt();
469
+		$this->_redirect_after_action(false, '', '', array('action' => 'default'), true);
470
+	}
471
+
472
+
473
+
474
+	/**
475
+	 * shows the big ol' System Information page
476
+	 */
477
+	public function _system_status()
478
+	{
479
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
480
+		$this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481
+		$this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482
+			array(
483
+				'action' => 'download_system_status',
484
+			),
485
+			EE_MAINTENANCE_ADMIN_URL
486
+		);
487
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
488
+			$this->_template_args, true);
489
+		$this->display_admin_page_with_sidebar();
490
+	}
491
+
492
+	/**
493
+	 * Downloads an HTML file of the system status that can be easily stored or emailed
494
+	 */
495
+	public function _download_system_status()
496
+	{
497
+		$status_info = EEM_System_Status::instance()->get_system_stati();
498
+		header( 'Content-Disposition: attachment' );
499
+		header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
500
+		echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
+		echo "<h1>System Information for " . site_url() . "</h1>";
502
+		echo EEH_Template::layout_array_as_table( $status_info );
503
+		die;
504
+	}
505
+
506
+
507
+
508
+	public function _send_migration_crash_report()
509
+	{
510
+		$from = $this->_req_data['from'];
511
+		$from_name = $this->_req_data['from_name'];
512
+		$body = $this->_req_data['body'];
513
+		try {
514
+			$success = wp_mail(EE_SUPPORT_EMAIL,
515
+				'Migration Crash Report',
516
+				$body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
517
+				array(
518
+					"from:$from_name<$from>",
519
+					//					'content-type:text/html charset=UTF-8'
520
+				));
521
+		} catch (Exception $e) {
522
+			$success = false;
523
+		}
524
+		$this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"),
525
+			esc_html__("sent", "event_espresso"),
526
+			array('success' => $success, 'action' => 'confirm_migration_crash_report_sent'));
527
+	}
528
+
529
+
530
+
531
+	public function _confirm_migration_crash_report_sent()
532
+	{
533
+		try {
534
+			$most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
535
+		} catch (EE_Error $e) {
536
+			EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
537
+			//now, just so we can display the page correctly, make a error migration script stage object
538
+			//and also put the error on it. It only persists for the duration of this request
539
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
540
+			$most_recent_migration->add_error($e->getMessage());
541
+		}
542
+		$success = $this->_req_data['success'] == '1' ? true : false;
543
+		$this->_template_args['success'] = $success;
544
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;
545
+		$this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
546
+			EE_MAINTENANCE_ADMIN_URL);
547
+		$this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
548
+			EE_MAINTENANCE_ADMIN_URL);
549
+		$this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550
+			EE_MAINTENANCE_ADMIN_URL);
551
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
552
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553
+			$this->_template_args, true);
554
+		$this->display_admin_page_with_sidebar();
555
+	}
556
+
557
+
558
+
559
+	/**
560
+	 * Resets the entire EE4 database.
561
+	 * Currently basically only sets up ee4 database for a fresh install- doesn't
562
+	 * actually clean out the old wp options, or cpts (although does erase old ee table data)
563
+	 *
564
+	 * @param boolean $nuke_old_ee4_data controls whether or not we
565
+	 *                                   destroy the old ee4 data, or just try initializing ee4 default data
566
+	 */
567
+	public function _reset_db($nuke_old_ee4_data = true)
568
+	{
569
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
570
+		if ($nuke_old_ee4_data) {
571
+			EEH_Activation::delete_all_espresso_cpt_data();
572
+			EEH_Activation::delete_all_espresso_tables_and_data(false);
573
+			EEH_Activation::remove_cron_tasks();
574
+		}
575
+		//make sure when we reset the registry's config that it
576
+		//switches to using the new singleton
577
+		EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
578
+		EE_System::instance()->initialize_db_if_no_migrations_required(true);
579
+		EE_System::instance()->redirect_to_about_ee();
580
+	}
581
+
582
+
583
+
584
+	/**
585
+	 * Deletes ALL EE tables, Records, and Options from the database.
586
+	 */
587
+	public function _delete_db()
588
+	{
589
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
590
+		EEH_Activation::delete_all_espresso_cpt_data();
591
+		EEH_Activation::delete_all_espresso_tables_and_data();
592
+		EEH_Activation::remove_cron_tasks();
593
+		EEH_Activation::deactivate_event_espresso();
594
+		wp_safe_redirect(admin_url('plugins.php'));
595
+		exit;
596
+	}
597
+
598
+
599
+
600
+	/**
601
+	 * sets up EE4 to rerun the migrations from ee3 to ee4
602
+	 */
603
+	public function _rerun_migration_from_ee3()
604
+	{
605
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
606
+		EEH_Activation::delete_all_espresso_cpt_data();
607
+		EEH_Activation::delete_all_espresso_tables_and_data(false);
608
+		//set the db state to something that will require migrations
609
+		update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
610
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
611
+		$this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso'));
612
+	}
613
+
614
+
615
+
616
+	//none of the below group are currently used for Gateway Settings
617
+	protected function _add_screen_options()
618
+	{
619
+	}
620
+
621
+
622
+
623
+	protected function _add_feature_pointers()
624
+	{
625
+	}
626
+
627 627
 
628 628
 
629
-    public function admin_init()
630
-    {
631
-    }
632
-
633
-
634
-
635
-    public function admin_notices()
636
-    {
637
-    }
638
-
629
+	public function admin_init()
630
+	{
631
+	}
632
+
633
+
634
+
635
+	public function admin_notices()
636
+	{
637
+	}
638
+
639 639
 
640 640
 
641
-    public function admin_footer_scripts()
642
-    {
643
-    }
641
+	public function admin_footer_scripts()
642
+	{
643
+	}
644 644
 
645 645
 
646 646
 
647
-    public function load_scripts_styles()
648
-    {
649
-        wp_enqueue_script('ee_admin_js');
647
+	public function load_scripts_styles()
648
+	{
649
+		wp_enqueue_script('ee_admin_js');
650 650
 //		wp_enqueue_media();
651 651
 //		wp_enqueue_script('media-upload');
652
-        wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
653
-            EVENT_ESPRESSO_VERSION, true);
654
-        wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
655
-            EVENT_ESPRESSO_VERSION);
656
-        wp_enqueue_style('espresso_maintenance');
657
-        //localize script stuff
658
-        wp_localize_script('ee-maintenance', 'ee_maintenance', array(
659
-            'migrating'                        => esc_html__("Updating Database...", "event_espresso"),
660
-            'next'                             => esc_html__("Next", "event_espresso"),
661
-            'fatal_error'                      => esc_html__("A Fatal Error Has Occurred", "event_espresso"),
662
-            'click_next_when_ready'            => esc_html__(
663
-                "The current Database Update has ended. Click 'next' when ready to proceed",
664
-                "event_espresso"
665
-            ),
666
-            'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
667
-            'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
668
-            'status_completed'                 => EE_Data_Migration_Manager::status_completed,
669
-            'confirm'                          => esc_html__(
670
-                'Are you sure you want to do this? It CANNOT be undone!',
671
-                'event_espresso'
672
-            ),
673
-            'confirm_skip_migration' => esc_html__(
674
-                'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
675
-                'event_espresso'
676
-            )
677
-        ));
678
-    }
679
-
680
-
681
-
682
-    public function load_scripts_styles_default()
683
-    {
684
-        //styles
652
+		wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
653
+			EVENT_ESPRESSO_VERSION, true);
654
+		wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
655
+			EVENT_ESPRESSO_VERSION);
656
+		wp_enqueue_style('espresso_maintenance');
657
+		//localize script stuff
658
+		wp_localize_script('ee-maintenance', 'ee_maintenance', array(
659
+			'migrating'                        => esc_html__("Updating Database...", "event_espresso"),
660
+			'next'                             => esc_html__("Next", "event_espresso"),
661
+			'fatal_error'                      => esc_html__("A Fatal Error Has Occurred", "event_espresso"),
662
+			'click_next_when_ready'            => esc_html__(
663
+				"The current Database Update has ended. Click 'next' when ready to proceed",
664
+				"event_espresso"
665
+			),
666
+			'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
667
+			'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
668
+			'status_completed'                 => EE_Data_Migration_Manager::status_completed,
669
+			'confirm'                          => esc_html__(
670
+				'Are you sure you want to do this? It CANNOT be undone!',
671
+				'event_espresso'
672
+			),
673
+			'confirm_skip_migration' => esc_html__(
674
+				'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
675
+				'event_espresso'
676
+			)
677
+		));
678
+	}
679
+
680
+
681
+
682
+	public function load_scripts_styles_default()
683
+	{
684
+		//styles
685 685
 //		wp_enqueue_style('ee-text-links');
686 686
 //		//scripts
687 687
 //		wp_enqueue_script('ee-text-links');
688
-    }
689
-
690
-
691
-    /**
692
-     * Enqueue scripts and styles for the datetime tools page.
693
-     */
694
-    public function load_scripts_styles_datetime_tools()
695
-    {
696
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
697
-    }
698
-
699
-
700
-    protected function _datetime_tools()
701
-    {
702
-        $form_action = EE_Admin_Page::add_query_args_and_nonce(
703
-            array(
704
-                'action' => 'run_datetime_offset_fix',
705
-                'return_action' => $this->_req_action
706
-            ),
707
-            EE_MAINTENANCE_ADMIN_URL
708
-        );
709
-        $form = $this->_get_datetime_offset_fix_form();
710
-        $this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso');
711
-        $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
712
-                                                      . $form->get_html_and_js()
713
-                                                      . $form->form_close();
714
-        $this->display_admin_page_with_no_sidebar();
715
-    }
716
-
717
-
718
-
719
-    protected function _get_datetime_offset_fix_form()
720
-    {
721
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
-            $this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
723
-                array(
724
-                    'name' => 'datetime_offset_fix_option',
725
-                    'layout_strategy' => new EE_Admin_Two_Column_Layout(),
726
-                    'subsections' => array(
727
-                        'title' => new EE_Form_Section_HTML(
728
-                            EEH_HTML::h2(
729
-                                esc_html__('Datetime Offset Tool', 'event_espresso')
730
-                            )
731
-                        ),
732
-                        'explanation' => new EE_Form_Section_HTML(
733
-                            EEH_HTML::p(
734
-                                esc_html__(
735
-                                    'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
736
-                                    'event_espresso'
737
-                                )
738
-                            )
739
-                            . EEH_HTML::p(
740
-                                esc_html__(
741
-                                    'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
742
-                                    'event_espresso'
743
-                                )
744
-                            )
745
-                        ),
746
-                        'offset_input' => new EE_Float_Input(
747
-                            array(
748
-                                'html_name' => 'offset_for_datetimes',
749
-                                'html_label_text' => esc_html__(
750
-                                    'Offset to apply (in hours):',
751
-                                    'event_espresso'
752
-                                ),
753
-                                'min_value' => '-12',
754
-                                'max_value' => '14',
755
-                                'step_value' => '.25',
756
-                                'default' => DatetimeOffsetFix::getOffset()
757
-                            )
758
-                        ),
759
-                        'date_range_explanation' => new EE_Form_Section_HTML(
760
-                            EEH_HTML::p(
761
-                                esc_html__(
762
-                                    'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
763
-                                    'event_espresso'
764
-                                )
765
-                            )
766
-                            . EEH_HTML::p(
767
-                                EEH_HTML::strong(
768
-                                    sprintf(
769
-                                        esc_html__(
770
-                                            'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
771
-                                            'event_espresso'
772
-                                        ),
773
-                                        '<a href="https://www.timeanddate.com/worldclock/converter.html">',
774
-                                        '</a>'
775
-                                    )
776
-                                )
777
-                            )
778
-                        ),
779
-                        'date_range_start_date' => new EE_Datepicker_Input(
780
-                            array(
781
-                                'html_name' => 'offset_date_start_range',
782
-                                'html_label_text' => esc_html__(
783
-                                    'Start Date for dates the offset applied to:',
784
-                                    'event_espresso'
785
-                                )
786
-                            )
787
-                        ),
788
-                        'date_range_end_date' => new EE_Datepicker_Input(
789
-                            array(
790
-                                'html_name' => 'offset_date_end_range',
791
-                                'html_label_text' => esc_html(
792
-                                    'End Date for dates the offset is applied to:',
793
-                                    'event_espresso'
794
-                                )
795
-                            )
796
-                        ),
797
-                        'submit' => new EE_Submit_Input(
798
-                            array(
799
-                                'html_label_text' => '',
800
-                                'default' => esc_html__('Apply Offset', 'event_espresso')
801
-                            )
802
-                        ),
803
-                    )
804
-                )
805
-            );
806
-        }
807
-        return $this->datetime_fix_offset_form;
808
-    }
809
-
810
-
811
-    /**
812
-     * Callback for the run_datetime_offset_fix route.
813
-     * @throws EE_Error
814
-     */
815
-    protected function _apply_datetime_offset()
816
-    {
817
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
818
-            $form = $this->_get_datetime_offset_fix_form();
819
-            $form->receive_form_submission($this->_req_data);
820
-            if ($form->is_valid()) {
821
-                //save offset data so batch processor can get it.
822
-                DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
823
-                $utc_timezone = new DateTimeZone('UTC');
824
-                $date_range_start_date = DateTime::createFromFormat(
825
-                    'm/d/Y H:i:s',
826
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
827
-                    $utc_timezone
828
-                );
829
-                $date_range_end_date = DateTime::createFromFormat(
830
-                        'm/d/Y H:i:s',
831
-                        $form->get_input_value('date_range_end_date') . ' 23:59:59',
832
-                        $utc_timezone
833
-                );
834
-                if ($date_range_start_date instanceof DateTime) {
835
-                    DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
836
-                }
837
-                if ($date_range_end_date instanceof DateTime) {
838
-                    DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
839
-                }
840
-                //redirect to batch tool
841
-                wp_redirect(
842
-                    EE_Admin_Page::add_query_args_and_nonce(
843
-                        array(
844
-                            'page' => 'espresso_batch',
845
-                            'batch' => 'job',
846
-                            'label' => esc_html__('Applying Offset', 'event_espresso'),
847
-                            'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
848
-                            'return_url' => urlencode(
849
-                                add_query_arg(
850
-                                    array(
851
-                                        'action' => 'datetime_tools',
852
-                                    ),
853
-                                    EEH_URL::current_url_without_query_paramaters(
854
-                                        array(
855
-                                            'return_action',
856
-                                            'run_datetime_offset_fix_nonce',
857
-                                            'return',
858
-                                            'datetime_tools_nonce'
859
-                                        )
860
-                                    )
861
-                                )
862
-                            )
863
-                        ),
864
-                        admin_url()
865
-                    )
866
-                );
867
-                exit;
868
-            }
869
-        }
870
-    }
688
+	}
689
+
690
+
691
+	/**
692
+	 * Enqueue scripts and styles for the datetime tools page.
693
+	 */
694
+	public function load_scripts_styles_datetime_tools()
695
+	{
696
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
697
+	}
698
+
699
+
700
+	protected function _datetime_tools()
701
+	{
702
+		$form_action = EE_Admin_Page::add_query_args_and_nonce(
703
+			array(
704
+				'action' => 'run_datetime_offset_fix',
705
+				'return_action' => $this->_req_action
706
+			),
707
+			EE_MAINTENANCE_ADMIN_URL
708
+		);
709
+		$form = $this->_get_datetime_offset_fix_form();
710
+		$this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso');
711
+		$this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
712
+													  . $form->get_html_and_js()
713
+													  . $form->form_close();
714
+		$this->display_admin_page_with_no_sidebar();
715
+	}
716
+
717
+
718
+
719
+	protected function _get_datetime_offset_fix_form()
720
+	{
721
+		if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
+			$this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
723
+				array(
724
+					'name' => 'datetime_offset_fix_option',
725
+					'layout_strategy' => new EE_Admin_Two_Column_Layout(),
726
+					'subsections' => array(
727
+						'title' => new EE_Form_Section_HTML(
728
+							EEH_HTML::h2(
729
+								esc_html__('Datetime Offset Tool', 'event_espresso')
730
+							)
731
+						),
732
+						'explanation' => new EE_Form_Section_HTML(
733
+							EEH_HTML::p(
734
+								esc_html__(
735
+									'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
736
+									'event_espresso'
737
+								)
738
+							)
739
+							. EEH_HTML::p(
740
+								esc_html__(
741
+									'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
742
+									'event_espresso'
743
+								)
744
+							)
745
+						),
746
+						'offset_input' => new EE_Float_Input(
747
+							array(
748
+								'html_name' => 'offset_for_datetimes',
749
+								'html_label_text' => esc_html__(
750
+									'Offset to apply (in hours):',
751
+									'event_espresso'
752
+								),
753
+								'min_value' => '-12',
754
+								'max_value' => '14',
755
+								'step_value' => '.25',
756
+								'default' => DatetimeOffsetFix::getOffset()
757
+							)
758
+						),
759
+						'date_range_explanation' => new EE_Form_Section_HTML(
760
+							EEH_HTML::p(
761
+								esc_html__(
762
+									'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
763
+									'event_espresso'
764
+								)
765
+							)
766
+							. EEH_HTML::p(
767
+								EEH_HTML::strong(
768
+									sprintf(
769
+										esc_html__(
770
+											'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
771
+											'event_espresso'
772
+										),
773
+										'<a href="https://www.timeanddate.com/worldclock/converter.html">',
774
+										'</a>'
775
+									)
776
+								)
777
+							)
778
+						),
779
+						'date_range_start_date' => new EE_Datepicker_Input(
780
+							array(
781
+								'html_name' => 'offset_date_start_range',
782
+								'html_label_text' => esc_html__(
783
+									'Start Date for dates the offset applied to:',
784
+									'event_espresso'
785
+								)
786
+							)
787
+						),
788
+						'date_range_end_date' => new EE_Datepicker_Input(
789
+							array(
790
+								'html_name' => 'offset_date_end_range',
791
+								'html_label_text' => esc_html(
792
+									'End Date for dates the offset is applied to:',
793
+									'event_espresso'
794
+								)
795
+							)
796
+						),
797
+						'submit' => new EE_Submit_Input(
798
+							array(
799
+								'html_label_text' => '',
800
+								'default' => esc_html__('Apply Offset', 'event_espresso')
801
+							)
802
+						),
803
+					)
804
+				)
805
+			);
806
+		}
807
+		return $this->datetime_fix_offset_form;
808
+	}
809
+
810
+
811
+	/**
812
+	 * Callback for the run_datetime_offset_fix route.
813
+	 * @throws EE_Error
814
+	 */
815
+	protected function _apply_datetime_offset()
816
+	{
817
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
818
+			$form = $this->_get_datetime_offset_fix_form();
819
+			$form->receive_form_submission($this->_req_data);
820
+			if ($form->is_valid()) {
821
+				//save offset data so batch processor can get it.
822
+				DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
823
+				$utc_timezone = new DateTimeZone('UTC');
824
+				$date_range_start_date = DateTime::createFromFormat(
825
+					'm/d/Y H:i:s',
826
+					$form->get_input_value('date_range_start_date') . ' 00:00:00',
827
+					$utc_timezone
828
+				);
829
+				$date_range_end_date = DateTime::createFromFormat(
830
+						'm/d/Y H:i:s',
831
+						$form->get_input_value('date_range_end_date') . ' 23:59:59',
832
+						$utc_timezone
833
+				);
834
+				if ($date_range_start_date instanceof DateTime) {
835
+					DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
836
+				}
837
+				if ($date_range_end_date instanceof DateTime) {
838
+					DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
839
+				}
840
+				//redirect to batch tool
841
+				wp_redirect(
842
+					EE_Admin_Page::add_query_args_and_nonce(
843
+						array(
844
+							'page' => 'espresso_batch',
845
+							'batch' => 'job',
846
+							'label' => esc_html__('Applying Offset', 'event_espresso'),
847
+							'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
848
+							'return_url' => urlencode(
849
+								add_query_arg(
850
+									array(
851
+										'action' => 'datetime_tools',
852
+									),
853
+									EEH_URL::current_url_without_query_paramaters(
854
+										array(
855
+											'return_action',
856
+											'run_datetime_offset_fix_nonce',
857
+											'return',
858
+											'datetime_tools_nonce'
859
+										)
860
+									)
861
+								)
862
+							)
863
+						),
864
+						admin_url()
865
+					)
866
+				);
867
+				exit;
868
+			}
869
+		}
870
+	}
871 871
 } //end Maintenance_Admin_Page class
Please login to merge, or discard this patch.
core/admin/EE_Admin.core.php 2 patches
Indentation   +896 added lines, -896 removed lines patch added patch discarded remove patch
@@ -22,454 +22,454 @@  discard block
 block discarded – undo
22 22
 final class EE_Admin implements InterminableInterface
23 23
 {
24 24
 
25
-    /**
26
-     * @var EE_Admin $_instance
27
-     */
28
-    private static $_instance;
29
-
30
-    /**
31
-     * @var PersistentAdminNoticeManager $persistent_admin_notice_manager
32
-     */
33
-    private $persistent_admin_notice_manager;
34
-
35
-    /**
36
-     * @singleton method used to instantiate class object
37
-     * @return EE_Admin
38
-     * @throws EE_Error
39
-     */
40
-    public static function instance()
41
-    {
42
-        // check if class object is instantiated
43
-        if (! self::$_instance instanceof EE_Admin) {
44
-            self::$_instance = new self();
45
-        }
46
-        return self::$_instance;
47
-    }
48
-
49
-
50
-    /**
51
-     * @return EE_Admin
52
-     * @throws EE_Error
53
-     */
54
-    public static function reset()
55
-    {
56
-        self::$_instance = null;
57
-        return self::instance();
58
-    }
59
-
60
-
61
-    /**
62
-     * class constructor
63
-     *
64
-     * @throws EE_Error
65
-     * @throws InvalidDataTypeException
66
-     * @throws InvalidInterfaceException
67
-     * @throws InvalidArgumentException
68
-     */
69
-    protected function __construct()
70
-    {
71
-        // define global EE_Admin constants
72
-        $this->_define_all_constants();
73
-        // set autoloaders for our admin page classes based on included path information
74
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_ADMIN);
75
-        // admin hooks
76
-        add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2);
77
-        // load EE_Request_Handler early
78
-        add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'get_request'));
79
-        add_action('AHEE__EE_System__initialize_last', array($this, 'init'));
80
-        add_action('AHEE__EE_Admin_Page__route_admin_request', array($this, 'route_admin_request'), 100, 2);
81
-        add_action('wp_loaded', array($this, 'wp_loaded'), 100);
82
-        add_action('admin_init', array($this, 'admin_init'), 100);
83
-        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20);
84
-        add_action('admin_notices', array($this, 'display_admin_notices'), 10);
85
-        add_action('network_admin_notices', array($this, 'display_admin_notices'), 10);
86
-        add_filter('pre_update_option', array($this, 'check_for_invalid_datetime_formats'), 100, 2);
87
-        add_filter('admin_footer_text', array($this, 'espresso_admin_footer'));
88
-        //reset Environment config (we only do this on admin page loads);
89
-        EE_Registry::instance()->CFG->environment->recheck_values();
90
-        do_action('AHEE__EE_Admin__loaded');
91
-    }
92
-
93
-
94
-
95
-    /**
96
-     * _define_all_constants
97
-     * define constants that are set globally for all admin pages
98
-     *
99
-     * @return void
100
-     */
101
-    private function _define_all_constants()
102
-    {
103
-        if (! defined('EE_ADMIN_URL')) {
104
-            define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/');
105
-            define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/');
106
-            define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS);
107
-            define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/');
108
-            define('WP_AJAX_URL', admin_url('admin-ajax.php'));
109
-        }
110
-    }
111
-
112
-
113
-    /**
114
-     * filter_plugin_actions - adds links to the Plugins page listing
115
-     *
116
-     * @param    array  $links
117
-     * @param    string $plugin
118
-     * @return    array
119
-     */
120
-    public function filter_plugin_actions($links, $plugin)
121
-    {
122
-        // set $main_file in stone
123
-        static $main_file;
124
-        // if $main_file is not set yet
125
-        if (! $main_file) {
126
-            $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE);
127
-        }
128
-        if ($plugin === $main_file) {
129
-            // compare current plugin to this one
130
-            if (EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance) {
131
-                $maintenance_link = '<a href="admin.php?page=espresso_maintenance_settings"'
132
-                                    . ' title="Event Espresso is in maintenance mode.  Click this link to learn why.">'
133
-                                    . esc_html__('Maintenance Mode Active', 'event_espresso')
134
-                                    . '</a>';
135
-                array_unshift($links, $maintenance_link);
136
-            } else {
137
-                $org_settings_link = '<a href="admin.php?page=espresso_general_settings">'
138
-                                     . esc_html__('Settings', 'event_espresso')
139
-                                     . '</a>';
140
-                $events_link       = '<a href="admin.php?page=espresso_events">'
141
-                                     . esc_html__('Events', 'event_espresso')
142
-                                     . '</a>';
143
-                // add before other links
144
-                array_unshift($links, $org_settings_link, $events_link);
145
-            }
146
-        }
147
-        return $links;
148
-    }
149
-
150
-
151
-    /**
152
-     * _get_request
153
-     *
154
-     * @return void
155
-     * @throws EE_Error
156
-     * @throws InvalidArgumentException
157
-     * @throws InvalidDataTypeException
158
-     * @throws InvalidInterfaceException
159
-     * @throws ReflectionException
160
-     */
161
-    public function get_request()
162
-    {
163
-        EE_Registry::instance()->load_core('Request_Handler');
164
-        EE_Registry::instance()->load_core('CPT_Strategy');
165
-    }
166
-
167
-
168
-
169
-    /**
170
-     * hide_admin_pages_except_maintenance_mode
171
-     *
172
-     * @param array $admin_page_folder_names
173
-     * @return array
174
-     */
175
-    public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array())
176
-    {
177
-        return array(
178
-            'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS,
179
-            'about'       => EE_ADMIN_PAGES . 'about' . DS,
180
-            'support'     => EE_ADMIN_PAGES . 'support' . DS,
181
-        );
182
-    }
183
-
184
-
185
-
186
-    /**
187
-     * init- should fire after shortcode, module,  addon, other plugin (default priority), and even
188
-     * EE_Front_Controller's init phases have run
189
-     *
190
-     * @return void
191
-     * @throws EE_Error
192
-     * @throws InvalidArgumentException
193
-     * @throws InvalidDataTypeException
194
-     * @throws InvalidInterfaceException
195
-     * @throws ReflectionException
196
-     * @throws ServiceNotFoundException
197
-     */
198
-    public function init()
199
-    {
200
-        //only enable most of the EE_Admin IF we're not in full maintenance mode
201
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
202
-            //ok so we want to enable the entire admin
203
-            $this->persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
204
-                'EventEspresso\core\services\notifications\PersistentAdminNoticeManager',
205
-                array(
206
-                    EE_Admin_Page::add_query_args_and_nonce(
207
-                        array(
208
-                            'page'   => EE_Registry::instance()->REQ->get('page', ''),
209
-                            'action' => EE_Registry::instance()->REQ->get('action', ''),
210
-                        ),
211
-                        EE_ADMIN_URL
212
-                    ),
213
-                )
214
-            );
215
-            $this->maybeSetDatetimeWarningNotice();
216
-            //at a glance dashboard widget
217
-            add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10);
218
-            //filter for get_edit_post_link used on comments for custom post types
219
-            add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2);
220
-        }
221
-        // run the admin page factory but ONLY if we are doing an ee admin ajax request
222
-        if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) {
223
-            try {
224
-                //this loads the controller for the admin pages which will setup routing etc
225
-                EE_Registry::instance()->load_core('Admin_Page_Loader');
226
-            } catch (EE_Error $e) {
227
-                $e->get_error();
228
-            }
229
-        }
230
-        add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1);
231
-        //make sure our CPTs and custom taxonomy metaboxes get shown for first time users
232
-        add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10);
233
-        add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10);
234
-        //exclude EE critical pages from all nav menus and wp_list_pages
235
-        add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10);
236
-    }
237
-
238
-
239
-    /**
240
-     *    get_persistent_admin_notices
241
-     *
242
-     * @access    public
243
-     * @return void
244
-     * @throws EE_Error
245
-     * @throws InvalidArgumentException
246
-     * @throws InvalidDataTypeException
247
-     * @throws InvalidInterfaceException
248
-     */
249
-    public function maybeSetDatetimeWarningNotice()
250
-    {
251
-        //add dismissable notice for datetime changes.  Only valid if site does not have a timezone_string set.
252
-        //@todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version
253
-        //with this.  But after enough time (indeterminate at this point) we can just remove this notice.
254
-        //this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626
255
-        if (! get_option('timezone_string') && EEM_Event::instance()->count() > 0) {
256
-            new PersistentAdminNotice(
257
-                'datetime_fix_notice',
258
-                sprintf(
259
-                    esc_html__(
260
-                        '%1$sImportant announcement related to your install of Event Espresso%2$s: There are some changes made to your site that could affect how dates display for your events and other related items with dates and times.  Read more about it %3$shere%4$s. If your dates and times are displaying incorrectly (incorrect offset), you can fix it using the tool on %5$sthis page%4$s.',
261
-                        'event_espresso'
262
-                    ),
263
-                    '<strong>',
264
-                    '</strong>',
265
-                    '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">',
266
-                    '</a>',
267
-                    '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
268
-                        array(
269
-                            'page' => 'espresso_maintenance_settings',
270
-                            'action' => 'datetime_tools'
271
-                        ),
272
-                        admin_url('admin.php')
273
-                    ) . '">'
274
-                ),
275
-                false,
276
-                'manage_options',
277
-                'datetime_fix_persistent_notice'
278
-            );
279
-        }
280
-    }
281
-
282
-
283
-
284
-    /**
285
-     * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from
286
-     * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in
287
-     * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that
288
-     * to override any queries found in the existing query for the given post type.  Note that _default_query is not a
289
-     * normal property on the post_type object.  It's found ONLY in this particular context.
290
-     *
291
-     * @param WP_Post $post_type WP post type object
292
-     * @return WP_Post
293
-     * @throws InvalidArgumentException
294
-     * @throws InvalidDataTypeException
295
-     * @throws InvalidInterfaceException
296
-     */
297
-    public function remove_pages_from_nav_menu($post_type)
298
-    {
299
-        //if this isn't the "pages" post type let's get out
300
-        if ($post_type->name !== 'page') {
301
-            return $post_type;
302
-        }
303
-        $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array();
304
-        $post_type->_default_query = array(
305
-            'post__not_in' => $critical_pages,
306
-        );
307
-        return $post_type;
308
-    }
309
-
310
-
311
-
312
-    /**
313
-     * WP by default only shows three metaboxes in "nav-menus.php" for first times users.  We want to make sure our
314
-     * metaboxes get shown as well
315
-     *
316
-     * @return void
317
-     */
318
-    public function enable_hidden_ee_nav_menu_metaboxes()
319
-    {
320
-        global $wp_meta_boxes, $pagenow;
321
-        if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') {
322
-            return;
323
-        }
324
-        $user = wp_get_current_user();
325
-        //has this been done yet?
326
-        if (get_user_option('ee_nav_menu_initialized', $user->ID)) {
327
-            return;
328
-        }
329
-
330
-        $hidden_meta_boxes  = get_user_option('metaboxhidden_nav-menus', $user->ID);
331
-        $initial_meta_boxes = apply_filters(
332
-            'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes',
333
-            array(
334
-                'nav-menu-theme-locations',
335
-                'add-page',
336
-                'add-custom-links',
337
-                'add-category',
338
-                'add-espresso_events',
339
-                'add-espresso_venues',
340
-                'add-espresso_event_categories',
341
-                'add-espresso_venue_categories',
342
-                'add-post-type-post',
343
-                'add-post-type-page',
344
-            )
345
-        );
346
-
347
-        if (is_array($hidden_meta_boxes)) {
348
-            foreach ($hidden_meta_boxes as $key => $meta_box_id) {
349
-                if (in_array($meta_box_id, $initial_meta_boxes, true)) {
350
-                    unset($hidden_meta_boxes[$key]);
351
-                }
352
-            }
353
-        }
354
-        update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true);
355
-        update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true);
356
-    }
357
-
358
-
359
-
360
-    /**
361
-     * This method simply registers custom nav menu boxes for "nav_menus.php route"
362
-     * Currently EE is using this to make sure there are menu options for our CPT archive page routes.
363
-     *
364
-     * @todo   modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by
365
-     *         addons etc.
366
-     * @return void
367
-     */
368
-    public function register_custom_nav_menu_boxes()
369
-    {
370
-        add_meta_box(
371
-            'add-extra-nav-menu-pages',
372
-            esc_html__('Event Espresso Pages', 'event_espresso'),
373
-            array($this, 'ee_cpt_archive_pages'),
374
-            'nav-menus',
375
-            'side',
376
-            'core'
377
-        );
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * Use this to edit the post link for our cpts so that the edit link points to the correct page.
384
-     *
385
-     * @since   4.3.0
386
-     * @param string $link the original link generated by wp
387
-     * @param int    $id   post id
388
-     * @return string  the (maybe) modified link
389
-     */
390
-    public function modify_edit_post_link($link, $id)
391
-    {
392
-        if (! $post = get_post($id)) {
393
-            return $link;
394
-        }
395
-        if ($post->post_type === 'espresso_attendees') {
396
-            $query_args = array(
397
-                'action' => 'edit_attendee',
398
-                'post'   => $id,
399
-            );
400
-            return EEH_URL::add_query_args_and_nonce(
401
-                $query_args,
402
-                admin_url('admin.php?page=espresso_registrations')
403
-            );
404
-        }
405
-        return $link;
406
-    }
407
-
408
-
409
-
410
-    public function ee_cpt_archive_pages()
411
-    {
412
-        global $nav_menu_selected_id;
413
-        $db_fields   = false;
414
-        $walker      = new Walker_Nav_Menu_Checklist($db_fields);
415
-        $current_tab = 'event-archives';
416
-        $removed_args = array(
417
-            'action',
418
-            'customlink-tab',
419
-            'edit-menu-item',
420
-            'menu-item',
421
-            'page-tab',
422
-            '_wpnonce',
423
-        );
424
-        ?>
25
+	/**
26
+	 * @var EE_Admin $_instance
27
+	 */
28
+	private static $_instance;
29
+
30
+	/**
31
+	 * @var PersistentAdminNoticeManager $persistent_admin_notice_manager
32
+	 */
33
+	private $persistent_admin_notice_manager;
34
+
35
+	/**
36
+	 * @singleton method used to instantiate class object
37
+	 * @return EE_Admin
38
+	 * @throws EE_Error
39
+	 */
40
+	public static function instance()
41
+	{
42
+		// check if class object is instantiated
43
+		if (! self::$_instance instanceof EE_Admin) {
44
+			self::$_instance = new self();
45
+		}
46
+		return self::$_instance;
47
+	}
48
+
49
+
50
+	/**
51
+	 * @return EE_Admin
52
+	 * @throws EE_Error
53
+	 */
54
+	public static function reset()
55
+	{
56
+		self::$_instance = null;
57
+		return self::instance();
58
+	}
59
+
60
+
61
+	/**
62
+	 * class constructor
63
+	 *
64
+	 * @throws EE_Error
65
+	 * @throws InvalidDataTypeException
66
+	 * @throws InvalidInterfaceException
67
+	 * @throws InvalidArgumentException
68
+	 */
69
+	protected function __construct()
70
+	{
71
+		// define global EE_Admin constants
72
+		$this->_define_all_constants();
73
+		// set autoloaders for our admin page classes based on included path information
74
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_ADMIN);
75
+		// admin hooks
76
+		add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2);
77
+		// load EE_Request_Handler early
78
+		add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'get_request'));
79
+		add_action('AHEE__EE_System__initialize_last', array($this, 'init'));
80
+		add_action('AHEE__EE_Admin_Page__route_admin_request', array($this, 'route_admin_request'), 100, 2);
81
+		add_action('wp_loaded', array($this, 'wp_loaded'), 100);
82
+		add_action('admin_init', array($this, 'admin_init'), 100);
83
+		add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20);
84
+		add_action('admin_notices', array($this, 'display_admin_notices'), 10);
85
+		add_action('network_admin_notices', array($this, 'display_admin_notices'), 10);
86
+		add_filter('pre_update_option', array($this, 'check_for_invalid_datetime_formats'), 100, 2);
87
+		add_filter('admin_footer_text', array($this, 'espresso_admin_footer'));
88
+		//reset Environment config (we only do this on admin page loads);
89
+		EE_Registry::instance()->CFG->environment->recheck_values();
90
+		do_action('AHEE__EE_Admin__loaded');
91
+	}
92
+
93
+
94
+
95
+	/**
96
+	 * _define_all_constants
97
+	 * define constants that are set globally for all admin pages
98
+	 *
99
+	 * @return void
100
+	 */
101
+	private function _define_all_constants()
102
+	{
103
+		if (! defined('EE_ADMIN_URL')) {
104
+			define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/');
105
+			define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/');
106
+			define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS);
107
+			define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/');
108
+			define('WP_AJAX_URL', admin_url('admin-ajax.php'));
109
+		}
110
+	}
111
+
112
+
113
+	/**
114
+	 * filter_plugin_actions - adds links to the Plugins page listing
115
+	 *
116
+	 * @param    array  $links
117
+	 * @param    string $plugin
118
+	 * @return    array
119
+	 */
120
+	public function filter_plugin_actions($links, $plugin)
121
+	{
122
+		// set $main_file in stone
123
+		static $main_file;
124
+		// if $main_file is not set yet
125
+		if (! $main_file) {
126
+			$main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE);
127
+		}
128
+		if ($plugin === $main_file) {
129
+			// compare current plugin to this one
130
+			if (EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance) {
131
+				$maintenance_link = '<a href="admin.php?page=espresso_maintenance_settings"'
132
+									. ' title="Event Espresso is in maintenance mode.  Click this link to learn why.">'
133
+									. esc_html__('Maintenance Mode Active', 'event_espresso')
134
+									. '</a>';
135
+				array_unshift($links, $maintenance_link);
136
+			} else {
137
+				$org_settings_link = '<a href="admin.php?page=espresso_general_settings">'
138
+									 . esc_html__('Settings', 'event_espresso')
139
+									 . '</a>';
140
+				$events_link       = '<a href="admin.php?page=espresso_events">'
141
+									 . esc_html__('Events', 'event_espresso')
142
+									 . '</a>';
143
+				// add before other links
144
+				array_unshift($links, $org_settings_link, $events_link);
145
+			}
146
+		}
147
+		return $links;
148
+	}
149
+
150
+
151
+	/**
152
+	 * _get_request
153
+	 *
154
+	 * @return void
155
+	 * @throws EE_Error
156
+	 * @throws InvalidArgumentException
157
+	 * @throws InvalidDataTypeException
158
+	 * @throws InvalidInterfaceException
159
+	 * @throws ReflectionException
160
+	 */
161
+	public function get_request()
162
+	{
163
+		EE_Registry::instance()->load_core('Request_Handler');
164
+		EE_Registry::instance()->load_core('CPT_Strategy');
165
+	}
166
+
167
+
168
+
169
+	/**
170
+	 * hide_admin_pages_except_maintenance_mode
171
+	 *
172
+	 * @param array $admin_page_folder_names
173
+	 * @return array
174
+	 */
175
+	public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array())
176
+	{
177
+		return array(
178
+			'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS,
179
+			'about'       => EE_ADMIN_PAGES . 'about' . DS,
180
+			'support'     => EE_ADMIN_PAGES . 'support' . DS,
181
+		);
182
+	}
183
+
184
+
185
+
186
+	/**
187
+	 * init- should fire after shortcode, module,  addon, other plugin (default priority), and even
188
+	 * EE_Front_Controller's init phases have run
189
+	 *
190
+	 * @return void
191
+	 * @throws EE_Error
192
+	 * @throws InvalidArgumentException
193
+	 * @throws InvalidDataTypeException
194
+	 * @throws InvalidInterfaceException
195
+	 * @throws ReflectionException
196
+	 * @throws ServiceNotFoundException
197
+	 */
198
+	public function init()
199
+	{
200
+		//only enable most of the EE_Admin IF we're not in full maintenance mode
201
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
202
+			//ok so we want to enable the entire admin
203
+			$this->persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
204
+				'EventEspresso\core\services\notifications\PersistentAdminNoticeManager',
205
+				array(
206
+					EE_Admin_Page::add_query_args_and_nonce(
207
+						array(
208
+							'page'   => EE_Registry::instance()->REQ->get('page', ''),
209
+							'action' => EE_Registry::instance()->REQ->get('action', ''),
210
+						),
211
+						EE_ADMIN_URL
212
+					),
213
+				)
214
+			);
215
+			$this->maybeSetDatetimeWarningNotice();
216
+			//at a glance dashboard widget
217
+			add_filter('dashboard_glance_items', array($this, 'dashboard_glance_items'), 10);
218
+			//filter for get_edit_post_link used on comments for custom post types
219
+			add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2);
220
+		}
221
+		// run the admin page factory but ONLY if we are doing an ee admin ajax request
222
+		if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) {
223
+			try {
224
+				//this loads the controller for the admin pages which will setup routing etc
225
+				EE_Registry::instance()->load_core('Admin_Page_Loader');
226
+			} catch (EE_Error $e) {
227
+				$e->get_error();
228
+			}
229
+		}
230
+		add_filter('content_save_pre', array($this, 'its_eSpresso'), 10, 1);
231
+		//make sure our CPTs and custom taxonomy metaboxes get shown for first time users
232
+		add_action('admin_head', array($this, 'enable_hidden_ee_nav_menu_metaboxes'), 10);
233
+		add_action('admin_head', array($this, 'register_custom_nav_menu_boxes'), 10);
234
+		//exclude EE critical pages from all nav menus and wp_list_pages
235
+		add_filter('nav_menu_meta_box_object', array($this, 'remove_pages_from_nav_menu'), 10);
236
+	}
237
+
238
+
239
+	/**
240
+	 *    get_persistent_admin_notices
241
+	 *
242
+	 * @access    public
243
+	 * @return void
244
+	 * @throws EE_Error
245
+	 * @throws InvalidArgumentException
246
+	 * @throws InvalidDataTypeException
247
+	 * @throws InvalidInterfaceException
248
+	 */
249
+	public function maybeSetDatetimeWarningNotice()
250
+	{
251
+		//add dismissable notice for datetime changes.  Only valid if site does not have a timezone_string set.
252
+		//@todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version
253
+		//with this.  But after enough time (indeterminate at this point) we can just remove this notice.
254
+		//this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626
255
+		if (! get_option('timezone_string') && EEM_Event::instance()->count() > 0) {
256
+			new PersistentAdminNotice(
257
+				'datetime_fix_notice',
258
+				sprintf(
259
+					esc_html__(
260
+						'%1$sImportant announcement related to your install of Event Espresso%2$s: There are some changes made to your site that could affect how dates display for your events and other related items with dates and times.  Read more about it %3$shere%4$s. If your dates and times are displaying incorrectly (incorrect offset), you can fix it using the tool on %5$sthis page%4$s.',
261
+						'event_espresso'
262
+					),
263
+					'<strong>',
264
+					'</strong>',
265
+					'<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">',
266
+					'</a>',
267
+					'<a href="' . EE_Admin_Page::add_query_args_and_nonce(
268
+						array(
269
+							'page' => 'espresso_maintenance_settings',
270
+							'action' => 'datetime_tools'
271
+						),
272
+						admin_url('admin.php')
273
+					) . '">'
274
+				),
275
+				false,
276
+				'manage_options',
277
+				'datetime_fix_persistent_notice'
278
+			);
279
+		}
280
+	}
281
+
282
+
283
+
284
+	/**
285
+	 * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from
286
+	 * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in
287
+	 * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that
288
+	 * to override any queries found in the existing query for the given post type.  Note that _default_query is not a
289
+	 * normal property on the post_type object.  It's found ONLY in this particular context.
290
+	 *
291
+	 * @param WP_Post $post_type WP post type object
292
+	 * @return WP_Post
293
+	 * @throws InvalidArgumentException
294
+	 * @throws InvalidDataTypeException
295
+	 * @throws InvalidInterfaceException
296
+	 */
297
+	public function remove_pages_from_nav_menu($post_type)
298
+	{
299
+		//if this isn't the "pages" post type let's get out
300
+		if ($post_type->name !== 'page') {
301
+			return $post_type;
302
+		}
303
+		$critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array();
304
+		$post_type->_default_query = array(
305
+			'post__not_in' => $critical_pages,
306
+		);
307
+		return $post_type;
308
+	}
309
+
310
+
311
+
312
+	/**
313
+	 * WP by default only shows three metaboxes in "nav-menus.php" for first times users.  We want to make sure our
314
+	 * metaboxes get shown as well
315
+	 *
316
+	 * @return void
317
+	 */
318
+	public function enable_hidden_ee_nav_menu_metaboxes()
319
+	{
320
+		global $wp_meta_boxes, $pagenow;
321
+		if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') {
322
+			return;
323
+		}
324
+		$user = wp_get_current_user();
325
+		//has this been done yet?
326
+		if (get_user_option('ee_nav_menu_initialized', $user->ID)) {
327
+			return;
328
+		}
329
+
330
+		$hidden_meta_boxes  = get_user_option('metaboxhidden_nav-menus', $user->ID);
331
+		$initial_meta_boxes = apply_filters(
332
+			'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes',
333
+			array(
334
+				'nav-menu-theme-locations',
335
+				'add-page',
336
+				'add-custom-links',
337
+				'add-category',
338
+				'add-espresso_events',
339
+				'add-espresso_venues',
340
+				'add-espresso_event_categories',
341
+				'add-espresso_venue_categories',
342
+				'add-post-type-post',
343
+				'add-post-type-page',
344
+			)
345
+		);
346
+
347
+		if (is_array($hidden_meta_boxes)) {
348
+			foreach ($hidden_meta_boxes as $key => $meta_box_id) {
349
+				if (in_array($meta_box_id, $initial_meta_boxes, true)) {
350
+					unset($hidden_meta_boxes[$key]);
351
+				}
352
+			}
353
+		}
354
+		update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true);
355
+		update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true);
356
+	}
357
+
358
+
359
+
360
+	/**
361
+	 * This method simply registers custom nav menu boxes for "nav_menus.php route"
362
+	 * Currently EE is using this to make sure there are menu options for our CPT archive page routes.
363
+	 *
364
+	 * @todo   modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by
365
+	 *         addons etc.
366
+	 * @return void
367
+	 */
368
+	public function register_custom_nav_menu_boxes()
369
+	{
370
+		add_meta_box(
371
+			'add-extra-nav-menu-pages',
372
+			esc_html__('Event Espresso Pages', 'event_espresso'),
373
+			array($this, 'ee_cpt_archive_pages'),
374
+			'nav-menus',
375
+			'side',
376
+			'core'
377
+		);
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * Use this to edit the post link for our cpts so that the edit link points to the correct page.
384
+	 *
385
+	 * @since   4.3.0
386
+	 * @param string $link the original link generated by wp
387
+	 * @param int    $id   post id
388
+	 * @return string  the (maybe) modified link
389
+	 */
390
+	public function modify_edit_post_link($link, $id)
391
+	{
392
+		if (! $post = get_post($id)) {
393
+			return $link;
394
+		}
395
+		if ($post->post_type === 'espresso_attendees') {
396
+			$query_args = array(
397
+				'action' => 'edit_attendee',
398
+				'post'   => $id,
399
+			);
400
+			return EEH_URL::add_query_args_and_nonce(
401
+				$query_args,
402
+				admin_url('admin.php?page=espresso_registrations')
403
+			);
404
+		}
405
+		return $link;
406
+	}
407
+
408
+
409
+
410
+	public function ee_cpt_archive_pages()
411
+	{
412
+		global $nav_menu_selected_id;
413
+		$db_fields   = false;
414
+		$walker      = new Walker_Nav_Menu_Checklist($db_fields);
415
+		$current_tab = 'event-archives';
416
+		$removed_args = array(
417
+			'action',
418
+			'customlink-tab',
419
+			'edit-menu-item',
420
+			'menu-item',
421
+			'page-tab',
422
+			'_wpnonce',
423
+		);
424
+		?>
425 425
         <div id="posttype-extra-nav-menu-pages" class="posttypediv">
426 426
             <ul id="posttype-extra-nav-menu-pages-tabs" class="posttype-tabs add-menu-item-tabs">
427 427
                 <li <?php echo('event-archives' === $current_tab ? ' class="tabs"' : ''); ?>>
428 428
                     <a class="nav-tab-link" data-type="tabs-panel-posttype-extra-nav-menu-pages-event-archives"
429 429
                        href="<?php if ($nav_menu_selected_id) {
430
-                            echo esc_url(
431
-                                add_query_arg(
432
-                                    'extra-nav-menu-pages-tab',
433
-                                    'event-archives',
434
-                                    remove_query_arg($removed_args)
435
-                                )
436
-                            );
437
-                       } ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives">
430
+							echo esc_url(
431
+								add_query_arg(
432
+									'extra-nav-menu-pages-tab',
433
+									'event-archives',
434
+									remove_query_arg($removed_args)
435
+								)
436
+							);
437
+					   } ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives">
438 438
                         <?php _e('Event Archive Pages', 'event_espresso'); ?>
439 439
                     </a>
440 440
                 </li>
441 441
             </ul><!-- .posttype-tabs -->
442 442
 
443 443
             <div id="tabs-panel-posttype-extra-nav-menu-pages-event-archives" class="tabs-panel <?php
444
-                echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive');
445
-                ?>">
444
+				echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive');
445
+				?>">
446 446
                     <ul id="extra-nav-menu-pageschecklist-event-archives" class="categorychecklist form-no-clear">
447 447
                         <?php
448
-                        $pages          = $this->_get_extra_nav_menu_pages_items();
449
-                        $args['walker'] = $walker;
450
-                        echo walk_nav_menu_tree(
451
-                            array_map(
452
-                                array($this, '_setup_extra_nav_menu_pages_items'),
453
-                                $pages
454
-                            ),
455
-                            0,
456
-                            (object) $args
457
-                        );
458
-                        ?>
448
+						$pages          = $this->_get_extra_nav_menu_pages_items();
449
+						$args['walker'] = $walker;
450
+						echo walk_nav_menu_tree(
451
+							array_map(
452
+								array($this, '_setup_extra_nav_menu_pages_items'),
453
+								$pages
454
+							),
455
+							0,
456
+							(object) $args
457
+						);
458
+						?>
459 459
                     </ul>
460 460
                 </div><!-- /.tabs-panel -->
461 461
 
462 462
                 <p class="button-controls">
463 463
                 <span class="list-controls">
464 464
                     <a href="<?php
465
-                    echo esc_url(add_query_arg(
466
-                        array(
467
-                            'extra-nav-menu-pages-tab' => 'event-archives',
468
-                            'selectall'                => 1,
469
-                        ),
470
-                        remove_query_arg($removed_args)
471
-                    ));
472
-                    ?>#posttype-extra-nav-menu-pages>" class="select-all"><?php _e('Select All'); ?></a>
465
+					echo esc_url(add_query_arg(
466
+						array(
467
+							'extra-nav-menu-pages-tab' => 'event-archives',
468
+							'selectall'                => 1,
469
+						),
470
+						remove_query_arg($removed_args)
471
+					));
472
+					?>#posttype-extra-nav-menu-pages>" class="select-all"><?php _e('Select All'); ?></a>
473 473
                 </span>
474 474
                 <span class="add-to-menu">
475 475
                     <input type="submit"<?php wp_nav_menu_disabled_check($nav_menu_selected_id); ?>
@@ -482,471 +482,471 @@  discard block
 block discarded – undo
482 482
 
483 483
         </div><!-- /.posttypediv -->
484 484
         <?php
485
-    }
486
-
487
-
488
-    /**
489
-     * Returns an array of event archive nav items.
490
-     *
491
-     * @todo  for now this method is just in place so when it gets abstracted further we can substitute in whatever
492
-     *        method we use for getting the extra nav menu items
493
-     * @return array
494
-     */
495
-    private function _get_extra_nav_menu_pages_items()
496
-    {
497
-        $menuitems[] = array(
498
-            'title'       => esc_html__('Event List', 'event_espresso'),
499
-            'url'         => get_post_type_archive_link('espresso_events'),
500
-            'description' => esc_html__('Archive page for all events.', 'event_espresso'),
501
-        );
502
-        return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems);
503
-    }
504
-
505
-
506
-    /**
507
-     * Setup nav menu walker item for usage in the event archive nav menu metabox.  It receives a menu_item array with
508
-     * the properties and converts it to the menu item object.
509
-     *
510
-     * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php
511
-     * @param $menu_item_values
512
-     * @return stdClass
513
-     */
514
-    private function _setup_extra_nav_menu_pages_items($menu_item_values)
515
-    {
516
-        $menu_item = new stdClass();
517
-        $keys      = array(
518
-            'ID'               => 0,
519
-            'db_id'            => 0,
520
-            'menu_item_parent' => 0,
521
-            'object_id'        => -1,
522
-            'post_parent'      => 0,
523
-            'type'             => 'custom',
524
-            'object'           => '',
525
-            'type_label'       => esc_html__('Extra Nav Menu Item', 'event_espresso'),
526
-            'title'            => '',
527
-            'url'              => '',
528
-            'target'           => '',
529
-            'attr_title'       => '',
530
-            'description'      => '',
531
-            'classes'          => array(),
532
-            'xfn'              => '',
533
-        );
534
-
535
-        foreach ($keys as $key => $value) {
536
-            $menu_item->{$key} = isset($menu_item_values[$key]) ? $menu_item_values[$key] : $value;
537
-        }
538
-        return $menu_item;
539
-    }
540
-
541
-
542
-    /**
543
-     * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an
544
-     * EE_Admin_Page route is called.
545
-     *
546
-     * @return void
547
-     */
548
-    public function route_admin_request()
549
-    {
550
-    }
551
-
552
-
553
-    /**
554
-     * wp_loaded should fire on the WordPress wp_loaded hook.  This fires on a VERY late priority.
555
-     *
556
-     * @return void
557
-     */
558
-    public function wp_loaded()
559
-    {
560
-    }
561
-
562
-
563
-    /**
564
-     * admin_init
565
-     *
566
-     * @return void
567
-     * @throws EE_Error
568
-     * @throws InvalidArgumentException
569
-     * @throws InvalidDataTypeException
570
-     * @throws InvalidInterfaceException
571
-     * @throws ReflectionException
572
-     */
573
-    public function admin_init()
574
-    {
575
-
576
-        /**
577
-         * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php),
578
-         * so any hooking into core WP routes is taken care of.  So in this next few lines of code:
579
-         * - check if doing post processing.
580
-         * - check if doing post processing of one of EE CPTs
581
-         * - instantiate the corresponding EE CPT model for the post_type being processed.
582
-         */
583
-        if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') {
584
-            EE_Registry::instance()->load_core('Register_CPTs');
585
-            EE_Register_CPTs::instantiate_cpt_models($_POST['post_type']);
586
-        }
587
-
588
-
589
-        /**
590
-         * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting
591
-         * critical pages.  The only place critical pages need included in a generated dropdown is on the "Critical
592
-         * Pages" tab in the EE General Settings Admin page.
593
-         * This is for user-proofing.
594
-         */
595
-        add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages'));
596
-    }
597
-
598
-
599
-    /**
600
-     * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection.
601
-     *
602
-     * @param string $output Current output.
603
-     * @return string
604
-     * @throws InvalidArgumentException
605
-     * @throws InvalidDataTypeException
606
-     * @throws InvalidInterfaceException
607
-     */
608
-    public function modify_dropdown_pages($output)
609
-    {
610
-        //get critical pages
611
-        $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array();
612
-
613
-        //split current output by line break for easier parsing.
614
-        $split_output = explode("\n", $output);
615
-
616
-        //loop through to remove any critical pages from the array.
617
-        foreach ($critical_pages as $page_id) {
618
-            $needle = 'value="' . $page_id . '"';
619
-            foreach ($split_output as $key => $haystack) {
620
-                if (strpos($haystack, $needle) !== false) {
621
-                    unset($split_output[$key]);
622
-                }
623
-            }
624
-        }
625
-        //replace output with the new contents
626
-        return implode("\n", $split_output);
627
-    }
628
-
629
-
630
-    /**
631
-     * enqueue all admin scripts that need loaded for admin pages
632
-     *
633
-     * @return void
634
-     */
635
-    public function enqueue_admin_scripts()
636
-    {
637
-        // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js.
638
-        // Note: the intention of this script is to only do TARGETED injections.  I.E, only injecting on certain script
639
-        // calls.
640
-        wp_enqueue_script(
641
-            'ee-inject-wp',
642
-            EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
643
-            array('jquery'),
644
-            EVENT_ESPRESSO_VERSION,
645
-            true
646
-        );
647
-        // register cookie script for future dependencies
648
-        wp_register_script(
649
-            'jquery-cookie',
650
-            EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
651
-            array('jquery'),
652
-            '2.1',
653
-            true
654
-        );
655
-        //joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again
656
-        // via: add_filter('FHEE_load_joyride', '__return_true' );
657
-        if (apply_filters('FHEE_load_joyride', false)) {
658
-            //joyride style
659
-            wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1');
660
-            wp_register_style(
661
-                'ee-joyride-css',
662
-                EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
663
-                array('joyride-css'),
664
-                EVENT_ESPRESSO_VERSION
665
-            );
666
-            wp_register_script(
667
-                'joyride-modernizr',
668
-                EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
669
-                array(),
670
-                '2.1',
671
-                true
672
-            );
673
-            //joyride JS
674
-            wp_register_script(
675
-                'jquery-joyride',
676
-                EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
677
-                array('jquery-cookie', 'joyride-modernizr'),
678
-                '2.1',
679
-                true
680
-            );
681
-            // wanna go for a joyride?
682
-            wp_enqueue_style('ee-joyride-css');
683
-            wp_enqueue_script('jquery-joyride');
684
-        }
685
-    }
686
-
687
-
688
-    /**
689
-     * display_admin_notices
690
-     *
691
-     * @return void
692
-     */
693
-    public function display_admin_notices()
694
-    {
695
-        echo EE_Error::get_notices();
696
-    }
697
-
698
-
699
-
700
-    /**
701
-     * @param array $elements
702
-     * @return array
703
-     * @throws EE_Error
704
-     * @throws InvalidArgumentException
705
-     * @throws InvalidDataTypeException
706
-     * @throws InvalidInterfaceException
707
-     */
708
-    public function dashboard_glance_items($elements)
709
-    {
710
-        $elements                        = is_array($elements) ? $elements : array($elements);
711
-        $events                          = EEM_Event::instance()->count();
712
-        $items['events']['url']          = EE_Admin_Page::add_query_args_and_nonce(
713
-            array('page' => 'espresso_events'),
714
-            admin_url('admin.php')
715
-        );
716
-        $items['events']['text']         = sprintf(_n('%s Event', '%s Events', $events), number_format_i18n($events));
717
-        $items['events']['title']        = esc_html__('Click to view all Events', 'event_espresso');
718
-        $registrations                   = EEM_Registration::instance()->count(
719
-            array(
720
-                array(
721
-                    'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
722
-                ),
723
-            )
724
-        );
725
-        $items['registrations']['url']   = EE_Admin_Page::add_query_args_and_nonce(
726
-            array('page' => 'espresso_registrations'),
727
-            admin_url('admin.php')
728
-        );
729
-        $items['registrations']['text']  = sprintf(
730
-            _n('%s Registration', '%s Registrations', $registrations),
731
-            number_format_i18n($registrations)
732
-        );
733
-        $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso');
734
-
735
-        $items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items);
736
-
737
-        foreach ($items as $type => $item_properties) {
738
-            $elements[] = sprintf(
739
-                '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>',
740
-                $item_properties['url'],
741
-                $item_properties['title'],
742
-                $item_properties['text']
743
-            );
744
-        }
745
-        return $elements;
746
-    }
747
-
748
-
749
-    /**
750
-     * check_for_invalid_datetime_formats
751
-     * if an admin changes their date or time format settings on the WP General Settings admin page, verify that
752
-     * their selected format can be parsed by PHP
753
-     *
754
-     * @param    $value
755
-     * @param    $option
756
-     * @throws EE_Error
757
-     * @return    string
758
-     */
759
-    public function check_for_invalid_datetime_formats($value, $option)
760
-    {
761
-        // check for date_format or time_format
762
-        switch ($option) {
763
-            case 'date_format':
764
-                $date_time_format = $value . ' ' . get_option('time_format');
765
-                break;
766
-            case 'time_format':
767
-                $date_time_format = get_option('date_format') . ' ' . $value;
768
-                break;
769
-            default:
770
-                $date_time_format = false;
771
-        }
772
-        // do we have a date_time format to check ?
773
-        if ($date_time_format) {
774
-            $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format);
775
-
776
-            if (is_array($error_msg)) {
777
-                $msg = '<p>'
778
-                       . sprintf(
779
-                           esc_html__(
780
-                               'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:',
781
-                               'event_espresso'
782
-                           ),
783
-                           date($date_time_format),
784
-                           $date_time_format
785
-                       )
786
-                       . '</p><p><ul>';
787
-
788
-
789
-                foreach ($error_msg as $error) {
790
-                    $msg .= '<li>' . $error . '</li>';
791
-                }
792
-
793
-                $msg .= '</ul></p><p>'
794
-                        . sprintf(
795
-                            esc_html__(
796
-                                '%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s',
797
-                                'event_espresso'
798
-                            ),
799
-                            '<span style="color:#D54E21;">',
800
-                            '</span>'
801
-                        )
802
-                        . '</p>';
803
-
804
-                // trigger WP settings error
805
-                add_settings_error(
806
-                    'date_format',
807
-                    'date_format',
808
-                    $msg
809
-                );
810
-
811
-                // set format to something valid
812
-                switch ($option) {
813
-                    case 'date_format':
814
-                        $value = 'F j, Y';
815
-                        break;
816
-                    case 'time_format':
817
-                        $value = 'g:i a';
818
-                        break;
819
-                }
820
-            }
821
-        }
822
-        return $value;
823
-    }
824
-
825
-
826
-    /**
827
-     * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso"
828
-     *
829
-     * @param $content
830
-     * @return    string
831
-     */
832
-    public function its_eSpresso($content)
833
-    {
834
-        return str_replace('[EXPRESSO_', '[ESPRESSO_', $content);
835
-    }
836
-
837
-
838
-    /**
839
-     * espresso_admin_footer
840
-     *
841
-     * @return    string
842
-     */
843
-    public function espresso_admin_footer()
844
-    {
845
-        return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer'));
846
-    }
847
-
848
-
849
-    /**
850
-     * static method for registering ee admin page.
851
-     * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register.
852
-     *
853
-     * @since      4.3.0
854
-     * @deprecated 4.3.0    Use EE_Register_Admin_Page::register() instead
855
-     * @see        EE_Register_Admin_Page::register()
856
-     * @param       $page_basename
857
-     * @param       $page_path
858
-     * @param array $config
859
-     * @return void
860
-     * @throws EE_Error
861
-     */
862
-    public static function register_ee_admin_page($page_basename, $page_path, $config = array())
863
-    {
864
-        EE_Error::doing_it_wrong(
865
-            __METHOD__,
866
-            sprintf(
867
-                esc_html__(
868
-                    'Usage is deprecated.  Use EE_Register_Admin_Page::register() for registering the %s admin page.',
869
-                    'event_espresso'
870
-                ),
871
-                $page_basename
872
-            ),
873
-            '4.3'
874
-        );
875
-        if (class_exists('EE_Register_Admin_Page')) {
876
-            $config['page_path'] = $page_path;
877
-        }
878
-        EE_Register_Admin_Page::register($page_basename, $config);
879
-    }
880
-
881
-
882
-    /**
883
-     * @deprecated 4.8.41
884
-     * @param  int      $post_ID
885
-     * @param  \WP_Post $post
886
-     * @return void
887
-     */
888
-    public static function parse_post_content_on_save($post_ID, $post)
889
-    {
890
-        EE_Error::doing_it_wrong(
891
-            __METHOD__,
892
-            esc_html__('Usage is deprecated', 'event_espresso'),
893
-            '4.8.41'
894
-        );
895
-    }
896
-
897
-
898
-    /**
899
-     * @deprecated 4.8.41
900
-     * @param  $option
901
-     * @param  $old_value
902
-     * @param  $value
903
-     * @return void
904
-     */
905
-    public function reset_page_for_posts_on_change($option, $old_value, $value)
906
-    {
907
-        EE_Error::doing_it_wrong(
908
-            __METHOD__,
909
-            esc_html__('Usage is deprecated', 'event_espresso'),
910
-            '4.8.41'
911
-        );
912
-    }
913
-
914
-
915
-
916
-    /**
917
-     * @deprecated 4.9.27
918
-     * @return void
919
-     */
920
-    public function get_persistent_admin_notices()
921
-    {
922
-        EE_Error::doing_it_wrong(
923
-            __METHOD__,
924
-            sprintf(
925
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
926
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
927
-            ),
928
-            '4.9.27'
929
-        );
930
-    }
931
-
932
-
933
-
934
-    /**
935
-     * @deprecated 4.9.27
936
-     * @throws InvalidInterfaceException
937
-     * @throws InvalidDataTypeException
938
-     * @throws DomainException
939
-     */
940
-    public function dismiss_ee_nag_notice_callback()
941
-    {
942
-        EE_Error::doing_it_wrong(
943
-            __METHOD__,
944
-            sprintf(
945
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
946
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
947
-            ),
948
-            '4.9.27'
949
-        );
950
-        $this->persistent_admin_notice_manager->dismissNotice();
951
-    }
485
+	}
486
+
487
+
488
+	/**
489
+	 * Returns an array of event archive nav items.
490
+	 *
491
+	 * @todo  for now this method is just in place so when it gets abstracted further we can substitute in whatever
492
+	 *        method we use for getting the extra nav menu items
493
+	 * @return array
494
+	 */
495
+	private function _get_extra_nav_menu_pages_items()
496
+	{
497
+		$menuitems[] = array(
498
+			'title'       => esc_html__('Event List', 'event_espresso'),
499
+			'url'         => get_post_type_archive_link('espresso_events'),
500
+			'description' => esc_html__('Archive page for all events.', 'event_espresso'),
501
+		);
502
+		return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems);
503
+	}
504
+
505
+
506
+	/**
507
+	 * Setup nav menu walker item for usage in the event archive nav menu metabox.  It receives a menu_item array with
508
+	 * the properties and converts it to the menu item object.
509
+	 *
510
+	 * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php
511
+	 * @param $menu_item_values
512
+	 * @return stdClass
513
+	 */
514
+	private function _setup_extra_nav_menu_pages_items($menu_item_values)
515
+	{
516
+		$menu_item = new stdClass();
517
+		$keys      = array(
518
+			'ID'               => 0,
519
+			'db_id'            => 0,
520
+			'menu_item_parent' => 0,
521
+			'object_id'        => -1,
522
+			'post_parent'      => 0,
523
+			'type'             => 'custom',
524
+			'object'           => '',
525
+			'type_label'       => esc_html__('Extra Nav Menu Item', 'event_espresso'),
526
+			'title'            => '',
527
+			'url'              => '',
528
+			'target'           => '',
529
+			'attr_title'       => '',
530
+			'description'      => '',
531
+			'classes'          => array(),
532
+			'xfn'              => '',
533
+		);
534
+
535
+		foreach ($keys as $key => $value) {
536
+			$menu_item->{$key} = isset($menu_item_values[$key]) ? $menu_item_values[$key] : $value;
537
+		}
538
+		return $menu_item;
539
+	}
540
+
541
+
542
+	/**
543
+	 * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an
544
+	 * EE_Admin_Page route is called.
545
+	 *
546
+	 * @return void
547
+	 */
548
+	public function route_admin_request()
549
+	{
550
+	}
551
+
552
+
553
+	/**
554
+	 * wp_loaded should fire on the WordPress wp_loaded hook.  This fires on a VERY late priority.
555
+	 *
556
+	 * @return void
557
+	 */
558
+	public function wp_loaded()
559
+	{
560
+	}
561
+
562
+
563
+	/**
564
+	 * admin_init
565
+	 *
566
+	 * @return void
567
+	 * @throws EE_Error
568
+	 * @throws InvalidArgumentException
569
+	 * @throws InvalidDataTypeException
570
+	 * @throws InvalidInterfaceException
571
+	 * @throws ReflectionException
572
+	 */
573
+	public function admin_init()
574
+	{
575
+
576
+		/**
577
+		 * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php),
578
+		 * so any hooking into core WP routes is taken care of.  So in this next few lines of code:
579
+		 * - check if doing post processing.
580
+		 * - check if doing post processing of one of EE CPTs
581
+		 * - instantiate the corresponding EE CPT model for the post_type being processed.
582
+		 */
583
+		if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') {
584
+			EE_Registry::instance()->load_core('Register_CPTs');
585
+			EE_Register_CPTs::instantiate_cpt_models($_POST['post_type']);
586
+		}
587
+
588
+
589
+		/**
590
+		 * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting
591
+		 * critical pages.  The only place critical pages need included in a generated dropdown is on the "Critical
592
+		 * Pages" tab in the EE General Settings Admin page.
593
+		 * This is for user-proofing.
594
+		 */
595
+		add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages'));
596
+	}
597
+
598
+
599
+	/**
600
+	 * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection.
601
+	 *
602
+	 * @param string $output Current output.
603
+	 * @return string
604
+	 * @throws InvalidArgumentException
605
+	 * @throws InvalidDataTypeException
606
+	 * @throws InvalidInterfaceException
607
+	 */
608
+	public function modify_dropdown_pages($output)
609
+	{
610
+		//get critical pages
611
+		$critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array();
612
+
613
+		//split current output by line break for easier parsing.
614
+		$split_output = explode("\n", $output);
615
+
616
+		//loop through to remove any critical pages from the array.
617
+		foreach ($critical_pages as $page_id) {
618
+			$needle = 'value="' . $page_id . '"';
619
+			foreach ($split_output as $key => $haystack) {
620
+				if (strpos($haystack, $needle) !== false) {
621
+					unset($split_output[$key]);
622
+				}
623
+			}
624
+		}
625
+		//replace output with the new contents
626
+		return implode("\n", $split_output);
627
+	}
628
+
629
+
630
+	/**
631
+	 * enqueue all admin scripts that need loaded for admin pages
632
+	 *
633
+	 * @return void
634
+	 */
635
+	public function enqueue_admin_scripts()
636
+	{
637
+		// this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js.
638
+		// Note: the intention of this script is to only do TARGETED injections.  I.E, only injecting on certain script
639
+		// calls.
640
+		wp_enqueue_script(
641
+			'ee-inject-wp',
642
+			EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
643
+			array('jquery'),
644
+			EVENT_ESPRESSO_VERSION,
645
+			true
646
+		);
647
+		// register cookie script for future dependencies
648
+		wp_register_script(
649
+			'jquery-cookie',
650
+			EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
651
+			array('jquery'),
652
+			'2.1',
653
+			true
654
+		);
655
+		//joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again
656
+		// via: add_filter('FHEE_load_joyride', '__return_true' );
657
+		if (apply_filters('FHEE_load_joyride', false)) {
658
+			//joyride style
659
+			wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1');
660
+			wp_register_style(
661
+				'ee-joyride-css',
662
+				EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
663
+				array('joyride-css'),
664
+				EVENT_ESPRESSO_VERSION
665
+			);
666
+			wp_register_script(
667
+				'joyride-modernizr',
668
+				EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
669
+				array(),
670
+				'2.1',
671
+				true
672
+			);
673
+			//joyride JS
674
+			wp_register_script(
675
+				'jquery-joyride',
676
+				EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
677
+				array('jquery-cookie', 'joyride-modernizr'),
678
+				'2.1',
679
+				true
680
+			);
681
+			// wanna go for a joyride?
682
+			wp_enqueue_style('ee-joyride-css');
683
+			wp_enqueue_script('jquery-joyride');
684
+		}
685
+	}
686
+
687
+
688
+	/**
689
+	 * display_admin_notices
690
+	 *
691
+	 * @return void
692
+	 */
693
+	public function display_admin_notices()
694
+	{
695
+		echo EE_Error::get_notices();
696
+	}
697
+
698
+
699
+
700
+	/**
701
+	 * @param array $elements
702
+	 * @return array
703
+	 * @throws EE_Error
704
+	 * @throws InvalidArgumentException
705
+	 * @throws InvalidDataTypeException
706
+	 * @throws InvalidInterfaceException
707
+	 */
708
+	public function dashboard_glance_items($elements)
709
+	{
710
+		$elements                        = is_array($elements) ? $elements : array($elements);
711
+		$events                          = EEM_Event::instance()->count();
712
+		$items['events']['url']          = EE_Admin_Page::add_query_args_and_nonce(
713
+			array('page' => 'espresso_events'),
714
+			admin_url('admin.php')
715
+		);
716
+		$items['events']['text']         = sprintf(_n('%s Event', '%s Events', $events), number_format_i18n($events));
717
+		$items['events']['title']        = esc_html__('Click to view all Events', 'event_espresso');
718
+		$registrations                   = EEM_Registration::instance()->count(
719
+			array(
720
+				array(
721
+					'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
722
+				),
723
+			)
724
+		);
725
+		$items['registrations']['url']   = EE_Admin_Page::add_query_args_and_nonce(
726
+			array('page' => 'espresso_registrations'),
727
+			admin_url('admin.php')
728
+		);
729
+		$items['registrations']['text']  = sprintf(
730
+			_n('%s Registration', '%s Registrations', $registrations),
731
+			number_format_i18n($registrations)
732
+		);
733
+		$items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso');
734
+
735
+		$items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items);
736
+
737
+		foreach ($items as $type => $item_properties) {
738
+			$elements[] = sprintf(
739
+				'<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>',
740
+				$item_properties['url'],
741
+				$item_properties['title'],
742
+				$item_properties['text']
743
+			);
744
+		}
745
+		return $elements;
746
+	}
747
+
748
+
749
+	/**
750
+	 * check_for_invalid_datetime_formats
751
+	 * if an admin changes their date or time format settings on the WP General Settings admin page, verify that
752
+	 * their selected format can be parsed by PHP
753
+	 *
754
+	 * @param    $value
755
+	 * @param    $option
756
+	 * @throws EE_Error
757
+	 * @return    string
758
+	 */
759
+	public function check_for_invalid_datetime_formats($value, $option)
760
+	{
761
+		// check for date_format or time_format
762
+		switch ($option) {
763
+			case 'date_format':
764
+				$date_time_format = $value . ' ' . get_option('time_format');
765
+				break;
766
+			case 'time_format':
767
+				$date_time_format = get_option('date_format') . ' ' . $value;
768
+				break;
769
+			default:
770
+				$date_time_format = false;
771
+		}
772
+		// do we have a date_time format to check ?
773
+		if ($date_time_format) {
774
+			$error_msg = EEH_DTT_Helper::validate_format_string($date_time_format);
775
+
776
+			if (is_array($error_msg)) {
777
+				$msg = '<p>'
778
+					   . sprintf(
779
+						   esc_html__(
780
+							   'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:',
781
+							   'event_espresso'
782
+						   ),
783
+						   date($date_time_format),
784
+						   $date_time_format
785
+					   )
786
+					   . '</p><p><ul>';
787
+
788
+
789
+				foreach ($error_msg as $error) {
790
+					$msg .= '<li>' . $error . '</li>';
791
+				}
792
+
793
+				$msg .= '</ul></p><p>'
794
+						. sprintf(
795
+							esc_html__(
796
+								'%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s',
797
+								'event_espresso'
798
+							),
799
+							'<span style="color:#D54E21;">',
800
+							'</span>'
801
+						)
802
+						. '</p>';
803
+
804
+				// trigger WP settings error
805
+				add_settings_error(
806
+					'date_format',
807
+					'date_format',
808
+					$msg
809
+				);
810
+
811
+				// set format to something valid
812
+				switch ($option) {
813
+					case 'date_format':
814
+						$value = 'F j, Y';
815
+						break;
816
+					case 'time_format':
817
+						$value = 'g:i a';
818
+						break;
819
+				}
820
+			}
821
+		}
822
+		return $value;
823
+	}
824
+
825
+
826
+	/**
827
+	 * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso"
828
+	 *
829
+	 * @param $content
830
+	 * @return    string
831
+	 */
832
+	public function its_eSpresso($content)
833
+	{
834
+		return str_replace('[EXPRESSO_', '[ESPRESSO_', $content);
835
+	}
836
+
837
+
838
+	/**
839
+	 * espresso_admin_footer
840
+	 *
841
+	 * @return    string
842
+	 */
843
+	public function espresso_admin_footer()
844
+	{
845
+		return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer'));
846
+	}
847
+
848
+
849
+	/**
850
+	 * static method for registering ee admin page.
851
+	 * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register.
852
+	 *
853
+	 * @since      4.3.0
854
+	 * @deprecated 4.3.0    Use EE_Register_Admin_Page::register() instead
855
+	 * @see        EE_Register_Admin_Page::register()
856
+	 * @param       $page_basename
857
+	 * @param       $page_path
858
+	 * @param array $config
859
+	 * @return void
860
+	 * @throws EE_Error
861
+	 */
862
+	public static function register_ee_admin_page($page_basename, $page_path, $config = array())
863
+	{
864
+		EE_Error::doing_it_wrong(
865
+			__METHOD__,
866
+			sprintf(
867
+				esc_html__(
868
+					'Usage is deprecated.  Use EE_Register_Admin_Page::register() for registering the %s admin page.',
869
+					'event_espresso'
870
+				),
871
+				$page_basename
872
+			),
873
+			'4.3'
874
+		);
875
+		if (class_exists('EE_Register_Admin_Page')) {
876
+			$config['page_path'] = $page_path;
877
+		}
878
+		EE_Register_Admin_Page::register($page_basename, $config);
879
+	}
880
+
881
+
882
+	/**
883
+	 * @deprecated 4.8.41
884
+	 * @param  int      $post_ID
885
+	 * @param  \WP_Post $post
886
+	 * @return void
887
+	 */
888
+	public static function parse_post_content_on_save($post_ID, $post)
889
+	{
890
+		EE_Error::doing_it_wrong(
891
+			__METHOD__,
892
+			esc_html__('Usage is deprecated', 'event_espresso'),
893
+			'4.8.41'
894
+		);
895
+	}
896
+
897
+
898
+	/**
899
+	 * @deprecated 4.8.41
900
+	 * @param  $option
901
+	 * @param  $old_value
902
+	 * @param  $value
903
+	 * @return void
904
+	 */
905
+	public function reset_page_for_posts_on_change($option, $old_value, $value)
906
+	{
907
+		EE_Error::doing_it_wrong(
908
+			__METHOD__,
909
+			esc_html__('Usage is deprecated', 'event_espresso'),
910
+			'4.8.41'
911
+		);
912
+	}
913
+
914
+
915
+
916
+	/**
917
+	 * @deprecated 4.9.27
918
+	 * @return void
919
+	 */
920
+	public function get_persistent_admin_notices()
921
+	{
922
+		EE_Error::doing_it_wrong(
923
+			__METHOD__,
924
+			sprintf(
925
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
926
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
927
+			),
928
+			'4.9.27'
929
+		);
930
+	}
931
+
932
+
933
+
934
+	/**
935
+	 * @deprecated 4.9.27
936
+	 * @throws InvalidInterfaceException
937
+	 * @throws InvalidDataTypeException
938
+	 * @throws DomainException
939
+	 */
940
+	public function dismiss_ee_nag_notice_callback()
941
+	{
942
+		EE_Error::doing_it_wrong(
943
+			__METHOD__,
944
+			sprintf(
945
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
946
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
947
+			),
948
+			'4.9.27'
949
+		);
950
+		$this->persistent_admin_notice_manager->dismissNotice();
951
+	}
952 952
 }
Please login to merge, or discard this patch.
Spacing   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
     public static function instance()
41 41
     {
42 42
         // check if class object is instantiated
43
-        if (! self::$_instance instanceof EE_Admin) {
43
+        if ( ! self::$_instance instanceof EE_Admin) {
44 44
             self::$_instance = new self();
45 45
         }
46 46
         return self::$_instance;
@@ -100,11 +100,11 @@  discard block
 block discarded – undo
100 100
      */
101 101
     private function _define_all_constants()
102 102
     {
103
-        if (! defined('EE_ADMIN_URL')) {
104
-            define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL . 'core/admin/');
105
-            define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL . 'admin_pages/');
106
-            define('EE_ADMIN_TEMPLATE', EE_ADMIN . 'templates' . DS);
107
-            define('WP_ADMIN_PATH', ABSPATH . 'wp-admin/');
103
+        if ( ! defined('EE_ADMIN_URL')) {
104
+            define('EE_ADMIN_URL', EE_PLUGIN_DIR_URL.'core/admin/');
105
+            define('EE_ADMIN_PAGES_URL', EE_PLUGIN_DIR_URL.'admin_pages/');
106
+            define('EE_ADMIN_TEMPLATE', EE_ADMIN.'templates'.DS);
107
+            define('WP_ADMIN_PATH', ABSPATH.'wp-admin/');
108 108
             define('WP_AJAX_URL', admin_url('admin-ajax.php'));
109 109
         }
110 110
     }
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
         // set $main_file in stone
123 123
         static $main_file;
124 124
         // if $main_file is not set yet
125
-        if (! $main_file) {
125
+        if ( ! $main_file) {
126 126
             $main_file = plugin_basename(EVENT_ESPRESSO_MAIN_FILE);
127 127
         }
128 128
         if ($plugin === $main_file) {
@@ -175,9 +175,9 @@  discard block
 block discarded – undo
175 175
     public function hide_admin_pages_except_maintenance_mode($admin_page_folder_names = array())
176 176
     {
177 177
         return array(
178
-            'maintenance' => EE_ADMIN_PAGES . 'maintenance' . DS,
179
-            'about'       => EE_ADMIN_PAGES . 'about' . DS,
180
-            'support'     => EE_ADMIN_PAGES . 'support' . DS,
178
+            'maintenance' => EE_ADMIN_PAGES.'maintenance'.DS,
179
+            'about'       => EE_ADMIN_PAGES.'about'.DS,
180
+            'support'     => EE_ADMIN_PAGES.'support'.DS,
181 181
         );
182 182
     }
183 183
 
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
             add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 2);
220 220
         }
221 221
         // run the admin page factory but ONLY if we are doing an ee admin ajax request
222
-        if (! defined('DOING_AJAX') || EE_ADMIN_AJAX) {
222
+        if ( ! defined('DOING_AJAX') || EE_ADMIN_AJAX) {
223 223
             try {
224 224
                 //this loads the controller for the admin pages which will setup routing etc
225 225
                 EE_Registry::instance()->load_core('Admin_Page_Loader');
@@ -252,7 +252,7 @@  discard block
 block discarded – undo
252 252
         //@todo This needs to stay in core for a bit to catch anyone upgrading from a version without this to a version
253 253
         //with this.  But after enough time (indeterminate at this point) we can just remove this notice.
254 254
         //this was added with https://events.codebasehq.com/projects/event-espresso/tickets/10626
255
-        if (! get_option('timezone_string') && EEM_Event::instance()->count() > 0) {
255
+        if ( ! get_option('timezone_string') && EEM_Event::instance()->count() > 0) {
256 256
             new PersistentAdminNotice(
257 257
                 'datetime_fix_notice',
258 258
                 sprintf(
@@ -264,13 +264,13 @@  discard block
 block discarded – undo
264 264
                     '</strong>',
265 265
                     '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">',
266 266
                     '</a>',
267
-                    '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
267
+                    '<a href="'.EE_Admin_Page::add_query_args_and_nonce(
268 268
                         array(
269 269
                             'page' => 'espresso_maintenance_settings',
270 270
                             'action' => 'datetime_tools'
271 271
                         ),
272 272
                         admin_url('admin.php')
273
-                    ) . '">'
273
+                    ).'">'
274 274
                 ),
275 275
                 false,
276 276
                 'manage_options',
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
     public function enable_hidden_ee_nav_menu_metaboxes()
319 319
     {
320 320
         global $wp_meta_boxes, $pagenow;
321
-        if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') {
321
+        if ( ! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') {
322 322
             return;
323 323
         }
324 324
         $user = wp_get_current_user();
@@ -389,7 +389,7 @@  discard block
 block discarded – undo
389 389
      */
390 390
     public function modify_edit_post_link($link, $id)
391 391
     {
392
-        if (! $post = get_post($id)) {
392
+        if ( ! $post = get_post($id)) {
393 393
             return $link;
394 394
         }
395 395
         if ($post->post_type === 'espresso_attendees') {
@@ -615,7 +615,7 @@  discard block
 block discarded – undo
615 615
 
616 616
         //loop through to remove any critical pages from the array.
617 617
         foreach ($critical_pages as $page_id) {
618
-            $needle = 'value="' . $page_id . '"';
618
+            $needle = 'value="'.$page_id.'"';
619 619
             foreach ($split_output as $key => $haystack) {
620 620
                 if (strpos($haystack, $needle) !== false) {
621 621
                     unset($split_output[$key]);
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
         // calls.
640 640
         wp_enqueue_script(
641 641
             'ee-inject-wp',
642
-            EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
642
+            EE_ADMIN_URL.'assets/ee-cpt-wp-injects.js',
643 643
             array('jquery'),
644 644
             EVENT_ESPRESSO_VERSION,
645 645
             true
@@ -647,7 +647,7 @@  discard block
 block discarded – undo
647 647
         // register cookie script for future dependencies
648 648
         wp_register_script(
649 649
             'jquery-cookie',
650
-            EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
650
+            EE_THIRD_PARTY_URL.'joyride/jquery.cookie.js',
651 651
             array('jquery'),
652 652
             '2.1',
653 653
             true
@@ -656,16 +656,16 @@  discard block
 block discarded – undo
656 656
         // via: add_filter('FHEE_load_joyride', '__return_true' );
657 657
         if (apply_filters('FHEE_load_joyride', false)) {
658 658
             //joyride style
659
-            wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1');
659
+            wp_register_style('joyride-css', EE_THIRD_PARTY_URL.'joyride/joyride-2.1.css', array(), '2.1');
660 660
             wp_register_style(
661 661
                 'ee-joyride-css',
662
-                EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
662
+                EE_GLOBAL_ASSETS_URL.'css/ee-joyride-styles.css',
663 663
                 array('joyride-css'),
664 664
                 EVENT_ESPRESSO_VERSION
665 665
             );
666 666
             wp_register_script(
667 667
                 'joyride-modernizr',
668
-                EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
668
+                EE_THIRD_PARTY_URL.'joyride/modernizr.mq.js',
669 669
                 array(),
670 670
                 '2.1',
671 671
                 true
@@ -673,7 +673,7 @@  discard block
 block discarded – undo
673 673
             //joyride JS
674 674
             wp_register_script(
675 675
                 'jquery-joyride',
676
-                EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
676
+                EE_THIRD_PARTY_URL.'joyride/jquery.joyride-2.1.js',
677 677
                 array('jquery-cookie', 'joyride-modernizr'),
678 678
                 '2.1',
679 679
                 true
@@ -722,21 +722,21 @@  discard block
 block discarded – undo
722 722
                 ),
723 723
             )
724 724
         );
725
-        $items['registrations']['url']   = EE_Admin_Page::add_query_args_and_nonce(
725
+        $items['registrations']['url'] = EE_Admin_Page::add_query_args_and_nonce(
726 726
             array('page' => 'espresso_registrations'),
727 727
             admin_url('admin.php')
728 728
         );
729
-        $items['registrations']['text']  = sprintf(
729
+        $items['registrations']['text'] = sprintf(
730 730
             _n('%s Registration', '%s Registrations', $registrations),
731 731
             number_format_i18n($registrations)
732 732
         );
733 733
         $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso');
734 734
 
735
-        $items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items);
735
+        $items = (array) apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items);
736 736
 
737 737
         foreach ($items as $type => $item_properties) {
738 738
             $elements[] = sprintf(
739
-                '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>',
739
+                '<a class="ee-dashboard-link-'.$type.'" href="%s" title="%s">%s</a>',
740 740
                 $item_properties['url'],
741 741
                 $item_properties['title'],
742 742
                 $item_properties['text']
@@ -761,10 +761,10 @@  discard block
 block discarded – undo
761 761
         // check for date_format or time_format
762 762
         switch ($option) {
763 763
             case 'date_format':
764
-                $date_time_format = $value . ' ' . get_option('time_format');
764
+                $date_time_format = $value.' '.get_option('time_format');
765 765
                 break;
766 766
             case 'time_format':
767
-                $date_time_format = get_option('date_format') . ' ' . $value;
767
+                $date_time_format = get_option('date_format').' '.$value;
768 768
                 break;
769 769
             default:
770 770
                 $date_time_format = false;
@@ -787,7 +787,7 @@  discard block
 block discarded – undo
787 787
 
788 788
 
789 789
                 foreach ($error_msg as $error) {
790
-                    $msg .= '<li>' . $error . '</li>';
790
+                    $msg .= '<li>'.$error.'</li>';
791 791
                 }
792 792
 
793 793
                 $msg .= '</ul></p><p>'
Please login to merge, or discard this patch.
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 2 patches
Indentation   +640 added lines, -640 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 /**
@@ -28,596 +28,596 @@  discard block
 block discarded – undo
28 28
 class Registration_Form_Admin_Page extends EE_Admin_Page
29 29
 {
30 30
 
31
-    /**
32
-     * _question
33
-     * holds the specific question object for the question details screen
34
-     *
35
-     * @var EE_Question $_question
36
-     */
37
-    protected $_question;
38
-
39
-    /**
40
-     * _question_group
41
-     * holds the specific question group object for the question group details screen
42
-     *
43
-     * @var EE_Question_Group $_question_group
44
-     */
45
-    protected $_question_group;
46
-
47
-    /**
48
-     *_question_model EEM_Question model instance (for queries)
49
-     *
50
-     * @var EEM_Question $_question_model ;
51
-     */
52
-    protected $_question_model;
53
-
54
-    /**
55
-     * _question_group_model EEM_Question_group instance (for queries)
56
-     *
57
-     * @var EEM_Question_Group $_question_group_model
58
-     */
59
-    protected $_question_group_model;
60
-
61
-
62
-    /**
63
-     * @Constructor
64
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
65
-     * @access public
66
-     */
67
-    public function __construct($routing = true)
68
-    {
69
-        require_once(EE_MODELS . 'EEM_Question.model.php');
70
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
71
-        $this->_question_model       = EEM_Question::instance();
72
-        $this->_question_group_model = EEM_Question_Group::instance();
73
-        parent::__construct($routing);
74
-    }
75
-
76
-
77
-    protected function _init_page_props()
78
-    {
79
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
80
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
81
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
82
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
83
-    }
84
-
85
-
86
-    protected function _ajax_hooks()
87
-    {
88
-    }
89
-
90
-
91
-    protected function _define_page_props()
92
-    {
93
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
94
-        $this->_labels           = array(
95
-            'buttons' => array(
96
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
97
-            ),
98
-        );
99
-    }
100
-
101
-
102
-    /**
103
-     *_set_page_routes
104
-     */
105
-    protected function _set_page_routes()
106
-    {
107
-        $qst_id             = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
108
-        $this->_page_routes = array(
109
-            'default' => array(
110
-                'func'       => '_questions_overview_list_table',
111
-                'capability' => 'ee_read_questions',
112
-            ),
113
-
114
-            'edit_question' => array(
115
-                'func'       => '_edit_question',
116
-                'capability' => 'ee_edit_question',
117
-                'obj_id'     => $qst_id,
118
-                'args'       => array('edit'),
119
-            ),
120
-
121
-            'question_groups' => array(
122
-                'func'       => '_questions_groups_preview',
123
-                'capability' => 'ee_read_question_groups',
124
-            ),
125
-
126
-            'update_question' => array(
127
-                'func'       => '_insert_or_update_question',
128
-                'args'       => array('new_question' => false),
129
-                'capability' => 'ee_edit_question',
130
-                'obj_id'     => $qst_id,
131
-                'noheader'   => true,
132
-            ),
133
-        );
134
-    }
135
-
136
-
137
-    protected function _set_page_config()
138
-    {
139
-        $this->_page_config = array(
140
-            'default' => array(
141
-                'nav'           => array(
142
-                    'label' => esc_html__('Questions', 'event_espresso'),
143
-                    'order' => 10,
144
-                ),
145
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
146
-                'metaboxes'     => $this->_default_espresso_metaboxes,
147
-                'help_tabs'     => array(
148
-                    'registration_form_questions_overview_help_tab'                           => array(
149
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
150
-                        'filename' => 'registration_form_questions_overview',
151
-                    ),
152
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => array(
153
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
154
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
155
-                    ),
156
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array(
157
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
158
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
159
-                    ),
160
-                ),
161
-                'help_tour'     => array('Registration_Form_Questions_Overview_Help_Tour'),
162
-                'require_nonce' => false,
163
-                'qtips'         => array(
164
-                    'EE_Registration_Form_Tips',
165
-                )/**/
166
-            ),
167
-
168
-            'question_groups' => array(
169
-                'nav'           => array(
170
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
171
-                    'order' => 20,
172
-                ),
173
-                'metaboxes'     => $this->_default_espresso_metaboxes,
174
-                'help_tabs'     => array(
175
-                    'registration_form_question_groups_help_tab' => array(
176
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
177
-                        'filename' => 'registration_form_question_groups',
178
-                    ),
179
-                ),
180
-                'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
181
-                'require_nonce' => false,
182
-            ),
183
-
184
-            'edit_question' => array(
185
-                'nav'           => array(
186
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
187
-                    'order'      => 15,
188
-                    'persistent' => false,
189
-                    'url'        => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']),
190
-                        $this->_current_page_view_url) : $this->_admin_base_url,
191
-                ),
192
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
193
-                'help_tabs'     => array(
194
-                    'registration_form_edit_question_group_help_tab' => array(
195
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
196
-                        'filename' => 'registration_form_edit_question',
197
-                    ),
198
-                ),
199
-                'help_tour'     => array('Registration_Form_Edit_Question_Help_Tour'),
200
-                'require_nonce' => false,
201
-            ),
202
-        );
203
-    }
204
-
205
-
206
-    protected function _add_screen_options()
207
-    {
208
-        //todo
209
-    }
210
-
211
-    protected function _add_screen_options_default()
212
-    {
213
-        $page_title              = $this->_admin_page_title;
214
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
215
-        $this->_per_page_screen_option();
216
-        $this->_admin_page_title = $page_title;
217
-    }
218
-
219
-    protected function _add_screen_options_question_groups()
220
-    {
221
-        $page_title              = $this->_admin_page_title;
222
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
223
-        $this->_per_page_screen_option();
224
-        $this->_admin_page_title = $page_title;
225
-    }
226
-
227
-    //none of the below group are currently used for Event Categories
228
-    protected function _add_feature_pointers()
229
-    {
230
-    }
231
-
232
-    public function load_scripts_styles()
233
-    {
234
-        wp_register_style('espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236
-        wp_enqueue_style('espresso_registration');
237
-    }
238
-
239
-    public function admin_init()
240
-    {
241
-    }
242
-
243
-    public function admin_notices()
244
-    {
245
-    }
246
-
247
-    public function admin_footer_scripts()
248
-    {
249
-    }
250
-
251
-
252
-    public function load_scripts_styles_default()
253
-    {
254
-    }
255
-
256
-
257
-    public function load_scripts_styles_add_question()
258
-    {
259
-        $this->load_scripts_styles_forms();
260
-        wp_register_script('espresso_registration_form_single',
261
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262
-            EVENT_ESPRESSO_VERSION, true);
263
-        wp_enqueue_script('espresso_registration_form_single');
264
-    }
265
-
266
-    public function load_scripts_styles_edit_question()
267
-    {
268
-        $this->load_scripts_styles_forms();
269
-        wp_register_script('espresso_registration_form_single',
270
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271
-            EVENT_ESPRESSO_VERSION, true);
272
-        wp_enqueue_script('espresso_registration_form_single');
273
-    }
274
-
275
-
276
-    public function recaptcha_info_help_tab()
277
-    {
278
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
279
-        EEH_Template::display_template($template, array());
280
-    }
281
-
282
-
283
-    public function load_scripts_styles_forms()
284
-    {
285
-        //styles
286
-        wp_enqueue_style('espresso-ui-theme');
287
-        //scripts
288
-        wp_enqueue_script('ee_admin_js');
289
-    }
290
-
291
-
292
-    protected function _set_list_table_views_default()
293
-    {
294
-        $this->_views = array(
295
-            'all' => array(
296
-                'slug'  => 'all',
297
-                'label' => esc_html__('View All Questions', 'event_espresso'),
298
-                'count' => 0,
31
+	/**
32
+	 * _question
33
+	 * holds the specific question object for the question details screen
34
+	 *
35
+	 * @var EE_Question $_question
36
+	 */
37
+	protected $_question;
38
+
39
+	/**
40
+	 * _question_group
41
+	 * holds the specific question group object for the question group details screen
42
+	 *
43
+	 * @var EE_Question_Group $_question_group
44
+	 */
45
+	protected $_question_group;
46
+
47
+	/**
48
+	 *_question_model EEM_Question model instance (for queries)
49
+	 *
50
+	 * @var EEM_Question $_question_model ;
51
+	 */
52
+	protected $_question_model;
53
+
54
+	/**
55
+	 * _question_group_model EEM_Question_group instance (for queries)
56
+	 *
57
+	 * @var EEM_Question_Group $_question_group_model
58
+	 */
59
+	protected $_question_group_model;
60
+
61
+
62
+	/**
63
+	 * @Constructor
64
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
65
+	 * @access public
66
+	 */
67
+	public function __construct($routing = true)
68
+	{
69
+		require_once(EE_MODELS . 'EEM_Question.model.php');
70
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
71
+		$this->_question_model       = EEM_Question::instance();
72
+		$this->_question_group_model = EEM_Question_Group::instance();
73
+		parent::__construct($routing);
74
+	}
75
+
76
+
77
+	protected function _init_page_props()
78
+	{
79
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
80
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
81
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
82
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
83
+	}
84
+
85
+
86
+	protected function _ajax_hooks()
87
+	{
88
+	}
89
+
90
+
91
+	protected function _define_page_props()
92
+	{
93
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
94
+		$this->_labels           = array(
95
+			'buttons' => array(
96
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
97
+			),
98
+		);
99
+	}
100
+
101
+
102
+	/**
103
+	 *_set_page_routes
104
+	 */
105
+	protected function _set_page_routes()
106
+	{
107
+		$qst_id             = ! empty($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0;
108
+		$this->_page_routes = array(
109
+			'default' => array(
110
+				'func'       => '_questions_overview_list_table',
111
+				'capability' => 'ee_read_questions',
112
+			),
113
+
114
+			'edit_question' => array(
115
+				'func'       => '_edit_question',
116
+				'capability' => 'ee_edit_question',
117
+				'obj_id'     => $qst_id,
118
+				'args'       => array('edit'),
119
+			),
120
+
121
+			'question_groups' => array(
122
+				'func'       => '_questions_groups_preview',
123
+				'capability' => 'ee_read_question_groups',
124
+			),
125
+
126
+			'update_question' => array(
127
+				'func'       => '_insert_or_update_question',
128
+				'args'       => array('new_question' => false),
129
+				'capability' => 'ee_edit_question',
130
+				'obj_id'     => $qst_id,
131
+				'noheader'   => true,
132
+			),
133
+		);
134
+	}
135
+
136
+
137
+	protected function _set_page_config()
138
+	{
139
+		$this->_page_config = array(
140
+			'default' => array(
141
+				'nav'           => array(
142
+					'label' => esc_html__('Questions', 'event_espresso'),
143
+					'order' => 10,
144
+				),
145
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
146
+				'metaboxes'     => $this->_default_espresso_metaboxes,
147
+				'help_tabs'     => array(
148
+					'registration_form_questions_overview_help_tab'                           => array(
149
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
150
+						'filename' => 'registration_form_questions_overview',
151
+					),
152
+					'registration_form_questions_overview_table_column_headings_help_tab'     => array(
153
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
154
+						'filename' => 'registration_form_questions_overview_table_column_headings',
155
+					),
156
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => array(
157
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
158
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
159
+					),
160
+				),
161
+				'help_tour'     => array('Registration_Form_Questions_Overview_Help_Tour'),
162
+				'require_nonce' => false,
163
+				'qtips'         => array(
164
+					'EE_Registration_Form_Tips',
165
+				)/**/
166
+			),
167
+
168
+			'question_groups' => array(
169
+				'nav'           => array(
170
+					'label' => esc_html__('Question Groups', 'event_espresso'),
171
+					'order' => 20,
172
+				),
173
+				'metaboxes'     => $this->_default_espresso_metaboxes,
174
+				'help_tabs'     => array(
175
+					'registration_form_question_groups_help_tab' => array(
176
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
177
+						'filename' => 'registration_form_question_groups',
178
+					),
179
+				),
180
+				'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
181
+				'require_nonce' => false,
182
+			),
183
+
184
+			'edit_question' => array(
185
+				'nav'           => array(
186
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
187
+					'order'      => 15,
188
+					'persistent' => false,
189
+					'url'        => isset($this->_req_data['question_id']) ? add_query_arg(array('question_id' => $this->_req_data['question_id']),
190
+						$this->_current_page_view_url) : $this->_admin_base_url,
191
+				),
192
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
193
+				'help_tabs'     => array(
194
+					'registration_form_edit_question_group_help_tab' => array(
195
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
196
+						'filename' => 'registration_form_edit_question',
197
+					),
198
+				),
199
+				'help_tour'     => array('Registration_Form_Edit_Question_Help_Tour'),
200
+				'require_nonce' => false,
201
+			),
202
+		);
203
+	}
204
+
205
+
206
+	protected function _add_screen_options()
207
+	{
208
+		//todo
209
+	}
210
+
211
+	protected function _add_screen_options_default()
212
+	{
213
+		$page_title              = $this->_admin_page_title;
214
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
215
+		$this->_per_page_screen_option();
216
+		$this->_admin_page_title = $page_title;
217
+	}
218
+
219
+	protected function _add_screen_options_question_groups()
220
+	{
221
+		$page_title              = $this->_admin_page_title;
222
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
223
+		$this->_per_page_screen_option();
224
+		$this->_admin_page_title = $page_title;
225
+	}
226
+
227
+	//none of the below group are currently used for Event Categories
228
+	protected function _add_feature_pointers()
229
+	{
230
+	}
231
+
232
+	public function load_scripts_styles()
233
+	{
234
+		wp_register_style('espresso_registration',
235
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236
+		wp_enqueue_style('espresso_registration');
237
+	}
238
+
239
+	public function admin_init()
240
+	{
241
+	}
242
+
243
+	public function admin_notices()
244
+	{
245
+	}
246
+
247
+	public function admin_footer_scripts()
248
+	{
249
+	}
250
+
251
+
252
+	public function load_scripts_styles_default()
253
+	{
254
+	}
255
+
256
+
257
+	public function load_scripts_styles_add_question()
258
+	{
259
+		$this->load_scripts_styles_forms();
260
+		wp_register_script('espresso_registration_form_single',
261
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262
+			EVENT_ESPRESSO_VERSION, true);
263
+		wp_enqueue_script('espresso_registration_form_single');
264
+	}
265
+
266
+	public function load_scripts_styles_edit_question()
267
+	{
268
+		$this->load_scripts_styles_forms();
269
+		wp_register_script('espresso_registration_form_single',
270
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271
+			EVENT_ESPRESSO_VERSION, true);
272
+		wp_enqueue_script('espresso_registration_form_single');
273
+	}
274
+
275
+
276
+	public function recaptcha_info_help_tab()
277
+	{
278
+		$template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
279
+		EEH_Template::display_template($template, array());
280
+	}
281
+
282
+
283
+	public function load_scripts_styles_forms()
284
+	{
285
+		//styles
286
+		wp_enqueue_style('espresso-ui-theme');
287
+		//scripts
288
+		wp_enqueue_script('ee_admin_js');
289
+	}
290
+
291
+
292
+	protected function _set_list_table_views_default()
293
+	{
294
+		$this->_views = array(
295
+			'all' => array(
296
+				'slug'  => 'all',
297
+				'label' => esc_html__('View All Questions', 'event_espresso'),
298
+				'count' => 0,
299 299
 //				'bulk_action' => array(
300 300
 //					'trash_questions' => esc_html__('Trash', 'event_espresso'),
301 301
 //					)
302
-            ),
303
-        );
304
-
305
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
306
-            'espresso_registration_form_trash_questions')
307
-        ) {
308
-            $this->_views['trash'] = array(
309
-                'slug'  => 'trash',
310
-                'label' => esc_html__('Trash', 'event_espresso'),
311
-                'count' => 0,
302
+			),
303
+		);
304
+
305
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_questions',
306
+			'espresso_registration_form_trash_questions')
307
+		) {
308
+			$this->_views['trash'] = array(
309
+				'slug'  => 'trash',
310
+				'label' => esc_html__('Trash', 'event_espresso'),
311
+				'count' => 0,
312 312
 //				'bulk_action' => array(
313 313
 //					'delete_questions' => esc_html__('Delete Permanently', 'event_espresso'),
314 314
 //					'restore_questions' => esc_html__('Restore', 'event_espresso'),
315
-            );
316
-        }
317
-    }
318
-
319
-    /**
320
-     * This just previews the question groups tab that comes in caffeinated.
321
-     *
322
-     * @return string html
323
-     */
324
-    protected function _questions_groups_preview()
325
-    {
326
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
-        $this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
-                'event_espresso') . '" />';
329
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
-                'event_espresso') . '</strong>';
331
-        $this->display_admin_caf_preview_page('question_groups_tab');
332
-    }
333
-
334
-
335
-    /**
336
-     * Extracts the question field's values from the POST request to update or insert them
337
-     *
338
-     * @param \EEM_Base $model
339
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
340
-     */
341
-    protected function _set_column_values_for(EEM_Base $model)
342
-    {
343
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
344
-        $set_column_values = array();
345
-
346
-        //some initial checks for proper values.
347
-        //if QST_admin_only, then no matter what QST_required is we disable.
348
-        if (! empty($this->_req_data['QST_admin_only'])) {
349
-            $this->_req_data['QST_required'] = 0;
350
-        }
351
-        foreach ($model->field_settings() as $fieldName => $settings) {
352
-            // basically if QSG_identifier is empty or not set
353
-            if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354
-                $QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
-                $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
315
+			);
316
+		}
317
+	}
318
+
319
+	/**
320
+	 * This just previews the question groups tab that comes in caffeinated.
321
+	 *
322
+	 * @return string html
323
+	 */
324
+	protected function _questions_groups_preview()
325
+	{
326
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
+		$this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
+				'event_espresso') . '" />';
329
+		$this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
+				'event_espresso') . '</strong>';
331
+		$this->display_admin_caf_preview_page('question_groups_tab');
332
+	}
333
+
334
+
335
+	/**
336
+	 * Extracts the question field's values from the POST request to update or insert them
337
+	 *
338
+	 * @param \EEM_Base $model
339
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
340
+	 */
341
+	protected function _set_column_values_for(EEM_Base $model)
342
+	{
343
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
344
+		$set_column_values = array();
345
+
346
+		//some initial checks for proper values.
347
+		//if QST_admin_only, then no matter what QST_required is we disable.
348
+		if (! empty($this->_req_data['QST_admin_only'])) {
349
+			$this->_req_data['QST_required'] = 0;
350
+		}
351
+		foreach ($model->field_settings() as $fieldName => $settings) {
352
+			// basically if QSG_identifier is empty or not set
353
+			if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354
+				$QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
+				$set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
356 356
 //				dd($set_column_values);
357
-            } //if the admin label is blank, use a slug version of the question text
358
-            else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359
-                $QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360
-                $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
-            } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
362
-                $set_column_values[$fieldName] = 0;
363
-            } else if ($fieldName === 'QST_max') {
364
-                $qst_system = EEM_Question::instance()->get_var(
365
-                    array(
366
-                        array(
367
-                            'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0,
368
-                        ),
369
-                    ),
370
-                    'QST_system');
371
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372
-                if (empty($this->_req_data['QST_max']) ||
373
-                    $this->_req_data['QST_max'] > $max_max
374
-                ) {
375
-                    $set_column_values[$fieldName] = $max_max;
376
-                }
377
-            }
378
-
379
-
380
-            //only add a property to the array if it's not null (otherwise the model should just use the default value)
381
-            if (
382
-                ! isset($set_column_values[$fieldName]) &&
383
-                isset($this->_req_data[$fieldName])
384
-            ) {
385
-                $set_column_values[$fieldName] = $this->_req_data[$fieldName];
386
-            }
387
-
388
-        }
389
-        return $set_column_values;//validation fo this data to be performed by the model before insertion.
390
-    }
391
-
392
-
393
-    /**
394
-     *_questions_overview_list_table
395
-     */
396
-    protected function _questions_overview_list_table()
397
-    {
398
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
399
-        $this->display_admin_list_table_page_with_sidebar();
400
-    }
401
-
402
-
403
-    /**
404
-     * _edit_question
405
-     */
406
-    protected function _edit_question()
407
-    {
408
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
409
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false;
410
-
411
-        switch ($this->_req_action) {
412
-            case 'add_question' :
413
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
414
-                break;
415
-            case 'edit_question' :
416
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
417
-                break;
418
-            default :
419
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
420
-        }
421
-
422
-        // add PRC_ID to title if editing
423
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
424
-        if ($ID) {
425
-            $question                 = $this->_question_model->get_one_by_ID($ID);
426
-            $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
427
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
428
-        } else {
429
-            $question = EE_Question::new_instance();
430
-            $question->set_order_to_latest();
431
-            $this->_set_add_edit_form_tags('insert_question');
432
-        }
433
-        if( $question->system_ID() === EEM_Attendee::system_question_phone ){
434
-            $question_types = array_intersect_key(
435
-                EEM_Question::instance()->allowed_question_types(),
436
-                array_flip(
437
-                    array(
438
-                        EEM_Question::QST_type_text,
439
-                        EEM_Question::QST_type_us_phone
440
-                    )
441
-                )
442
-            );
443
-        } else {
444
-            $question_types = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types();
445
-        }
446
-        $this->_template_args['QST_ID']                     = $ID;
447
-        $this->_template_args['question']                   = $question;
448
-        $this->_template_args['question_types']             = $question_types;
449
-        $this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question(
450
-            $question->system_ID()
451
-        );
452
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
453
-        $this->_set_publish_post_box_vars('id', $ID);
454
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
455
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
456
-            $this->_template_args, true
457
-        );
458
-
459
-        // the details template wrapper
460
-        $this->display_admin_page_with_sidebar();
461
-    }
462
-
463
-
464
-    /**
465
-     * @return string
466
-     */
467
-    protected function _get_question_type_descriptions()
468
-    {
469
-        EE_Registry::instance()->load_helper('HTML');
470
-        $descriptions               = '';
471
-        $question_type_descriptions = EEM_Question::instance()->question_descriptions();
472
-        foreach ($question_type_descriptions as $type => $question_type_description) {
473
-            if ($type == 'HTML_TEXTAREA') {
474
-                $html = new EE_Simple_HTML_Validation_Strategy();
475
-                $question_type_description .= sprintf(
476
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
477
-                    '<br/>',
478
-                    $html->get_list_of_allowed_tags()
479
-                );
480
-            }
481
-            $descriptions .= EEH_HTML::p(
482
-                $question_type_description,
483
-                'question_type_description-' . $type,
484
-                'question_type_description description',
485
-                'display:none;'
486
-            );
487
-        }
488
-        return $descriptions;
489
-    }
490
-
491
-
492
-    /**
493
-     * @param bool|true $new_question
494
-     * @throws \EE_Error
495
-     */
496
-    protected function _insert_or_update_question($new_question = true)
497
-    {
498
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
499
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
500
-        if ($new_question) {
501
-            $question = EE_Question::new_instance($set_column_values);
502
-            $action_desc = 'added';
503
-        } else {
504
-            $question     = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505
-            foreach($set_column_values as $field => $new_value) {
506
-                $question->set($field, $new_value);
507
-            }
508
-            $action_desc = 'updated';
509
-        }
510
-        $success = $question->save();
511
-        $ID = $question->ID();
512
-        if ($ID && $question->should_have_question_options()) {
513
-            //save the related options
514
-            //trash removed options, save old ones
515
-            //get list of all options
516
-            $options  = $question->options();
517
-            if (! empty($options)) {
518
-                foreach ($options as $option_ID => $option) {
519
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
520
-                    if ($option_req_index !== false) {
521
-                        $option->save($this->_req_data['question_options'][$option_req_index]);
522
-                    } else {
523
-                        //not found, remove it
524
-                        $option->delete();
525
-                    }
526
-                }
527
-            }
528
-            //save new related options
529
-            foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
530
-                //skip $index that is from our sample
531
-                if ( $index === 'xxcountxx' ) {
532
-                    continue;
533
-                }
534
-                //note we allow saving blank options.
535
-                if (empty($option_req_data['QSO_ID'])
536
-                ) {//no ID! save it!
537
-                    $new_option = EE_Question_Option::new_instance(array(
538
-                        'QSO_value' => $option_req_data['QSO_value'],
539
-                        'QSO_desc'  => $option_req_data['QSO_desc'],
540
-                        'QSO_order' => $option_req_data['QSO_order'],
541
-                        'QST_ID'    => $question->ID(),
542
-                    ));
543
-                    $new_option->save();
544
-                }
545
-            }
546
-        }
547
-        $query_args = array('action' => 'edit_question', 'QST_ID' => $ID);
548
-        if ($success !== false) {
549
-            $msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
550
-                $this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'),
551
-                $this->_question_model->item_name());
552
-            EE_Error::add_success($msg);
553
-        }
554
-
555
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
556
-    }
557
-
558
-
559
-    /**
560
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
561
-     * by ID
562
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
563
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
564
-     *
565
-     * @param int $ID of the question option to find
566
-     * @return int index in question_options array if successful, FALSE if unsuccessful
567
-     */
568
-    protected function _get_option_req_data_index($ID)
569
-    {
570
-        $req_data_for_question_options = $this->_req_data['question_options'];
571
-        foreach ($req_data_for_question_options as $num => $option_data) {
572
-            if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
573
-                return $num;
574
-            }
575
-        }
576
-        return false;
577
-    }
578
-
579
-
580
-
581
-
582
-    /***********/
583
-    /* QUERIES */
584
-    /**
585
-     * For internal use in getting all the query parameters
586
-     * (because it's pretty well the same between question, question groups,
587
-     * and for both when searching for trashed and untrashed ones)
588
-     *
589
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
590
-     * @param int      $per_page
591
-     * @param int      $current_page
592
-     * @return array lik EEM_Base::get_all's $query_params parameter
593
-     */
594
-    protected function get_query_params($model, $per_page = 10, $current_page = 10)
595
-    {
596
-        $query_params             = array();
597
-        $offset                   = ($current_page - 1) * $per_page;
598
-        $query_params['limit']    = array($offset, $per_page);
599
-        $order                    = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
600
-        $orderby_field            = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
601
-        $field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
602
-        $query_params['order_by'] = array($field_to_order_by => $order);
603
-        $search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
604
-        if (! empty($search_string)) {
605
-            if ($model instanceof EEM_Question_Group) {
606
-                $query_params[0] = array(
607
-                    'OR' => array(
608
-                        'QSG_name' => array('LIKE', "%$search_string%"),
609
-                        'QSG_desc' => array('LIKE', "%$search_string%"),
610
-                    ),
611
-                );
612
-            } else {
613
-                $query_params[0] = array(
614
-                    'QST_display_text' => array('LIKE', "%$search_string%"),
615
-                );
616
-            }
617
-        }
618
-
619
-        //capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
620
-        /*if ( $model instanceof EEM_Question_Group ) {
357
+			} //if the admin label is blank, use a slug version of the question text
358
+			else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359
+				$QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360
+				$set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
+			} else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
362
+				$set_column_values[$fieldName] = 0;
363
+			} else if ($fieldName === 'QST_max') {
364
+				$qst_system = EEM_Question::instance()->get_var(
365
+					array(
366
+						array(
367
+							'QST_ID' => isset($this->_req_data['QST_ID']) ? $this->_req_data['QST_ID'] : 0,
368
+						),
369
+					),
370
+					'QST_system');
371
+				$max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372
+				if (empty($this->_req_data['QST_max']) ||
373
+					$this->_req_data['QST_max'] > $max_max
374
+				) {
375
+					$set_column_values[$fieldName] = $max_max;
376
+				}
377
+			}
378
+
379
+
380
+			//only add a property to the array if it's not null (otherwise the model should just use the default value)
381
+			if (
382
+				! isset($set_column_values[$fieldName]) &&
383
+				isset($this->_req_data[$fieldName])
384
+			) {
385
+				$set_column_values[$fieldName] = $this->_req_data[$fieldName];
386
+			}
387
+
388
+		}
389
+		return $set_column_values;//validation fo this data to be performed by the model before insertion.
390
+	}
391
+
392
+
393
+	/**
394
+	 *_questions_overview_list_table
395
+	 */
396
+	protected function _questions_overview_list_table()
397
+	{
398
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
399
+		$this->display_admin_list_table_page_with_sidebar();
400
+	}
401
+
402
+
403
+	/**
404
+	 * _edit_question
405
+	 */
406
+	protected function _edit_question()
407
+	{
408
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
409
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID']) ? absint($this->_req_data['QST_ID']) : false;
410
+
411
+		switch ($this->_req_action) {
412
+			case 'add_question' :
413
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
414
+				break;
415
+			case 'edit_question' :
416
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
417
+				break;
418
+			default :
419
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
420
+		}
421
+
422
+		// add PRC_ID to title if editing
423
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
424
+		if ($ID) {
425
+			$question                 = $this->_question_model->get_one_by_ID($ID);
426
+			$additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
427
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
428
+		} else {
429
+			$question = EE_Question::new_instance();
430
+			$question->set_order_to_latest();
431
+			$this->_set_add_edit_form_tags('insert_question');
432
+		}
433
+		if( $question->system_ID() === EEM_Attendee::system_question_phone ){
434
+			$question_types = array_intersect_key(
435
+				EEM_Question::instance()->allowed_question_types(),
436
+				array_flip(
437
+					array(
438
+						EEM_Question::QST_type_text,
439
+						EEM_Question::QST_type_us_phone
440
+					)
441
+				)
442
+			);
443
+		} else {
444
+			$question_types = $question->has_answers() ? $this->_question_model->question_types_in_same_category($question->type()) : $this->_question_model->allowed_question_types();
445
+		}
446
+		$this->_template_args['QST_ID']                     = $ID;
447
+		$this->_template_args['question']                   = $question;
448
+		$this->_template_args['question_types']             = $question_types;
449
+		$this->_template_args['max_max']                    = EEM_Question::instance()->absolute_max_for_system_question(
450
+			$question->system_ID()
451
+		);
452
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
453
+		$this->_set_publish_post_box_vars('id', $ID);
454
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
455
+			REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
456
+			$this->_template_args, true
457
+		);
458
+
459
+		// the details template wrapper
460
+		$this->display_admin_page_with_sidebar();
461
+	}
462
+
463
+
464
+	/**
465
+	 * @return string
466
+	 */
467
+	protected function _get_question_type_descriptions()
468
+	{
469
+		EE_Registry::instance()->load_helper('HTML');
470
+		$descriptions               = '';
471
+		$question_type_descriptions = EEM_Question::instance()->question_descriptions();
472
+		foreach ($question_type_descriptions as $type => $question_type_description) {
473
+			if ($type == 'HTML_TEXTAREA') {
474
+				$html = new EE_Simple_HTML_Validation_Strategy();
475
+				$question_type_description .= sprintf(
476
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
477
+					'<br/>',
478
+					$html->get_list_of_allowed_tags()
479
+				);
480
+			}
481
+			$descriptions .= EEH_HTML::p(
482
+				$question_type_description,
483
+				'question_type_description-' . $type,
484
+				'question_type_description description',
485
+				'display:none;'
486
+			);
487
+		}
488
+		return $descriptions;
489
+	}
490
+
491
+
492
+	/**
493
+	 * @param bool|true $new_question
494
+	 * @throws \EE_Error
495
+	 */
496
+	protected function _insert_or_update_question($new_question = true)
497
+	{
498
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
499
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
500
+		if ($new_question) {
501
+			$question = EE_Question::new_instance($set_column_values);
502
+			$action_desc = 'added';
503
+		} else {
504
+			$question     = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505
+			foreach($set_column_values as $field => $new_value) {
506
+				$question->set($field, $new_value);
507
+			}
508
+			$action_desc = 'updated';
509
+		}
510
+		$success = $question->save();
511
+		$ID = $question->ID();
512
+		if ($ID && $question->should_have_question_options()) {
513
+			//save the related options
514
+			//trash removed options, save old ones
515
+			//get list of all options
516
+			$options  = $question->options();
517
+			if (! empty($options)) {
518
+				foreach ($options as $option_ID => $option) {
519
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
520
+					if ($option_req_index !== false) {
521
+						$option->save($this->_req_data['question_options'][$option_req_index]);
522
+					} else {
523
+						//not found, remove it
524
+						$option->delete();
525
+					}
526
+				}
527
+			}
528
+			//save new related options
529
+			foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
530
+				//skip $index that is from our sample
531
+				if ( $index === 'xxcountxx' ) {
532
+					continue;
533
+				}
534
+				//note we allow saving blank options.
535
+				if (empty($option_req_data['QSO_ID'])
536
+				) {//no ID! save it!
537
+					$new_option = EE_Question_Option::new_instance(array(
538
+						'QSO_value' => $option_req_data['QSO_value'],
539
+						'QSO_desc'  => $option_req_data['QSO_desc'],
540
+						'QSO_order' => $option_req_data['QSO_order'],
541
+						'QST_ID'    => $question->ID(),
542
+					));
543
+					$new_option->save();
544
+				}
545
+			}
546
+		}
547
+		$query_args = array('action' => 'edit_question', 'QST_ID' => $ID);
548
+		if ($success !== false) {
549
+			$msg = $new_question ? sprintf(esc_html__('The %s has been created', 'event_espresso'),
550
+				$this->_question_model->item_name()) : sprintf(esc_html__('The %s has been updated', 'event_espresso'),
551
+				$this->_question_model->item_name());
552
+			EE_Error::add_success($msg);
553
+		}
554
+
555
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
556
+	}
557
+
558
+
559
+	/**
560
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
561
+	 * by ID
562
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
563
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
564
+	 *
565
+	 * @param int $ID of the question option to find
566
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
567
+	 */
568
+	protected function _get_option_req_data_index($ID)
569
+	{
570
+		$req_data_for_question_options = $this->_req_data['question_options'];
571
+		foreach ($req_data_for_question_options as $num => $option_data) {
572
+			if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
573
+				return $num;
574
+			}
575
+		}
576
+		return false;
577
+	}
578
+
579
+
580
+
581
+
582
+	/***********/
583
+	/* QUERIES */
584
+	/**
585
+	 * For internal use in getting all the query parameters
586
+	 * (because it's pretty well the same between question, question groups,
587
+	 * and for both when searching for trashed and untrashed ones)
588
+	 *
589
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
590
+	 * @param int      $per_page
591
+	 * @param int      $current_page
592
+	 * @return array lik EEM_Base::get_all's $query_params parameter
593
+	 */
594
+	protected function get_query_params($model, $per_page = 10, $current_page = 10)
595
+	{
596
+		$query_params             = array();
597
+		$offset                   = ($current_page - 1) * $per_page;
598
+		$query_params['limit']    = array($offset, $per_page);
599
+		$order                    = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'ASC';
600
+		$orderby_field            = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
601
+		$field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
602
+		$query_params['order_by'] = array($field_to_order_by => $order);
603
+		$search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
604
+		if (! empty($search_string)) {
605
+			if ($model instanceof EEM_Question_Group) {
606
+				$query_params[0] = array(
607
+					'OR' => array(
608
+						'QSG_name' => array('LIKE', "%$search_string%"),
609
+						'QSG_desc' => array('LIKE', "%$search_string%"),
610
+					),
611
+				);
612
+			} else {
613
+				$query_params[0] = array(
614
+					'QST_display_text' => array('LIKE', "%$search_string%"),
615
+				);
616
+			}
617
+		}
618
+
619
+		//capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
620
+		/*if ( $model instanceof EEM_Question_Group ) {
621 621
             if ( ! EE_Registry::instance()->CAP->current_user_can( 'edit_others_question_groups', 'espresso_registration_form_edit_question_group' ) ) {
622 622
                 $query_params[0] = array(
623 623
                     'AND' => array(
@@ -647,62 +647,62 @@  discard block
 block discarded – undo
647 647
             }
648 648
         }/**/
649 649
 
650
-        return $query_params;
651
-
652
-    }
653
-
654
-
655
-    /**
656
-     * @param int        $per_page
657
-     * @param int        $current_page
658
-     * @param bool|false $count
659
-     * @return \EE_Soft_Delete_Base_Class[]|int
660
-     */
661
-    public function get_questions($per_page = 10, $current_page = 1, $count = false)
662
-    {
663
-        $QST          = EEM_Question::instance();
664
-        $query_params = $this->get_query_params($QST, $per_page, $current_page);
665
-        if ($count) {
666
-            $where   = isset($query_params[0]) ? array($query_params[0]) : array();
667
-            $results = $QST->count($where);
668
-        } else {
669
-            $results = $QST->get_all($query_params);
670
-        }
671
-        return $results;
672
-
673
-    }
674
-
675
-
676
-    /**
677
-     * @param            $per_page
678
-     * @param int        $current_page
679
-     * @param bool|false $count
680
-     * @return \EE_Soft_Delete_Base_Class[]|int
681
-     */
682
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
683
-    {
684
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
685
-        $where        = isset($query_params[0]) ? array($query_params[0]) : array();
686
-        $questions    = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params);
687
-        return $questions;
688
-    }
689
-
690
-
691
-    /**
692
-     * @param            $per_page
693
-     * @param int        $current_page
694
-     * @param bool|false $count
695
-     * @return \EE_Soft_Delete_Base_Class[]
696
-     */
697
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
698
-    {
699
-        /** @type EEM_Question_Group $questionGroupModel */
700
-        $questionGroupModel = EEM_Question_Group::instance();
701
-        //note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
702
-        return $questionGroupModel->get_all(
703
-            $this->get_query_params($questionGroupModel, $per_page, $current_page)
704
-        );
705
-    }
650
+		return $query_params;
651
+
652
+	}
653
+
654
+
655
+	/**
656
+	 * @param int        $per_page
657
+	 * @param int        $current_page
658
+	 * @param bool|false $count
659
+	 * @return \EE_Soft_Delete_Base_Class[]|int
660
+	 */
661
+	public function get_questions($per_page = 10, $current_page = 1, $count = false)
662
+	{
663
+		$QST          = EEM_Question::instance();
664
+		$query_params = $this->get_query_params($QST, $per_page, $current_page);
665
+		if ($count) {
666
+			$where   = isset($query_params[0]) ? array($query_params[0]) : array();
667
+			$results = $QST->count($where);
668
+		} else {
669
+			$results = $QST->get_all($query_params);
670
+		}
671
+		return $results;
672
+
673
+	}
674
+
675
+
676
+	/**
677
+	 * @param            $per_page
678
+	 * @param int        $current_page
679
+	 * @param bool|false $count
680
+	 * @return \EE_Soft_Delete_Base_Class[]|int
681
+	 */
682
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
683
+	{
684
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
685
+		$where        = isset($query_params[0]) ? array($query_params[0]) : array();
686
+		$questions    = $count ? EEM_Question::instance()->count_deleted($where) : EEM_Question::instance()->get_all_deleted($query_params);
687
+		return $questions;
688
+	}
689
+
690
+
691
+	/**
692
+	 * @param            $per_page
693
+	 * @param int        $current_page
694
+	 * @param bool|false $count
695
+	 * @return \EE_Soft_Delete_Base_Class[]
696
+	 */
697
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
698
+	{
699
+		/** @type EEM_Question_Group $questionGroupModel */
700
+		$questionGroupModel = EEM_Question_Group::instance();
701
+		//note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
702
+		return $questionGroupModel->get_all(
703
+			$this->get_query_params($questionGroupModel, $per_page, $current_page)
704
+		);
705
+	}
706 706
 
707 707
 
708 708
 } //ends Registration_Form_Admin_Page class
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (! defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('NO direct script access allowed');
4 4
 }
5 5
 
@@ -66,8 +66,8 @@  discard block
 block discarded – undo
66 66
      */
67 67
     public function __construct($routing = true)
68 68
     {
69
-        require_once(EE_MODELS . 'EEM_Question.model.php');
70
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
69
+        require_once(EE_MODELS.'EEM_Question.model.php');
70
+        require_once(EE_MODELS.'EEM_Question_Group.model.php');
71 71
         $this->_question_model       = EEM_Question::instance();
72 72
         $this->_question_group_model = EEM_Question_Group::instance();
73 73
         parent::__construct($routing);
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
     public function load_scripts_styles()
233 233
     {
234 234
         wp_register_style('espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
235
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css', array(), EVENT_ESPRESSO_VERSION);
236 236
         wp_enqueue_style('espresso_registration');
237 237
     }
238 238
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
     {
259 259
         $this->load_scripts_styles_forms();
260 260
         wp_register_script('espresso_registration_form_single',
261
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
261
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
262 262
             EVENT_ESPRESSO_VERSION, true);
263 263
         wp_enqueue_script('espresso_registration_form_single');
264 264
     }
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
     {
268 268
         $this->load_scripts_styles_forms();
269 269
         wp_register_script('espresso_registration_form_single',
270
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
270
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js', array('jquery-ui-sortable'),
271 271
             EVENT_ESPRESSO_VERSION, true);
272 272
         wp_enqueue_script('espresso_registration_form_single');
273 273
     }
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
 
276 276
     public function recaptcha_info_help_tab()
277 277
     {
278
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
278
+        $template = REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php';
279 279
         EEH_Template::display_template($template, array());
280 280
     }
281 281
 
@@ -324,10 +324,10 @@  discard block
 block discarded – undo
324 324
     protected function _questions_groups_preview()
325 325
     {
326 326
         $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
327
-        $this->_template_args['preview_img']  = '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="' . esc_attr__('Preview Question Groups Overview List Table screenshot',
328
-                'event_espresso') . '" />';
329
-        $this->_template_args['preview_text'] = '<strong>' . esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
-                'event_espresso') . '</strong>';
327
+        $this->_template_args['preview_img']  = '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'.esc_attr__('Preview Question Groups Overview List Table screenshot',
328
+                'event_espresso').'" />';
329
+        $this->_template_args['preview_text'] = '<strong>'.esc_html__('Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
330
+                'event_espresso').'</strong>';
331 331
         $this->display_admin_caf_preview_page('question_groups_tab');
332 332
     }
333 333
 
@@ -345,20 +345,20 @@  discard block
 block discarded – undo
345 345
 
346 346
         //some initial checks for proper values.
347 347
         //if QST_admin_only, then no matter what QST_required is we disable.
348
-        if (! empty($this->_req_data['QST_admin_only'])) {
348
+        if ( ! empty($this->_req_data['QST_admin_only'])) {
349 349
             $this->_req_data['QST_required'] = 0;
350 350
         }
351 351
         foreach ($model->field_settings() as $fieldName => $settings) {
352 352
             // basically if QSG_identifier is empty or not set
353 353
             if ($fieldName === 'QSG_identifier' && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))) {
354 354
                 $QSG_name                      = isset($this->_req_data['QSG_name']) ? $this->_req_data['QSG_name'] : '';
355
-                $set_column_values[$fieldName] = sanitize_title($QSG_name) . '-' . uniqid('', true);
355
+                $set_column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true);
356 356
 //				dd($set_column_values);
357 357
             } //if the admin label is blank, use a slug version of the question text
358 358
             else if ($fieldName === 'QST_admin_label' && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))) {
359 359
                 $QST_text                      = isset($this->_req_data['QST_display_text']) ? $this->_req_data['QST_display_text'] : '';
360 360
                 $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
361
-            } else if ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
361
+            } else if ($fieldName === 'QST_admin_only' && ( ! isset($this->_req_data['QST_admin_only']))) {
362 362
                 $set_column_values[$fieldName] = 0;
363 363
             } else if ($fieldName === 'QST_max') {
364 364
                 $qst_system = EEM_Question::instance()->get_var(
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
                         ),
369 369
                     ),
370 370
                     'QST_system');
371
-                $max_max    = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
371
+                $max_max = EEM_Question::instance()->absolute_max_for_system_question($qst_system);
372 372
                 if (empty($this->_req_data['QST_max']) ||
373 373
                     $this->_req_data['QST_max'] > $max_max
374 374
                 ) {
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
             }
387 387
 
388 388
         }
389
-        return $set_column_values;//validation fo this data to be performed by the model before insertion.
389
+        return $set_column_values; //validation fo this data to be performed by the model before insertion.
390 390
     }
391 391
 
392 392
 
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
         }
421 421
 
422 422
         // add PRC_ID to title if editing
423
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
423
+        $this->_admin_page_title = $ID ? $this->_admin_page_title.' # '.$ID : $this->_admin_page_title;
424 424
         if ($ID) {
425 425
             $question                 = $this->_question_model->get_one_by_ID($ID);
426 426
             $additional_hidden_fields = array('QST_ID' => array('type' => 'hidden', 'value' => $ID));
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
             $question->set_order_to_latest();
431 431
             $this->_set_add_edit_form_tags('insert_question');
432 432
         }
433
-        if( $question->system_ID() === EEM_Attendee::system_question_phone ){
433
+        if ($question->system_ID() === EEM_Attendee::system_question_phone) {
434 434
             $question_types = array_intersect_key(
435 435
                 EEM_Question::instance()->allowed_question_types(),
436 436
                 array_flip(
@@ -452,7 +452,7 @@  discard block
 block discarded – undo
452 452
         $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
453 453
         $this->_set_publish_post_box_vars('id', $ID);
454 454
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
455
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
455
+            REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php',
456 456
             $this->_template_args, true
457 457
         );
458 458
 
@@ -480,7 +480,7 @@  discard block
 block discarded – undo
480 480
             }
481 481
             $descriptions .= EEH_HTML::p(
482 482
                 $question_type_description,
483
-                'question_type_description-' . $type,
483
+                'question_type_description-'.$type,
484 484
                 'question_type_description description',
485 485
                 'display:none;'
486 486
             );
@@ -501,8 +501,8 @@  discard block
 block discarded – undo
501 501
             $question = EE_Question::new_instance($set_column_values);
502 502
             $action_desc = 'added';
503 503
         } else {
504
-            $question     = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505
-            foreach($set_column_values as $field => $new_value) {
504
+            $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
505
+            foreach ($set_column_values as $field => $new_value) {
506 506
                 $question->set($field, $new_value);
507 507
             }
508 508
             $action_desc = 'updated';
@@ -513,8 +513,8 @@  discard block
 block discarded – undo
513 513
             //save the related options
514 514
             //trash removed options, save old ones
515 515
             //get list of all options
516
-            $options  = $question->options();
517
-            if (! empty($options)) {
516
+            $options = $question->options();
517
+            if ( ! empty($options)) {
518 518
                 foreach ($options as $option_ID => $option) {
519 519
                     $option_req_index = $this->_get_option_req_data_index($option_ID);
520 520
                     if ($option_req_index !== false) {
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
             //save new related options
529 529
             foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
530 530
                 //skip $index that is from our sample
531
-                if ( $index === 'xxcountxx' ) {
531
+                if ($index === 'xxcountxx') {
532 532
                     continue;
533 533
                 }
534 534
                 //note we allow saving blank options.
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
     {
570 570
         $req_data_for_question_options = $this->_req_data['question_options'];
571 571
         foreach ($req_data_for_question_options as $num => $option_data) {
572
-            if (array_key_exists('QSO_ID', $option_data) && (int)$option_data['QSO_ID'] === $ID) {
572
+            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
573 573
                 return $num;
574 574
             }
575 575
         }
@@ -601,7 +601,7 @@  discard block
 block discarded – undo
601 601
         $field_to_order_by        = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
602 602
         $query_params['order_by'] = array($field_to_order_by => $order);
603 603
         $search_string            = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
604
-        if (! empty($search_string)) {
604
+        if ( ! empty($search_string)) {
605 605
             if ($model instanceof EEM_Question_Group) {
606 606
                 $query_params[0] = array(
607 607
                     'OR' => array(
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -38,217 +38,217 @@
 block discarded – undo
38 38
  * @since       4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 
64 64
 } else {
65
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
-        /**
68
-         * espresso_minimum_php_version_error
69
-         *
70
-         * @return void
71
-         */
72
-        function espresso_minimum_php_version_error()
73
-        {
74
-            ?>
65
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
+		/**
68
+		 * espresso_minimum_php_version_error
69
+		 *
70
+		 * @return void
71
+		 */
72
+		function espresso_minimum_php_version_error()
73
+		{
74
+			?>
75 75
             <div class="error">
76 76
                 <p>
77 77
                     <?php
78
-                    printf(
79
-                        esc_html__(
80
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
-                            'event_espresso'
82
-                        ),
83
-                        EE_MIN_PHP_VER_REQUIRED,
84
-                        PHP_VERSION,
85
-                        '<br/>',
86
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
-                    );
88
-                    ?>
78
+					printf(
79
+						esc_html__(
80
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
+							'event_espresso'
82
+						),
83
+						EE_MIN_PHP_VER_REQUIRED,
84
+						PHP_VERSION,
85
+						'<br/>',
86
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
+					);
88
+					?>
89 89
                 </p>
90 90
             </div>
91 91
             <?php
92
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
93
-        }
92
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
93
+		}
94 94
 
95
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
-    } else {
97
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
-        /**
99
-         * espresso_version
100
-         * Returns the plugin version
101
-         *
102
-         * @return string
103
-         */
104
-        function espresso_version()
105
-        {
106
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.52.rc.005');
107
-        }
95
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
+	} else {
97
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
+		/**
99
+		 * espresso_version
100
+		 * Returns the plugin version
101
+		 *
102
+		 * @return string
103
+		 */
104
+		function espresso_version()
105
+		{
106
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.52.rc.005');
107
+		}
108 108
 
109
-        /**
110
-         * espresso_plugin_activation
111
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
-         */
113
-        function espresso_plugin_activation()
114
-        {
115
-            update_option('ee_espresso_activation', true);
116
-        }
109
+		/**
110
+		 * espresso_plugin_activation
111
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
+		 */
113
+		function espresso_plugin_activation()
114
+		{
115
+			update_option('ee_espresso_activation', true);
116
+		}
117 117
 
118
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
-        /**
120
-         *    espresso_load_error_handling
121
-         *    this function loads EE's class for handling exceptions and errors
122
-         */
123
-        function espresso_load_error_handling()
124
-        {
125
-            static $error_handling_loaded = false;
126
-            if ($error_handling_loaded) {
127
-                return;
128
-            }
129
-            // load debugging tools
130
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
-                require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
-                \EEH_Debug_Tools::instance();
133
-            }
134
-            // load error handling
135
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
-                require_once EE_CORE . 'EE_Error.core.php';
137
-            } else {
138
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
-            }
140
-            $error_handling_loaded = true;
141
-        }
118
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
+		/**
120
+		 *    espresso_load_error_handling
121
+		 *    this function loads EE's class for handling exceptions and errors
122
+		 */
123
+		function espresso_load_error_handling()
124
+		{
125
+			static $error_handling_loaded = false;
126
+			if ($error_handling_loaded) {
127
+				return;
128
+			}
129
+			// load debugging tools
130
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
+				require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
+				\EEH_Debug_Tools::instance();
133
+			}
134
+			// load error handling
135
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
+				require_once EE_CORE . 'EE_Error.core.php';
137
+			} else {
138
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
+			}
140
+			$error_handling_loaded = true;
141
+		}
142 142
 
143
-        /**
144
-         *    espresso_load_required
145
-         *    given a class name and path, this function will load that file or throw an exception
146
-         *
147
-         * @param    string $classname
148
-         * @param    string $full_path_to_file
149
-         * @throws    EE_Error
150
-         */
151
-        function espresso_load_required($classname, $full_path_to_file)
152
-        {
153
-            if (is_readable($full_path_to_file)) {
154
-                require_once $full_path_to_file;
155
-            } else {
156
-                throw new \EE_Error (
157
-                    sprintf(
158
-                        esc_html__(
159
-                            'The %s class file could not be located or is not readable due to file permissions.',
160
-                            'event_espresso'
161
-                        ),
162
-                        $classname
163
-                    )
164
-                );
165
-            }
166
-        }
143
+		/**
144
+		 *    espresso_load_required
145
+		 *    given a class name and path, this function will load that file or throw an exception
146
+		 *
147
+		 * @param    string $classname
148
+		 * @param    string $full_path_to_file
149
+		 * @throws    EE_Error
150
+		 */
151
+		function espresso_load_required($classname, $full_path_to_file)
152
+		{
153
+			if (is_readable($full_path_to_file)) {
154
+				require_once $full_path_to_file;
155
+			} else {
156
+				throw new \EE_Error (
157
+					sprintf(
158
+						esc_html__(
159
+							'The %s class file could not be located or is not readable due to file permissions.',
160
+							'event_espresso'
161
+						),
162
+						$classname
163
+					)
164
+				);
165
+			}
166
+		}
167 167
 
168
-        /**
169
-         * @since 4.9.27
170
-         * @throws \EE_Error
171
-         * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
-         * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
-         * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
-         * @throws \EventEspresso\core\exceptions\InvalidClassException
175
-         * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
-         * @throws \OutOfBoundsException
179
-         */
180
-        function bootstrap_espresso()
181
-        {
182
-            require_once __DIR__ . '/core/espresso_definitions.php';
183
-            try {
184
-                espresso_load_error_handling();
185
-                espresso_load_required(
186
-                    'EEH_Base',
187
-                    EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
-                );
189
-                espresso_load_required(
190
-                    'EEH_File',
191
-                    EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
-                );
193
-                espresso_load_required(
194
-                    'EEH_File',
195
-                    EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
-                );
197
-                espresso_load_required(
198
-                    'EEH_Array',
199
-                    EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
-                );
201
-                // instantiate and configure PSR4 autoloader
202
-                espresso_load_required(
203
-                    'Psr4Autoloader',
204
-                    EE_CORE . 'Psr4Autoloader.php'
205
-                );
206
-                espresso_load_required(
207
-                    'EE_Psr4AutoloaderInit',
208
-                    EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
-                );
210
-                $AutoloaderInit = new EE_Psr4AutoloaderInit();
211
-                $AutoloaderInit->initializeAutoloader();
212
-                espresso_load_required(
213
-                    'EE_Request',
214
-                    EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
-                );
216
-                espresso_load_required(
217
-                    'EE_Response',
218
-                    EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
-                );
220
-                espresso_load_required(
221
-                    'EE_Bootstrap',
222
-                    EE_CORE . 'EE_Bootstrap.core.php'
223
-                );
224
-                // bootstrap EE and the request stack
225
-                new EE_Bootstrap(
226
-                    new EE_Request($_GET, $_POST, $_COOKIE),
227
-                    new EE_Response()
228
-                );
229
-            } catch (Exception $e) {
230
-                require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
-                new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
-            }
233
-        }
234
-        bootstrap_espresso();
235
-    }
168
+		/**
169
+		 * @since 4.9.27
170
+		 * @throws \EE_Error
171
+		 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
+		 * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
+		 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
+		 * @throws \EventEspresso\core\exceptions\InvalidClassException
175
+		 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
+		 * @throws \OutOfBoundsException
179
+		 */
180
+		function bootstrap_espresso()
181
+		{
182
+			require_once __DIR__ . '/core/espresso_definitions.php';
183
+			try {
184
+				espresso_load_error_handling();
185
+				espresso_load_required(
186
+					'EEH_Base',
187
+					EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
+				);
189
+				espresso_load_required(
190
+					'EEH_File',
191
+					EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
+				);
193
+				espresso_load_required(
194
+					'EEH_File',
195
+					EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
+				);
197
+				espresso_load_required(
198
+					'EEH_Array',
199
+					EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
+				);
201
+				// instantiate and configure PSR4 autoloader
202
+				espresso_load_required(
203
+					'Psr4Autoloader',
204
+					EE_CORE . 'Psr4Autoloader.php'
205
+				);
206
+				espresso_load_required(
207
+					'EE_Psr4AutoloaderInit',
208
+					EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
+				);
210
+				$AutoloaderInit = new EE_Psr4AutoloaderInit();
211
+				$AutoloaderInit->initializeAutoloader();
212
+				espresso_load_required(
213
+					'EE_Request',
214
+					EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
+				);
216
+				espresso_load_required(
217
+					'EE_Response',
218
+					EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
+				);
220
+				espresso_load_required(
221
+					'EE_Bootstrap',
222
+					EE_CORE . 'EE_Bootstrap.core.php'
223
+				);
224
+				// bootstrap EE and the request stack
225
+				new EE_Bootstrap(
226
+					new EE_Request($_GET, $_POST, $_COOKIE),
227
+					new EE_Response()
228
+				);
229
+			} catch (Exception $e) {
230
+				require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
+				new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
+			}
233
+		}
234
+		bootstrap_espresso();
235
+	}
236 236
 }
237 237
 if (! function_exists('espresso_deactivate_plugin')) {
238
-    /**
239
-     *    deactivate_plugin
240
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
-     *
242
-     * @access public
243
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
-     * @return    void
245
-     */
246
-    function espresso_deactivate_plugin($plugin_basename = '')
247
-    {
248
-        if (! function_exists('deactivate_plugins')) {
249
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
-        }
251
-        unset($_GET['activate'], $_REQUEST['activate']);
252
-        deactivate_plugins($plugin_basename);
253
-    }
238
+	/**
239
+	 *    deactivate_plugin
240
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
+	 *
242
+	 * @access public
243
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
+	 * @return    void
245
+	 */
246
+	function espresso_deactivate_plugin($plugin_basename = '')
247
+	{
248
+		if (! function_exists('deactivate_plugins')) {
249
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
+		}
251
+		unset($_GET['activate'], $_REQUEST['activate']);
252
+		deactivate_plugins($plugin_basename);
253
+	}
254 254
 }
Please login to merge, or discard this patch.
core/EE_Session.core.php 1 patch
Indentation   +1192 added lines, -1192 removed lines patch added patch discarded remove patch
@@ -20,1198 +20,1198 @@  discard block
 block discarded – undo
20 20
 class EE_Session implements SessionIdentifierInterface
21 21
 {
22 22
 
23
-    const session_id_prefix    = 'ee_ssn_';
24
-
25
-    const hash_check_prefix    = 'ee_shc_';
26
-
27
-    const OPTION_NAME_SETTINGS = 'ee_session_settings';
28
-
29
-    /**
30
-     * instance of the EE_Session object
31
-     *
32
-     * @var EE_Session
33
-     */
34
-    private static $_instance;
35
-
36
-    /**
37
-     * @var CacheStorageInterface $cache_storage
38
-     */
39
-    protected $cache_storage;
40
-
41
-    /**
42
-     * EE_Encryption object
43
-     *
44
-     * @var EE_Encryption
45
-     */
46
-    protected $encryption;
47
-
48
-    /**
49
-     * the session id
50
-     *
51
-     * @var string
52
-     */
53
-    private $_sid;
54
-
55
-    /**
56
-     * session id salt
57
-     *
58
-     * @var string
59
-     */
60
-    private $_sid_salt;
61
-
62
-    /**
63
-     * session data
64
-     *
65
-     * @var array
66
-     */
67
-    private $_session_data = array();
68
-
69
-    /**
70
-     * how long an EE session lasts
71
-     * default session lifespan of 2 hours (for not so instant IPNs)
72
-     *
73
-     * @var int
74
-     */
75
-    private $_lifespan;
76
-
77
-    /**
78
-     * session expiration time as Unix timestamp in GMT
79
-     *
80
-     * @var int
81
-     */
82
-    private $_expiration;
83
-
84
-    /**
85
-     * whether or not session has expired at some point
86
-     *
87
-     * @var boolean
88
-     */
89
-    private $_expired = false;
90
-
91
-    /**
92
-     * current time as Unix timestamp in GMT
93
-     *
94
-     * @var int
95
-     */
96
-    private $_time;
97
-
98
-    /**
99
-     * whether to encrypt session data
100
-     *
101
-     * @var bool
102
-     */
103
-    private $_use_encryption;
104
-
105
-    /**
106
-     * well... according to the server...
107
-     *
108
-     * @var null
109
-     */
110
-    private $_user_agent;
111
-
112
-    /**
113
-     * do you really trust the server ?
114
-     *
115
-     * @var null
116
-     */
117
-    private $_ip_address;
118
-
119
-    /**
120
-     * current WP user_id
121
-     *
122
-     * @var null
123
-     */
124
-    private $_wp_user_id;
125
-
126
-    /**
127
-     * array for defining default session vars
128
-     *
129
-     * @var array
130
-     */
131
-    private $_default_session_vars = array(
132
-        'id'            => null,
133
-        'user_id'       => null,
134
-        'ip_address'    => null,
135
-        'user_agent'    => null,
136
-        'init_access'   => null,
137
-        'last_access'   => null,
138
-        'expiration'    => null,
139
-        'pages_visited' => array(),
140
-    );
141
-
142
-    /**
143
-     * timestamp for when last garbage collection cycle was performed
144
-     *
145
-     * @var int $_last_gc
146
-     */
147
-    private $_last_gc;
148
-
149
-    /**
150
-     * @var EE_Request
151
-     */
152
-    protected $request;
153
-
154
-
155
-
156
-    /**
157
-     * @singleton method used to instantiate class object
158
-     * @param CacheStorageInterface $cache_storage
159
-     * @param EE_Request            $request
160
-     * @param EE_Encryption         $encryption
161
-     * @return EE_Session
162
-     * @throws InvalidArgumentException
163
-     * @throws InvalidDataTypeException
164
-     * @throws InvalidInterfaceException
165
-     */
166
-    public static function instance(
167
-        CacheStorageInterface $cache_storage = null,
168
-        EE_Request $request = null,
169
-        EE_Encryption $encryption = null
170
-    ) {
171
-        // check if class object is instantiated
172
-        // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
173
-        // add_filter( 'FHEE_load_EE_Session', '__return_false' );
174
-        if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
175
-            self::$_instance = new self($cache_storage, $request, $encryption);
176
-        }
177
-        return self::$_instance;
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     * protected constructor to prevent direct creation
184
-     *
185
-     * @param CacheStorageInterface $cache_storage
186
-     * @param EE_Request            $request
187
-     * @param EE_Encryption         $encryption
188
-     * @throws InvalidArgumentException
189
-     * @throws InvalidDataTypeException
190
-     * @throws InvalidInterfaceException
191
-     */
192
-    protected function __construct(
193
-        CacheStorageInterface $cache_storage,
194
-        EE_Request $request,
195
-        EE_Encryption $encryption = null
196
-    ) {
197
-        // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
198
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
199
-            return;
200
-        }
201
-        $this->request = $request;
202
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
203
-        if (! defined('ESPRESSO_SESSION')) {
204
-            define('ESPRESSO_SESSION', true);
205
-        }
206
-        // default session lifespan in seconds
207
-        $this->_lifespan = apply_filters(
208
-                               'FHEE__EE_Session__construct___lifespan',
209
-                               60 * MINUTE_IN_SECONDS
210
-                           ) + 1;
211
-        /*
23
+	const session_id_prefix    = 'ee_ssn_';
24
+
25
+	const hash_check_prefix    = 'ee_shc_';
26
+
27
+	const OPTION_NAME_SETTINGS = 'ee_session_settings';
28
+
29
+	/**
30
+	 * instance of the EE_Session object
31
+	 *
32
+	 * @var EE_Session
33
+	 */
34
+	private static $_instance;
35
+
36
+	/**
37
+	 * @var CacheStorageInterface $cache_storage
38
+	 */
39
+	protected $cache_storage;
40
+
41
+	/**
42
+	 * EE_Encryption object
43
+	 *
44
+	 * @var EE_Encryption
45
+	 */
46
+	protected $encryption;
47
+
48
+	/**
49
+	 * the session id
50
+	 *
51
+	 * @var string
52
+	 */
53
+	private $_sid;
54
+
55
+	/**
56
+	 * session id salt
57
+	 *
58
+	 * @var string
59
+	 */
60
+	private $_sid_salt;
61
+
62
+	/**
63
+	 * session data
64
+	 *
65
+	 * @var array
66
+	 */
67
+	private $_session_data = array();
68
+
69
+	/**
70
+	 * how long an EE session lasts
71
+	 * default session lifespan of 2 hours (for not so instant IPNs)
72
+	 *
73
+	 * @var int
74
+	 */
75
+	private $_lifespan;
76
+
77
+	/**
78
+	 * session expiration time as Unix timestamp in GMT
79
+	 *
80
+	 * @var int
81
+	 */
82
+	private $_expiration;
83
+
84
+	/**
85
+	 * whether or not session has expired at some point
86
+	 *
87
+	 * @var boolean
88
+	 */
89
+	private $_expired = false;
90
+
91
+	/**
92
+	 * current time as Unix timestamp in GMT
93
+	 *
94
+	 * @var int
95
+	 */
96
+	private $_time;
97
+
98
+	/**
99
+	 * whether to encrypt session data
100
+	 *
101
+	 * @var bool
102
+	 */
103
+	private $_use_encryption;
104
+
105
+	/**
106
+	 * well... according to the server...
107
+	 *
108
+	 * @var null
109
+	 */
110
+	private $_user_agent;
111
+
112
+	/**
113
+	 * do you really trust the server ?
114
+	 *
115
+	 * @var null
116
+	 */
117
+	private $_ip_address;
118
+
119
+	/**
120
+	 * current WP user_id
121
+	 *
122
+	 * @var null
123
+	 */
124
+	private $_wp_user_id;
125
+
126
+	/**
127
+	 * array for defining default session vars
128
+	 *
129
+	 * @var array
130
+	 */
131
+	private $_default_session_vars = array(
132
+		'id'            => null,
133
+		'user_id'       => null,
134
+		'ip_address'    => null,
135
+		'user_agent'    => null,
136
+		'init_access'   => null,
137
+		'last_access'   => null,
138
+		'expiration'    => null,
139
+		'pages_visited' => array(),
140
+	);
141
+
142
+	/**
143
+	 * timestamp for when last garbage collection cycle was performed
144
+	 *
145
+	 * @var int $_last_gc
146
+	 */
147
+	private $_last_gc;
148
+
149
+	/**
150
+	 * @var EE_Request
151
+	 */
152
+	protected $request;
153
+
154
+
155
+
156
+	/**
157
+	 * @singleton method used to instantiate class object
158
+	 * @param CacheStorageInterface $cache_storage
159
+	 * @param EE_Request            $request
160
+	 * @param EE_Encryption         $encryption
161
+	 * @return EE_Session
162
+	 * @throws InvalidArgumentException
163
+	 * @throws InvalidDataTypeException
164
+	 * @throws InvalidInterfaceException
165
+	 */
166
+	public static function instance(
167
+		CacheStorageInterface $cache_storage = null,
168
+		EE_Request $request = null,
169
+		EE_Encryption $encryption = null
170
+	) {
171
+		// check if class object is instantiated
172
+		// session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
173
+		// add_filter( 'FHEE_load_EE_Session', '__return_false' );
174
+		if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
175
+			self::$_instance = new self($cache_storage, $request, $encryption);
176
+		}
177
+		return self::$_instance;
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 * protected constructor to prevent direct creation
184
+	 *
185
+	 * @param CacheStorageInterface $cache_storage
186
+	 * @param EE_Request            $request
187
+	 * @param EE_Encryption         $encryption
188
+	 * @throws InvalidArgumentException
189
+	 * @throws InvalidDataTypeException
190
+	 * @throws InvalidInterfaceException
191
+	 */
192
+	protected function __construct(
193
+		CacheStorageInterface $cache_storage,
194
+		EE_Request $request,
195
+		EE_Encryption $encryption = null
196
+	) {
197
+		// session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
198
+		if (! apply_filters('FHEE_load_EE_Session', true)) {
199
+			return;
200
+		}
201
+		$this->request = $request;
202
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
203
+		if (! defined('ESPRESSO_SESSION')) {
204
+			define('ESPRESSO_SESSION', true);
205
+		}
206
+		// default session lifespan in seconds
207
+		$this->_lifespan = apply_filters(
208
+							   'FHEE__EE_Session__construct___lifespan',
209
+							   60 * MINUTE_IN_SECONDS
210
+						   ) + 1;
211
+		/*
212 212
          * do something like the following to adjust the session lifespan:
213 213
          * 		public static function session_lifespan() {
214 214
          * 			return 15 * MINUTE_IN_SECONDS;
215 215
          * 		}
216 216
          */
217
-        // retrieve session options from db
218
-        $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
219
-        if (! empty($session_settings)) {
220
-            // cycle though existing session options
221
-            foreach ($session_settings as $var_name => $session_setting) {
222
-                // set values for class properties
223
-                $var_name          = '_' . $var_name;
224
-                $this->{$var_name} = $session_setting;
225
-            }
226
-        }
227
-        $this->cache_storage = $cache_storage;
228
-        // are we using encryption?
229
-        $this->_use_encryption = $encryption instanceof EE_Encryption
230
-                                 && EE_Registry::instance()->CFG->admin->encode_session_data();
231
-        // \EEH_Debug_Tools::printr($this->_use_encryption, '$this->_use_encryption', __FILE__, __LINE__);
232
-        // encrypt data via: $this->encryption->encrypt();
233
-        $this->encryption = $encryption;
234
-        // filter hook allows outside functions/classes/plugins to change default empty cart
235
-        $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
236
-        array_merge($this->_default_session_vars, $extra_default_session_vars);
237
-        // apply default session vars
238
-        $this->_set_defaults();
239
-        add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
240
-        // check request for 'clear_session' param
241
-        add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
242
-        // once everything is all said and done,
243
-        add_action('shutdown', array($this, 'update'), 100);
244
-        add_action('shutdown', array($this, 'garbageCollection'), 1000);
245
-        $this->configure_garbage_collection_filters();
246
-    }
247
-
248
-
249
-
250
-    /**
251
-     * @return void
252
-     * @throws EE_Error
253
-     * @throws InvalidArgumentException
254
-     * @throws InvalidDataTypeException
255
-     * @throws InvalidInterfaceException
256
-     * @throws InvalidSessionDataException
257
-     */
258
-    public function open_session()
259
-    {
260
-        // check for existing session and retrieve it from db
261
-        if (! $this->_espresso_session()) {
262
-            // or just start a new one
263
-            $this->_create_espresso_session();
264
-        }
265
-    }
266
-
267
-
268
-
269
-    /**
270
-     * @return bool
271
-     */
272
-    public function expired()
273
-    {
274
-        return $this->_expired;
275
-    }
276
-
277
-
278
-
279
-    /**
280
-     * @return void
281
-     */
282
-    public function reset_expired()
283
-    {
284
-        $this->_expired = false;
285
-    }
286
-
287
-
288
-    /**
289
-     * @return int
290
-     */
291
-    public function expiration()
292
-    {
293
-        return $this->_expiration;
294
-    }
295
-
296
-
297
-
298
-    /**
299
-     * @return int
300
-     */
301
-    public function extension()
302
-    {
303
-        return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
304
-    }
305
-
306
-
307
-
308
-    /**
309
-     * @param int $time number of seconds to add to session expiration
310
-     */
311
-    public function extend_expiration($time = 0)
312
-    {
313
-        $time              = $time ? $time : $this->extension();
314
-        $this->_expiration += absint($time);
315
-    }
316
-
317
-
318
-
319
-    /**
320
-     * @return int
321
-     */
322
-    public function lifespan()
323
-    {
324
-        return $this->_lifespan;
325
-    }
326
-
327
-
328
-
329
-    /**
330
-     * This just sets some defaults for the _session data property
331
-     *
332
-     * @access private
333
-     * @return void
334
-     */
335
-    private function _set_defaults()
336
-    {
337
-        // set some defaults
338
-        foreach ($this->_default_session_vars as $key => $default_var) {
339
-            if (is_array($default_var)) {
340
-                $this->_session_data[ $key ] = array();
341
-            } else {
342
-                $this->_session_data[ $key ] = '';
343
-            }
344
-        }
345
-    }
217
+		// retrieve session options from db
218
+		$session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
219
+		if (! empty($session_settings)) {
220
+			// cycle though existing session options
221
+			foreach ($session_settings as $var_name => $session_setting) {
222
+				// set values for class properties
223
+				$var_name          = '_' . $var_name;
224
+				$this->{$var_name} = $session_setting;
225
+			}
226
+		}
227
+		$this->cache_storage = $cache_storage;
228
+		// are we using encryption?
229
+		$this->_use_encryption = $encryption instanceof EE_Encryption
230
+								 && EE_Registry::instance()->CFG->admin->encode_session_data();
231
+		// \EEH_Debug_Tools::printr($this->_use_encryption, '$this->_use_encryption', __FILE__, __LINE__);
232
+		// encrypt data via: $this->encryption->encrypt();
233
+		$this->encryption = $encryption;
234
+		// filter hook allows outside functions/classes/plugins to change default empty cart
235
+		$extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
236
+		array_merge($this->_default_session_vars, $extra_default_session_vars);
237
+		// apply default session vars
238
+		$this->_set_defaults();
239
+		add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
240
+		// check request for 'clear_session' param
241
+		add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
242
+		// once everything is all said and done,
243
+		add_action('shutdown', array($this, 'update'), 100);
244
+		add_action('shutdown', array($this, 'garbageCollection'), 1000);
245
+		$this->configure_garbage_collection_filters();
246
+	}
247
+
248
+
249
+
250
+	/**
251
+	 * @return void
252
+	 * @throws EE_Error
253
+	 * @throws InvalidArgumentException
254
+	 * @throws InvalidDataTypeException
255
+	 * @throws InvalidInterfaceException
256
+	 * @throws InvalidSessionDataException
257
+	 */
258
+	public function open_session()
259
+	{
260
+		// check for existing session and retrieve it from db
261
+		if (! $this->_espresso_session()) {
262
+			// or just start a new one
263
+			$this->_create_espresso_session();
264
+		}
265
+	}
266
+
267
+
268
+
269
+	/**
270
+	 * @return bool
271
+	 */
272
+	public function expired()
273
+	{
274
+		return $this->_expired;
275
+	}
276
+
277
+
278
+
279
+	/**
280
+	 * @return void
281
+	 */
282
+	public function reset_expired()
283
+	{
284
+		$this->_expired = false;
285
+	}
286
+
287
+
288
+	/**
289
+	 * @return int
290
+	 */
291
+	public function expiration()
292
+	{
293
+		return $this->_expiration;
294
+	}
295
+
296
+
297
+
298
+	/**
299
+	 * @return int
300
+	 */
301
+	public function extension()
302
+	{
303
+		return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
304
+	}
305
+
306
+
307
+
308
+	/**
309
+	 * @param int $time number of seconds to add to session expiration
310
+	 */
311
+	public function extend_expiration($time = 0)
312
+	{
313
+		$time              = $time ? $time : $this->extension();
314
+		$this->_expiration += absint($time);
315
+	}
316
+
317
+
318
+
319
+	/**
320
+	 * @return int
321
+	 */
322
+	public function lifespan()
323
+	{
324
+		return $this->_lifespan;
325
+	}
326
+
327
+
328
+
329
+	/**
330
+	 * This just sets some defaults for the _session data property
331
+	 *
332
+	 * @access private
333
+	 * @return void
334
+	 */
335
+	private function _set_defaults()
336
+	{
337
+		// set some defaults
338
+		foreach ($this->_default_session_vars as $key => $default_var) {
339
+			if (is_array($default_var)) {
340
+				$this->_session_data[ $key ] = array();
341
+			} else {
342
+				$this->_session_data[ $key ] = '';
343
+			}
344
+		}
345
+	}
346 346
 
347 347
 
348
-
349
-    /**
350
-     * @retrieve  session data
351
-     * @access    public
352
-     * @return    string
353
-     */
354
-    public function id()
355
-    {
356
-        return $this->_sid;
357
-    }
348
+
349
+	/**
350
+	 * @retrieve  session data
351
+	 * @access    public
352
+	 * @return    string
353
+	 */
354
+	public function id()
355
+	{
356
+		return $this->_sid;
357
+	}
358 358
 
359 359
 
360 360
 
361
-    /**
362
-     * @param \EE_Cart $cart
363
-     * @return bool
364
-     */
365
-    public function set_cart(EE_Cart $cart)
366
-    {
367
-        $this->_session_data['cart'] = $cart;
368
-        return true;
369
-    }
361
+	/**
362
+	 * @param \EE_Cart $cart
363
+	 * @return bool
364
+	 */
365
+	public function set_cart(EE_Cart $cart)
366
+	{
367
+		$this->_session_data['cart'] = $cart;
368
+		return true;
369
+	}
370 370
 
371 371
 
372 372
 
373
-    /**
374
-     * reset_cart
375
-     */
376
-    public function reset_cart()
377
-    {
378
-        do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
379
-        $this->_session_data['cart'] = null;
380
-    }
381
-
382
-
383
-
384
-    /**
385
-     * @return \EE_Cart
386
-     */
387
-    public function cart()
388
-    {
389
-        return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
390
-            ? $this->_session_data['cart']
391
-            : null;
392
-    }
393
-
394
-
395
-
396
-    /**
397
-     * @param \EE_Checkout $checkout
398
-     * @return bool
399
-     */
400
-    public function set_checkout(EE_Checkout $checkout)
401
-    {
402
-        $this->_session_data['checkout'] = $checkout;
403
-        return true;
404
-    }
405
-
406
-
407
-
408
-    /**
409
-     * reset_checkout
410
-     */
411
-    public function reset_checkout()
412
-    {
413
-        do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
414
-        $this->_session_data['checkout'] = null;
415
-    }
416
-
417
-
418
-
419
-    /**
420
-     * @return \EE_Checkout
421
-     */
422
-    public function checkout()
423
-    {
424
-        return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
425
-            ? $this->_session_data['checkout']
426
-            : null;
427
-    }
428
-
429
-
430
-
431
-    /**
432
-     * @param \EE_Transaction $transaction
433
-     * @return bool
434
-     * @throws EE_Error
435
-     */
436
-    public function set_transaction(EE_Transaction $transaction)
437
-    {
438
-        // first remove the session from the transaction before we save the transaction in the session
439
-        $transaction->set_txn_session_data(null);
440
-        $this->_session_data['transaction'] = $transaction;
441
-        return true;
442
-    }
443
-
444
-
445
-
446
-    /**
447
-     * reset_transaction
448
-     */
449
-    public function reset_transaction()
450
-    {
451
-        do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
452
-        $this->_session_data['transaction'] = null;
453
-    }
454
-
455
-
456
-
457
-    /**
458
-     * @return \EE_Transaction
459
-     */
460
-    public function transaction()
461
-    {
462
-        return isset($this->_session_data['transaction'])
463
-               && $this->_session_data['transaction'] instanceof EE_Transaction
464
-            ? $this->_session_data['transaction']
465
-            : null;
466
-    }
467
-
468
-
469
-
470
-    /**
471
-     * retrieve session data
472
-     *
473
-     * @access    public
474
-     * @param null $key
475
-     * @param bool $reset_cache
476
-     * @return    array
477
-     */
478
-    public function get_session_data($key = null, $reset_cache = false)
479
-    {
480
-        if ($reset_cache) {
481
-            $this->reset_cart();
482
-            $this->reset_checkout();
483
-            $this->reset_transaction();
484
-        }
485
-        if (! empty($key)) {
486
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
487
-        }
488
-        return $this->_session_data;
489
-    }
490
-
491
-
492
-
493
-    /**
494
-     * set session data
495
-     *
496
-     * @access    public
497
-     * @param    array $data
498
-     * @return    TRUE on success, FALSE on fail
499
-     */
500
-    public function set_session_data($data)
501
-    {
502
-
503
-        // nothing ??? bad data ??? go home!
504
-        if (empty($data) || ! is_array($data)) {
505
-            EE_Error::add_error(__('No session data or invalid session data was provided.', 'event_espresso'), __FILE__,
506
-                __FUNCTION__, __LINE__);
507
-            return false;
508
-        }
509
-        foreach ($data as $key => $value) {
510
-            if (isset($this->_default_session_vars[ $key ])) {
511
-                EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
512
-                    'event_espresso'), $key), __FILE__, __FUNCTION__, __LINE__);
513
-                return false;
514
-            }
515
-            $this->_session_data[ $key ] = $value;
516
-        }
517
-        return true;
518
-    }
519
-
520
-
521
-
522
-    /**
523
-     * @initiate session
524
-     * @access   private
525
-     * @return TRUE on success, FALSE on fail
526
-     * @throws EE_Error
527
-     * @throws InvalidArgumentException
528
-     * @throws InvalidDataTypeException
529
-     * @throws InvalidInterfaceException
530
-     * @throws InvalidSessionDataException
531
-     */
532
-    private function _espresso_session()
533
-    {
534
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
535
-        // check that session has started
536
-        if (session_id() === '') {
537
-            //starts a new session if one doesn't already exist, or re-initiates an existing one
538
-            session_start();
539
-        }
540
-        // get our modified session ID
541
-        $this->_sid = $this->_generate_session_id();
542
-        // and the visitors IP
543
-        $this->_ip_address = $this->request->ip_address();
544
-        // set the "user agent"
545
-        $this->_user_agent = $this->request->userAgent();
546
-        // now let's retrieve what's in the db
547
-        $session_data = $this->_retrieve_session_data();
548
-        if (! empty($session_data)) {
549
-            // get the current time in UTC
550
-            $this->_time = $this->_time !== null ? $this->_time : time();
551
-            // and reset the session expiration
552
-            $this->_expiration = isset($session_data['expiration'])
553
-                ? $session_data['expiration']
554
-                : $this->_time + $this->_lifespan;
555
-        } else {
556
-            // set initial site access time and the session expiration
557
-            $this->_set_init_access_and_expiration();
558
-            // set referer
559
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
560
-                ? esc_attr($_SERVER['HTTP_REFERER'])
561
-                : '';
562
-            // no previous session = go back and create one (on top of the data above)
563
-            return false;
564
-        }
565
-        // now the user agent
566
-        if ($session_data['user_agent'] !== $this->_user_agent) {
567
-            return false;
568
-        }
569
-        // wait a minute... how old are you?
570
-        if ($this->_time > $this->_expiration) {
571
-            // yer too old fer me!
572
-            $this->_expired = true;
573
-            // wipe out everything that isn't a default session datum
574
-            $this->clear_session(__CLASS__, __FUNCTION__);
575
-        }
576
-        // make event espresso session data available to plugin
577
-        $this->_session_data = array_merge($this->_session_data, $session_data);
578
-        return true;
579
-    }
580
-
581
-
582
-
583
-    /**
584
-     * _get_session_data
585
-     * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
586
-     * databases
587
-     *
588
-     * @return array
589
-     * @throws EE_Error
590
-     * @throws InvalidArgumentException
591
-     * @throws InvalidSessionDataException
592
-     * @throws InvalidDataTypeException
593
-     * @throws InvalidInterfaceException
594
-     */
595
-    protected function _retrieve_session_data()
596
-    {
597
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
598
-        try {
599
-            // we're using WP's Transient API to store session data using the PHP session ID as the option name
600
-            $session_data = $this->cache_storage->get($ssn_key, false);
601
-            if (empty($session_data)) {
602
-                return array();
603
-            }
604
-            if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
605
-                $hash_check = $this->cache_storage->get(
606
-                    EE_Session::hash_check_prefix . $this->_sid,
607
-                    false
608
-                );
609
-                if ($hash_check && $hash_check !== md5($session_data)) {
610
-                    EE_Error::add_error(
611
-                        sprintf(
612
-                            __(
613
-                                'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
614
-                                'event_espresso'
615
-                            ),
616
-                            EE_Session::session_id_prefix . $this->_sid
617
-                        ),
618
-                        __FILE__, __FUNCTION__, __LINE__
619
-                    );
620
-                }
621
-            }
622
-        } catch (Exception $e) {
623
-            // let's just eat that error for now and attempt to correct any corrupted data
624
-            global $wpdb;
625
-            $row          = $wpdb->get_row(
626
-                $wpdb->prepare(
627
-                    "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
628
-                    '_transient_' . $ssn_key
629
-                )
630
-            );
631
-            $session_data = is_object($row) ? $row->option_value : null;
632
-            if ($session_data) {
633
-                $session_data = preg_replace_callback(
634
-                    '!s:(d+):"(.*?)";!',
635
-                    function ($match)
636
-                    {
637
-                        return $match[1] === strlen($match[2])
638
-                            ? $match[0]
639
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
640
-                    },
641
-                    $session_data
642
-                );
643
-            }
644
-            $session_data = maybe_unserialize($session_data);
645
-        }
646
-        // in case the data is encoded... try to decode it
647
-        $session_data = $this->encryption instanceof EE_Encryption
648
-            ? $this->encryption->base64_string_decode($session_data)
649
-            : $session_data;
650
-        if (! is_array($session_data)) {
651
-            try {
652
-                $session_data = maybe_unserialize($session_data);
653
-            } catch (Exception $e) {
654
-                $msg = esc_html__(
655
-                    'An error occurred while attempting to unserialize the session data.',
656
-                    'event_espresso'
657
-                );
658
-                $msg .= WP_DEBUG
659
-                    ? '<br><pre>'
660
-                      . print_r($session_data, true)
661
-                      . '</pre><br>'
662
-                      . $this->find_serialize_error($session_data)
663
-                    : '';
664
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
665
-                throw new InvalidSessionDataException($msg, 0, $e);
666
-            }
667
-        }
668
-        // just a check to make sure the session array is indeed an array
669
-        if (! is_array($session_data)) {
670
-            // no?!?! then something is wrong
671
-            $msg = esc_html__(
672
-                'The session data is missing, invalid, or corrupted.',
673
-                'event_espresso'
674
-            );
675
-            $msg .= WP_DEBUG
676
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
677
-                : '';
678
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
679
-            throw new InvalidSessionDataException($msg);
680
-        }
681
-        if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
682
-            $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
683
-                $session_data['transaction']
684
-            );
685
-        }
686
-        return $session_data;
687
-    }
688
-
689
-
690
-
691
-    /**
692
-     * _generate_session_id
693
-     * Retrieves the PHP session id either directly from the PHP session,
694
-     * or from the $_REQUEST array if it was passed in from an AJAX request.
695
-     * The session id is then salted and hashed (mmm sounds tasty)
696
-     * so that it can be safely used as a $_REQUEST param
697
-     *
698
-     * @return string
699
-     */
700
-    protected function _generate_session_id()
701
-    {
702
-        // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
703
-        if (isset($_REQUEST['EESID'])) {
704
-            $session_id = sanitize_text_field($_REQUEST['EESID']);
705
-        } else {
706
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
707
-        }
708
-        return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
709
-    }
710
-
711
-
712
-
713
-    /**
714
-     * _get_sid_salt
715
-     *
716
-     * @return string
717
-     */
718
-    protected function _get_sid_salt()
719
-    {
720
-        // was session id salt already saved to db ?
721
-        if (empty($this->_sid_salt)) {
722
-            // no?  then maybe use WP defined constant
723
-            if (defined('AUTH_SALT')) {
724
-                $this->_sid_salt = AUTH_SALT;
725
-            }
726
-            // if salt doesn't exist or is too short
727
-            if (strlen($this->_sid_salt) < 32) {
728
-                // create a new one
729
-                $this->_sid_salt = wp_generate_password(64);
730
-            }
731
-            // and save it as a permanent session setting
732
-            $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
733
-        }
734
-        return $this->_sid_salt;
735
-    }
736
-
737
-
738
-
739
-    /**
740
-     * _set_init_access_and_expiration
741
-     *
742
-     * @return void
743
-     */
744
-    protected function _set_init_access_and_expiration()
745
-    {
746
-        $this->_time       = time();
747
-        $this->_expiration = $this->_time + $this->_lifespan;
748
-        // set initial site access time
749
-        $this->_session_data['init_access'] = $this->_time;
750
-        // and the session expiration
751
-        $this->_session_data['expiration'] = $this->_expiration;
752
-    }
753
-
754
-
755
-
756
-    /**
757
-     * @update session data  prior to saving to the db
758
-     * @access public
759
-     * @param bool $new_session
760
-     * @return TRUE on success, FALSE on fail
761
-     * @throws EE_Error
762
-     * @throws InvalidArgumentException
763
-     * @throws InvalidDataTypeException
764
-     * @throws InvalidInterfaceException
765
-     */
766
-    public function update($new_session = false)
767
-    {
768
-        $this->_session_data = $this->_session_data !== null
769
-                               && is_array($this->_session_data)
770
-                               && isset($this->_session_data['id'])
771
-            ? $this->_session_data
772
-            : array();
773
-        if (empty($this->_session_data)) {
774
-            $this->_set_defaults();
775
-        }
776
-        $session_data = array();
777
-        foreach ($this->_session_data as $key => $value) {
778
-
779
-            switch ($key) {
780
-
781
-                case 'id' :
782
-                    // session ID
783
-                    $session_data['id'] = $this->_sid;
784
-                    break;
785
-                case 'ip_address' :
786
-                    // visitor ip address
787
-                    $session_data['ip_address'] = $this->request->ip_address();
788
-                    break;
789
-                case 'user_agent' :
790
-                    // visitor user_agent
791
-                    $session_data['user_agent'] = $this->_user_agent;
792
-                    break;
793
-                case 'init_access' :
794
-                    $session_data['init_access'] = absint($value);
795
-                    break;
796
-                case 'last_access' :
797
-                    // current access time
798
-                    $session_data['last_access'] = $this->_time;
799
-                    break;
800
-                case 'expiration' :
801
-                    // when the session expires
802
-                    $session_data['expiration'] = ! empty($this->_expiration)
803
-                        ? $this->_expiration
804
-                        : $session_data['init_access'] + $this->_lifespan;
805
-                    break;
806
-                case 'user_id' :
807
-                    // current user if logged in
808
-                    $session_data['user_id'] = $this->_wp_user_id();
809
-                    break;
810
-                case 'pages_visited' :
811
-                    $page_visit = $this->_get_page_visit();
812
-                    if ($page_visit) {
813
-                        // set pages visited where the first will be the http referrer
814
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
815
-                        // we'll only save the last 10 page visits.
816
-                        $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
817
-                    }
818
-                    break;
819
-                default :
820
-                    // carry any other data over
821
-                    $session_data[ $key ] = $this->_session_data[ $key ];
822
-            }
823
-        }
824
-        $this->_session_data = $session_data;
825
-        // creating a new session does not require saving to the db just yet
826
-        if (! $new_session) {
827
-            // ready? let's save
828
-            if ($this->_save_session_to_db()) {
829
-                return true;
830
-            }
831
-            return false;
832
-        }
833
-        // meh, why not?
834
-        return true;
835
-    }
836
-
837
-
838
-
839
-    /**
840
-     * @create session data array
841
-     * @access public
842
-     * @return bool
843
-     * @throws EE_Error
844
-     * @throws InvalidArgumentException
845
-     * @throws InvalidDataTypeException
846
-     * @throws InvalidInterfaceException
847
-     */
848
-    private function _create_espresso_session()
849
-    {
850
-        do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
851
-        // use the update function for now with $new_session arg set to TRUE
852
-        return $this->update(true) ? true : false;
853
-    }
854
-
855
-
856
-
857
-    /**
858
-     * _save_session_to_db
859
-     *
860
-     * @access public
861
-     * @return string
862
-     * @throws EE_Error
863
-     * @throws InvalidArgumentException
864
-     * @throws InvalidDataTypeException
865
-     * @throws InvalidInterfaceException
866
-     */
867
-    private function _save_session_to_db()
868
-    {
869
-        if (
870
-            $this->request->isBot()
871
-            // if the current request is NOT one of the following
872
-            || ! (
873
-                // an an AJAX request from the frontend
874
-                EE_Registry::instance()->REQ->front_ajax
875
-                || (
876
-                    // OR an admin request that is NOT AJAX
877
-                    ! (defined('DOING_AJAX') && DOING_AJAX)
878
-                    && is_admin()
879
-                )
880
-                || (
881
-                    // OR an espresso page
882
-                    EE_Registry::instance()->REQ instanceof EE_Request_Handler
883
-                    && EE_Registry::instance()->REQ->is_espresso_page()
884
-                )
885
-            )
886
-        ) {
887
-            return false;
888
-        }
889
-        $transaction = $this->transaction();
890
-        if ($transaction instanceof EE_Transaction) {
891
-            if (! $transaction->ID()) {
892
-                $transaction->save();
893
-            }
894
-            $this->_session_data['transaction'] = $transaction->ID();
895
-        }
896
-        // then serialize all of our session data
897
-        $session_data = serialize($this->_session_data);
898
-        // do we need to also encode it to avoid corrupted data when saved to the db?
899
-        $session_data = $this->_use_encryption
900
-            ? $this->encryption->base64_string_encode($session_data)
901
-            : $session_data;
902
-        // maybe save hash check
903
-        if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
904
-            $this->cache_storage->add(
905
-                EE_Session::hash_check_prefix . $this->_sid,
906
-                md5($session_data),
907
-                $this->_lifespan
908
-            );
909
-        }
910
-        // we're using the Transient API for storing session data,
911
-        return $this->cache_storage->add(
912
-            EE_Session::session_id_prefix . $this->_sid,
913
-            $session_data,
914
-            $this->_lifespan
915
-        );
916
-    }
917
-
918
-
919
-    /**
920
-     * @get    the full page request the visitor is accessing
921
-     * @access public
922
-     * @return string
923
-     */
924
-    public function _get_page_visit()
925
-    {
926
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
927
-        // check for request url
928
-        if (isset($_SERVER['REQUEST_URI'])) {
929
-            $http_host   = '';
930
-            $page_id     = '?';
931
-            $e_reg       = '';
932
-            $request_uri = esc_url($_SERVER['REQUEST_URI']);
933
-            $ru_bits     = explode('?', $request_uri);
934
-            $request_uri = $ru_bits[0];
935
-            // check for and grab host as well
936
-            if (isset($_SERVER['HTTP_HOST'])) {
937
-                $http_host = esc_url($_SERVER['HTTP_HOST']);
938
-            }
939
-            // check for page_id in SERVER REQUEST
940
-            if (isset($_REQUEST['page_id'])) {
941
-                // rebuild $e_reg without any of the extra parameters
942
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
943
-            }
944
-            // check for $e_reg in SERVER REQUEST
945
-            if (isset($_REQUEST['ee'])) {
946
-                // rebuild $e_reg without any of the extra parameters
947
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
948
-            }
949
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
950
-        }
951
-        return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
952
-    }
953
-
954
-
955
-
956
-    /**
957
-     * @the    current wp user id
958
-     * @access public
959
-     * @return int
960
-     */
961
-    public function _wp_user_id()
962
-    {
963
-        // if I need to explain the following lines of code, then you shouldn't be looking at this!
964
-        $this->_wp_user_id = get_current_user_id();
965
-        return $this->_wp_user_id;
966
-    }
967
-
968
-
969
-
970
-    /**
971
-     * Clear EE_Session data
972
-     *
973
-     * @access public
974
-     * @param string $class
975
-     * @param string $function
976
-     * @return void
977
-     * @throws EE_Error
978
-     * @throws InvalidArgumentException
979
-     * @throws InvalidDataTypeException
980
-     * @throws InvalidInterfaceException
981
-     */
982
-    public function clear_session($class = '', $function = '')
983
-    {
984
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
985
-        $this->reset_cart();
986
-        $this->reset_checkout();
987
-        $this->reset_transaction();
988
-        // wipe out everything that isn't a default session datum
989
-        $this->reset_data(array_keys($this->_session_data));
990
-        // reset initial site access time and the session expiration
991
-        $this->_set_init_access_and_expiration();
992
-        $this->_save_session_to_db();
993
-    }
994
-
995
-
996
-
997
-    /**
998
-     * @resets all non-default session vars
999
-     * @access public
1000
-     * @param array|mixed $data_to_reset
1001
-     * @param bool        $show_all_notices
1002
-     * @return TRUE on success, FALSE on fail
1003
-     */
1004
-    public function reset_data($data_to_reset = array(), $show_all_notices = false)
1005
-    {
1006
-        // if $data_to_reset is not in an array, then put it in one
1007
-        if (! is_array($data_to_reset)) {
1008
-            $data_to_reset = array($data_to_reset);
1009
-        }
1010
-        // nothing ??? go home!
1011
-        if (empty($data_to_reset)) {
1012
-            EE_Error::add_error(__('No session data could be reset, because no session var name was provided.',
1013
-                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1014
-            return false;
1015
-        }
1016
-        $return_value = true;
1017
-        // since $data_to_reset is an array, cycle through the values
1018
-        foreach ($data_to_reset as $reset) {
1019
-
1020
-            // first check to make sure it is a valid session var
1021
-            if (isset($this->_session_data[ $reset ])) {
1022
-                // then check to make sure it is not a default var
1023
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1024
-                    // remove session var
1025
-                    unset($this->_session_data[ $reset ]);
1026
-                    if ($show_all_notices) {
1027
-                        EE_Error::add_success(sprintf(__('The session variable %s was removed.', 'event_espresso'),
1028
-                            $reset), __FILE__, __FUNCTION__, __LINE__);
1029
-                    }
1030
-                } else {
1031
-                    // yeeeeeeeeerrrrrrrrrrr OUT !!!!
1032
-                    if ($show_all_notices) {
1033
-                        EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
1034
-                            'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1035
-                    }
1036
-                    $return_value = false;
1037
-                }
1038
-            } elseif ($show_all_notices) {
1039
-                // oops! that session var does not exist!
1040
-                EE_Error::add_error(sprintf(__('The session item provided, %s, is invalid or does not exist.',
1041
-                    'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1042
-                $return_value = false;
1043
-            }
1044
-        } // end of foreach
1045
-        return $return_value;
1046
-    }
1047
-
1048
-
1049
-
1050
-    /**
1051
-     *   wp_loaded
1052
-     *
1053
-     * @access public
1054
-     * @throws EE_Error
1055
-     * @throws InvalidDataTypeException
1056
-     * @throws InvalidInterfaceException
1057
-     * @throws InvalidArgumentException
1058
-     */
1059
-    public function wp_loaded()
1060
-    {
1061
-        if ($this->request->is_set('clear_session')) {
1062
-            $this->clear_session(__CLASS__, __FUNCTION__);
1063
-        }
1064
-    }
1065
-
1066
-
1067
-
1068
-    /**
1069
-     * Used to reset the entire object (for tests).
1070
-     *
1071
-     * @since 4.3.0
1072
-     * @throws EE_Error
1073
-     * @throws InvalidDataTypeException
1074
-     * @throws InvalidInterfaceException
1075
-     * @throws InvalidArgumentException
1076
-     */
1077
-    public function reset_instance()
1078
-    {
1079
-        $this->clear_session();
1080
-        self::$_instance = null;
1081
-    }
1082
-
1083
-
1084
-
1085
-    public function configure_garbage_collection_filters()
1086
-    {
1087
-        // run old filter we had for controlling session cleanup
1088
-        $expired_session_transient_delete_query_limit = absint(
1089
-            apply_filters(
1090
-                'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1091
-                50
1092
-            )
1093
-        );
1094
-        // is there a value? or one that is different than the default 50 records?
1095
-        if ($expired_session_transient_delete_query_limit === 0) {
1096
-            // hook into TransientCacheStorage in case Session cleanup was turned off
1097
-            add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1098
-        } elseif ($expired_session_transient_delete_query_limit !== 50) {
1099
-            // or use that for the new transient cleanup query limit
1100
-            add_filter(
1101
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1102
-                function () use ($expired_session_transient_delete_query_limit)
1103
-                {
1104
-                    return $expired_session_transient_delete_query_limit;
1105
-                }
1106
-            );
1107
-        }
1108
-    }
1109
-
1110
-
1111
-
1112
-    /**
1113
-     * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1114
-     * @param $data1
1115
-     * @return string
1116
-     */
1117
-    private function find_serialize_error($data1)
1118
-    {
1119
-        $error = '<pre>';
1120
-        $data2 = preg_replace_callback(
1121
-            '!s:(\d+):"(.*?)";!',
1122
-            function ($match)
1123
-            {
1124
-                return ($match[1] === strlen($match[2]))
1125
-                    ? $match[0]
1126
-                    : 's:'
1127
-                      . strlen($match[2])
1128
-                      . ':"'
1129
-                      . $match[2]
1130
-                      . '";';
1131
-            },
1132
-            $data1
1133
-        );
1134
-        $max   = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1135
-        $error .= $data1 . PHP_EOL;
1136
-        $error .= $data2 . PHP_EOL;
1137
-        for ($i = 0; $i < $max; $i++) {
1138
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1139
-                $error  .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1140
-                $error  .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1141
-                $error  .= "\t-> Line Number = $i" . PHP_EOL;
1142
-                $start  = ($i - 20);
1143
-                $start  = ($start < 0) ? 0 : $start;
1144
-                $length = 40;
1145
-                $point  = $max - $i;
1146
-                if ($point < 20) {
1147
-                    $rlength = 1;
1148
-                    $rpoint  = -$point;
1149
-                } else {
1150
-                    $rpoint  = $length - 20;
1151
-                    $rlength = 1;
1152
-                }
1153
-                $error .= "\t-> Section Data1  = ";
1154
-                $error .= substr_replace(
1155
-                    substr($data1, $start, $length),
1156
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1157
-                    $rpoint,
1158
-                    $rlength
1159
-                );
1160
-                $error .= PHP_EOL;
1161
-                $error .= "\t-> Section Data2  = ";
1162
-                $error .= substr_replace(
1163
-                    substr($data2, $start, $length),
1164
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1165
-                    $rpoint,
1166
-                    $rlength
1167
-                );
1168
-                $error .= PHP_EOL;
1169
-            }
1170
-        }
1171
-        $error .= '</pre>';
1172
-        return $error;
1173
-    }
1174
-
1175
-
1176
-    /**
1177
-     * Saves an  array of settings used for configuring aspects of session behaviour
1178
-     *
1179
-     * @param array $updated_settings
1180
-     */
1181
-    private function updateSessionSettings(array $updated_settings = array())
1182
-    {
1183
-        // add existing settings, but only if not included in incoming $updated_settings array
1184
-        $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1185
-        update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1186
-    }
1187
-
1188
-
1189
-    /**
1190
-     * garbage_collection
1191
-     */
1192
-    public function garbageCollection()
1193
-    {
1194
-        // only perform during regular requests if last garbage collection was over an hour ago
1195
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1196
-            $this->_last_gc = time();
1197
-            $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1198
-            /** @type WPDB $wpdb */
1199
-            global $wpdb;
1200
-            // filter the query limit. Set to 0 to turn off garbage collection
1201
-            $expired_session_transient_delete_query_limit = absint(
1202
-                apply_filters(
1203
-                    'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1204
-                    50
1205
-                )
1206
-            );
1207
-            // non-zero LIMIT means take out the trash
1208
-            if ($expired_session_transient_delete_query_limit) {
1209
-                $session_key    = str_replace('_', '\_', EE_Session::session_id_prefix);
1210
-                $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1211
-                // since transient expiration timestamps are set in the future, we can compare against NOW
1212
-                // but we only want to pick up any trash that's been around for more than a day
1213
-                $expiration = time() - DAY_IN_SECONDS;
1214
-                $SQL        = "
373
+	/**
374
+	 * reset_cart
375
+	 */
376
+	public function reset_cart()
377
+	{
378
+		do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
379
+		$this->_session_data['cart'] = null;
380
+	}
381
+
382
+
383
+
384
+	/**
385
+	 * @return \EE_Cart
386
+	 */
387
+	public function cart()
388
+	{
389
+		return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
390
+			? $this->_session_data['cart']
391
+			: null;
392
+	}
393
+
394
+
395
+
396
+	/**
397
+	 * @param \EE_Checkout $checkout
398
+	 * @return bool
399
+	 */
400
+	public function set_checkout(EE_Checkout $checkout)
401
+	{
402
+		$this->_session_data['checkout'] = $checkout;
403
+		return true;
404
+	}
405
+
406
+
407
+
408
+	/**
409
+	 * reset_checkout
410
+	 */
411
+	public function reset_checkout()
412
+	{
413
+		do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
414
+		$this->_session_data['checkout'] = null;
415
+	}
416
+
417
+
418
+
419
+	/**
420
+	 * @return \EE_Checkout
421
+	 */
422
+	public function checkout()
423
+	{
424
+		return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
425
+			? $this->_session_data['checkout']
426
+			: null;
427
+	}
428
+
429
+
430
+
431
+	/**
432
+	 * @param \EE_Transaction $transaction
433
+	 * @return bool
434
+	 * @throws EE_Error
435
+	 */
436
+	public function set_transaction(EE_Transaction $transaction)
437
+	{
438
+		// first remove the session from the transaction before we save the transaction in the session
439
+		$transaction->set_txn_session_data(null);
440
+		$this->_session_data['transaction'] = $transaction;
441
+		return true;
442
+	}
443
+
444
+
445
+
446
+	/**
447
+	 * reset_transaction
448
+	 */
449
+	public function reset_transaction()
450
+	{
451
+		do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
452
+		$this->_session_data['transaction'] = null;
453
+	}
454
+
455
+
456
+
457
+	/**
458
+	 * @return \EE_Transaction
459
+	 */
460
+	public function transaction()
461
+	{
462
+		return isset($this->_session_data['transaction'])
463
+			   && $this->_session_data['transaction'] instanceof EE_Transaction
464
+			? $this->_session_data['transaction']
465
+			: null;
466
+	}
467
+
468
+
469
+
470
+	/**
471
+	 * retrieve session data
472
+	 *
473
+	 * @access    public
474
+	 * @param null $key
475
+	 * @param bool $reset_cache
476
+	 * @return    array
477
+	 */
478
+	public function get_session_data($key = null, $reset_cache = false)
479
+	{
480
+		if ($reset_cache) {
481
+			$this->reset_cart();
482
+			$this->reset_checkout();
483
+			$this->reset_transaction();
484
+		}
485
+		if (! empty($key)) {
486
+			return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
487
+		}
488
+		return $this->_session_data;
489
+	}
490
+
491
+
492
+
493
+	/**
494
+	 * set session data
495
+	 *
496
+	 * @access    public
497
+	 * @param    array $data
498
+	 * @return    TRUE on success, FALSE on fail
499
+	 */
500
+	public function set_session_data($data)
501
+	{
502
+
503
+		// nothing ??? bad data ??? go home!
504
+		if (empty($data) || ! is_array($data)) {
505
+			EE_Error::add_error(__('No session data or invalid session data was provided.', 'event_espresso'), __FILE__,
506
+				__FUNCTION__, __LINE__);
507
+			return false;
508
+		}
509
+		foreach ($data as $key => $value) {
510
+			if (isset($this->_default_session_vars[ $key ])) {
511
+				EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
512
+					'event_espresso'), $key), __FILE__, __FUNCTION__, __LINE__);
513
+				return false;
514
+			}
515
+			$this->_session_data[ $key ] = $value;
516
+		}
517
+		return true;
518
+	}
519
+
520
+
521
+
522
+	/**
523
+	 * @initiate session
524
+	 * @access   private
525
+	 * @return TRUE on success, FALSE on fail
526
+	 * @throws EE_Error
527
+	 * @throws InvalidArgumentException
528
+	 * @throws InvalidDataTypeException
529
+	 * @throws InvalidInterfaceException
530
+	 * @throws InvalidSessionDataException
531
+	 */
532
+	private function _espresso_session()
533
+	{
534
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
535
+		// check that session has started
536
+		if (session_id() === '') {
537
+			//starts a new session if one doesn't already exist, or re-initiates an existing one
538
+			session_start();
539
+		}
540
+		// get our modified session ID
541
+		$this->_sid = $this->_generate_session_id();
542
+		// and the visitors IP
543
+		$this->_ip_address = $this->request->ip_address();
544
+		// set the "user agent"
545
+		$this->_user_agent = $this->request->userAgent();
546
+		// now let's retrieve what's in the db
547
+		$session_data = $this->_retrieve_session_data();
548
+		if (! empty($session_data)) {
549
+			// get the current time in UTC
550
+			$this->_time = $this->_time !== null ? $this->_time : time();
551
+			// and reset the session expiration
552
+			$this->_expiration = isset($session_data['expiration'])
553
+				? $session_data['expiration']
554
+				: $this->_time + $this->_lifespan;
555
+		} else {
556
+			// set initial site access time and the session expiration
557
+			$this->_set_init_access_and_expiration();
558
+			// set referer
559
+			$this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
560
+				? esc_attr($_SERVER['HTTP_REFERER'])
561
+				: '';
562
+			// no previous session = go back and create one (on top of the data above)
563
+			return false;
564
+		}
565
+		// now the user agent
566
+		if ($session_data['user_agent'] !== $this->_user_agent) {
567
+			return false;
568
+		}
569
+		// wait a minute... how old are you?
570
+		if ($this->_time > $this->_expiration) {
571
+			// yer too old fer me!
572
+			$this->_expired = true;
573
+			// wipe out everything that isn't a default session datum
574
+			$this->clear_session(__CLASS__, __FUNCTION__);
575
+		}
576
+		// make event espresso session data available to plugin
577
+		$this->_session_data = array_merge($this->_session_data, $session_data);
578
+		return true;
579
+	}
580
+
581
+
582
+
583
+	/**
584
+	 * _get_session_data
585
+	 * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
586
+	 * databases
587
+	 *
588
+	 * @return array
589
+	 * @throws EE_Error
590
+	 * @throws InvalidArgumentException
591
+	 * @throws InvalidSessionDataException
592
+	 * @throws InvalidDataTypeException
593
+	 * @throws InvalidInterfaceException
594
+	 */
595
+	protected function _retrieve_session_data()
596
+	{
597
+		$ssn_key = EE_Session::session_id_prefix . $this->_sid;
598
+		try {
599
+			// we're using WP's Transient API to store session data using the PHP session ID as the option name
600
+			$session_data = $this->cache_storage->get($ssn_key, false);
601
+			if (empty($session_data)) {
602
+				return array();
603
+			}
604
+			if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
605
+				$hash_check = $this->cache_storage->get(
606
+					EE_Session::hash_check_prefix . $this->_sid,
607
+					false
608
+				);
609
+				if ($hash_check && $hash_check !== md5($session_data)) {
610
+					EE_Error::add_error(
611
+						sprintf(
612
+							__(
613
+								'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
614
+								'event_espresso'
615
+							),
616
+							EE_Session::session_id_prefix . $this->_sid
617
+						),
618
+						__FILE__, __FUNCTION__, __LINE__
619
+					);
620
+				}
621
+			}
622
+		} catch (Exception $e) {
623
+			// let's just eat that error for now and attempt to correct any corrupted data
624
+			global $wpdb;
625
+			$row          = $wpdb->get_row(
626
+				$wpdb->prepare(
627
+					"SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
628
+					'_transient_' . $ssn_key
629
+				)
630
+			);
631
+			$session_data = is_object($row) ? $row->option_value : null;
632
+			if ($session_data) {
633
+				$session_data = preg_replace_callback(
634
+					'!s:(d+):"(.*?)";!',
635
+					function ($match)
636
+					{
637
+						return $match[1] === strlen($match[2])
638
+							? $match[0]
639
+							: 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
640
+					},
641
+					$session_data
642
+				);
643
+			}
644
+			$session_data = maybe_unserialize($session_data);
645
+		}
646
+		// in case the data is encoded... try to decode it
647
+		$session_data = $this->encryption instanceof EE_Encryption
648
+			? $this->encryption->base64_string_decode($session_data)
649
+			: $session_data;
650
+		if (! is_array($session_data)) {
651
+			try {
652
+				$session_data = maybe_unserialize($session_data);
653
+			} catch (Exception $e) {
654
+				$msg = esc_html__(
655
+					'An error occurred while attempting to unserialize the session data.',
656
+					'event_espresso'
657
+				);
658
+				$msg .= WP_DEBUG
659
+					? '<br><pre>'
660
+					  . print_r($session_data, true)
661
+					  . '</pre><br>'
662
+					  . $this->find_serialize_error($session_data)
663
+					: '';
664
+				$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
665
+				throw new InvalidSessionDataException($msg, 0, $e);
666
+			}
667
+		}
668
+		// just a check to make sure the session array is indeed an array
669
+		if (! is_array($session_data)) {
670
+			// no?!?! then something is wrong
671
+			$msg = esc_html__(
672
+				'The session data is missing, invalid, or corrupted.',
673
+				'event_espresso'
674
+			);
675
+			$msg .= WP_DEBUG
676
+				? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
677
+				: '';
678
+			$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
679
+			throw new InvalidSessionDataException($msg);
680
+		}
681
+		if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
682
+			$session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
683
+				$session_data['transaction']
684
+			);
685
+		}
686
+		return $session_data;
687
+	}
688
+
689
+
690
+
691
+	/**
692
+	 * _generate_session_id
693
+	 * Retrieves the PHP session id either directly from the PHP session,
694
+	 * or from the $_REQUEST array if it was passed in from an AJAX request.
695
+	 * The session id is then salted and hashed (mmm sounds tasty)
696
+	 * so that it can be safely used as a $_REQUEST param
697
+	 *
698
+	 * @return string
699
+	 */
700
+	protected function _generate_session_id()
701
+	{
702
+		// check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
703
+		if (isset($_REQUEST['EESID'])) {
704
+			$session_id = sanitize_text_field($_REQUEST['EESID']);
705
+		} else {
706
+			$session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
707
+		}
708
+		return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
709
+	}
710
+
711
+
712
+
713
+	/**
714
+	 * _get_sid_salt
715
+	 *
716
+	 * @return string
717
+	 */
718
+	protected function _get_sid_salt()
719
+	{
720
+		// was session id salt already saved to db ?
721
+		if (empty($this->_sid_salt)) {
722
+			// no?  then maybe use WP defined constant
723
+			if (defined('AUTH_SALT')) {
724
+				$this->_sid_salt = AUTH_SALT;
725
+			}
726
+			// if salt doesn't exist or is too short
727
+			if (strlen($this->_sid_salt) < 32) {
728
+				// create a new one
729
+				$this->_sid_salt = wp_generate_password(64);
730
+			}
731
+			// and save it as a permanent session setting
732
+			$this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
733
+		}
734
+		return $this->_sid_salt;
735
+	}
736
+
737
+
738
+
739
+	/**
740
+	 * _set_init_access_and_expiration
741
+	 *
742
+	 * @return void
743
+	 */
744
+	protected function _set_init_access_and_expiration()
745
+	{
746
+		$this->_time       = time();
747
+		$this->_expiration = $this->_time + $this->_lifespan;
748
+		// set initial site access time
749
+		$this->_session_data['init_access'] = $this->_time;
750
+		// and the session expiration
751
+		$this->_session_data['expiration'] = $this->_expiration;
752
+	}
753
+
754
+
755
+
756
+	/**
757
+	 * @update session data  prior to saving to the db
758
+	 * @access public
759
+	 * @param bool $new_session
760
+	 * @return TRUE on success, FALSE on fail
761
+	 * @throws EE_Error
762
+	 * @throws InvalidArgumentException
763
+	 * @throws InvalidDataTypeException
764
+	 * @throws InvalidInterfaceException
765
+	 */
766
+	public function update($new_session = false)
767
+	{
768
+		$this->_session_data = $this->_session_data !== null
769
+							   && is_array($this->_session_data)
770
+							   && isset($this->_session_data['id'])
771
+			? $this->_session_data
772
+			: array();
773
+		if (empty($this->_session_data)) {
774
+			$this->_set_defaults();
775
+		}
776
+		$session_data = array();
777
+		foreach ($this->_session_data as $key => $value) {
778
+
779
+			switch ($key) {
780
+
781
+				case 'id' :
782
+					// session ID
783
+					$session_data['id'] = $this->_sid;
784
+					break;
785
+				case 'ip_address' :
786
+					// visitor ip address
787
+					$session_data['ip_address'] = $this->request->ip_address();
788
+					break;
789
+				case 'user_agent' :
790
+					// visitor user_agent
791
+					$session_data['user_agent'] = $this->_user_agent;
792
+					break;
793
+				case 'init_access' :
794
+					$session_data['init_access'] = absint($value);
795
+					break;
796
+				case 'last_access' :
797
+					// current access time
798
+					$session_data['last_access'] = $this->_time;
799
+					break;
800
+				case 'expiration' :
801
+					// when the session expires
802
+					$session_data['expiration'] = ! empty($this->_expiration)
803
+						? $this->_expiration
804
+						: $session_data['init_access'] + $this->_lifespan;
805
+					break;
806
+				case 'user_id' :
807
+					// current user if logged in
808
+					$session_data['user_id'] = $this->_wp_user_id();
809
+					break;
810
+				case 'pages_visited' :
811
+					$page_visit = $this->_get_page_visit();
812
+					if ($page_visit) {
813
+						// set pages visited where the first will be the http referrer
814
+						$this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
815
+						// we'll only save the last 10 page visits.
816
+						$session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
817
+					}
818
+					break;
819
+				default :
820
+					// carry any other data over
821
+					$session_data[ $key ] = $this->_session_data[ $key ];
822
+			}
823
+		}
824
+		$this->_session_data = $session_data;
825
+		// creating a new session does not require saving to the db just yet
826
+		if (! $new_session) {
827
+			// ready? let's save
828
+			if ($this->_save_session_to_db()) {
829
+				return true;
830
+			}
831
+			return false;
832
+		}
833
+		// meh, why not?
834
+		return true;
835
+	}
836
+
837
+
838
+
839
+	/**
840
+	 * @create session data array
841
+	 * @access public
842
+	 * @return bool
843
+	 * @throws EE_Error
844
+	 * @throws InvalidArgumentException
845
+	 * @throws InvalidDataTypeException
846
+	 * @throws InvalidInterfaceException
847
+	 */
848
+	private function _create_espresso_session()
849
+	{
850
+		do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
851
+		// use the update function for now with $new_session arg set to TRUE
852
+		return $this->update(true) ? true : false;
853
+	}
854
+
855
+
856
+
857
+	/**
858
+	 * _save_session_to_db
859
+	 *
860
+	 * @access public
861
+	 * @return string
862
+	 * @throws EE_Error
863
+	 * @throws InvalidArgumentException
864
+	 * @throws InvalidDataTypeException
865
+	 * @throws InvalidInterfaceException
866
+	 */
867
+	private function _save_session_to_db()
868
+	{
869
+		if (
870
+			$this->request->isBot()
871
+			// if the current request is NOT one of the following
872
+			|| ! (
873
+				// an an AJAX request from the frontend
874
+				EE_Registry::instance()->REQ->front_ajax
875
+				|| (
876
+					// OR an admin request that is NOT AJAX
877
+					! (defined('DOING_AJAX') && DOING_AJAX)
878
+					&& is_admin()
879
+				)
880
+				|| (
881
+					// OR an espresso page
882
+					EE_Registry::instance()->REQ instanceof EE_Request_Handler
883
+					&& EE_Registry::instance()->REQ->is_espresso_page()
884
+				)
885
+			)
886
+		) {
887
+			return false;
888
+		}
889
+		$transaction = $this->transaction();
890
+		if ($transaction instanceof EE_Transaction) {
891
+			if (! $transaction->ID()) {
892
+				$transaction->save();
893
+			}
894
+			$this->_session_data['transaction'] = $transaction->ID();
895
+		}
896
+		// then serialize all of our session data
897
+		$session_data = serialize($this->_session_data);
898
+		// do we need to also encode it to avoid corrupted data when saved to the db?
899
+		$session_data = $this->_use_encryption
900
+			? $this->encryption->base64_string_encode($session_data)
901
+			: $session_data;
902
+		// maybe save hash check
903
+		if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
904
+			$this->cache_storage->add(
905
+				EE_Session::hash_check_prefix . $this->_sid,
906
+				md5($session_data),
907
+				$this->_lifespan
908
+			);
909
+		}
910
+		// we're using the Transient API for storing session data,
911
+		return $this->cache_storage->add(
912
+			EE_Session::session_id_prefix . $this->_sid,
913
+			$session_data,
914
+			$this->_lifespan
915
+		);
916
+	}
917
+
918
+
919
+	/**
920
+	 * @get    the full page request the visitor is accessing
921
+	 * @access public
922
+	 * @return string
923
+	 */
924
+	public function _get_page_visit()
925
+	{
926
+		$page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
927
+		// check for request url
928
+		if (isset($_SERVER['REQUEST_URI'])) {
929
+			$http_host   = '';
930
+			$page_id     = '?';
931
+			$e_reg       = '';
932
+			$request_uri = esc_url($_SERVER['REQUEST_URI']);
933
+			$ru_bits     = explode('?', $request_uri);
934
+			$request_uri = $ru_bits[0];
935
+			// check for and grab host as well
936
+			if (isset($_SERVER['HTTP_HOST'])) {
937
+				$http_host = esc_url($_SERVER['HTTP_HOST']);
938
+			}
939
+			// check for page_id in SERVER REQUEST
940
+			if (isset($_REQUEST['page_id'])) {
941
+				// rebuild $e_reg without any of the extra parameters
942
+				$page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
943
+			}
944
+			// check for $e_reg in SERVER REQUEST
945
+			if (isset($_REQUEST['ee'])) {
946
+				// rebuild $e_reg without any of the extra parameters
947
+				$e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
948
+			}
949
+			$page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
950
+		}
951
+		return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
952
+	}
953
+
954
+
955
+
956
+	/**
957
+	 * @the    current wp user id
958
+	 * @access public
959
+	 * @return int
960
+	 */
961
+	public function _wp_user_id()
962
+	{
963
+		// if I need to explain the following lines of code, then you shouldn't be looking at this!
964
+		$this->_wp_user_id = get_current_user_id();
965
+		return $this->_wp_user_id;
966
+	}
967
+
968
+
969
+
970
+	/**
971
+	 * Clear EE_Session data
972
+	 *
973
+	 * @access public
974
+	 * @param string $class
975
+	 * @param string $function
976
+	 * @return void
977
+	 * @throws EE_Error
978
+	 * @throws InvalidArgumentException
979
+	 * @throws InvalidDataTypeException
980
+	 * @throws InvalidInterfaceException
981
+	 */
982
+	public function clear_session($class = '', $function = '')
983
+	{
984
+		do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
985
+		$this->reset_cart();
986
+		$this->reset_checkout();
987
+		$this->reset_transaction();
988
+		// wipe out everything that isn't a default session datum
989
+		$this->reset_data(array_keys($this->_session_data));
990
+		// reset initial site access time and the session expiration
991
+		$this->_set_init_access_and_expiration();
992
+		$this->_save_session_to_db();
993
+	}
994
+
995
+
996
+
997
+	/**
998
+	 * @resets all non-default session vars
999
+	 * @access public
1000
+	 * @param array|mixed $data_to_reset
1001
+	 * @param bool        $show_all_notices
1002
+	 * @return TRUE on success, FALSE on fail
1003
+	 */
1004
+	public function reset_data($data_to_reset = array(), $show_all_notices = false)
1005
+	{
1006
+		// if $data_to_reset is not in an array, then put it in one
1007
+		if (! is_array($data_to_reset)) {
1008
+			$data_to_reset = array($data_to_reset);
1009
+		}
1010
+		// nothing ??? go home!
1011
+		if (empty($data_to_reset)) {
1012
+			EE_Error::add_error(__('No session data could be reset, because no session var name was provided.',
1013
+				'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1014
+			return false;
1015
+		}
1016
+		$return_value = true;
1017
+		// since $data_to_reset is an array, cycle through the values
1018
+		foreach ($data_to_reset as $reset) {
1019
+
1020
+			// first check to make sure it is a valid session var
1021
+			if (isset($this->_session_data[ $reset ])) {
1022
+				// then check to make sure it is not a default var
1023
+				if (! array_key_exists($reset, $this->_default_session_vars)) {
1024
+					// remove session var
1025
+					unset($this->_session_data[ $reset ]);
1026
+					if ($show_all_notices) {
1027
+						EE_Error::add_success(sprintf(__('The session variable %s was removed.', 'event_espresso'),
1028
+							$reset), __FILE__, __FUNCTION__, __LINE__);
1029
+					}
1030
+				} else {
1031
+					// yeeeeeeeeerrrrrrrrrrr OUT !!!!
1032
+					if ($show_all_notices) {
1033
+						EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
1034
+							'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1035
+					}
1036
+					$return_value = false;
1037
+				}
1038
+			} elseif ($show_all_notices) {
1039
+				// oops! that session var does not exist!
1040
+				EE_Error::add_error(sprintf(__('The session item provided, %s, is invalid or does not exist.',
1041
+					'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1042
+				$return_value = false;
1043
+			}
1044
+		} // end of foreach
1045
+		return $return_value;
1046
+	}
1047
+
1048
+
1049
+
1050
+	/**
1051
+	 *   wp_loaded
1052
+	 *
1053
+	 * @access public
1054
+	 * @throws EE_Error
1055
+	 * @throws InvalidDataTypeException
1056
+	 * @throws InvalidInterfaceException
1057
+	 * @throws InvalidArgumentException
1058
+	 */
1059
+	public function wp_loaded()
1060
+	{
1061
+		if ($this->request->is_set('clear_session')) {
1062
+			$this->clear_session(__CLASS__, __FUNCTION__);
1063
+		}
1064
+	}
1065
+
1066
+
1067
+
1068
+	/**
1069
+	 * Used to reset the entire object (for tests).
1070
+	 *
1071
+	 * @since 4.3.0
1072
+	 * @throws EE_Error
1073
+	 * @throws InvalidDataTypeException
1074
+	 * @throws InvalidInterfaceException
1075
+	 * @throws InvalidArgumentException
1076
+	 */
1077
+	public function reset_instance()
1078
+	{
1079
+		$this->clear_session();
1080
+		self::$_instance = null;
1081
+	}
1082
+
1083
+
1084
+
1085
+	public function configure_garbage_collection_filters()
1086
+	{
1087
+		// run old filter we had for controlling session cleanup
1088
+		$expired_session_transient_delete_query_limit = absint(
1089
+			apply_filters(
1090
+				'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1091
+				50
1092
+			)
1093
+		);
1094
+		// is there a value? or one that is different than the default 50 records?
1095
+		if ($expired_session_transient_delete_query_limit === 0) {
1096
+			// hook into TransientCacheStorage in case Session cleanup was turned off
1097
+			add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1098
+		} elseif ($expired_session_transient_delete_query_limit !== 50) {
1099
+			// or use that for the new transient cleanup query limit
1100
+			add_filter(
1101
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1102
+				function () use ($expired_session_transient_delete_query_limit)
1103
+				{
1104
+					return $expired_session_transient_delete_query_limit;
1105
+				}
1106
+			);
1107
+		}
1108
+	}
1109
+
1110
+
1111
+
1112
+	/**
1113
+	 * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1114
+	 * @param $data1
1115
+	 * @return string
1116
+	 */
1117
+	private function find_serialize_error($data1)
1118
+	{
1119
+		$error = '<pre>';
1120
+		$data2 = preg_replace_callback(
1121
+			'!s:(\d+):"(.*?)";!',
1122
+			function ($match)
1123
+			{
1124
+				return ($match[1] === strlen($match[2]))
1125
+					? $match[0]
1126
+					: 's:'
1127
+					  . strlen($match[2])
1128
+					  . ':"'
1129
+					  . $match[2]
1130
+					  . '";';
1131
+			},
1132
+			$data1
1133
+		);
1134
+		$max   = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1135
+		$error .= $data1 . PHP_EOL;
1136
+		$error .= $data2 . PHP_EOL;
1137
+		for ($i = 0; $i < $max; $i++) {
1138
+			if (@$data1[ $i ] !== @$data2[ $i ]) {
1139
+				$error  .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1140
+				$error  .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1141
+				$error  .= "\t-> Line Number = $i" . PHP_EOL;
1142
+				$start  = ($i - 20);
1143
+				$start  = ($start < 0) ? 0 : $start;
1144
+				$length = 40;
1145
+				$point  = $max - $i;
1146
+				if ($point < 20) {
1147
+					$rlength = 1;
1148
+					$rpoint  = -$point;
1149
+				} else {
1150
+					$rpoint  = $length - 20;
1151
+					$rlength = 1;
1152
+				}
1153
+				$error .= "\t-> Section Data1  = ";
1154
+				$error .= substr_replace(
1155
+					substr($data1, $start, $length),
1156
+					"<b style=\"color:green\">{$data1[ $i ]}</b>",
1157
+					$rpoint,
1158
+					$rlength
1159
+				);
1160
+				$error .= PHP_EOL;
1161
+				$error .= "\t-> Section Data2  = ";
1162
+				$error .= substr_replace(
1163
+					substr($data2, $start, $length),
1164
+					"<b style=\"color:red\">{$data2[ $i ]}</b>",
1165
+					$rpoint,
1166
+					$rlength
1167
+				);
1168
+				$error .= PHP_EOL;
1169
+			}
1170
+		}
1171
+		$error .= '</pre>';
1172
+		return $error;
1173
+	}
1174
+
1175
+
1176
+	/**
1177
+	 * Saves an  array of settings used for configuring aspects of session behaviour
1178
+	 *
1179
+	 * @param array $updated_settings
1180
+	 */
1181
+	private function updateSessionSettings(array $updated_settings = array())
1182
+	{
1183
+		// add existing settings, but only if not included in incoming $updated_settings array
1184
+		$updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1185
+		update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1186
+	}
1187
+
1188
+
1189
+	/**
1190
+	 * garbage_collection
1191
+	 */
1192
+	public function garbageCollection()
1193
+	{
1194
+		// only perform during regular requests if last garbage collection was over an hour ago
1195
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1196
+			$this->_last_gc = time();
1197
+			$this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1198
+			/** @type WPDB $wpdb */
1199
+			global $wpdb;
1200
+			// filter the query limit. Set to 0 to turn off garbage collection
1201
+			$expired_session_transient_delete_query_limit = absint(
1202
+				apply_filters(
1203
+					'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1204
+					50
1205
+				)
1206
+			);
1207
+			// non-zero LIMIT means take out the trash
1208
+			if ($expired_session_transient_delete_query_limit) {
1209
+				$session_key    = str_replace('_', '\_', EE_Session::session_id_prefix);
1210
+				$hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1211
+				// since transient expiration timestamps are set in the future, we can compare against NOW
1212
+				// but we only want to pick up any trash that's been around for more than a day
1213
+				$expiration = time() - DAY_IN_SECONDS;
1214
+				$SQL        = "
1215 1215
                     SELECT option_name
1216 1216
                     FROM {$wpdb->options}
1217 1217
                     WHERE
@@ -1220,19 +1220,19 @@  discard block
 block discarded – undo
1220 1220
                     AND option_value < {$expiration}
1221 1221
                     LIMIT {$expired_session_transient_delete_query_limit}
1222 1222
                 ";
1223
-                // produces something like:
1224
-                // SELECT option_name FROM wp_options
1225
-                // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1226
-                // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1227
-                // AND option_value < 1508368198 LIMIT 50
1228
-                $expired_sessions = $wpdb->get_col($SQL);
1229
-                // valid results?
1230
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1231
-                    $this->cache_storage->deleteMany($expired_sessions, true);
1232
-                }
1233
-            }
1234
-        }
1235
-    }
1223
+				// produces something like:
1224
+				// SELECT option_name FROM wp_options
1225
+				// WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1226
+				// OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1227
+				// AND option_value < 1508368198 LIMIT 50
1228
+				$expired_sessions = $wpdb->get_col($SQL);
1229
+				// valid results?
1230
+				if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1231
+					$this->cache_storage->deleteMany($expired_sessions, true);
1232
+				}
1233
+			}
1234
+		}
1235
+	}
1236 1236
 
1237 1237
 
1238 1238
 
Please login to merge, or discard this patch.
core/services/loaders/CoreLoader.php 2 patches
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -32,76 +32,76 @@
 block discarded – undo
32 32
 class CoreLoader implements LoaderDecoratorInterface
33 33
 {
34 34
 
35
-    /**
36
-     * @var EE_Registry|CoffeeShop $generator
37
-     */
38
-    private $generator;
39
-
40
-
41
-
42
-    /**
43
-     * CoreLoader constructor.
44
-     *
45
-     * @param EE_Registry|CoffeeShop $generator
46
-     * @throws InvalidArgumentException
47
-     */
48
-    public function __construct($generator)
49
-    {
50
-        if(!($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) {
51
-            throw new InvalidArgumentException(
52
-                esc_html__(
53
-                    'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.',
54
-                    'event_espresso'
55
-                )
56
-            );
57
-        }
58
-        $this->generator = $generator;
59
-    }
60
-
61
-
62
-
63
-    /**
64
-     * @param string $fqcn
65
-     * @param array  $arguments
66
-     * @param bool   $shared
67
-     * @return mixed
68
-     * @throws OutOfBoundsException
69
-     * @throws ServiceExistsException
70
-     * @throws InstantiationException
71
-     * @throws InvalidIdentifierException
72
-     * @throws InvalidDataTypeException
73
-     * @throws InvalidClassException
74
-     * @throws EE_Error
75
-     * @throws ServiceNotFoundException
76
-     * @throws ReflectionException
77
-     */
78
-    public function load($fqcn, $arguments = array(), $shared = true)
79
-    {
80
-        if($this->generator instanceof EE_Registry) {
81
-            return $this->generator->create($fqcn, $arguments, $shared);
82
-        }
83
-        return $this->generator->brew(
84
-            $fqcn,
85
-            $arguments,
86
-            $shared ? CoffeeMaker::BREW_SHARED : CoffeeMaker::BREW_NEW
87
-        );
88
-
89
-    }
90
-
91
-
92
-
93
-    /**
94
-     * calls reset() on generator if method exists
95
-     *
96
-     * @throws EE_Error
97
-     * @throws ReflectionException
98
-     */
99
-    public function reset()
100
-    {
101
-        if ($this->generator instanceof EE_Registry) {
102
-            EE_Registry::reset();
103
-        }
104
-    }
35
+	/**
36
+	 * @var EE_Registry|CoffeeShop $generator
37
+	 */
38
+	private $generator;
39
+
40
+
41
+
42
+	/**
43
+	 * CoreLoader constructor.
44
+	 *
45
+	 * @param EE_Registry|CoffeeShop $generator
46
+	 * @throws InvalidArgumentException
47
+	 */
48
+	public function __construct($generator)
49
+	{
50
+		if(!($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) {
51
+			throw new InvalidArgumentException(
52
+				esc_html__(
53
+					'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.',
54
+					'event_espresso'
55
+				)
56
+			);
57
+		}
58
+		$this->generator = $generator;
59
+	}
60
+
61
+
62
+
63
+	/**
64
+	 * @param string $fqcn
65
+	 * @param array  $arguments
66
+	 * @param bool   $shared
67
+	 * @return mixed
68
+	 * @throws OutOfBoundsException
69
+	 * @throws ServiceExistsException
70
+	 * @throws InstantiationException
71
+	 * @throws InvalidIdentifierException
72
+	 * @throws InvalidDataTypeException
73
+	 * @throws InvalidClassException
74
+	 * @throws EE_Error
75
+	 * @throws ServiceNotFoundException
76
+	 * @throws ReflectionException
77
+	 */
78
+	public function load($fqcn, $arguments = array(), $shared = true)
79
+	{
80
+		if($this->generator instanceof EE_Registry) {
81
+			return $this->generator->create($fqcn, $arguments, $shared);
82
+		}
83
+		return $this->generator->brew(
84
+			$fqcn,
85
+			$arguments,
86
+			$shared ? CoffeeMaker::BREW_SHARED : CoffeeMaker::BREW_NEW
87
+		);
88
+
89
+	}
90
+
91
+
92
+
93
+	/**
94
+	 * calls reset() on generator if method exists
95
+	 *
96
+	 * @throws EE_Error
97
+	 * @throws ReflectionException
98
+	 */
99
+	public function reset()
100
+	{
101
+		if ($this->generator instanceof EE_Registry) {
102
+			EE_Registry::reset();
103
+		}
104
+	}
105 105
 
106 106
 }
107 107
 // End of file CoreLoader.php
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -47,7 +47,7 @@  discard block
 block discarded – undo
47 47
      */
48 48
     public function __construct($generator)
49 49
     {
50
-        if(!($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) {
50
+        if ( ! ($generator instanceof EE_Registry || $generator instanceof CoffeeShop)) {
51 51
             throw new InvalidArgumentException(
52 52
                 esc_html__(
53 53
                     'The CoreLoader class must receive an instance of EE_Registry or the CoffeeShop DI container.',
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
      */
78 78
     public function load($fqcn, $arguments = array(), $shared = true)
79 79
     {
80
-        if($this->generator instanceof EE_Registry) {
80
+        if ($this->generator instanceof EE_Registry) {
81 81
             return $this->generator->create($fqcn, $arguments, $shared);
82 82
         }
83 83
         return $this->generator->brew(
Please login to merge, or discard this patch.
core/services/container/DependencyInjector.php 2 patches
Indentation   +218 added lines, -218 removed lines patch added patch discarded remove patch
@@ -8,7 +8,7 @@  discard block
 block discarded – undo
8 8
 use UnexpectedValueException;
9 9
 
10 10
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
11
-    exit('No direct script access allowed');
11
+	exit('No direct script access allowed');
12 12
 }
13 13
 
14 14
 
@@ -26,223 +26,223 @@  discard block
 block discarded – undo
26 26
 class DependencyInjector implements InjectorInterface
27 27
 {
28 28
 
29
-    /**
30
-     * @var CoffeePotInterface $coffee_pot
31
-     */
32
-    private $coffee_pot;
33
-
34
-    /**
35
-     * @var EEH_Array $array_helper
36
-     */
37
-    private $array_helper;
38
-
39
-    /**
40
-     * @var ReflectionClass[] $reflectors
41
-     */
42
-    private $reflectors;
43
-
44
-    /**
45
-     * @var ReflectionMethod[] $constructors
46
-     */
47
-    private $constructors;
48
-
49
-    /**
50
-     * @var ReflectionParameter[] $parameters
51
-     */
52
-    private $parameters;
53
-
54
-
55
-
56
-    /**
57
-     * DependencyInjector constructor
58
-     *
59
-     * @param CoffeePotInterface $coffee_pot
60
-     * @param EEH_Array         $array_helper
61
-     */
62
-    public function __construct(CoffeePotInterface $coffee_pot, EEH_Array $array_helper)
63
-    {
64
-        $this->coffee_pot = $coffee_pot;
65
-        $this->array_helper = $array_helper;
66
-    }
67
-
68
-
69
-
70
-    /**
71
-     * getReflectionClass
72
-     * checks if a ReflectionClass object has already been generated for a class
73
-     * and returns that instead of creating a new one
74
-     *
75
-     * @param string $class_name
76
-     * @return ReflectionClass
77
-     */
78
-    public function getReflectionClass($class_name)
79
-    {
80
-        if (
81
-            ! isset($this->reflectors[$class_name])
82
-            || ! $this->reflectors[$class_name] instanceof ReflectionClass
83
-        ) {
84
-            $this->reflectors[$class_name] = new ReflectionClass($class_name);
85
-        }
86
-        return $this->reflectors[$class_name];
87
-    }
88
-
89
-
90
-
91
-    /**
92
-     * getConstructor
93
-     * checks if a ReflectionMethod object has already been generated for the class constructor
94
-     * and returns that instead of creating a new one
95
-     *
96
-     * @param ReflectionClass $reflector
97
-     * @return ReflectionMethod
98
-     */
99
-    protected function getConstructor(ReflectionClass $reflector)
100
-    {
101
-        if (
102
-            ! isset($this->constructors[$reflector->getName()])
103
-            || ! $this->constructors[$reflector->getName()] instanceof ReflectionMethod
104
-        ) {
105
-            $this->constructors[$reflector->getName()] = $reflector->getConstructor();
106
-        }
107
-        return $this->constructors[$reflector->getName()];
108
-    }
109
-
110
-
111
-
112
-    /**
113
-     * getParameters
114
-     * checks if an array of ReflectionParameter objects has already been generated for the class constructor
115
-     * and returns that instead of creating a new one
116
-     *
117
-     * @param ReflectionMethod $constructor
118
-     * @return ReflectionParameter[]
119
-     */
120
-    protected function getParameters(ReflectionMethod $constructor)
121
-    {
122
-        if ( ! isset($this->parameters[$constructor->class])) {
123
-            $this->parameters[$constructor->class] = $constructor->getParameters();
124
-        }
125
-        return $this->parameters[$constructor->class];
126
-    }
127
-
128
-
129
-
130
-    /**
131
-     * resolveDependencies
132
-     * examines the constructor for the requested class to determine
133
-     * if any dependencies exist, and if they can be injected.
134
-     * If so, then those classes will be added to the array of arguments passed to the constructor
135
-     * PLZ NOTE: this is achieved by type hinting the constructor params
136
-     * For example:
137
-     *        if attempting to load a class "Foo" with the following constructor:
138
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
139
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
140
-     *        but only IF they are NOT already present in the incoming arguments array,
141
-     *        and the correct classes can be loaded
142
-     *
143
-     * @param RecipeInterface  $recipe
144
-     * @param ReflectionClass $reflector
145
-     * @param array            $arguments
146
-     * @return array
147
-     * @throws UnexpectedValueException
148
-     */
149
-    public function resolveDependencies(RecipeInterface $recipe, ReflectionClass $reflector, $arguments = array())
150
-    {
151
-        // if arguments array is numerically and sequentially indexed, then we want it to remain as is,
152
-        // else wrap it in an additional array so that it doesn't get split into multiple parameters
153
-        $arguments = $this->array_helper->is_array_numerically_and_sequentially_indexed($arguments)
154
-            ? $arguments
155
-            : array($arguments);
156
-        $resolved_parameters = array();
157
-        // let's examine the constructor
158
-        // let's examine the constructor
159
-        $constructor = $this->getConstructor($reflector);
160
-        // whu? huh? nothing?
161
-        if ( ! $constructor) {
162
-            return $arguments;
163
-        }
164
-        // get constructor parameters
165
-        $params = $this->getParameters($constructor);
166
-        if (empty($params)) {
167
-            return $resolved_parameters;
168
-        }
169
-        $ingredients = $recipe->ingredients();
170
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
171
-        $argument_keys = array_keys($arguments);
172
-        // now loop thru all of the constructors expected parameters
173
-        foreach ($params as $index => $param) {
174
-            if ( ! $param instanceof ReflectionParameter) {
175
-                continue;
176
-            }
177
-            // is this a dependency for a specific class ?
178
-            $param_class = $param->getClass() ? $param->getClass()->name : '';
179
-            $param_name = $param->getName() ? $param->getName() : '';
180
-            if (
181
-                // param is not a class but is specified in the list of ingredients for this Recipe
182
-                is_string($param_name) && isset($ingredients[$param_name])
183
-            ) {
184
-                // attempt to inject the dependency
185
-                $resolved_parameters[$index] = $ingredients[ $param_name ];
186
-            } else if (
187
-                // param is specified in the list of ingredients for this Recipe
188
-                isset($ingredients[$param_class])
189
-            ) {
190
-                // attempt to inject the dependency
191
-                $resolved_parameters[$index] = $this->injectDependency($ingredients[$param_class]);
192
-            } else if (
193
-                // param is not even a class
194
-                empty($param_class)
195
-                // and something already exists in the incoming arguments for this param
196
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
197
-            ) {
198
-                // add parameter from incoming arguments
199
-                $resolved_parameters[$index] = $arguments[$argument_keys[$index]];
200
-            } else if (
201
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
202
-                ! empty($param_class)
203
-                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
204
-                && $arguments[$argument_keys[$index]] instanceof $param_class
205
-            ) {
206
-                // add parameter from incoming arguments
207
-                $resolved_parameters[$index] = $arguments[$argument_keys[$index]];
208
-            } else if (
209
-                // parameter is type hinted as a class, and should be injected
210
-                ! empty($param_class)
211
-            ) {
212
-                // attempt to inject the dependency
213
-                $resolved_parameters[$index] = $this->injectDependency($param_class);
214
-            } else if ($param->isOptional()) {
215
-                $resolved_parameters[$index] = $param->getDefaultValue();
216
-            } else {
217
-                $resolved_parameters[$index] = null;
218
-            }
219
-        }
220
-        return $resolved_parameters;
221
-    }
222
-
223
-
224
-
225
-    /**
226
-     * @param string $param_class
227
-     * @return mixed
228
-     * @throws UnexpectedValueException
229
-     */
230
-    private function injectDependency($param_class)
231
-    {
232
-        $dependency = $this->coffee_pot->brew($param_class);
233
-        if ( ! $dependency instanceof $param_class) {
234
-            throw new UnexpectedValueException(
235
-                sprintf(
236
-                    __(
237
-                        'Could not resolve dependency for "%1$s" for the "%2$s" class constructor.',
238
-                        'event_espresso'
239
-                    ),
240
-                    $param_class
241
-                )
242
-            );
243
-        }
244
-        return $dependency;
245
-    }
29
+	/**
30
+	 * @var CoffeePotInterface $coffee_pot
31
+	 */
32
+	private $coffee_pot;
33
+
34
+	/**
35
+	 * @var EEH_Array $array_helper
36
+	 */
37
+	private $array_helper;
38
+
39
+	/**
40
+	 * @var ReflectionClass[] $reflectors
41
+	 */
42
+	private $reflectors;
43
+
44
+	/**
45
+	 * @var ReflectionMethod[] $constructors
46
+	 */
47
+	private $constructors;
48
+
49
+	/**
50
+	 * @var ReflectionParameter[] $parameters
51
+	 */
52
+	private $parameters;
53
+
54
+
55
+
56
+	/**
57
+	 * DependencyInjector constructor
58
+	 *
59
+	 * @param CoffeePotInterface $coffee_pot
60
+	 * @param EEH_Array         $array_helper
61
+	 */
62
+	public function __construct(CoffeePotInterface $coffee_pot, EEH_Array $array_helper)
63
+	{
64
+		$this->coffee_pot = $coffee_pot;
65
+		$this->array_helper = $array_helper;
66
+	}
67
+
68
+
69
+
70
+	/**
71
+	 * getReflectionClass
72
+	 * checks if a ReflectionClass object has already been generated for a class
73
+	 * and returns that instead of creating a new one
74
+	 *
75
+	 * @param string $class_name
76
+	 * @return ReflectionClass
77
+	 */
78
+	public function getReflectionClass($class_name)
79
+	{
80
+		if (
81
+			! isset($this->reflectors[$class_name])
82
+			|| ! $this->reflectors[$class_name] instanceof ReflectionClass
83
+		) {
84
+			$this->reflectors[$class_name] = new ReflectionClass($class_name);
85
+		}
86
+		return $this->reflectors[$class_name];
87
+	}
88
+
89
+
90
+
91
+	/**
92
+	 * getConstructor
93
+	 * checks if a ReflectionMethod object has already been generated for the class constructor
94
+	 * and returns that instead of creating a new one
95
+	 *
96
+	 * @param ReflectionClass $reflector
97
+	 * @return ReflectionMethod
98
+	 */
99
+	protected function getConstructor(ReflectionClass $reflector)
100
+	{
101
+		if (
102
+			! isset($this->constructors[$reflector->getName()])
103
+			|| ! $this->constructors[$reflector->getName()] instanceof ReflectionMethod
104
+		) {
105
+			$this->constructors[$reflector->getName()] = $reflector->getConstructor();
106
+		}
107
+		return $this->constructors[$reflector->getName()];
108
+	}
109
+
110
+
111
+
112
+	/**
113
+	 * getParameters
114
+	 * checks if an array of ReflectionParameter objects has already been generated for the class constructor
115
+	 * and returns that instead of creating a new one
116
+	 *
117
+	 * @param ReflectionMethod $constructor
118
+	 * @return ReflectionParameter[]
119
+	 */
120
+	protected function getParameters(ReflectionMethod $constructor)
121
+	{
122
+		if ( ! isset($this->parameters[$constructor->class])) {
123
+			$this->parameters[$constructor->class] = $constructor->getParameters();
124
+		}
125
+		return $this->parameters[$constructor->class];
126
+	}
127
+
128
+
129
+
130
+	/**
131
+	 * resolveDependencies
132
+	 * examines the constructor for the requested class to determine
133
+	 * if any dependencies exist, and if they can be injected.
134
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
135
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
136
+	 * For example:
137
+	 *        if attempting to load a class "Foo" with the following constructor:
138
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
139
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
140
+	 *        but only IF they are NOT already present in the incoming arguments array,
141
+	 *        and the correct classes can be loaded
142
+	 *
143
+	 * @param RecipeInterface  $recipe
144
+	 * @param ReflectionClass $reflector
145
+	 * @param array            $arguments
146
+	 * @return array
147
+	 * @throws UnexpectedValueException
148
+	 */
149
+	public function resolveDependencies(RecipeInterface $recipe, ReflectionClass $reflector, $arguments = array())
150
+	{
151
+		// if arguments array is numerically and sequentially indexed, then we want it to remain as is,
152
+		// else wrap it in an additional array so that it doesn't get split into multiple parameters
153
+		$arguments = $this->array_helper->is_array_numerically_and_sequentially_indexed($arguments)
154
+			? $arguments
155
+			: array($arguments);
156
+		$resolved_parameters = array();
157
+		// let's examine the constructor
158
+		// let's examine the constructor
159
+		$constructor = $this->getConstructor($reflector);
160
+		// whu? huh? nothing?
161
+		if ( ! $constructor) {
162
+			return $arguments;
163
+		}
164
+		// get constructor parameters
165
+		$params = $this->getParameters($constructor);
166
+		if (empty($params)) {
167
+			return $resolved_parameters;
168
+		}
169
+		$ingredients = $recipe->ingredients();
170
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
171
+		$argument_keys = array_keys($arguments);
172
+		// now loop thru all of the constructors expected parameters
173
+		foreach ($params as $index => $param) {
174
+			if ( ! $param instanceof ReflectionParameter) {
175
+				continue;
176
+			}
177
+			// is this a dependency for a specific class ?
178
+			$param_class = $param->getClass() ? $param->getClass()->name : '';
179
+			$param_name = $param->getName() ? $param->getName() : '';
180
+			if (
181
+				// param is not a class but is specified in the list of ingredients for this Recipe
182
+				is_string($param_name) && isset($ingredients[$param_name])
183
+			) {
184
+				// attempt to inject the dependency
185
+				$resolved_parameters[$index] = $ingredients[ $param_name ];
186
+			} else if (
187
+				// param is specified in the list of ingredients for this Recipe
188
+				isset($ingredients[$param_class])
189
+			) {
190
+				// attempt to inject the dependency
191
+				$resolved_parameters[$index] = $this->injectDependency($ingredients[$param_class]);
192
+			} else if (
193
+				// param is not even a class
194
+				empty($param_class)
195
+				// and something already exists in the incoming arguments for this param
196
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
197
+			) {
198
+				// add parameter from incoming arguments
199
+				$resolved_parameters[$index] = $arguments[$argument_keys[$index]];
200
+			} else if (
201
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
202
+				! empty($param_class)
203
+				&& isset($argument_keys[$index], $arguments[$argument_keys[$index]])
204
+				&& $arguments[$argument_keys[$index]] instanceof $param_class
205
+			) {
206
+				// add parameter from incoming arguments
207
+				$resolved_parameters[$index] = $arguments[$argument_keys[$index]];
208
+			} else if (
209
+				// parameter is type hinted as a class, and should be injected
210
+				! empty($param_class)
211
+			) {
212
+				// attempt to inject the dependency
213
+				$resolved_parameters[$index] = $this->injectDependency($param_class);
214
+			} else if ($param->isOptional()) {
215
+				$resolved_parameters[$index] = $param->getDefaultValue();
216
+			} else {
217
+				$resolved_parameters[$index] = null;
218
+			}
219
+		}
220
+		return $resolved_parameters;
221
+	}
222
+
223
+
224
+
225
+	/**
226
+	 * @param string $param_class
227
+	 * @return mixed
228
+	 * @throws UnexpectedValueException
229
+	 */
230
+	private function injectDependency($param_class)
231
+	{
232
+		$dependency = $this->coffee_pot->brew($param_class);
233
+		if ( ! $dependency instanceof $param_class) {
234
+			throw new UnexpectedValueException(
235
+				sprintf(
236
+					__(
237
+						'Could not resolve dependency for "%1$s" for the "%2$s" class constructor.',
238
+						'event_espresso'
239
+					),
240
+					$param_class
241
+				)
242
+			);
243
+		}
244
+		return $dependency;
245
+	}
246 246
 
247 247
 }
248 248
 // End of file DependencyInjector.php
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -182,7 +182,7 @@
 block discarded – undo
182 182
                 is_string($param_name) && isset($ingredients[$param_name])
183 183
             ) {
184 184
                 // attempt to inject the dependency
185
-                $resolved_parameters[$index] = $ingredients[ $param_name ];
185
+                $resolved_parameters[$index] = $ingredients[$param_name];
186 186
             } else if (
187 187
                 // param is specified in the list of ingredients for this Recipe
188 188
                 isset($ingredients[$param_class])
Please login to merge, or discard this patch.
core/services/container/Recipe.php 2 patches
Indentation   +321 added lines, -321 removed lines patch added patch discarded remove patch
@@ -8,7 +8,7 @@  discard block
 block discarded – undo
8 8
 use RuntimeException;
9 9
 
10 10
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
11
-    exit('No direct script access allowed');
11
+	exit('No direct script access allowed');
12 12
 }
13 13
 
14 14
 
@@ -24,326 +24,326 @@  discard block
 block discarded – undo
24 24
 class Recipe implements RecipeInterface
25 25
 {
26 26
 
27
-    /**
28
-     * A default Recipe to use if none is specified for a class
29
-     */
30
-    const DEFAULT_ID = '*';
31
-
32
-    /**
33
-     * Identifier for the entity class to be constructed.
34
-     * Typically a Fully Qualified Class Name
35
-     *
36
-     * @var string $identifier
37
-     */
38
-    private $identifier;
39
-
40
-    /**
41
-     * Fully Qualified Class Name
42
-     *
43
-     * @var string $fqcn
44
-     */
45
-    private $fqcn;
46
-
47
-    /**
48
-     * a dependency class map array
49
-     * If a Recipe is for a single class (or group of classes that shares the EXACT SAME constructor arguments),
50
-     * and that class type hints for an interface, then this property allows you to configure what dependencies
51
-     * get used when instantiating the class.
52
-     * For example:
53
-     *  There's a class called Coffee, and one of its constructor arguments is BeanInterface
54
-     *  There are two implementations of BeanInterface: HonduranBean, and KenyanBean
55
-     *  We want one Coffee object to use HonduranBean for its BeanInterface,
56
-     *  and the 2nd Coffee object to use KenyanBean for its BeanInterface.
57
-     *  To do this, we need to create two Recipes:
58
-     *      one with an identifier of 'HonduranCoffee' using the following ingredients :
59
-     *          array('BeanInterface' => 'HonduranBean')
60
-     *      and the other with an identifier of 'KenyanCoffee' using the following ingredients :
61
-     *          array('BeanInterface' => 'KenyanBean')
62
-     *  Then, whenever the CoffeeShop brews an instance of HonduranCoffee,
63
-     *  an instance of HonduranBean will get injected for the BeanInterface dependency,
64
-     *  and whenever the CoffeeShop brews an instance of KenyanCoffee,
65
-     *  an instance of KenyanBean will get injected for the BeanInterface dependency
66
-     *
67
-     * @var array $ingredients
68
-     */
69
-    private $ingredients = array();
70
-
71
-    /**
72
-     * one of the class constants from CoffeeShop:
73
-     *  CoffeeMaker::BREW_NEW - creates a new instance
74
-     *  CoffeeMaker::BREW_SHARED - creates a shared instance
75
-     *  CoffeeMaker::BREW_LOAD_ONLY - loads but does not instantiate
76
-     *
77
-     * @var string $type
78
-     */
79
-    private $type;
80
-
81
-    /**
82
-     * class name aliases - typically a Fully Qualified Interface that the class implements
83
-     * identifiers passed to the CoffeeShop will be run through the filters to find the correct class name
84
-     *
85
-     * @var array $filters
86
-     */
87
-    private $filters = array();
88
-
89
-    /**
90
-     * array of full server filepaths to files that may contain the class
91
-     *
92
-     * @var array $paths
93
-     */
94
-    private $paths = array();
95
-
96
-
97
-
98
-    /**
99
-     * Recipe constructor.
100
-     *
101
-     * @param string $identifier    class identifier, can be an alias, or FQCN, or whatever
102
-     * @param string $fqcn          \Fully\Qualified\ClassName, optional if $identifier is FQCN
103
-     * @param array  $ingredients   array of dependencies that can not be resolved automatically,
104
-     *                              used for resolving concrete classes for type hinted interfaces
105
-     *                              for the dependencies of THIS class
106
-     * @param string $type          recipe type: one of the class constants on
107
-     *                              \EventEspresso\core\services\container\CoffeeMaker
108
-     * @param array  $filters       array of class aliases, or class interfaces
109
-     *                              this works somewhat opposite to the $ingredients array above,
110
-     *                              in that this array specifies interfaces or aliases
111
-     *                              that this Recipe can be used for when resolving OTHER class's dependencies
112
-     * @param array  $paths         if class can not be loaded via PSR-4 autoloading,
113
-     *                              then supply a filepath, or array of filepaths, so that it can be included
114
-     * @throws InvalidIdentifierException
115
-     * @throws RuntimeException
116
-     * @throws InvalidInterfaceException
117
-     * @throws InvalidClassException
118
-     * @throws InvalidDataTypeException
119
-     */
120
-    public function __construct(
121
-	    $identifier,
122
-        $fqcn = '',
123
-        array $filters = array(),
124
-        array $ingredients = array(),
125
-	    $type = CoffeeMaker::BREW_NEW,
126
-        array $paths = array()
127
-    )
128
-    {
129
-        $this->setIdentifier($identifier);
130
-        $this->setFilters($filters);
131
-        $this->setIngredients($ingredients);
132
-        $this->setType($type);
133
-        $this->setPaths($paths);
134
-        $this->setFqcn($fqcn);
135
-    }
136
-
137
-
138
-
139
-    /**
140
-     * @return string
141
-     */
142
-    public function identifier()
143
-    {
144
-        return $this->identifier;
145
-    }
146
-
147
-
148
-
149
-    /**
150
-     * @return string
151
-     */
152
-    public function fqcn()
153
-    {
154
-        return $this->fqcn;
155
-    }
156
-
157
-
158
-
159
-    /**
160
-     * @return array
161
-     */
162
-    public function filters()
163
-    {
164
-        return $this->filters;
165
-    }
166
-
167
-
168
-
169
-    /**
170
-     * @return array
171
-     */
172
-    public function ingredients()
173
-    {
174
-        return $this->ingredients;
175
-    }
176
-
177
-
178
-
179
-    /**
180
-     * @return string
181
-     */
182
-    public function type()
183
-    {
184
-        return $this->type;
185
-    }
186
-
187
-
188
-
189
-    /**
190
-     * @return array
191
-     */
192
-    public function paths()
193
-    {
194
-        return $this->paths;
195
-    }
196
-
197
-
198
-
199
-    /**
200
-     * @param  string $identifier Identifier for the entity class that the Recipe applies to
201
-     *                            Typically a Fully Qualified Class Name
202
-     * @throws InvalidIdentifierException
203
-     */
204
-    public function setIdentifier($identifier)
205
-    {
206
-        if ( ! is_string($identifier) || empty($identifier)) {
207
-            throw new InvalidIdentifierException(
208
-                is_object($identifier) ? get_class($identifier) : gettype($identifier),
209
-                __('class identifier (typically a \Fully\Qualified\ClassName)', 'event_espresso')
210
-            );
211
-        }
212
-        $this->identifier = $identifier;
213
-    }
214
-
215
-
216
-
217
-    /**
218
-     * Ensures incoming string is a valid Fully Qualified Class Name,
219
-     * except if this is the default wildcard Recipe ( * ),
220
-     * or it's NOT an actual FQCN because the Recipe is using filepaths
221
-     * for classes that are not PSR-4 compatible
222
-     * PLZ NOTE:
223
-     *  Recipe::setFqcn() has a check to see if Recipe::$paths is empty or not,
224
-     *  therefore you should always call Recipe::setPaths() before Recipe::setFqcn()
225
-     *
226
-     * @param string $fqcn
227
-     * @throws InvalidDataTypeException
228
-     * @throws InvalidClassException
229
-     * @throws InvalidInterfaceException
230
-     */
231
-    public function setFqcn($fqcn)
232
-    {
233
-	    $fqcn = ! empty($fqcn) ? $fqcn : $this->identifier;
234
-        if ( ! is_string($fqcn)) {
235
-            throw new InvalidDataTypeException(
236
-                '$fqcn',
237
-                is_object($fqcn) ? get_class($fqcn) : gettype($fqcn),
238
-                __('string (Fully\Qualified\ClassName)', 'event_espresso')
239
-            );
240
-        }
241
-        $fqcn = ltrim($fqcn, '\\');
242
-        if (
243
-            $fqcn !== Recipe::DEFAULT_ID
244
-            && ! empty($fqcn)
245
-            && empty($this->paths)
246
-            && ! (class_exists($fqcn) || interface_exists($fqcn))
247
-        ) {
248
-            throw new InvalidClassException($fqcn);
249
-        }
250
-        $this->fqcn = $fqcn;
251
-    }
252
-
253
-
254
-
255
-    /**
256
-     * @param array $ingredients    an array of dependencies where keys are the aliases and values are the FQCNs
257
-     *                              example:
258
-     *                              array( 'ClassInterface' => 'Fully\Qualified\ClassName' )
259
-     * @throws InvalidDataTypeException
260
-     */
261
-    public function setIngredients(array $ingredients)
262
-    {
263
-        if (empty($ingredients)) {
264
-            return;
265
-        }
266
-        if ( ! is_array($ingredients)) {
267
-            throw new InvalidDataTypeException(
268
-                '$ingredients',
269
-                is_object($ingredients) ? get_class($ingredients) : gettype($ingredients),
270
-                __('array of class dependencies', 'event_espresso')
271
-            );
272
-        }
273
-        $this->ingredients = array_merge($this->ingredients, $ingredients);
274
-    }
275
-
276
-
277
-    /**
278
-     * @param string $type one of the class constants returned from CoffeeMaker::getTypes()
279
-     * @throws InvalidIdentifierException
280
-     */
281
-    public function setType($type = CoffeeMaker::BREW_NEW)
282
-    {
283
-        $this->type = CoffeeMaker::validateType($type);
284
-    }
285
-
286
-
287
-
288
-    /**
289
-     * @param array $filters    an array of filters where keys are the aliases and values are the FQCNs
290
-     *                          example:
291
-     *                          array( 'ClassInterface' => 'Fully\Qualified\ClassName' )
292
-     * @throws InvalidDataTypeException
293
-     */
294
-    public function setFilters(array $filters)
295
-    {
296
-        if (empty($filters)) {
297
-            return;
298
-        }
299
-        if ( ! is_array($filters)) {
300
-            throw new InvalidDataTypeException(
301
-                '$filters',
302
-                is_object($filters) ? get_class($filters) : gettype($filters),
303
-                __('array of class aliases', 'event_espresso')
304
-            );
305
-        }
306
-        $this->filters = array_merge($this->filters, $filters);
307
-    }
308
-
309
-
310
-
311
-    /**
312
-     * Ensures incoming paths is a valid filepath, or array of valid filepaths,
313
-     * and merges them in with any existing filepaths
314
-     * PLZ NOTE:
315
-     *  Recipe::setFqcn() has a check to see if Recipe::$paths is empty or not,
316
-     *  therefore you should always call Recipe::setPaths() before Recipe::setFqcn()
317
-     *
318
-     * @param string|array $paths
319
-     * @throws RuntimeException
320
-     * @throws InvalidDataTypeException
321
-     */
322
-    public function setPaths($paths = array())
323
-    {
324
-        if (empty($paths)) {
325
-            return;
326
-        }
327
-        if ( ! (is_string($paths) || is_array($paths))) {
328
-            throw new InvalidDataTypeException(
329
-                '$path',
330
-                is_object($paths) ? get_class($paths) : gettype($paths),
331
-                __('string or array of strings (full server filepath(s))', 'event_espresso')
332
-            );
333
-        }
334
-        $paths = (array)$paths;
335
-        foreach ($paths as $path) {
336
-            if (strpos($path, '*') === false && ! is_readable($path)) {
337
-                throw new RuntimeException(
338
-                    sprintf(
339
-                        __('The following filepath is not readable: "%1$s"', 'event_espresso'),
340
-                        $path
341
-                    )
342
-                );
343
-            }
344
-        }
345
-        $this->paths = array_merge($this->paths, $paths);
346
-    }
27
+	/**
28
+	 * A default Recipe to use if none is specified for a class
29
+	 */
30
+	const DEFAULT_ID = '*';
31
+
32
+	/**
33
+	 * Identifier for the entity class to be constructed.
34
+	 * Typically a Fully Qualified Class Name
35
+	 *
36
+	 * @var string $identifier
37
+	 */
38
+	private $identifier;
39
+
40
+	/**
41
+	 * Fully Qualified Class Name
42
+	 *
43
+	 * @var string $fqcn
44
+	 */
45
+	private $fqcn;
46
+
47
+	/**
48
+	 * a dependency class map array
49
+	 * If a Recipe is for a single class (or group of classes that shares the EXACT SAME constructor arguments),
50
+	 * and that class type hints for an interface, then this property allows you to configure what dependencies
51
+	 * get used when instantiating the class.
52
+	 * For example:
53
+	 *  There's a class called Coffee, and one of its constructor arguments is BeanInterface
54
+	 *  There are two implementations of BeanInterface: HonduranBean, and KenyanBean
55
+	 *  We want one Coffee object to use HonduranBean for its BeanInterface,
56
+	 *  and the 2nd Coffee object to use KenyanBean for its BeanInterface.
57
+	 *  To do this, we need to create two Recipes:
58
+	 *      one with an identifier of 'HonduranCoffee' using the following ingredients :
59
+	 *          array('BeanInterface' => 'HonduranBean')
60
+	 *      and the other with an identifier of 'KenyanCoffee' using the following ingredients :
61
+	 *          array('BeanInterface' => 'KenyanBean')
62
+	 *  Then, whenever the CoffeeShop brews an instance of HonduranCoffee,
63
+	 *  an instance of HonduranBean will get injected for the BeanInterface dependency,
64
+	 *  and whenever the CoffeeShop brews an instance of KenyanCoffee,
65
+	 *  an instance of KenyanBean will get injected for the BeanInterface dependency
66
+	 *
67
+	 * @var array $ingredients
68
+	 */
69
+	private $ingredients = array();
70
+
71
+	/**
72
+	 * one of the class constants from CoffeeShop:
73
+	 *  CoffeeMaker::BREW_NEW - creates a new instance
74
+	 *  CoffeeMaker::BREW_SHARED - creates a shared instance
75
+	 *  CoffeeMaker::BREW_LOAD_ONLY - loads but does not instantiate
76
+	 *
77
+	 * @var string $type
78
+	 */
79
+	private $type;
80
+
81
+	/**
82
+	 * class name aliases - typically a Fully Qualified Interface that the class implements
83
+	 * identifiers passed to the CoffeeShop will be run through the filters to find the correct class name
84
+	 *
85
+	 * @var array $filters
86
+	 */
87
+	private $filters = array();
88
+
89
+	/**
90
+	 * array of full server filepaths to files that may contain the class
91
+	 *
92
+	 * @var array $paths
93
+	 */
94
+	private $paths = array();
95
+
96
+
97
+
98
+	/**
99
+	 * Recipe constructor.
100
+	 *
101
+	 * @param string $identifier    class identifier, can be an alias, or FQCN, or whatever
102
+	 * @param string $fqcn          \Fully\Qualified\ClassName, optional if $identifier is FQCN
103
+	 * @param array  $ingredients   array of dependencies that can not be resolved automatically,
104
+	 *                              used for resolving concrete classes for type hinted interfaces
105
+	 *                              for the dependencies of THIS class
106
+	 * @param string $type          recipe type: one of the class constants on
107
+	 *                              \EventEspresso\core\services\container\CoffeeMaker
108
+	 * @param array  $filters       array of class aliases, or class interfaces
109
+	 *                              this works somewhat opposite to the $ingredients array above,
110
+	 *                              in that this array specifies interfaces or aliases
111
+	 *                              that this Recipe can be used for when resolving OTHER class's dependencies
112
+	 * @param array  $paths         if class can not be loaded via PSR-4 autoloading,
113
+	 *                              then supply a filepath, or array of filepaths, so that it can be included
114
+	 * @throws InvalidIdentifierException
115
+	 * @throws RuntimeException
116
+	 * @throws InvalidInterfaceException
117
+	 * @throws InvalidClassException
118
+	 * @throws InvalidDataTypeException
119
+	 */
120
+	public function __construct(
121
+		$identifier,
122
+		$fqcn = '',
123
+		array $filters = array(),
124
+		array $ingredients = array(),
125
+		$type = CoffeeMaker::BREW_NEW,
126
+		array $paths = array()
127
+	)
128
+	{
129
+		$this->setIdentifier($identifier);
130
+		$this->setFilters($filters);
131
+		$this->setIngredients($ingredients);
132
+		$this->setType($type);
133
+		$this->setPaths($paths);
134
+		$this->setFqcn($fqcn);
135
+	}
136
+
137
+
138
+
139
+	/**
140
+	 * @return string
141
+	 */
142
+	public function identifier()
143
+	{
144
+		return $this->identifier;
145
+	}
146
+
147
+
148
+
149
+	/**
150
+	 * @return string
151
+	 */
152
+	public function fqcn()
153
+	{
154
+		return $this->fqcn;
155
+	}
156
+
157
+
158
+
159
+	/**
160
+	 * @return array
161
+	 */
162
+	public function filters()
163
+	{
164
+		return $this->filters;
165
+	}
166
+
167
+
168
+
169
+	/**
170
+	 * @return array
171
+	 */
172
+	public function ingredients()
173
+	{
174
+		return $this->ingredients;
175
+	}
176
+
177
+
178
+
179
+	/**
180
+	 * @return string
181
+	 */
182
+	public function type()
183
+	{
184
+		return $this->type;
185
+	}
186
+
187
+
188
+
189
+	/**
190
+	 * @return array
191
+	 */
192
+	public function paths()
193
+	{
194
+		return $this->paths;
195
+	}
196
+
197
+
198
+
199
+	/**
200
+	 * @param  string $identifier Identifier for the entity class that the Recipe applies to
201
+	 *                            Typically a Fully Qualified Class Name
202
+	 * @throws InvalidIdentifierException
203
+	 */
204
+	public function setIdentifier($identifier)
205
+	{
206
+		if ( ! is_string($identifier) || empty($identifier)) {
207
+			throw new InvalidIdentifierException(
208
+				is_object($identifier) ? get_class($identifier) : gettype($identifier),
209
+				__('class identifier (typically a \Fully\Qualified\ClassName)', 'event_espresso')
210
+			);
211
+		}
212
+		$this->identifier = $identifier;
213
+	}
214
+
215
+
216
+
217
+	/**
218
+	 * Ensures incoming string is a valid Fully Qualified Class Name,
219
+	 * except if this is the default wildcard Recipe ( * ),
220
+	 * or it's NOT an actual FQCN because the Recipe is using filepaths
221
+	 * for classes that are not PSR-4 compatible
222
+	 * PLZ NOTE:
223
+	 *  Recipe::setFqcn() has a check to see if Recipe::$paths is empty or not,
224
+	 *  therefore you should always call Recipe::setPaths() before Recipe::setFqcn()
225
+	 *
226
+	 * @param string $fqcn
227
+	 * @throws InvalidDataTypeException
228
+	 * @throws InvalidClassException
229
+	 * @throws InvalidInterfaceException
230
+	 */
231
+	public function setFqcn($fqcn)
232
+	{
233
+		$fqcn = ! empty($fqcn) ? $fqcn : $this->identifier;
234
+		if ( ! is_string($fqcn)) {
235
+			throw new InvalidDataTypeException(
236
+				'$fqcn',
237
+				is_object($fqcn) ? get_class($fqcn) : gettype($fqcn),
238
+				__('string (Fully\Qualified\ClassName)', 'event_espresso')
239
+			);
240
+		}
241
+		$fqcn = ltrim($fqcn, '\\');
242
+		if (
243
+			$fqcn !== Recipe::DEFAULT_ID
244
+			&& ! empty($fqcn)
245
+			&& empty($this->paths)
246
+			&& ! (class_exists($fqcn) || interface_exists($fqcn))
247
+		) {
248
+			throw new InvalidClassException($fqcn);
249
+		}
250
+		$this->fqcn = $fqcn;
251
+	}
252
+
253
+
254
+
255
+	/**
256
+	 * @param array $ingredients    an array of dependencies where keys are the aliases and values are the FQCNs
257
+	 *                              example:
258
+	 *                              array( 'ClassInterface' => 'Fully\Qualified\ClassName' )
259
+	 * @throws InvalidDataTypeException
260
+	 */
261
+	public function setIngredients(array $ingredients)
262
+	{
263
+		if (empty($ingredients)) {
264
+			return;
265
+		}
266
+		if ( ! is_array($ingredients)) {
267
+			throw new InvalidDataTypeException(
268
+				'$ingredients',
269
+				is_object($ingredients) ? get_class($ingredients) : gettype($ingredients),
270
+				__('array of class dependencies', 'event_espresso')
271
+			);
272
+		}
273
+		$this->ingredients = array_merge($this->ingredients, $ingredients);
274
+	}
275
+
276
+
277
+	/**
278
+	 * @param string $type one of the class constants returned from CoffeeMaker::getTypes()
279
+	 * @throws InvalidIdentifierException
280
+	 */
281
+	public function setType($type = CoffeeMaker::BREW_NEW)
282
+	{
283
+		$this->type = CoffeeMaker::validateType($type);
284
+	}
285
+
286
+
287
+
288
+	/**
289
+	 * @param array $filters    an array of filters where keys are the aliases and values are the FQCNs
290
+	 *                          example:
291
+	 *                          array( 'ClassInterface' => 'Fully\Qualified\ClassName' )
292
+	 * @throws InvalidDataTypeException
293
+	 */
294
+	public function setFilters(array $filters)
295
+	{
296
+		if (empty($filters)) {
297
+			return;
298
+		}
299
+		if ( ! is_array($filters)) {
300
+			throw new InvalidDataTypeException(
301
+				'$filters',
302
+				is_object($filters) ? get_class($filters) : gettype($filters),
303
+				__('array of class aliases', 'event_espresso')
304
+			);
305
+		}
306
+		$this->filters = array_merge($this->filters, $filters);
307
+	}
308
+
309
+
310
+
311
+	/**
312
+	 * Ensures incoming paths is a valid filepath, or array of valid filepaths,
313
+	 * and merges them in with any existing filepaths
314
+	 * PLZ NOTE:
315
+	 *  Recipe::setFqcn() has a check to see if Recipe::$paths is empty or not,
316
+	 *  therefore you should always call Recipe::setPaths() before Recipe::setFqcn()
317
+	 *
318
+	 * @param string|array $paths
319
+	 * @throws RuntimeException
320
+	 * @throws InvalidDataTypeException
321
+	 */
322
+	public function setPaths($paths = array())
323
+	{
324
+		if (empty($paths)) {
325
+			return;
326
+		}
327
+		if ( ! (is_string($paths) || is_array($paths))) {
328
+			throw new InvalidDataTypeException(
329
+				'$path',
330
+				is_object($paths) ? get_class($paths) : gettype($paths),
331
+				__('string or array of strings (full server filepath(s))', 'event_espresso')
332
+			);
333
+		}
334
+		$paths = (array)$paths;
335
+		foreach ($paths as $path) {
336
+			if (strpos($path, '*') === false && ! is_readable($path)) {
337
+				throw new RuntimeException(
338
+					sprintf(
339
+						__('The following filepath is not readable: "%1$s"', 'event_espresso'),
340
+						$path
341
+					)
342
+				);
343
+			}
344
+		}
345
+		$this->paths = array_merge($this->paths, $paths);
346
+	}
347 347
 
348 348
 
349 349
 
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -331,7 +331,7 @@
 block discarded – undo
331 331
                 __('string or array of strings (full server filepath(s))', 'event_espresso')
332 332
             );
333 333
         }
334
-        $paths = (array)$paths;
334
+        $paths = (array) $paths;
335 335
         foreach ($paths as $path) {
336 336
             if (strpos($path, '*') === false && ! is_readable($path)) {
337 337
                 throw new RuntimeException(
Please login to merge, or discard this patch.