Completed
Branch BUG-11108-ticket-reserved-coun... (144d27)
by
unknown
14:21 queued 17s
created

EE_Admin::instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
4
use EventEspresso\core\exceptions\InvalidDataTypeException;
5
use EventEspresso\core\exceptions\InvalidInterfaceException;
6
use EventEspresso\core\interfaces\InterminableInterface;
7
use EventEspresso\core\services\container\exceptions\ServiceNotFoundException;
8
use EventEspresso\core\services\loaders\LoaderFactory;
9
use EventEspresso\core\services\notifications\PersistentAdminNoticeManager;
10
11
defined('EVENT_ESPRESSO_VERSION') || exit('No direct script access allowed');
12
13
14
15
/**
16
 * EE_Admin
17
 *
18
 * @package               Event Espresso
19
 * @subpackage            /core/admin/
20
 * @author                Brent Christensen
21
 */
22
final class EE_Admin implements InterminableInterface
23
{
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 View Code Duplication
    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
            );
206
            $this->persistent_admin_notice_manager->setReturnUrl(
207
                EE_Admin_Page::add_query_args_and_nonce(
208
                    array(
209
                        'page'   => EE_Registry::instance()->REQ->get('page', ''),
210
                        'action' => EE_Registry::instance()->REQ->get('action', ''),
211
                    ),
212
                    EE_ADMIN_URL
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 (apply_filters('FHEE__EE_Admin__maybeSetDatetimeWarningNotice', true)
256
            && ! get_option('timezone_string')
257
            && EEM_Event::instance()->count() > 0
258
        ) {
259
            new PersistentAdminNotice(
260
                'datetime_fix_notice',
261
                sprintf(
262
                    esc_html__(
263
                        '%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.',
264
                        'event_espresso'
265
                    ),
266
                    '<strong>',
267
                    '</strong>',
268
                    '<a href="https://eventespresso.com/2017/08/important-upcoming-changes-dates-times">',
269
                    '</a>',
270
                    '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
271
                        array(
272
                            'page' => 'espresso_maintenance_settings',
273
                            'action' => 'datetime_tools'
274
                        ),
275
                        admin_url('admin.php')
276
                    ) . '">'
277
                ),
278
                false,
279
                'manage_options',
280
                'datetime_fix_persistent_notice'
281
            );
282
        }
283
    }
284
285
286
287
    /**
288
     * this simply hooks into the nav menu setup of pages metabox and makes sure that we remove EE critical pages from
289
     * the list of options. the wp function "wp_nav_menu_item_post_type_meta_box" found in
290
     * wp-admin/includes/nav-menu.php looks for the "_default_query" property on the post_type object and it uses that
291
     * to override any queries found in the existing query for the given post type.  Note that _default_query is not a
292
     * normal property on the post_type object.  It's found ONLY in this particular context.
293
     *
294
     * @param WP_Post $post_type WP post type object
295
     * @return WP_Post
296
     * @throws InvalidArgumentException
297
     * @throws InvalidDataTypeException
298
     * @throws InvalidInterfaceException
299
     */
300
    public function remove_pages_from_nav_menu($post_type)
301
    {
302
        //if this isn't the "pages" post type let's get out
303
        if ($post_type->name !== 'page') {
304
            return $post_type;
305
        }
306
        $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array();
307
        $post_type->_default_query = array(
308
            'post__not_in' => $critical_pages,
309
        );
310
        return $post_type;
311
    }
312
313
314
315
    /**
316
     * WP by default only shows three metaboxes in "nav-menus.php" for first times users.  We want to make sure our
317
     * metaboxes get shown as well
318
     *
319
     * @return void
320
     */
321
    public function enable_hidden_ee_nav_menu_metaboxes()
