/** * Menu loader event * * This will render the contextual help and 'per_page' settings, based * on the selected menu. If the menu callback has a matching 'Load' method, * it will be called too, containing the current screen as an argument. * * For example, if the menu callback is `onRenderMenu()`, and a method called * `onRenderMenuLoad()` exists, then it will be called prior to `onRenderMenu()`. * * This could be used, for instance, to add screen settings: * <code> * add_action('screen_settings', ($this, 'screen_settings_callback')); * </code> * * where the `screen_settings_callback()` will return the details to be displayed. * */ public function onMenuLoad() { if (($active_menu = $this->getActiveMenu()) !== false) { // Test if there's a method to call before the actual callback $before_callback = Helpers::validCallback($active_menu->_properties['callback'], static::PRE_MENU_CALLBACK_SUFFIX); if ($before_callback) { call_user_func($before_callback, get_current_screen()); } $current_screen = get_current_screen(); $context_help = $active_menu->context_help; // Set contextual help if (!empty($context_help)) { if (is_object($current_screen) && is_callable(array($current_screen, 'add_help_tab'))) { // As of WP 3.3 if ($context_help instanceof \Pf4wp\Help\ContextHelp) { $context_help->addTabs($current_screen); } else { $current_screen->add_help_tab(array('title' => __('Overview'), 'id' => 'overview', 'content' => $context_help)); } } else { add_contextual_help($current_screen, $context_help); } } $per_page_id = $active_menu->_properties['slug'] . $current_screen->id . MenuEntry::PER_PAGE_SUFFIX; // Check if the user has specified custom screen options if (isset($_POST['screen-options-apply']) && isset($_POST['wp_screen_options']['value']) && isset($_POST['wp_screen_options']['option']) && $_POST['wp_screen_options']['option'] == $per_page_id && wp_verify_nonce($_POST['screenoptionnonce'], 'screen-options-nonce')) { global $current_user; $value = (int) $_POST['wp_screen_options']['value']; // Let's be reasonable if ($value < 1) { $value = (int) $active_menu->per_page; } update_user_option($current_user->ID, $per_page_id, $value); // Columns $columns = apply_filters('manage_' . $current_screen->id . '_columns', array()); $existing_to_hide = get_user_option('manage' . $current_screen->id . 'columnshidden'); if (!is_array($existing_to_hide)) { $existing_to_hide = array(); } // Any existing columns to hide, but not part of the current $columns, are placed in $to_hide. $to_hide = array_diff($existing_to_hide, array_keys($columns)); foreach ($columns as $column_id => $column_title) { if (!in_array($column_id, array('_title', 'cb', 'comment', 'media', 'name', 'title', 'username', 'blogname')) && !isset($_POST[$column_id . '-hide'])) { $to_hide[] = $column_id; } } update_user_option($current_user->ID, 'manage' . $current_screen->id . 'columnshidden', $to_hide); } if ($active_menu->per_page) { // add_screen_option handles get_user_option, no need to pass value add_screen_option('per_page', array('label' => empty($active_menu->per_page_label) ? __('items per page', $this->textdomain) : $active_menu->per_page_label, 'option' => $per_page_id, 'default' => (int) $active_menu->per_page)); } } }
/** * Iterates blogs, performing an action after each switch (multisite) * * @param mixed $action Action to perform * @param mixed $args Array containing parameters to pass to the action * @internal */ private function iterateBlogsAction($action, array $args = array()) { if (!Helpers::validCallback($action)) { return; } // Perform action on the current blog first call_user_func_array($action, $args); // If in Network Admin mode, iterate all other blogs if (Helpers::isNetworkAdminMode()) { global $wpdb, $blog_id, $switched, $switched_stack; $orig_switched_stack = $switched_stack; // global $switched_stack $orig_switched = $switched; // global $switched $orig_blog_id = $blog_id; // global $blog_id $all_blog_ids = $wpdb->get_col($wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE blog_id <> %d", $orig_blog_id)); // global $wpdb foreach ($all_blog_ids as $a_blog_id) { switch_to_blog($a_blog_id); call_user_func_array($action, $args); } // Switch back to the original blog switch_to_blog($orig_blog_id); /* Reset the global $switched and $switched_stack, as we're back at the original now. * This is faster than calling restore_current_blog() after each completed switch. * See wp-includes/ms-blogs.php. */ $switched = $orig_switched; // global $switched $switched_stack = $orig_switched_stack; // global $switched_stack } }
/** * Event called before the user-defined menu callback is triggered. * * It also renders portions of the page, which includes a large icon, page title * and depending on the before_callback a header (ie., sub menu) and on after_callback * a footer. * * The actual callback depends on what is returned by the menu's "before_callback". If * that is NULL, it will use the callback defined for this MenuEntry's "callback", * otherwise the callback of the result is used. * * The callback is also passed an array containing various details about the menu * properties, its hook and any custom defined arguments. */ public function onMenuCallback() { $current_screen = get_current_screen(); $callback = $this->_properties['callback']; $callback_args = $this->_properties['callback_args']; $per_page_id = $this->_properties['slug'] . $current_screen->id . static::PER_PAGE_SUFFIX; $per_page_def = $this->per_page; $capability = $this->capability; // Perform 'before_callback' event ob_start(); if (Helpers::validCallback($this->_properties['before_callback']) !== false) { $result = call_user_func($this->_properties['before_callback']); // If the result from 'before_callback' is not NULL, use the result as the actual callback and callback_args (override). if (!empty($result) && $result instanceof MenuEntry) { $callback = $result->_properties['callback']; $callback_args = $result->_properties['callback_args']; $per_page_id = $result->_properties['slug'] . $current_screen->id . static::PER_PAGE_SUFFIX; $per_page_def = $result->per_page; $capability = $result->capability; } } $before_callback_output = ob_get_clean(); // Extra permission check (if bypassed in WordPress) if (!current_user_can($capability)) { wp_die(__('You do not have sufficient permissions to access this page.', $this->textdomain)); } // Set final 'per page' variable $per_page = (int) get_user_option($per_page_id); if (empty($per_page)) { $per_page = $per_page_def; } /* Render page */ echo '<div class="wrap">'; // Render large icon if (!empty($this->large_icon)) { if (strpos($this->large_icon, '/') === false && substr($this->large_icon, 0, strlen('data:')) != 'data:') { // Use an icon by CSS ID $icon = sprintf('id="%s"', $this->large_icon); } else { // Ensure SSL is used $icon = is_ssl() ? preg_replace('#^http:#', 'https:', $this->large_icon) : $this->large_icon; // Use a background with specified URL or Data URI $icon = sprintf('style="background: url(\'%s\') no-repeat scroll center center transparent"', $icon); } } printf('<div class="icon32" %s><br /></div>', isset($icon) ? $icon : 'id="icon-options-general"'); // Render title if ($this->display_page_title) { printf('<h2>%s%s</h2>', $this->page_title, $this->page_title_extra); } // Render output of before_callback echo $before_callback_output; // Perform user-defined callback echo '<div class="clear"></div><div>'; if (Helpers::validCallback($callback)) { call_user_func($callback, $callback_args, $per_page); } echo '</div>'; // Perform 'afer_callback' event if (Helpers::validCallback($this->_properties['after_callback'])) { call_user_func($this->_properties['after_callback']); } echo '</div>'; // div wrap }