class-configuration-page.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Admin
  6. */
  7. /**
  8. * Loads the Yoast configuration wizard.
  9. */
  10. class WPSEO_Configuration_Page {
  11. /**
  12. * Admin page identifier.
  13. *
  14. * @var string
  15. */
  16. const PAGE_IDENTIFIER = 'wpseo_configurator';
  17. /**
  18. * Sets the hooks when the user has enough rights and is on the right page.
  19. */
  20. public function set_hooks() {
  21. if ( ! ( $this->is_config_page() && current_user_can( WPSEO_Configuration_Endpoint::CAPABILITY_RETRIEVE ) ) ) {
  22. return;
  23. }
  24. if ( $this->should_add_notification() ) {
  25. $this->add_notification();
  26. }
  27. // Register the page for the wizard.
  28. add_action( 'admin_menu', [ $this, 'add_wizard_page' ] );
  29. add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
  30. add_action( 'admin_init', [ $this, 'render_wizard_page' ] );
  31. }
  32. /**
  33. * Check if the configuration is finished. If so, just remove the notification.
  34. */
  35. public function catch_configuration_request() {
  36. $configuration_page = filter_input( INPUT_GET, 'configuration' );
  37. $page = filter_input( INPUT_GET, 'page' );
  38. if ( ! ( $configuration_page === 'finished' && ( $page === WPSEO_Admin::PAGE_IDENTIFIER ) ) ) {
  39. return;
  40. }
  41. $this->remove_notification();
  42. $this->remove_notification_option();
  43. wp_redirect( admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER ) );
  44. exit;
  45. }
  46. /**
  47. * Registers the page for the wizard.
  48. */
  49. public function add_wizard_page() {
  50. add_dashboard_page( '', '', 'wpseo_manage_options', self::PAGE_IDENTIFIER, '' );
  51. }
  52. /**
  53. * Renders the wizard page and exits to prevent the WordPress UI from loading.
  54. */
  55. public function render_wizard_page() {
  56. $this->show_wizard();
  57. exit;
  58. }
  59. /**
  60. * Enqueues the assets needed for the wizard.
  61. */
  62. public function enqueue_assets() {
  63. wp_enqueue_media();
  64. if ( ! wp_script_is( 'wp-element', 'registered' ) && function_exists( 'gutenberg_register_scripts_and_styles' ) ) {
  65. gutenberg_register_scripts_and_styles();
  66. }
  67. /*
  68. * Print the `forms.css` WP stylesheet before any Yoast style, this way
  69. * it's easier to override selectors with the same specificity later.
  70. */
  71. wp_enqueue_style( 'forms' );
  72. $asset_manager = new WPSEO_Admin_Asset_Manager();
  73. $asset_manager->register_wp_assets();
  74. $asset_manager->register_assets();
  75. $asset_manager->enqueue_script( 'configuration-wizard' );
  76. $asset_manager->enqueue_style( 'yoast-components' );
  77. $config = $this->get_config();
  78. wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard', 'yoastWizardConfig', $config );
  79. $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
  80. $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard' );
  81. }
  82. /**
  83. * Setup Wizard Header.
  84. */
  85. public function show_wizard() {
  86. $this->enqueue_assets();
  87. $dashboard_url = admin_url( '/admin.php?page=wpseo_dashboard' );
  88. $wizard_title = sprintf(
  89. /* translators: %s expands to Yoast SEO. */
  90. __( '%s &rsaquo; Configuration Wizard', 'wordpress-seo' ),
  91. 'Yoast SEO'
  92. );
  93. ?>
  94. <!DOCTYPE html>
  95. <!--[if IE 9]>
  96. <html class="ie9" <?php language_attributes(); ?> >
  97. <![endif]-->
  98. <!--[if !(IE 9) ]><!-->
  99. <html <?php language_attributes(); ?>>
  100. <!--<![endif]-->
  101. <head>
  102. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  103. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  104. <title><?php echo esc_html( $wizard_title ); ?></title>
  105. <?php
  106. wp_print_head_scripts();
  107. wp_print_styles( 'yoast-seo-yoast-components' );
  108. /**
  109. * Is called before the closing </head> tag in the Yoast Configuration wizard.
  110. *
  111. * Allows users to add their own scripts or styles.
  112. *
  113. * @since 4.0
  114. */
  115. do_action( 'wpseo_configuration_wizard_head' );
  116. ?>
  117. </head>
  118. <body class="wp-admin wp-core-ui">
  119. <div id="wizard"></div>
  120. <div role="contentinfo" class="yoast-wizard-return-link-container">
  121. <a class="button yoast-wizard-return-link" href="<?php echo esc_url( $dashboard_url ); ?>">
  122. <span aria-hidden="true" class="dashicons dashicons-no"></span>
  123. <?php
  124. esc_html_e( 'Close the Wizard', 'wordpress-seo' );
  125. ?>
  126. </a>
  127. </div>
  128. <?php
  129. wp_print_media_templates();
  130. wp_print_footer_scripts();
  131. /**
  132. * Is called before the closing </body> tag in the Yoast Configuration wizard.
  133. *
  134. * Allows users to add their own scripts.
  135. *
  136. * @since 4.0
  137. */
  138. do_action( 'wpseo_configuration_wizard_footer' );
  139. wp_print_scripts( 'yoast-seo-configuration-wizard' );
  140. ?>
  141. </body>
  142. </html>
  143. <?php
  144. }
  145. /**
  146. * Get the API config for the wizard.
  147. *
  148. * @return array The API endpoint config.
  149. */
  150. public function get_config() {
  151. $config = [
  152. 'namespace' => WPSEO_Configuration_Endpoint::REST_NAMESPACE,
  153. 'endpoint_retrieve' => WPSEO_Configuration_Endpoint::ENDPOINT_RETRIEVE,
  154. 'endpoint_store' => WPSEO_Configuration_Endpoint::ENDPOINT_STORE,
  155. 'nonce' => wp_create_nonce( 'wp_rest' ),
  156. 'root' => esc_url_raw( rest_url() ),
  157. 'ajaxurl' => admin_url( 'admin-ajax.php' ),
  158. 'finishUrl' => admin_url( 'admin.php?page=wpseo_dashboard&configuration=finished' ),
  159. ];
  160. return $config;
  161. }
  162. /**
  163. * Checks if the current page is the configuration page.
  164. *
  165. * @return bool
  166. */
  167. protected function is_config_page() {
  168. return ( filter_input( INPUT_GET, 'page' ) === self::PAGE_IDENTIFIER );
  169. }
  170. /**
  171. * Adds a notification to the notification center.
  172. */
  173. private function add_notification() {
  174. $notification_center = Yoast_Notification_Center::get();
  175. $notification_center->add_notification( self::get_notification() );
  176. }
  177. /**
  178. * Removes the notification from the notification center.
  179. */
  180. private function remove_notification() {
  181. $notification_center = Yoast_Notification_Center::get();
  182. $notification_center->remove_notification( self::get_notification() );
  183. }
  184. /**
  185. * Gets the notification.
  186. *
  187. * @return Yoast_Notification
  188. */
  189. private static function get_notification() {
  190. $message = __( 'The configuration wizard helps you to easily configure your site to have the optimal SEO settings.', 'wordpress-seo' );
  191. $message .= '<br/>';
  192. $message .= sprintf(
  193. /* 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 */
  194. __( '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' ),
  195. 'Yoast SEO',
  196. '<a href="' . admin_url( '?page=' . self::PAGE_IDENTIFIER ) . '">',
  197. '</a>'
  198. );
  199. $notification = new Yoast_Notification(
  200. $message,
  201. [
  202. 'type' => Yoast_Notification::WARNING,
  203. 'id' => 'wpseo-dismiss-onboarding-notice',
  204. 'capabilities' => 'wpseo_manage_options',
  205. 'priority' => 0.8,
  206. ]
  207. );
  208. return $notification;
  209. }
  210. /**
  211. * When the notice should be shown.
  212. *
  213. * @return bool
  214. */
  215. private function should_add_notification() {
  216. return ( WPSEO_Options::get( 'show_onboarding_notice' ) === true );
  217. }
  218. /**
  219. * Remove the options that triggers the notice for the configuration wizard.
  220. */
  221. private function remove_notification_option() {
  222. WPSEO_Options::set( 'show_onboarding_notice', false );
  223. }
  224. }