322
    {
323
        global $wp_meta_boxes, $pagenow;
324
        if (! is_array($wp_meta_boxes) || $pagenow !== 'nav-menus.php') {
325
            return;
326
        }
327
        $user = wp_get_current_user();
328
        //has this been done yet?
329
        if (get_user_option('ee_nav_menu_initialized', $user->ID)) {
330
            return;
331
        }
332
333
        $hidden_meta_boxes  = get_user_option('metaboxhidden_nav-menus', $user->ID);
334
        $initial_meta_boxes = apply_filters(
335
            'FHEE__EE_Admin__enable_hidden_ee_nav_menu_boxes__initial_meta_boxes',
336
            array(
337
                'nav-menu-theme-locations',
338
                'add-page',
339
                'add-custom-links',
340
                'add-category',
341
                'add-espresso_events',
342
                'add-espresso_venues',
343
                'add-espresso_event_categories',
344
                'add-espresso_venue_categories',
345
                'add-post-type-post',
346
                'add-post-type-page',
347
            )
348
        );
349
350
        if (is_array($hidden_meta_boxes)) {
351
            foreach ($hidden_meta_boxes as $key => $meta_box_id) {
352
                if (in_array($meta_box_id, $initial_meta_boxes, true)) {
353
                    unset($hidden_meta_boxes[$key]);
354
                }
355
            }
356
        }
357
        update_user_option($user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true);
358
        update_user_option($user->ID, 'ee_nav_menu_initialized', 1, true);
359
    }
360
361
362
363
    /**
364
     * This method simply registers custom nav menu boxes for "nav_menus.php route"
365
     * Currently EE is using this to make sure there are menu options for our CPT archive page routes.
366
     *
367
     * @todo   modify this so its more dynamic and automatic for all ee CPTs and setups and can also be hooked into by
368
     *         addons etc.
369
     * @return void
370
     */
371
    public function register_custom_nav_menu_boxes()
372
    {
373
        add_meta_box(
374
            'add-extra-nav-menu-pages',
375
            esc_html__('Event Espresso Pages', 'event_espresso'),
376
            array($this, 'ee_cpt_archive_pages'),
377
            'nav-menus',
378
            'side',
379
            'core'
380
        );
381
    }
382
383
384
385
    /**
386
     * Use this to edit the post link for our cpts so that the edit link points to the correct page.
387
     *
388
     * @since   4.3.0
389
     * @param string $link the original link generated by wp
390
     * @param int    $id   post id
391
     * @return string  the (maybe) modified link
392
     */
393
    public function modify_edit_post_link($link, $id)
394
    {
395
        if (! $post = get_post($id)) {
396
            return $link;
397
        }
398
        if ($post->post_type === 'espresso_attendees') {
399
            $query_args = array(
400
                'action' => 'edit_attendee',
401
                'post'   => $id,
402
            );
403
            return EEH_URL::add_query_args_and_nonce(
404
                $query_args,
405
                admin_url('admin.php?page=espresso_registrations')
406
            );
407
        }
408
        return $link;
409
    }
410
411
412
413
    public function ee_cpt_archive_pages()
414
    {
415
        global $nav_menu_selected_id;
416
        $db_fields   = false;
417
        $walker      = new Walker_Nav_Menu_Checklist($db_fields);
418
        $current_tab = 'event-archives';
419
        $removed_args = array(
420
            'action',
421
            'customlink-tab',
422
            'edit-menu-item',
423
            'menu-item',
424
            'page-tab',
425
            '_wpnonce',
426
        );
427
        ?>
428
        <div id="posttype-extra-nav-menu-pages" class="posttypediv">
429
            <ul id="posttype-extra-nav-menu-pages-tabs" class="posttype-tabs add-menu-item-tabs">
430
                <li <?php echo('event-archives' === $current_tab ? ' class="tabs"' : ''); ?>>
431
                    <a class="nav-tab-link" data-type="tabs-panel-posttype-extra-nav-menu-pages-event-archives"
432
                       href="<?php if ($nav_menu_selected_id) {
433
                            echo esc_url(
434
                                add_query_arg(
435
                                    'extra-nav-menu-pages-tab',
436
                                    'event-archives',
437
                                    remove_query_arg($removed_args)
438
                                )
439
                            );
440
                       } ?>#tabs-panel-posttype-extra-nav-menu-pages-event-archives">
441
                        <?php _e('Event Archive Pages', 'event_espresso'); ?>
442
                    </a>
443
                </li>
444
            </ul><!-- .posttype-tabs -->
445
446
            <div id="tabs-panel-posttype-extra-nav-menu-pages-event-archives" class="tabs-panel <?php
