class-configuration-page.php 7.28 KB
Newer Older
imac's avatar
imac committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
<?php
/**
 * @package WPSEO\Admin
 */

/**
 * @class WPSEO_Configuration_Wizard Loads the Yoast configuration wizard.
 */
class WPSEO_Configuration_Page {

	const PAGE_IDENTIFIER = 'wpseo_configurator';

	/**
	 * WPSEO_Configuration_Wizard constructor.
	 */
	public function __construct() {

		if ( $this->should_add_notification() ) {
			$this->add_notification();
		}

		if ( filter_input( INPUT_GET, 'page' ) !== self::PAGE_IDENTIFIER ) {
			return;
		}

		// Register the page for the wizard.
		add_action( 'admin_menu', array( $this, 'add_wizard_page' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
		add_action( 'admin_init', array( $this, 'render_wizard_page' ) );
	}

	/**
	 * Check if the configuration is finished. If so, just remove the notification.
	 */
	public function catch_configuration_request() {
		$configuration_page = filter_input( INPUT_GET, 'configuration' );
		$page               = filter_input( INPUT_GET, 'page' );

		if ( ! ( $configuration_page === 'finished' && ( $page === WPSEO_Admin::PAGE_IDENTIFIER ) ) ) {
			return;
		}

		$this->remove_notification();
		$this->remove_notification_option();

		wp_redirect( admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER ) );
		exit;
	}


	/**
	 *  Registers the page for the wizard.
	 */
	public function add_wizard_page() {
		add_dashboard_page( '', '', 'manage_options', self::PAGE_IDENTIFIER, '' );
	}

	/**
	 * Renders the wizard page and exits to prevent the wordpress UI from loading.
	 */
	public function render_wizard_page() {
		$this->show_wizard();
		exit;
	}

	/**
	 * Enqueues the assets needed for the wizard.
	 */
	public function enqueue_assets() {
		wp_enqueue_media();

		/*
		 * Print the `forms.css` WP stylesheet before any Yoast style, this way
		 * it's easier to override selectors with the same specificity later.
		 */
		wp_enqueue_style( 'forms' );
		$asset_manager = new WPSEO_Admin_Asset_Manager();
		$asset_manager->register_assets();
		$asset_manager->enqueue_script( 'configuration-wizard' );
		$asset_manager->enqueue_style( 'yoast-components' );

		$config = $this->get_config();

		wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard', 'yoastWizardConfig', $config );
	}

	/**
	 * Setup Wizard Header.
	 */
	public function show_wizard() {
		$this->enqueue_assets();
		$dashboard_url = admin_url( '/admin.php?page=wpseo_dashboard' );
		?>
		<!DOCTYPE html>
		<!--[if IE 9]>
		<html class="ie9" <?php language_attributes(); ?> >
		<![endif]-->
		<!--[if !(IE 9) ]><!-->
		<html <?php language_attributes(); ?>>
		<!--<![endif]-->
		<head>
			<meta name="viewport" content="width=device-width"/>
			<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
			<title><?php
				printf(
					/* translators: %s expands to Yoast SEO. */
					__( '%s &rsaquo; Configuration Wizard', 'wordpress-seo' ),
					'Yoast SEO'
				);
			?></title>
			<?php
			wp_print_head_scripts();
			wp_print_styles( 'yoast-seo-yoast-components' );

			/**
			 * Is called before the closing </head> tag in the Yoast Configuration wizard.
			 *
			 * Allows users to add their own scripts or styles.
			 *
			 * @since 4.0
			 */
			do_action( 'wpseo_configuration_wizard_head' );
			?>
		</head>
		<body class="wp-admin">
		<div id="wizard"></div>
		<a class="yoast-wizard-return-link" href="<?php echo $dashboard_url ?>">
			<?php
			printf(
				/* translators: %s expands to Yoast SEO. */
				__( 'Go back to the %s dashboard.', 'wordpress-seo' ),
				'Yoast SEO'
			);
			?>
		</a>
		<?php
			wp_print_media_templates();
			wp_print_footer_scripts();

			/**
			 * Is called before the closing </body> tag in the Yoast Configuration wizard.
			 *
			 * Allows users to add their own scripts or content.
			 *
			 * @since 4.0
			 */
			do_action( 'wpseo_configuration_wizard_footer' );

			wp_print_scripts( 'yoast-seo-configuration-wizard' );
		?>
		</body>
		</html>
		<?php

	}

	/**
	 * Get the API config for the wizard.
	 *
	 * @return array The API endpoint config.
	 */
	public function get_config() {
		$translations = $this->get_translations();
		$service      = new WPSEO_GSC_Service();
		$config       = array(
			'namespace'         => WPSEO_Configuration_Endpoint::REST_NAMESPACE,
			'endpoint_retrieve' => WPSEO_Configuration_Endpoint::ENDPOINT_RETRIEVE,
			'endpoint_store'    => WPSEO_Configuration_Endpoint::ENDPOINT_STORE,
			'nonce'             => wp_create_nonce( 'wp_rest' ),
			'root'              => esc_url_raw( rest_url() ),
			'ajaxurl'           => admin_url( 'admin-ajax.php' ),
			'finishUrl'         => admin_url( 'admin.php?page=wpseo_dashboard&configuration=finished' ),
			'gscAuthURL'        => $service->get_client()->createAuthUrl(),
			'gscProfiles'       => $service->get_sites(),
			'gscNonce'          => wp_create_nonce( 'wpseo-gsc-ajax-security' ),
			'translations'      => $translations,
		);

		return $config;
	}

	/**
	 * Returns the translations necessary for the configuration wizard.
	 *
	 * @returns array The translations for the configuration wizard.
	 */
	public function get_translations() {
		$file = plugin_dir_path( WPSEO_FILE ) . 'languages/yoast-components-' . WPSEO_Utils::get_user_locale() . '.json';
		if ( file_exists( $file ) && $file = file_get_contents( $file ) ) {
			return json_decode( $file, true );
		}

		return array();
	}

	/**
	 * Adds a notification to the notification center.
	 */
	private function add_notification() {
		$notification_center = Yoast_Notification_Center::get();
		$notification_center->add_notification( self::get_notification() );
	}

	/**
	 * Removes the notification from the notification center.
	 */
	private function remove_notification() {
		$notification_center = Yoast_Notification_Center::get();
		$notification_center->remove_notification( self::get_notification() );
	}

	/**
	 * Gets the notification.
	 *
	 * @return Yoast_Notification
	 */
	private static function get_notification() {
		$message = __( 'The configuration wizard helps you to easily configure your site to have the optimal SEO settings.', 'wordpress-seo' );
		$message .= '<br/>';
		$message .= sprintf(
			/* translators: %1$s resolves to Yoast SEO, %2$s resolves to the starting tag of the link to the wizard, %3$s resolves to the closing link tag */
			__( 'We have detected that you have not finished this wizard yet, so we recommend you to %2$sstart the configuration wizard to configure %1$s%3$s.', 'wordpress-seo' ),
			'Yoast SEO',
			'<a href="' . admin_url( '?page=' . self::PAGE_IDENTIFIER ) . '">',
			'</a>'
		);

		$notification = new Yoast_Notification(
			$message,
			array(
				'type'         => Yoast_Notification::WARNING,
				'id'           => 'wpseo-dismiss-onboarding-notice',
				'capabilities' => 'manage_options',
				'priority'     => 0.8,
			)
		);

		return $notification;
	}

	/**
	 * When the notice should be shown.
	 *
	 * @return bool
	 */
	private function should_add_notification() {
		$options = $this->get_options();

		return $options['show_onboarding_notice'] === true;
	}

	/**
	 * Remove the options that triggers the notice for the configuration wizard.
	 */
	private function remove_notification_option() {
		$options = $this->get_options();

		$options['show_onboarding_notice'] = false;

		update_option( 'wpseo', $options );
	}

	/**
	 * Returns the set options
	 *
	 * @return mixed|void
	 */
	private function get_options() {
		return get_option( 'wpseo' );
	}
}