PageRenderTime 25ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/blog/wp-content/plugins/wordpress-seo/admin/class-admin-init.php

https://gitlab.com/relacilia/cakra
PHP | 383 lines | 217 code | 52 blank | 114 comment | 32 complexity | fb13e3499d2e714c4192b57dfe9fd7bf MD5 | raw file
  1. <?php
  2. /**
  3. * @package WPSEO\Admin
  4. */
  5. /**
  6. * Performs the load on admin side.
  7. */
  8. class WPSEO_Admin_Init {
  9. /**
  10. * Holds the Yoast SEO Options
  11. *
  12. * @var array
  13. */
  14. private $options;
  15. /**
  16. * Holds the global `$pagenow` variable's value.
  17. *
  18. * @var string
  19. */
  20. private $pagenow;
  21. /**
  22. * Class constructor
  23. */
  24. public function __construct() {
  25. $this->options = WPSEO_Options::get_all();
  26. $GLOBALS['wpseo_admin'] = new WPSEO_Admin;
  27. $this->pagenow = $GLOBALS['pagenow'];
  28. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_dismissible' ) );
  29. add_action( 'admin_init', array( $this, 'after_update_notice' ), 15 );
  30. add_action( 'admin_init', array( $this, 'tagline_notice' ), 15 );
  31. add_action( 'admin_init', array( $this, 'ga_compatibility_notice' ), 15 );
  32. add_action( 'admin_init', array( $this, 'recalculate_notice' ), 15 );
  33. add_action( 'admin_init', array( $this, 'ignore_tour' ) );
  34. add_action( 'admin_init', array( $this, 'load_tour' ) );
  35. add_action( 'admin_init', array( $this, 'show_hook_deprecation_warnings' ) );
  36. $this->load_meta_boxes();
  37. $this->load_taxonomy_class();
  38. $this->load_admin_page_class();
  39. $this->load_admin_user_class();
  40. $this->load_xml_sitemaps_admin();
  41. }
  42. /**
  43. * For WP versions older than 4.2, this includes styles and a script to make notices dismissible.
  44. */
  45. public function enqueue_dismissible() {
  46. if ( version_compare( $GLOBALS['wp_version'], '4.2', '<' ) ) {
  47. wp_enqueue_style( 'wpseo-dismissible', plugins_url( 'css/wpseo-dismissible' . WPSEO_CSSJS_SUFFIX . '.css', WPSEO_FILE ), array(), WPSEO_VERSION );
  48. wp_enqueue_script( 'wpseo-dismissible', plugins_url( 'js/wp-seo-dismissible' . WPSEO_CSSJS_SUFFIX . '.js', WPSEO_FILE ), array( 'jquery' ), WPSEO_VERSION, true );
  49. }
  50. }
  51. /**
  52. * Redirect first time or just upgraded users to the about screen.
  53. */
  54. public function after_update_notice() {
  55. $can_access = is_multisite() ? WPSEO_Utils::grant_access() : current_user_can( 'manage_options' );
  56. if ( $can_access && $this->has_ignored_tour() && ! $this->seen_about() ) {
  57. if ( filter_input( INPUT_GET, 'intro' ) === '1' ) {
  58. update_user_meta( get_current_user_id(), 'wpseo_seen_about_version' , WPSEO_VERSION );
  59. return;
  60. }
  61. /* translators: %1$s expands to Yoast SEO, $2%s to the version number, %3$s and %4$s to anchor tags with link to intro page */
  62. $info_message = sprintf(
  63. __( '%1$s has been updated to version %2$s. %3$sClick here%4$s to find out what\'s new!', 'wordpress-seo' ),
  64. 'Yoast SEO',
  65. WPSEO_VERSION,
  66. '<a href="' . admin_url( 'admin.php?page=wpseo_dashboard&intro=1' ) . '">',
  67. '</a>'
  68. );
  69. $notification_options = array(
  70. 'type' => 'updated',
  71. 'id' => 'wpseo-dismiss-about',
  72. 'nonce' => wp_create_nonce( 'wpseo-dismiss-about' ),
  73. );
  74. Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $info_message, $notification_options ) );
  75. }
  76. }
  77. /**
  78. * Helper to verify if the current user has already seen the about page for the current version
  79. *
  80. * @return bool
  81. */
  82. private function seen_about() {
  83. return get_user_meta( get_current_user_id(), 'wpseo_seen_about_version', true ) === WPSEO_VERSION;
  84. }
  85. /**
  86. * Notify about the default tagline if the user hasn't changed it
  87. */
  88. public function tagline_notice() {
  89. if ( current_user_can( 'manage_options' ) && $this->has_default_tagline() && ! $this->seen_tagline_notice() ) {
  90. // Only add the notice on GET requests, not in the customizer, and not in "action" type submits to prevent faulty return url.
  91. if ( 'GET' !== filter_input( INPUT_SERVER, 'REQUEST_METHOD' ) || is_customize_preview() || null !== filter_input( INPUT_GET, 'action' ) ) {
  92. return;
  93. }
  94. $current_url = ( is_ssl() ? 'https://' : 'http://' );
  95. $current_url .= sanitize_text_field( $_SERVER['SERVER_NAME'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] );
  96. $customize_url = add_query_arg( array(
  97. 'url' => urlencode( $current_url ),
  98. ), wp_customize_url() );
  99. $info_message = sprintf(
  100. __( 'You still have the default WordPress tagline, even an empty one is probably better. %1$sYou can fix this in the customizer%2$s.', 'wordpress-seo' ),
  101. '<a href="' . esc_attr( $customize_url ) . '">',
  102. '</a>'
  103. );
  104. $notification_options = array(
  105. 'type' => 'error',
  106. 'id' => 'wpseo-dismiss-tagline-notice',
  107. 'nonce' => wp_create_nonce( 'wpseo-dismiss-tagline-notice' ),
  108. );
  109. Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $info_message, $notification_options ) );
  110. }
  111. }
  112. /**
  113. * Returns whether or not the site has the default tagline
  114. *
  115. * @return bool
  116. */
  117. public function has_default_tagline() {
  118. return __( 'Just another WordPress site' ) === get_bloginfo( 'description' );
  119. }
  120. /**
  121. * Returns whether or not the user has seen the tagline notice
  122. *
  123. * @return bool
  124. */
  125. public function seen_tagline_notice() {
  126. return 'seen' === get_user_meta( get_current_user_id(), 'wpseo_seen_tagline_notice', true );
  127. }
  128. /**
  129. * Shows a notice to the user if they have Google Analytics for WordPress 5.4.3 installed because it causes an error
  130. * on the google search console page.
  131. */
  132. public function ga_compatibility_notice() {
  133. if ( defined( 'GAWP_VERSION' ) && '5.4.3' === GAWP_VERSION ) {
  134. $info_message = sprintf(
  135. /* translators: %1$s expands to Yoast SEO, %2$s expands to 5.4.3, %3$s expands to Google Analytics by Yoast */
  136. __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ),
  137. 'Yoast SEO',
  138. '5.4.3',
  139. 'Google Analytics by Yoast'
  140. );
  141. $notification_options = array(
  142. 'type' => 'error',
  143. );
  144. Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $info_message, $notification_options ) );
  145. }
  146. }
  147. /**
  148. * Shows the notice for recalculating the post. the Notice will only be shown if the user hasn't dismissed it before.
  149. */
  150. public function recalculate_notice() {
  151. if ( filter_input( INPUT_GET, 'recalculate' ) === '1' ) {
  152. update_option( 'wpseo_dismiss_recalculate', '1' );
  153. return;
  154. }
  155. $can_access = is_multisite() ? WPSEO_Utils::grant_access() : current_user_can( 'manage_options' );
  156. if ( $can_access && ! $this->is_site_notice_dismissed( 'wpseo_dismiss_recalculate' ) ) {
  157. Yoast_Notification_Center::get()->add_notification(
  158. new Yoast_Notification(
  159. /* translators: 1: is a link to 'admin_url / admin.php?page=wpseo_tools&recalculate=1' 2: closing link tag */
  160. sprintf(
  161. __( 'We\'ve updated our SEO score algorithm. %1$sClick here to recalculate the SEO scores%2$s for all posts and pages.', 'wordpress-seo' ),
  162. '<a href="' . admin_url( 'admin.php?page=wpseo_tools&recalculate=1' ) . '">',
  163. '</a>'
  164. ),
  165. array(
  166. 'type' => 'updated yoast-dismissible',
  167. 'id' => 'wpseo-dismiss-recalculate',
  168. 'nonce' => wp_create_nonce( 'wpseo-dismiss-recalculate' ),
  169. )
  170. )
  171. );
  172. }
  173. }
  174. /**
  175. * Check if the user has dismissed the given notice (by $notice_name)
  176. *
  177. * @param string $notice_name The name of the notice that might be dismissed.
  178. *
  179. * @return bool
  180. */
  181. private function is_site_notice_dismissed( $notice_name ) {
  182. return '1' === get_option( $notice_name, true );
  183. }
  184. /**
  185. * Helper to verify if the user is currently visiting one of our admin pages.
  186. *
  187. * @return bool
  188. */
  189. private function on_wpseo_admin_page() {
  190. return 'admin.php' === $this->pagenow && strpos( filter_input( INPUT_GET, 'page' ), 'wpseo' ) === 0;
  191. }
  192. /**
  193. * Determine whether we should load the meta box class and if so, load it.
  194. */
  195. private function load_meta_boxes() {
  196. $is_editor = in_array( $this->pagenow, array( 'edit.php', 'post.php', 'post-new.php' ) );
  197. $is_inline_save = filter_input( INPUT_POST, 'action' ) === 'inline-save';
  198. /**
  199. * Filter: 'wpseo_always_register_metaboxes_on_admin' - Allow developers to change whether
  200. * the WPSEO metaboxes are only registered on the typical pages (lean loading) or always
  201. * registered when in admin.
  202. *
  203. * @api bool Whether to always register the metaboxes or not. Defaults to false.
  204. */
  205. if ( $is_editor || $is_inline_save || in_array( $this->pagenow, array(
  206. 'edit.php',
  207. 'post.php',
  208. 'post-new.php',
  209. ) ) || apply_filters( 'wpseo_always_register_metaboxes_on_admin', false )
  210. ) {
  211. $GLOBALS['wpseo_metabox'] = new WPSEO_Metabox;
  212. $GLOBALS['wpseo_meta_columns'] = new WPSEO_Meta_Columns();
  213. }
  214. }
  215. /**
  216. * Determine if we should load our taxonomy edit class and if so, load it.
  217. */
  218. private function load_taxonomy_class() {
  219. if ( 'edit-tags.php' === $this->pagenow ) {
  220. new WPSEO_Taxonomy;
  221. }
  222. }
  223. /**
  224. * Determine if we should load our admin pages class and if so, load it.
  225. *
  226. * Loads admin page class for all admin pages starting with `wpseo_`.
  227. */
  228. private function load_admin_user_class() {
  229. if ( in_array( $this->pagenow, array( 'user-edit.php', 'profile.php' ) ) && current_user_can( 'edit_users' ) ) {
  230. new WPSEO_Admin_User_Profile;
  231. }
  232. }
  233. /**
  234. * Determine if we should load our admin pages class and if so, load it.
  235. *
  236. * Loads admin page class for all admin pages starting with `wpseo_`.
  237. */
  238. private function load_admin_page_class() {
  239. if ( $this->on_wpseo_admin_page() ) {
  240. // For backwards compatabilty, this still needs a global, for now...
  241. $GLOBALS['wpseo_admin_pages'] = new WPSEO_Admin_Pages;
  242. $this->register_i18n_promo_class();
  243. }
  244. }
  245. /**
  246. * Register the promotion class for our GlotPress instance
  247. *
  248. * @link https://github.com/Yoast/i18n-module
  249. */
  250. private function register_i18n_promo_class() {
  251. new yoast_i18n(
  252. array(
  253. 'textdomain' => 'wordpress-seo',
  254. 'project_slug' => 'wordpress-seo',
  255. 'plugin_name' => 'Yoast SEO',
  256. 'hook' => 'wpseo_admin_footer',
  257. 'glotpress_url' => 'https://translate.yoast.com/',
  258. 'glotpress_name' => 'Yoast Translate',
  259. 'glotpress_logo' => 'https://cdn.yoast.com/wp-content/uploads/i18n-images/Yoast_Translate.svg',
  260. 'register_url' => 'https://translate.yoast.com/projects#utm_source=plugin&utm_medium=promo-box&utm_campaign=wpseo-i18n-promo',
  261. )
  262. );
  263. }
  264. /**
  265. * See if we should start our tour.
  266. */
  267. public function load_tour() {
  268. $restart_tour = filter_input( INPUT_GET, 'wpseo_restart_tour' );
  269. if ( $restart_tour ) {
  270. delete_user_meta( get_current_user_id(), 'wpseo_ignore_tour' );
  271. }
  272. if ( ! $this->has_ignored_tour() ) {
  273. add_action( 'admin_enqueue_scripts', array( 'WPSEO_Pointers', 'get_instance' ) );
  274. }
  275. }
  276. /**
  277. * See if we should start our XML Sitemaps Admin class
  278. */
  279. private function load_xml_sitemaps_admin() {
  280. if ( $this->options['enablexmlsitemap'] === true ) {
  281. new WPSEO_Sitemaps_Admin;
  282. }
  283. }
  284. /**
  285. * Returns the value of the ignore tour.
  286. *
  287. * @return bool
  288. */
  289. private function has_ignored_tour() {
  290. $user_meta = get_user_meta( get_current_user_id(), 'wpseo_ignore_tour' );
  291. return ! empty( $user_meta );
  292. }
  293. /**
  294. * Listener for the ignore tour GET value. If this one is set, just set the user meta to true.
  295. */
  296. public function ignore_tour() {
  297. if ( filter_input( INPUT_GET, 'wpseo_ignore_tour' ) && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'wpseo-ignore-tour' ) ) {
  298. update_user_meta( get_current_user_id(), 'wpseo_ignore_tour', true );
  299. }
  300. }
  301. /**
  302. * Shows deprecation warnings to the user if a plugin has registered a filter we have deprecated.
  303. */
  304. public function show_hook_deprecation_warnings() {
  305. global $wp_filter;
  306. if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
  307. return false;
  308. }
  309. // WordPress hooks that have been deprecated in Yoast SEO 3.0.
  310. $deprecated_30 = array(
  311. 'wpseo_pre_analysis_post_content',
  312. 'wpseo_metadesc_length',
  313. 'wpseo_metadesc_length_reason',
  314. 'wpseo_body_length_score',
  315. 'wpseo_linkdex_results',
  316. 'wpseo_snippet',
  317. );
  318. $deprecated_notices = array_intersect(
  319. $deprecated_30,
  320. array_keys( $wp_filter )
  321. );
  322. foreach ( $deprecated_notices as $deprecated_filter ) {
  323. _deprecated_function(
  324. /* %s expands to the actual filter/action that has been used. */
  325. sprintf( __( '%s filter/action', 'wordpress-seo' ), $deprecated_filter ),
  326. 'WPSEO 3.0',
  327. 'javascript'
  328. );
  329. }
  330. }
  331. }