447
                echo('event-archives' === $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive');
448
                ?>">
449
                    <ul id="extra-nav-menu-pageschecklist-event-archives" class="categorychecklist form-no-clear">
450
                        <?php
451
                        $pages          = $this->_get_extra_nav_menu_pages_items();
452
                        $args['walker'] = $walker;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
453
                        echo walk_nav_menu_tree(
454
                            array_map(
455
                                array($this, '_setup_extra_nav_menu_pages_items'),
456
                                $pages
457
                            ),
458
                            0,
459
                            (object) $args
460
                        );
461
                        ?>
462
                    </ul>
463
                </div><!-- /.tabs-panel -->
464
465
                <p class="button-controls">
466
                <span class="list-controls">
467
                    <a href="<?php
468
                    echo esc_url(add_query_arg(
469
                        array(
470
                            'extra-nav-menu-pages-tab' => 'event-archives',
471
                            'selectall'                => 1,
472
                        ),
473
                        remove_query_arg($removed_args)
474
                    ));
475
                    ?>#posttype-extra-nav-menu-pages>" class="select-all"><?php _e('Select All'); ?></a>
476
                </span>
477
                <span class="add-to-menu">
478
                    <input type="submit"<?php wp_nav_menu_disabled_check($nav_menu_selected_id); ?>
479
                       class="button-secondary submit-add-to-menu right"
480
                       value="<?php esc_attr_e(__('Add to Menu')); ?>" name="add-post-type-menu-item"
481
                       id="<?php esc_attr_e('submit-posttype-extra-nav-menu-pages'); ?>"/>
482
                    <span class="spinner"></span>
483
                </span>
484
                </p>
485
486
        </div><!-- /.posttypediv -->
487
        <?php
488
    }
489
490
491
    /**
492
     * Returns an array of event archive nav items.
493
     *
494
     * @todo  for now this method is just in place so when it gets abstracted further we can substitute in whatever
495
     *        method we use for getting the extra nav menu items
496
     * @return array
497
     */
498
    private function _get_extra_nav_menu_pages_items()
499
    {
500
        $menuitems[] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$menuitems was never initialized. Although not strictly required by PHP, it is generally a good practice to add $menuitems = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
501
            'title'       => esc_html__('Event List', 'event_espresso'),
502
            'url'         => get_post_type_archive_link('espresso_events'),
503
            'description' => esc_html__('Archive page for all events.', 'event_espresso'),
504
        );
505
        return apply_filters('FHEE__EE_Admin__get_extra_nav_menu_pages_items', $menuitems);
506
    }
507
508
509
    /**
510
     * Setup nav menu walker item for usage in the event archive nav menu metabox.  It receives a menu_item array with
511
     * the properties and converts it to the menu item object.
512
     *
513
     * @see wp_setup_nav_menu_item() in wp-includes/nav-menu.php
514
     * @param $menu_item_values
515
     * @return stdClass
516
     */
517
    private function _setup_extra_nav_menu_pages_items($menu_item_values)
518
    {
519
        $menu_item = new stdClass();
520
        $keys      = array(
521
            'ID'               => 0,
522
            'db_id'            => 0,
523
            'menu_item_parent' => 0,
524
            'object_id'        => -1,
525
            'post_parent'      => 0,
526
            'type'             => 'custom',
527
            'object'           => '',
528
            'type_label'       => esc_html__('Extra Nav Menu Item', 'event_espresso'),
529
            'title'            => '',
530
            'url'              => '',
531
            'target'           => '',
532
            'attr_title'       => '',
533
            'description'      => '',
534
            'classes'          => array(),
535
            'xfn'              => '',
536
        );
537
538
        foreach ($keys as $key => $value) {
539
            $menu_item->{$key} = isset($menu_item_values[$key]) ? $menu_item_values[$key] : $value;
540
        }
541
        return $menu_item;
542
    }
543
544
545
    /**
546
     * This is the action hook for the AHEE__EE_Admin_Page__route_admin_request hook that fires off right before an
547
     * EE_Admin_Page route is called.
548
     *
549
     * @return void
550
     */
551
    public function route_admin_request()
552
    {
553
    }
