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