WPSEO_Admin

Class that holds most of the admin functionality for Yoast SEO.

Defined (1)

The class is defined in the following location(s).

/admin/class-admin.php  
  1. class WPSEO_Admin { 
  2.  
  3. /** The page identifier used in WordPress to register the admin page !DO NOT CHANGE THIS! */ 
  4. const PAGE_IDENTIFIER = 'wpseo_dashboard'; 
  5.  
  6. /** 
  7. * @var array 
  8. */ 
  9. private $options; 
  10.  
  11. /** 
  12. * Array of classes that add admin functionality 
  13. * @var array 
  14. */ 
  15. protected $admin_features; 
  16.  
  17. /** 
  18. * Class constructor 
  19. */ 
  20. function __construct() { 
  21. global $pagenow; 
  22.  
  23. $this->options = WPSEO_Options::get_options( array( 'wpseo', 'wpseo_permalinks' ) ); 
  24.  
  25. if ( is_multisite() ) { 
  26. WPSEO_Options::maybe_set_multisite_defaults( false ); 
  27.  
  28. if ( $this->options['stripcategorybase'] === true ) { 
  29. add_action( 'created_category', array( $this, 'schedule_rewrite_flush' ) ); 
  30. add_action( 'edited_category', array( $this, 'schedule_rewrite_flush' ) ); 
  31. add_action( 'delete_category', array( $this, 'schedule_rewrite_flush' ) ); 
  32.  
  33. $this->admin_features = array( 
  34. // Google Search Console. 
  35. 'google_search_console' => new WPSEO_GSC(),  
  36. 'dashboard_widget' => new Yoast_Dashboard_Widget(),  
  37. ); 
  38.  
  39. if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) { 
  40. $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin(); 
  41.  
  42. if ( filter_input( INPUT_GET, 'page' ) === 'wpseo_tools' && filter_input( INPUT_GET, 'tool' ) === null ) { 
  43. new WPSEO_Recalculate_Scores(); 
  44.  
  45. // Needs the lower than default priority so other plugins can hook underneath it without issue. 
  46. add_action( 'admin_menu', array( $this, 'register_settings_page' ), 5 ); 
  47. add_action( 'network_admin_menu', array( $this, 'register_network_settings_page' ) ); 
  48.  
  49. add_filter( 'plugin_action_links_' . WPSEO_BASENAME, array( $this, 'add_action_link' ), 10, 2 ); 
  50.  
  51. add_action( 'admin_enqueue_scripts', array( $this, 'config_page_scripts' ) ); 
  52. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_global_style' ) ); 
  53.  
  54. if ( $this->options['cleanslugs'] === true ) { 
  55. add_filter( 'name_save_pre', array( $this, 'remove_stopwords_from_slug' ), 0 ); 
  56.  
  57. add_filter( 'user_contactmethods', array( $this, 'update_contactmethods' ), 10, 1 ); 
  58.  
  59. add_action( 'after_switch_theme', array( $this, 'switch_theme' ) ); 
  60. add_action( 'switch_theme', array( $this, 'switch_theme' ) ); 
  61.  
  62. add_filter( 'set-screen-option', array( $this, 'save_bulk_edit_options' ), 10, 3 ); 
  63.  
  64. add_action( 'admin_init', array( 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ), 10, 1 ); 
  65. add_action( 'admin_init', array( $this, 'import_plugin_hooks' ) ); 
  66.  
  67. add_filter( 'wpseo_submenu_pages', array( $this, 'filter_settings_pages' ) ); 
  68.  
  69. WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' ); 
  70.  
  71. if ( WPSEO_Utils::is_yoast_seo_page() ) { 
  72. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); 
  73.  
  74. if ( WPSEO_Utils::is_api_available() ) { 
  75. $configuration = new WPSEO_Configuration_Page; 
  76. $configuration->catch_configuration_request(); 
  77.  
  78. $this->set_upsell_notice(); 
  79.  
  80. $this->check_php_version(); 
  81. $this->initialize_cornerstone_content(); 
  82.  
  83. /** 
  84. * Setting the hooks for importing data from other plugins 
  85. */ 
  86. public function import_plugin_hooks() { 
  87. if ( current_user_can( $this->get_manage_options_cap() ) ) { 
  88. $plugin_imports = array( 
  89. 'wpSEO' => new WPSEO_Import_WPSEO_Hooks(),  
  90. 'aioseo' => new WPSEO_Import_AIOSEO_Hooks(),  
  91. ); 
  92.  
  93. /** 
  94. * Schedules a rewrite flush to happen at shutdown 
  95. */ 
  96. function schedule_rewrite_flush() { 
  97. add_action( 'shutdown', 'flush_rewrite_rules' ); 
  98.  
  99. /** 
  100. * Returns all the classes for the admin features 
  101. * @return array 
  102. */ 
  103. public function get_admin_features() { 
  104. return $this->admin_features; 
  105.  
  106. /** 
  107. * Register the menu item and its sub menu's. 
  108. * @global array $submenu used to change the label on the first item. 
  109. */ 
  110. function register_settings_page() { 
  111. if ( WPSEO_Utils::grant_access() !== true ) { 
  112. return; 
  113.  
  114. global $admin_page_hooks; 
  115.  
  116. // Base 64 encoded SVG image. 
  117. $icon_svg = WPSEO_Utils::get_icon_svg(); 
  118.  
  119. $manage_options_cap = $this->get_manage_options_cap(); 
  120.  
  121. $notification_center = Yoast_Notification_Center::get(); 
  122. $notification_count = $notification_center->get_notification_count(); 
  123.  
  124. // Add main page. 
  125. /** translators: %s: number of notifications */ 
  126. $counter_screen_reader_text = sprintf( _n( '%s notification', '%s notifications', $notification_count, 'wordpress-seo' ), number_format_i18n( $notification_count ) ); 
  127. $counter = sprintf( '<span class="update-plugins count-%1$d"><span class="plugin-count" aria-hidden="true">%1$d</span><span class="screen-reader-text">%2$s</span></span>', $notification_count, $counter_screen_reader_text ); 
  128.  
  129. $admin_page = add_menu_page( 'Yoast SEO: ' . __( 'Dashboard', 'wordpress-seo' ), __( 'SEO', 'wordpress-seo' ) . ' ' . $counter, $manage_options_cap, self::PAGE_IDENTIFIER, array( 
  130. $this,  
  131. 'load_page',  
  132. ), $icon_svg, '99.31337' ); 
  133.  
  134. $admin_page_hooks[ self::PAGE_IDENTIFIER ] = 'seo'; // Wipe notification bits from hooks. R. 
  135.  
  136. $license_page_title = defined( 'WPSEO_PREMIUM_PLUGIN_FILE' ) ? __( 'Premium', 'wordpress-seo' ) : __( 'Go Premium', 'wordpress-seo' ) . ' ' . $this->get_premium_indicator(); 
  137.  
  138. // Sub menu pages. 
  139. $submenu_pages = array( 
  140. array( 
  141. self::PAGE_IDENTIFIER,  
  142. '',  
  143. __( 'General', 'wordpress-seo' ),  
  144. $manage_options_cap,  
  145. self::PAGE_IDENTIFIER,  
  146. array( $this, 'load_page' ),  
  147. null,  
  148. ),  
  149. array( 
  150. self::PAGE_IDENTIFIER,  
  151. '',  
  152. __( 'Titles & Metas', 'wordpress-seo' ),  
  153. $manage_options_cap,  
  154. 'wpseo_titles',  
  155. array( $this, 'load_page' ),  
  156. ),  
  157. array( 
  158. self::PAGE_IDENTIFIER,  
  159. '',  
  160. __( 'Social', 'wordpress-seo' ),  
  161. $manage_options_cap,  
  162. 'wpseo_social',  
  163. array( $this, 'load_page' ),  
  164. null,  
  165. ),  
  166. array( 
  167. self::PAGE_IDENTIFIER,  
  168. '',  
  169. __( 'XML Sitemaps', 'wordpress-seo' ),  
  170. $manage_options_cap,  
  171. 'wpseo_xml',  
  172. array( $this, 'load_page' ),  
  173. null,  
  174. ),  
  175. array( 
  176. self::PAGE_IDENTIFIER,  
  177. '',  
  178. __( 'Advanced', 'wordpress-seo' ),  
  179. $manage_options_cap,  
  180. 'wpseo_advanced',  
  181. array( $this, 'load_page' ),  
  182. null,  
  183. ),  
  184. array( 
  185. self::PAGE_IDENTIFIER,  
  186. '',  
  187. __( 'Tools', 'wordpress-seo' ),  
  188. $manage_options_cap,  
  189. 'wpseo_tools',  
  190. array( $this, 'load_page' ),  
  191. null,  
  192. ),  
  193. array( 
  194. self::PAGE_IDENTIFIER,  
  195. '',  
  196. __( 'Search Console', 'wordpress-seo' ),  
  197. $manage_options_cap,  
  198. 'wpseo_search_console',  
  199. array( $this->admin_features['google_search_console'], 'display' ),  
  200. array( array( $this->admin_features['google_search_console'], 'set_help' ) ),  
  201. ),  
  202. array( 
  203. self::PAGE_IDENTIFIER,  
  204. '',  
  205. $license_page_title,  
  206. $manage_options_cap,  
  207. 'wpseo_licenses',  
  208. array( $this, 'load_page' ),  
  209. null,  
  210. ),  
  211. ); 
  212.  
  213. // Allow submenu pages manipulation. 
  214. $submenu_pages = apply_filters( 'wpseo_submenu_pages', $submenu_pages ); 
  215.  
  216. // Loop through submenu pages and add them. 
  217. if ( count( $submenu_pages ) ) { 
  218. foreach ( $submenu_pages as $submenu_page ) { 
  219.  
  220. $page_title = $submenu_page[2] . ' - Yoast SEO'; 
  221.  
  222. // We cannot use $submenu_page[1] because add-ons define that, so hard-code this value. 
  223. if ( 'wpseo_licenses' === $submenu_page[4] ) { 
  224. $page_title = __( 'Premium', 'wordpress-seo' ) . ' - Yoast SEO'; 
  225.  
  226. // Add submenu page. 
  227. $admin_page = add_submenu_page( $submenu_page[0], $page_title, $submenu_page[2], $submenu_page[3], $submenu_page[4], $submenu_page[5] ); 
  228.  
  229. // Check if we need to hook. 
  230. if ( isset( $submenu_page[6] ) && ( is_array( $submenu_page[6] ) && $submenu_page[6] !== array() ) ) { 
  231. foreach ( $submenu_page[6] as $submenu_page_action ) { 
  232. add_action( 'load-' . $admin_page, $submenu_page_action ); 
  233.  
  234. global $submenu; 
  235. if ( isset( $submenu[ self::PAGE_IDENTIFIER ] ) && current_user_can( $manage_options_cap ) ) { 
  236. $submenu[ self::PAGE_IDENTIFIER ][0][0] = __( 'Dashboard', 'wordpress-seo' ); 
  237.  
  238. /** 
  239. * Register assets needed on admin pages 
  240. */ 
  241. public function enqueue_assets() { 
  242. $asset_manager = new WPSEO_Admin_Asset_Manager(); 
  243. $asset_manager->enqueue_style( 'help-center' ); 
  244.  
  245. if ( 'wpseo_licenses' === filter_input( INPUT_GET, 'page' ) ) { 
  246. $asset_manager->enqueue_style( 'extensions' ); 
  247.  
  248. /** 
  249. * Returns the manage_options cap 
  250. * @return mixed|void 
  251. */ 
  252. private function get_manage_options_cap() { 
  253. /** 
  254. * Filter: 'wpseo_manage_options_capability' - Allow changing the capability users need to view the settings pages 
  255. * @api string unsigned The capability 
  256. */ 
  257. $manage_options_cap = apply_filters( 'wpseo_manage_options_capability', 'manage_options' ); 
  258.  
  259. return $manage_options_cap; 
  260.  
  261. /** 
  262. * Adds contextual help to the titles & metas page. 
  263. */ 
  264. function title_metas_help_tab() { 
  265. $screen = get_current_screen(); 
  266.  
  267. $screen->set_help_sidebar( ' 
  268. <p><strong>' . __( 'For more information:', 'wordpress-seo' ) . '</strong></p> 
  269. <p><a target="_blank" href="https://yoast.com/wordpress-seo/#titles">' . __( 'Title optimization', 'wordpress-seo' ) . '</a></p> 
  270. <p><a target="_blank" href="https://yoast.com/google-page-title/">' . __( 'Why Google won\'t display the right page title', 'wordpress-seo' ) . '</a></p>' 
  271. ); 
  272.  
  273. $screen->add_help_tab( 
  274. array( 
  275. 'id' => 'basic-help',  
  276. 'title' => __( 'Template explanation', 'wordpress-seo' ),  
  277. 'content' => "\n\t\t<h2>" . __( 'Template explanation', 'wordpress-seo' ) . "</h2>\n\t\t" . '<p>' . 
  278. sprintf( 
  279. /** translators: %1$s expands to Yoast SEO. */ 
  280. __( 'The title & metas settings for %1$s are made up of variables that are replaced by specific values from the page when the page is displayed. The tabs on the left explain the available variables.', 'wordpress-seo' ),  
  281. 'Yoast SEO' ) . 
  282. '</p><p>' . __( 'Note that not all variables can be used in every template.', 'wordpress-seo' ) . '</p>',  
  283. ); 
  284.  
  285. $screen->add_help_tab( 
  286. array( 
  287. 'id' => 'title-vars',  
  288. 'title' => __( 'Basic Variables', 'wordpress-seo' ),  
  289. 'content' => "\n\t\t<h2>" . __( 'Basic Variables', 'wordpress-seo' ) . "</h2>\n\t\t" . WPSEO_Replace_Vars::get_basic_help_texts(),  
  290. ); 
  291.  
  292. $screen->add_help_tab( 
  293. array( 
  294. 'id' => 'title-vars-advanced',  
  295. 'title' => __( 'Advanced Variables', 'wordpress-seo' ),  
  296. 'content' => "\n\t\t<h2>" . __( 'Advanced Variables', 'wordpress-seo' ) . "</h2>\n\t\t" . WPSEO_Replace_Vars::get_advanced_help_texts(),  
  297. ); 
  298.  
  299. /** 
  300. * Register the settings page for the Network settings. 
  301. */ 
  302. function register_network_settings_page() { 
  303. if ( WPSEO_Utils::grant_access() ) { 
  304. // Base 64 encoded SVG image. 
  305. $icon_svg = WPSEO_Utils::get_icon_svg(); 
  306.  
  307. add_menu_page( 'Yoast SEO: ' . __( 'MultiSite Settings', 'wordpress-seo' ), __( 'SEO', 'wordpress-seo' ), 'delete_users', self::PAGE_IDENTIFIER, array( 
  308. $this,  
  309. 'network_config_page',  
  310. ), $icon_svg ); 
  311.  
  312. if ( WPSEO_Utils::allow_system_file_edit() === true ) { 
  313. add_submenu_page( self::PAGE_IDENTIFIER, 'Yoast SEO: ' . __( 'Edit Files', 'wordpress-seo' ), __( 'Edit Files', 'wordpress-seo' ), 'delete_users', 'wpseo_files', array( 
  314. $this,  
  315. 'load_page',  
  316. ) ); 
  317.  
  318. // Add Extension submenu page. 
  319. add_submenu_page( self::PAGE_IDENTIFIER, 'Yoast SEO: ' . __( 'Extensions', 'wordpress-seo' ), __( 'Extensions', 'wordpress-seo' ), 'delete_users', 'wpseo_licenses', array( 
  320. $this,  
  321. 'load_page',  
  322. ) ); 
  323.  
  324.  
  325. /** 
  326. * Load the form for a WPSEO admin page 
  327. */ 
  328. function load_page() { 
  329. $page = filter_input( INPUT_GET, 'page' ); 
  330.  
  331. switch ( $page ) { 
  332. case 'wpseo_advanced': 
  333. require_once( WPSEO_PATH . 'admin/pages/advanced.php' ); 
  334. break; 
  335.  
  336. case 'wpseo_tools': 
  337. require_once( WPSEO_PATH . 'admin/pages/tools.php' ); 
  338. break; 
  339.  
  340. case 'wpseo_titles': 
  341. require_once( WPSEO_PATH . 'admin/pages/metas.php' ); 
  342. break; 
  343.  
  344. case 'wpseo_social': 
  345. require_once( WPSEO_PATH . 'admin/pages/social.php' ); 
  346. break; 
  347.  
  348. case 'wpseo_xml': 
  349. require_once( WPSEO_PATH . 'admin/pages/xml-sitemaps.php' ); 
  350. break; 
  351.  
  352. case 'wpseo_licenses': 
  353. require_once( WPSEO_PATH . 'admin/pages/licenses.php' ); 
  354. break; 
  355.  
  356. case 'wpseo_files': 
  357. require_once( WPSEO_PATH . 'admin/views/tool-file-editor.php' ); 
  358. break; 
  359.  
  360. case 'wpseo_tutorial_videos': 
  361. require_once( WPSEO_PATH . 'admin/pages/tutorial-videos.php' ); 
  362. break; 
  363.  
  364. case 'wpseo_configurator': 
  365. require_once( WPSEO_PATH . 'admin/config-ui/class-configuration-page.php' ); 
  366. break; 
  367.  
  368. case self::PAGE_IDENTIFIER: 
  369. default: 
  370. require_once( WPSEO_PATH . 'admin/pages/dashboard.php' ); 
  371. break; 
  372.  
  373. /** 
  374. * Loads the form for the network configuration page. 
  375. */ 
  376. function network_config_page() { 
  377. require_once( WPSEO_PATH . 'admin/pages/network.php' ); 
  378.  
  379.  
  380. /** 
  381. * Adds the ability to choose how many posts are displayed per page 
  382. * on the bulk edit pages. 
  383. */ 
  384. function bulk_edit_options() { 
  385. $option = 'per_page'; 
  386. $args = array( 
  387. 'label' => __( 'Posts', 'wordpress-seo' ),  
  388. 'default' => 10,  
  389. 'option' => 'wpseo_posts_per_page',  
  390. ); 
  391. add_screen_option( $option, $args ); 
  392.  
  393. /** 
  394. * Saves the posts per page limit for bulk edit pages. 
  395. * @param int $status Status value to pass through. 
  396. * @param string $option Option name. 
  397. * @param int $value Count value to check. 
  398. * @return int 
  399. */ 
  400. function save_bulk_edit_options( $status, $option, $value ) { 
  401. if ( 'wpseo_posts_per_page' === $option && ( $value > 0 && $value < 1000 ) ) { 
  402. return $value; 
  403.  
  404. return $status; 
  405.  
  406. /** 
  407. * Add a link to the settings page to the plugins list 
  408. * @staticvar string $this_plugin holds the directory & filename for the plugin 
  409. * @param array $links array of links for the plugins, adapted when the current plugin is found. 
  410. * @param string $file the filename for the current plugin, which the filter loops through. 
  411. * @return array $links 
  412. */ 
  413. function add_action_link( $links, $file ) { 
  414. if ( WPSEO_BASENAME === $file && WPSEO_Utils::grant_access() ) { 
  415. $settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=' . self::PAGE_IDENTIFIER ) ) . '">' . __( 'Settings', 'wordpress-seo' ) . '</a>'; 
  416. array_unshift( $links, $settings_link ); 
  417.  
  418. if ( class_exists( 'WPSEO_Product_Premium' ) ) { 
  419. $license_manager = new Yoast_Plugin_License_Manager( new WPSEO_Product_Premium() ); 
  420. if ( $license_manager->license_is_valid() ) { 
  421. return $links; 
  422.  
  423. // Add link to premium support landing page. 
  424. $premium_link = '<a href="https://yoast.com/wordpress/plugins/seo-premium/support/#utm_source=wordpress-seo-settings-link&utm_medium=textlink&utm_campaign=support-link">' . __( 'Premium Support', 'wordpress-seo' ) . '</a>'; 
  425. array_unshift( $links, $premium_link ); 
  426.  
  427. // Add link to docs. 
  428. $faq_link = '<a href="https://kb.yoast.com/kb/category/yoast-seo/#utm_source=wordpress-seo-faq-link&utm_medium=textlink&utm_campaign=faq-link">' . __( 'FAQ', 'wordpress-seo' ) . '</a>'; 
  429. array_unshift( $links, $faq_link ); 
  430.  
  431. return $links; 
  432.  
  433. /** 
  434. * Enqueues the (tiny) global JS needed for the plugin. 
  435. */ 
  436. function config_page_scripts() { 
  437. if ( WPSEO_Utils::grant_access() ) { 
  438. $asset_manager = new WPSEO_Admin_Asset_Manager(); 
  439. $asset_manager->enqueue_script( 'admin-global-script' ); 
  440.  
  441. wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-global-script', 'wpseoAdminGlobalL10n', $this->localize_admin_global_script() ); 
  442.  
  443. /** 
  444. * Enqueues the (tiny) global stylesheet needed for the plugin. 
  445. */ 
  446. public function enqueue_global_style() { 
  447. $asset_manager = new WPSEO_Admin_Asset_Manager(); 
  448. $asset_manager->enqueue_style( 'admin-global' ); 
  449.  
  450. /** 
  451. * Filter the $contactmethods array and add Facebook, Google+ and Twitter. 
  452. * These are used with the Facebook author, rel="author" and Twitter cards implementation. 
  453. * @param array $contactmethods currently set contactmethods. 
  454. * @return array $contactmethods with added contactmethods. 
  455. */ 
  456. public function update_contactmethods( $contactmethods ) { 
  457. // Add Google+. 
  458. $contactmethods['googleplus'] = __( 'Google+', 'wordpress-seo' ); 
  459. // Add Twitter. 
  460. $contactmethods['twitter'] = __( 'Twitter username (without @)', 'wordpress-seo' ); 
  461. // Add Facebook. 
  462. $contactmethods['facebook'] = __( 'Facebook profile URL', 'wordpress-seo' ); 
  463.  
  464. return $contactmethods; 
  465.  
  466. /** 
  467. * Cleans stopwords out of the slug, if the slug hasn't been set yet. 
  468. * @since 1.1.7 
  469. * @param string $slug if this isn't empty, the function will return an unaltered slug. 
  470. * @return string $clean_slug cleaned slug 
  471. */ 
  472. function remove_stopwords_from_slug( $slug ) { 
  473. return $this->filter_stopwords_from_slug( $slug, filter_input( INPUT_POST, 'post_title' ) ); 
  474.  
  475. /** 
  476. * Filter the stopwords from the slug 
  477. * @param string $slug The current slug, if not empty there will be done nothing. 
  478. * @param string $post_title The title which will be used in case of an empty slug. 
  479. * @return string 
  480. */ 
  481. public function filter_stopwords_from_slug( $slug, $post_title ) { 
  482. // Don't change an existing slug. 
  483. if ( isset( $slug ) && $slug !== '' ) { 
  484. return $slug; 
  485.  
  486. // When the post title is empty, just return the slug. 
  487. if ( empty( $post_title ) ) { 
  488. return $slug; 
  489.  
  490. // Don't change the slug if this is a multisite installation and the site has been switched. 
  491. if ( is_multisite() && ms_is_switched() ) { 
  492. return $slug; 
  493.  
  494. // Don't change slug if the post is a draft, this conflicts with polylang. 
  495. // Doesn't work with filter_input() since need current value, not originally submitted one. 
  496. if ( 'draft' === $_POST['post_status'] ) { 
  497. return $slug; 
  498.  
  499. // Lowercase the slug and strip slashes. 
  500. $new_slug = sanitize_title( stripslashes( $post_title ) ); 
  501.  
  502. $stop_words = new WPSEO_Admin_Stop_Words(); 
  503. return $stop_words->remove_in( $new_slug ); 
  504.  
  505. /** 
  506. * Filters all advanced settings pages from the given pages. 
  507. * @param array $pages The pages to filter. 
  508. * @return array 
  509. */ 
  510. public function filter_settings_pages( array $pages ) { 
  511. if ( wpseo_advanced_settings_enabled( $this->options ) ) { 
  512. return $pages; 
  513.  
  514. $pages_to_hide = WPSEO_Advanced_Settings::get_advanced_pages(); 
  515. $page = filter_input( INPUT_GET, 'page' ); 
  516.  
  517. if ( WPSEO_Advanced_Settings::is_advanced_settings_page( $page ) ) { 
  518. $pages_to_hide = $this->temporarily_enable_page( $pages_to_hide, $page ); 
  519.  
  520. foreach ( $pages as $page_key => $page ) { 
  521. $page_name = $page[4]; 
  522.  
  523. if ( in_array( $page_name, $pages_to_hide ) ) { 
  524. unset( $pages[ $page_key ] ); 
  525.  
  526. return $pages; 
  527.  
  528. /** 
  529. * Given a list of passed pages that will be disabled, removes the given page from the list so that it will no longer be disabled. 
  530. * @param array $pages The pages to search through. 
  531. * @param string $page The page to temporarily enable. 
  532. * @return array The remaining pages that need to be disabled. 
  533. */ 
  534. private function temporarily_enable_page( $pages, $page ) { 
  535. $enable_page = array_search( $page, $pages ); 
  536.  
  537. if ( $enable_page !== false ) { 
  538. unset( $pages[ $enable_page ] ); 
  539.  
  540. return $pages; 
  541.  
  542. /** 
  543. * Log the updated timestamp for user profiles when theme is changed 
  544. */ 
  545. function switch_theme() { 
  546. $users = get_users( array( 'who' => 'authors' ) ); 
  547. if ( is_array( $users ) && $users !== array() ) { 
  548. foreach ( $users as $user ) { 
  549. update_user_meta( $user->ID, '_yoast_wpseo_profile_updated', time() ); 
  550.  
  551. /** 
  552. * Localization for the dismiss urls. 
  553. * @return array 
  554. */ 
  555. private function localize_admin_global_script() { 
  556. return array( 
  557. 'dismiss_about_url' => $this->get_dismiss_url( 'wpseo-dismiss-about' ),  
  558. 'dismiss_tagline_url' => $this->get_dismiss_url( 'wpseo-dismiss-tagline-notice' ),  
  559. 'help_video_iframe_title' => __( 'Yoast SEO video tutorial', 'wordpress-seo' ),  
  560. 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ),  
  561. ); 
  562.  
  563. /** 
  564. * Extending the current page URL with two params to be able to ignore the notice. 
  565. * @param string $dismiss_param The param used to dismiss the notification. 
  566. * @return string 
  567. */ 
  568. private function get_dismiss_url( $dismiss_param ) { 
  569. $arr_params = array( 
  570. $dismiss_param => '1',  
  571. 'nonce' => wp_create_nonce( $dismiss_param ),  
  572. ); 
  573.  
  574. return esc_url( add_query_arg( $arr_params ) ); 
  575.  
  576. /** 
  577. * @return string 
  578. */ 
  579. private function get_premium_indicator() { 
  580. /** 
  581. * The class that will be applied to the premium indicator. 
  582. * @type array Classes that will be applied tot the premium indicator. 
  583. */ 
  584. $classes = apply_filters( 'wpseo_premium_indicator_classes', array( 
  585. 'wpseo-premium-indicator',  
  586. 'wpseo-premium-indicator--no',  
  587. 'wpseo-js-premium-indicator',  
  588. 'update-plugins',  
  589. ) ); 
  590.  
  591. /** 
  592. * The text to put inside the premium indicator. 
  593. * @type string The text to read to screen readers. 
  594. */ 
  595. $text = apply_filters( 'wpseo_premium_indicator_text', __( 'Disabled', 'wordpress-seo' ) ); 
  596.  
  597. $premium_indicator = sprintf( 
  598. "<span class='%s' aria-hidden='true'><svg width=\"20\" height=\"20\" viewBox=\"0 0 1792 1792\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"currentColor\" d=\"M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z\"/></svg></span><span class='screen-reader-text'>%s</span>",  
  599. esc_attr( implode( ' ', $classes ) ),  
  600. esc_html( $text ) 
  601. ); 
  602.  
  603. return $premium_indicator; 
  604.  
  605. /** 
  606. * Sets the upsell notice. 
  607. */ 
  608. protected function set_upsell_notice() { 
  609. $upsell = new WPSEO_Product_Upsell_Notice(); 
  610. $upsell->dismiss_notice_listener(); 
  611. $upsell->initialize(); 
  612.  
  613. /** 
  614. * Initializes Whip to show a notice for outdated PHP versions. 
  615. */ 
  616. protected function check_php_version() { 
  617. if ( ! current_user_can( 'manage_options' ) ) { 
  618. return; 
  619.  
  620. if ( ! $this->on_dashboard_page() ) { 
  621. return; 
  622.  
  623. whip_wp_check_versions( array( 
  624. 'php' => '>=5.3',  
  625. ) ); 
  626.  
  627. /** 
  628. * Whether we are on the admin dashboard page. 
  629. * @returns bool 
  630. */ 
  631. protected function on_dashboard_page() { 
  632. return 'index.php' === $GLOBALS['pagenow']; 
  633.  
  634. /** 
  635. * Loads the cornerstone filter 
  636. */ 
  637. protected function initialize_cornerstone_content() { 
  638. if ( ! $this->options['enable_cornerstone_content'] ) { 
  639. return false; 
  640.  
  641. $cornerstone = new WPSEO_Cornerstone(); 
  642. $cornerstone->register_hooks(); 
  643.  
  644. $cornerstone_filter = new WPSEO_Cornerstone_Filter(); 
  645. $cornerstone_filter->register_hooks(); 
  646.  
  647. /********************** DEPRECATED METHODS **********************/ 
  648.  
  649. // @codeCoverageIgnoreStart 
  650. /** 
  651. * Check whether the current user is allowed to access the configuration. 
  652. * @deprecated 1.5.0 
  653. * @deprecated use WPSEO_Utils::grant_access() 
  654. * @see WPSEO_Utils::grant_access() 
  655. * @return boolean 
  656. */ 
  657. function grant_access() { 
  658. _deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Utils::grant_access()' ); 
  659.  
  660. return WPSEO_Utils::grant_access(); 
  661.  
  662. /** 
  663. * Check whether the current user is allowed to access the configuration. 
  664. * @deprecated 1.5.0 
  665. * @deprecated use wpseo_do_upgrade() 
  666. * @see WPSEO_Upgrade 
  667. */ 
  668. function maybe_upgrade() { 
  669. _deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'wpseo_do_upgrade' ); 
  670. new WPSEO_Upgrade(); 
  671.  
  672. /** 
  673. * Clears the cache 
  674. * @deprecated 1.5.0 
  675. * @deprecated use WPSEO_Utils::clear_cache() 
  676. * @see WPSEO_Utils::clear_cache() 
  677. */ 
  678. function clear_cache() { 
  679. _deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Utils::clear_cache()' ); 
  680. WPSEO_Utils::clear_cache(); 
  681.  
  682. /** 
  683. * Clear rewrites 
  684. * @deprecated 1.5.0 
  685. * @deprecated use WPSEO_Utils::clear_rewrites() 
  686. * @see WPSEO_Utils::clear_rewrites() 
  687. */ 
  688. function clear_rewrites() { 
  689. _deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Utils::clear_rewrites()' ); 
  690. WPSEO_Utils::clear_rewrites(); 
  691.  
  692. /** 
  693. * Register all the options needed for the configuration pages. 
  694. * @deprecated 1.5.0 
  695. * @deprecated use WPSEO_Option::register_setting() on each individual option 
  696. * @see WPSEO_Option::register_setting() 
  697. */ 
  698. function options_init() { 
  699. _deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Option::register_setting()' ); 
  700.  
  701. /** 
  702. * Display an error message when the blog is set to private. 
  703. * @deprecated 3.3 
  704. */ 
  705. function blog_public_warning() { 
  706. _deprecated_function( __METHOD__, 'WPSEO 3.3.0' ); 
  707.  
  708. /** 
  709. * Display an error message when the theme contains a meta description tag. 
  710. * @since 1.4.14 
  711. * @deprecated 3.3 
  712. */ 
  713. function meta_description_warning() { 
  714. _deprecated_function( __FUNCTION__, 'WPSEO 3.3.0' ); 
  715.  
  716. /** 
  717. * Returns the stopwords for the current language 
  718. * @since 1.1.7 
  719. * @deprecated 3.1 Use WPSEO_Admin_Stop_Words::list_stop_words() instead. 
  720. * @return array $stopwords array of stop words to check and / or remove from slug 
  721. */ 
  722. function stopwords() { 
  723. _deprecated_function( __METHOD__, 'WPSEO 3.1', 'WPSEO_Admin_Stop_Words::list_stop_words' ); 
  724.  
  725. $stop_words = new WPSEO_Admin_Stop_Words(); 
  726. return $stop_words->list_stop_words(); 
  727.  
  728. /** 
  729. * Check whether the stopword appears in the string 
  730. * @deprecated 3.1 
  731. * @param string $haystack The string to be checked for the stopword. 
  732. * @param bool $checking_url Whether or not we're checking a URL. 
  733. * @return bool|mixed 
  734. */ 
  735. function stopwords_check( $haystack, $checking_url = false ) { 
  736. _deprecated_function( __METHOD__, 'WPSEO 3.1' ); 
  737.  
  738. $stop_words = $this->stopwords(); 
  739.  
  740. if ( is_array( $stop_words ) && $stop_words !== array() ) { 
  741. foreach ( $stop_words as $stop_word ) { 
  742. // If checking a URL remove the single quotes. 
  743. if ( $checking_url ) { 
  744. $stop_word = str_replace( "'", '', $stop_word ); 
  745.  
  746. // Check whether the stopword appears as a whole word. 
  747. // @todo [JRF => whomever] check whether the use of \b (=word boundary) would be more efficient ;-). 
  748. $res = preg_match( "`(^|[ \n\r\t\., '\(\)\"\+;!?:])" . preg_quote( $stop_word, '`' ) . "($|[ \n\r\t\., '\(\)\"\+;!?:])`iu", $haystack ); 
  749. if ( $res > 0 ) { 
  750. return $stop_word; 
  751.  
  752. return false; 
  753.  
  754. // @codeCoverageIgnoreEnd