554
555
556
    /**
557
     * wp_loaded should fire on the WordPress wp_loaded hook.  This fires on a VERY late priority.
558
     *
559
     * @return void
560
     */
561
    public function wp_loaded()
562
    {
563
    }
564
565
566
    /**
567
     * admin_init
568
     *
569
     * @return void
570
     * @throws EE_Error
571
     * @throws InvalidArgumentException
572
     * @throws InvalidDataTypeException
573
     * @throws InvalidInterfaceException
574
     * @throws ReflectionException
575
     */
576
    public function admin_init()
577
    {
578
579
        /**
580
         * our cpt models must be instantiated on WordPress post processing routes (wp-admin/post.php),
581
         * so any hooking into core WP routes is taken care of.  So in this next few lines of code:
582
         * - check if doing post processing.
583
         * - check if doing post processing of one of EE CPTs
584
         * - instantiate the corresponding EE CPT model for the post_type being processed.
585
         */
586
        if (isset($_POST['action'], $_POST['post_type']) && $_POST['action'] === 'editpost') {
587
            EE_Registry::instance()->load_core('Register_CPTs');
588
            EE_Register_CPTs::instantiate_cpt_models($_POST['post_type']);
589
        }
590
591
592
        /**
593
         * This code excludes EE critical pages anywhere `wp_dropdown_pages` is used to create a dropdown for selecting
594
         * critical pages.  The only place critical pages need included in a generated dropdown is on the "Critical
595
         * Pages" tab in the EE General Settings Admin page.
596
         * This is for user-proofing.
597
         */
598
        add_filter('wp_dropdown_pages', array($this, 'modify_dropdown_pages'));
599
    }
600
601
602
    /**
603
     * Callback for wp_dropdown_pages hook to remove ee critical pages from the dropdown selection.
604
     *
605
     * @param string $output Current output.
606
     * @return string
607
     * @throws InvalidArgumentException
608
     * @throws InvalidDataTypeException
609
     * @throws InvalidInterfaceException
610
     */
611
    public function modify_dropdown_pages($output)
612
    {
613
        //get critical pages
614
        $critical_pages = EE_Registry::instance()->CFG->core->get_critical_pages_array();
615
616
        //split current output by line break for easier parsing.
617
        $split_output = explode("\n", $output);
618
619
        //loop through to remove any critical pages from the array.
620
        foreach ($critical_pages as $page_id) {
621
            $needle = 'value="' . $page_id . '"';
622
            foreach ($split_output as $key => $haystack) {
623
                if (strpos($haystack, $needle) !== false) {
624
                    unset($split_output[$key]);
625
                }
626
            }
627
        }
628
        //replace output with the new contents
629
        return implode("\n", $split_output);
630
    }
631
632
633
    /**
634
     * enqueue all admin scripts that need loaded for admin pages
635
     *
636
     * @return void
637
     */
638
    public function enqueue_admin_scripts()
