capability = 'manage_network_options'; } $this->init(); } /** * Initializes the interface and binds hooks */ public function init() { $this->options = self::get_specific_options( $this->option_name ); if ( is_multisite() && defined( 'SMARTCRAWL_SITEWIDE' ) && SMARTCRAWL_SITEWIDE ) { $this->capability = 'manage_network_options'; } add_action( 'init', array( $this, 'defaults' ), 999 ); add_action( 'admin_body_class', array( $this, 'add_body_class' ), 20 ); if ( is_multisite() && smartcrawl_is_switch_active( 'SMARTCRAWL_SITEWIDE' ) ) { add_action( 'network_admin_menu', array( $this, 'add_page' ) ); } else { add_action( 'admin_menu', array( $this, 'add_page' ) ); } } private function is_current_screen() { $screen = get_current_screen(); return ! empty( $screen->id ) && ! empty( $this->smartcrawl_page_hook ) && strpos( $screen->id, $this->smartcrawl_page_hook ) === 0; } /** * Unified admin tab URL getter * * Also takes into account whether the tab is allowed or not * * @param string $tab Tab to check. * * @return string Unescaped admin URL, or tab anchor on failure */ public static function admin_url( $tab ) { $single_site_url = esc_url_raw( add_query_arg( 'page', $tab, admin_url( 'admin.php' ) ) ); if ( ! is_multisite() ) { return $single_site_url; } $network_admin_url = esc_url_raw( add_query_arg( 'page', $tab, network_admin_url( 'admin.php' ) ) ); $sitewide = smartcrawl_is_switch_active( 'SMARTCRAWL_SITEWIDE' ); return $sitewide ? $network_admin_url : $single_site_url; } /** * Validation abstraction * * @param array $input Raw input to validate. * * @return array */ abstract public function validate( $input ); /** * Add sub page to the Settings Menu */ public function add_page() { if ( ! $this->_is_current_tab_allowed() ) { return false; } $this->smartcrawl_page_hook = add_submenu_page( 'wds_wizard', $this->page_title, $this->get_title(), $this->capability, $this->slug, array( $this, 'options_page' ) ); // For pages that can deal with run requests, let's make sure they actually do that early enough. if ( is_callable( array( $this, 'process_run_action' ) ) ) { add_action( 'load-' . $this->smartcrawl_page_hook, array( $this, 'process_run_action' ) ); } add_action( "admin_print_styles-{$this->smartcrawl_page_hook}", array( $this, 'admin_styles' ) ); } abstract public function get_title(); /** * Check if the current tab (settings page) is allowed for access * * @return bool */ protected function _is_current_tab_allowed() { return ! empty( $this->slug ) ? self::is_tab_allowed( $this->slug ) : false; } /** * Check if a tab (settings page) is allowed for access * * It can be not allowed for access to site admins * * @param string $tab Tab to check. * * @return bool */ public static function is_tab_allowed( $tab ) { // On single installs, everything is good if ( ! is_multisite() ) { return true; } // Always good in network if ( is_network_admin() ) { return true; } // If we're sitewide, we're good *in network admin* pages if ( smartcrawl_is_switch_active( 'SMARTCRAWL_SITEWIDE' ) ) { return smartcrawl_is_switch_active( 'DOING_AJAX' ) ? true : is_network_admin(); } // We're network install and not sitewide. // Now let's see what's up. // SEO checkup not supported on sub-sites if ( $tab === self::TAB_CHECKUP ) { return is_main_site(); } // Dashboard shown on all sub-sites if ( $tab === self::TAB_DASHBOARD ) { return true; } // Check whether the tab is blocked on network level $allowed = Smartcrawl_Settings_Settings::get_blog_tabs(); $allowed = empty( $allowed ) ? array() : $allowed; return in_array( $tab, array_keys( $allowed ), true ) && ! empty( $allowed[ $tab ] ); } /** * Enqueue styles */ public function admin_styles() { wp_enqueue_style( Smartcrawl_Controller_Assets::APP_CSS ); } /** * Initiates a checkup run */ public function run_checkup() { if ( current_user_can( 'manage_options' ) ) { $service = Smartcrawl_Service::get( Smartcrawl_Service::SERVICE_CHECKUP ); $service->start(); } wp_safe_redirect( esc_url( remove_query_arg( array( 'run-checkup', '_wds_nonce' ) ) ) ); die; } /** * Display the admin options page */ public function options_page() { // phpcs:disable -- $_GET values need to be used without nonces $this->msg = ''; if ( ! empty( $_GET['updated'] ) || ! empty( $_GET['settings-updated'] ) ) { $this->msg = __( 'Settings updated', 'wds' ); if ( function_exists( 'w3tc_pgcache_flush' ) ) { w3tc_pgcache_flush(); $this->msg .= __( ' & W3 Total Cache Page Cache flushed', 'wds' ); } elseif ( function_exists( 'wp_cache_clear_cache' ) ) { wp_cache_clear_cache(); $this->msg .= __( ' & WP Super Cache flushed', 'wds' ); } } $errors = get_settings_errors( $this->option_name ); if ( $errors ) { set_transient( 'wds-settings-save-errors', $errors, 3 ); } // phpcs:enable } /** * Sets up contextual help * * @param string $contextual_help Help. * * @return string */ public function contextual_help( $contextual_help ) { $page = smartcrawl_get_array_value( $_GET, 'page' ); // phpcs:ignore -- Can't add nonce to the request if ( ! empty( $page ) && $page === $this->slug && ! empty( $this->contextual_help ) ) { $contextual_help = $this->contextual_help; } return $contextual_help; } /** * Adds body class * * @param string $classes Class that's being processed. * * @return string */ public function add_body_class( $classes ) { $sui_class = smartcrawl_sui_class(); if ( $this->is_current_screen() && strpos( $classes, $sui_class ) === false ) { $classes .= " {$sui_class} "; } return $classes; } /** * Renders the whole page view by calling `_render` * * As a side-effect, also calls `WDEV_Plugin_Ui::output()` * * @param string $view View file to load. * @param array $args Optional array of arguments to pass to view. * * @return bool */ protected function _render_page( $view, $args = array() ) { $this->_render( $view, $args ); return true; } protected function settings_fields( $option_group ) { echo ""; echo ''; wp_nonce_field( "$option_group-options", "_wpnonce", false ); } /** * Populates view defaults with view meta information * * @return array Defaults */ protected function _get_view_defaults() { $errors = get_transient( 'wds-settings-save-errors' ); $errors = ! empty( $errors ) ? $errors : array(); $service = Smartcrawl_Service::get( Smartcrawl_Service::SERVICE_SITE ); return array( '_view' => array( 'slug' => $this->slug, 'name' => $this->name, 'option_name' => $this->option_name, 'options' => $this->options, 'action_url' => $this->action_url, 'msg' => $this->msg, 'errors' => $errors, 'is_member' => $service->is_member(), ), ); } /** * Checks if the last active tab is stored in the transient and returns its value. If nothing is available then it returns the default value. * * @param string $default Fallback value. * * @return string The last active tab. */ protected function _get_active_tab( $default = '' ) { return empty( $_GET['tab'] ) ? $default : $_GET['tab']; } }