639
    {
640
        // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js.
641
        // Note: the intention of this script is to only do TARGETED injections.  I.E, only injecting on certain script
642
        // calls.
643
        wp_enqueue_script(
644
            'ee-inject-wp',
645
            EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
646
            array('jquery'),
647
            EVENT_ESPRESSO_VERSION,
648
            true
649
        );
650
        // register cookie script for future dependencies
651
        wp_register_script(
652
            'jquery-cookie',
653
            EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
654
            array('jquery'),
655
            '2.1',
656
            true
657
        );
658
        //joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook, can be turned back on again
659
        // via: add_filter('FHEE_load_joyride', '__return_true' );
660
        if (apply_filters('FHEE_load_joyride', false)) {
661
            //joyride style
662
            wp_register_style('joyride-css', EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css', array(), '2.1');
663
            wp_register_style(
664
                'ee-joyride-css',
665
                EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
666
                array('joyride-css'),
667
                EVENT_ESPRESSO_VERSION
668
            );
669
            wp_register_script(
670
                'joyride-modernizr',
671
                EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
672
                array(),
673
                '2.1',
674
                true
675
            );
676
            //joyride JS
677
            wp_register_script(
678
                'jquery-joyride',
679
                EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
680
                array('jquery-cookie', 'joyride-modernizr'),
681
                '2.1',
682
                true
683
            );
684
            // wanna go for a joyride?
685
            wp_enqueue_style('ee-joyride-css');
686
            wp_enqueue_script('jquery-joyride');
687
        }
688
    }
689
690
691
    /**
692
     * display_admin_notices
693
     *
694
     * @return void
695
     */
696
    public function display_admin_notices()
697
    {
698
        echo EE_Error::get_notices();
699
    }
700
701
702
703
    /**
704
     * @param array $elements
705
     * @return array
706
     * @throws EE_Error
707
     * @throws InvalidArgumentException
708
     * @throws InvalidDataTypeException
709
     * @throws InvalidInterfaceException
710
     */
711
    public function dashboard_glance_items($elements)
712
    {
713
        $elements                        = is_array($elements) ? $elements : array($elements);
714
        $events                          = EEM_Event::instance()->count();
715
        $items['events']['url']          = EE_Admin_Page::add_query_args_and_nonce(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$items was never initialized. Although not strictly required by PHP, it is generally a good practice to add $items = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
716
            array('page' => 'espresso_events'),
717
            admin_url('admin.php')
718
        );
719
        $items['events']['text']         = sprintf(_n('%s Event', '%s Events', $events), number_format_i18n($events));
720
        $items['events']['title']        = esc_html__('Click to view all Events', 'event_espresso');
721
        $registrations                   = EEM_Registration::instance()->count(
722
            array(
723
                array(
724
                    'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
725
                ),
726
            )
727
        );
728
        $items['registrations']['url']   = EE_Admin_Page::add_query_args_and_nonce(
729
            array('page' => 'espresso_registrations'),
730
            admin_url('admin.php')
731
        );
732
        $items['registrations']['text']  = sprintf(
733
            _n('%s Registration', '%s Registrations', $registrations),
734
            number_format_i18n($registrations)
735
        );
736
        $items['registrations']['title'] = esc_html__('Click to view all registrations', 'event_espresso');
737
738
        $items = (array)apply_filters('FHEE__EE_Admin__dashboard_glance_items__items', $items);
739
740
        foreach ($items as $type => $item_properties) {
741
            $elements[] = sprintf(
742
                '<a class="ee-dashboard-link-' . $type . '" href="%s" title="%s">%s</a>',
743
                $item_properties['url'],
744
                $item_properties['title'],
745
                $item_properties['text']
746
            );
747
        }
748
        return $elements;
749
    }
750
751
752
    /**
753
     * check_for_invalid_datetime_formats
754
     * if an admin changes their date or time format settings on the WP General Settings admin page, verify that
755
     * their selected format can be parsed by PHP
756
     *
757
     * @param    $value
758
     * @param    $option
759
     * @throws EE_Error
760
     * @return    string
761
     */
762
    public function check_for_invalid_datetime_formats($value, $option)
763
    {
764
        // check for date_format or time_format
765
        switch ($option) {
766
            case 'date_format':
767
                $date_time_format = $value . ' ' . get_option('time_format');
768
                break;
769
            case 'time_format':
770
                $date_time_format = get_option('date_format') . ' ' . $value;
771
                break;
772
            default:
773
                $date_time_format = false;
774
        }
775
        // do we have a date_time format to check ?
776
        if ($date_time_format) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $date_time_format of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
777
            $error_msg = EEH_DTT_Helper::validate_format_string($date_time_format);
778
779
            if (is_array($error_msg)) {
780
                $msg = '<p>'
781
                       . sprintf(
782
                           esc_html__(
783
                               'The following date time "%s" ( %s ) is difficult to be properly parsed by PHP for the following reasons:',
784
                               'event_espresso'
785
                           ),
786
                           date($date_time_format),
787
                           $date_time_format
788
                       )
789
                       . '</p><p><ul>';
790
791
792
                foreach ($error_msg as $error) {
793
                    $msg .= '<li>' . $error . '</li>';
794
                }
795
796
                $msg .= '</ul></p><p>'
797
                        . sprintf(
798
                            esc_html__(
799
                                '%sPlease note that your date and time formats have been reset to "F j, Y" and "g:i a" respectively.%s',
800
                                'event_espresso'
801
                            ),
802
                            '<span style="color:#D54E21;">',
803
                            '</span>'
804
                        )
805
                        . '</p>';
806
807
                // trigger WP settings error
808
                add_settings_error(
809
                    'date_format',
810
                    'date_format',
811
                    $msg
812
                );
813
814
                // set format to something valid
815
                switch ($option) {
816
                    case 'date_format':
817
                        $value = 'F j, Y';
818
                        break;
819
                    case 'time_format':
820
                        $value = 'g:i a';
821
                        break;
822
                }
823
            }
824
        }
825
        return $value;
826
    }
827
828
829
    /**
830
     * its_eSpresso - converts the less commonly used spelling of "Expresso" to "Espresso"
831
     *
832
     * @param $content
833
     * @return    string
834
     */
835
    public function its_eSpresso($content)
836
    {
837
        return str_replace('[EXPRESSO_', '[ESPRESSO_', $content);
838
    }
839
840
841
    /**
842
     * espresso_admin_footer
843
     *
844
     * @return    string
845
     */
846
    public function espresso_admin_footer()
847
    {
848
        return \EEH_Template::powered_by_event_espresso('aln-cntr', '', array('utm_content' => 'admin_footer'));
849
    }
850
851
852
    /**
853
     * static method for registering ee admin page.
854
     * This method is deprecated in favor of the new location in EE_Register_Admin_Page::register.
855
     *
856
     * @since      4.3.0
857
     * @deprecated 4.3.0    Use EE_Register_Admin_Page::register() instead
858
     * @see        EE_Register_Admin_Page::register()
859
     * @param       $page_basename
860
     * @param       $page_path
861
     * @param array $config
862
     * @return void
863
     * @throws EE_Error
864
     */
865
    public static function register_ee_admin_page($page_basename, $page_path, $config = array())
866
    {
867
        EE_Error::doing_it_wrong(
868
            __METHOD__,
869
            sprintf(
870
                esc_html__(
871
                    'Usage is deprecated.  Use EE_Register_Admin_Page::register() for registering the %s admin page.',
872
                    'event_espresso'
873
                ),
874
                $page_basename
875
            ),
876
            '4.3'
877
        );
878
        if (class_exists('EE_Register_Admin_Page')) {
879
            $config['page_path'] = $page_path;
880
        }
881
        EE_Register_Admin_Page::register($page_basename, $config);
882
    }
883
884
885
    /**
886
     * @deprecated 4.8.41
887
     * @param  int      $post_ID
888
     * @param  \WP_Post $post
889
     * @return void
890
     */
891
    public static function parse_post_content_on_save($post_ID, $post)
892
    {
893
        EE_Error::doing_it_wrong(
894
            __METHOD__,
895
            esc_html__('Usage is deprecated', 'event_espresso'),
896
            '4.8.41'
897
        );
898
    }
899
900
901
    /**
902
     * @deprecated 4.8.41
903
     * @param  $option
904
     * @param  $old_value
905
     * @param  $value
906
     * @return void
907
     */
908
    public function reset_page_for_posts_on_change($option, $old_value, $value)
909
    {
910
        EE_Error::doing_it_wrong(
911
            __METHOD__,
912
            esc_html__('Usage is deprecated', 'event_espresso'),
913
            '4.8.41'
914
        );
915
    }
916
917
918
919
    /**
920
     * @deprecated 4.9.27
921
     * @return void
922
     */
923
    public function get_persistent_admin_notices()
924
    {
925
        EE_Error::doing_it_wrong(
926
            __METHOD__,
927
            sprintf(
928
                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
929
                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
930
            ),
931
            '4.9.27'
932
        );
933
    }
934
935
936
937
    /**
938
     * @deprecated 4.9.27
939
     * @throws InvalidInterfaceException
940
     * @throws InvalidDataTypeException
941
     * @throws DomainException
942
     */
943
    public function dismiss_ee_nag_notice_callback()
944
    {
945
        EE_Error::doing_it_wrong(
946
            __METHOD__,
947
            sprintf(
948
                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
949
                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
950
            ),
951
            '4.9.27'
952
        );
953
        $this->persistent_admin_notice_manager->dismissNotice();
954
    }
955
}
956