2021-09-21 15:01:08 +02:00
< ? php
/**
* WPSEO plugin file .
*
* @ package WPSEO\Admin
*/
/**
* Class that holds most of the admin functionality for Yoast SEO .
*/
class WPSEO_Admin {
2021-09-21 15:05:30 +02:00
/**
* The page identifier used in WordPress to register the admin page .
*
* ! DO NOT CHANGE THIS !
*
* @ var string
*/
2021-09-21 15:01:08 +02:00
const PAGE_IDENTIFIER = 'wpseo_dashboard' ;
/**
* Array of classes that add admin functionality .
*
* @ var array
*/
protected $admin_features ;
/**
* Class constructor .
*/
public function __construct () {
2021-09-21 15:05:30 +02:00
$integrations = [];
2021-09-21 15:01:08 +02:00
global $pagenow ;
$wpseo_menu = new WPSEO_Menu ();
$wpseo_menu -> register_hooks ();
if ( is_multisite () ) {
WPSEO_Options :: maybe_set_multisite_defaults ( false );
}
if ( WPSEO_Options :: get ( 'stripcategorybase' ) === true ) {
2021-09-21 15:05:30 +02:00
add_action ( 'created_category' , [ $this , 'schedule_rewrite_flush' ] );
add_action ( 'edited_category' , [ $this , 'schedule_rewrite_flush' ] );
add_action ( 'delete_category' , [ $this , 'schedule_rewrite_flush' ] );
2021-09-21 15:01:08 +02:00
}
2021-09-21 15:05:30 +02:00
if ( WPSEO_Options :: get ( 'disable-attachment' ) === true ) {
add_filter ( 'wpseo_accessible_post_types' , [ 'WPSEO_Post_Type' , 'filter_attachment_post_type' ] );
2021-09-21 15:01:08 +02:00
}
2021-09-21 15:05:30 +02:00
add_filter ( 'plugin_action_links_' . WPSEO_BASENAME , [ $this , 'add_action_link' ], 10 , 2 );
add_filter ( 'network_admin_plugin_action_links_' . WPSEO_BASENAME , [ $this , 'add_action_link' ], 10 , 2 );
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
add_action ( 'admin_enqueue_scripts' , [ $this , 'config_page_scripts' ] );
add_action ( 'admin_enqueue_scripts' , [ $this , 'enqueue_global_style' ] );
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
add_filter ( 'user_contactmethods' , [ $this , 'update_contactmethods' ], 10 , 1 );
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
add_action ( 'after_switch_theme' , [ $this , 'switch_theme' ] );
add_action ( 'switch_theme' , [ $this , 'switch_theme' ] );
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
add_filter ( 'set-screen-option' , [ $this , 'save_bulk_edit_options' ], 10 , 3 );
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
add_action ( 'admin_init' , [ 'WPSEO_Plugin_Conflict' , 'hook_check_for_plugin_conflicts' ], 10 , 1 );
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
add_action ( 'admin_init' , [ $this , 'map_manage_options_cap' ] );
2021-09-21 15:01:08 +02:00
WPSEO_Sitemaps_Cache :: register_clear_on_option_update ( 'wpseo' );
WPSEO_Sitemaps_Cache :: register_clear_on_option_update ( 'home' );
2021-09-21 15:05:30 +02:00
if ( YoastSEO () -> helpers -> current_page -> is_yoast_seo_page () ) {
add_action ( 'admin_enqueue_scripts' , [ $this , 'enqueue_assets' ] );
2021-09-21 15:01:08 +02:00
}
if ( WPSEO_Utils :: is_api_available () ) {
$configuration = new WPSEO_Configuration_Page ();
$configuration -> set_hooks ();
$configuration -> catch_configuration_request ();
}
$this -> set_upsell_notice ();
$this -> initialize_cornerstone_content ();
2021-09-21 15:05:30 +02:00
if ( WPSEO_Utils :: is_plugin_network_active () ) {
$integrations [] = new Yoast_Network_Admin ();
}
$this -> admin_features = [
'dashboard_widget' => new Yoast_Dashboard_Widget (),
];
if ( WPSEO_Metabox :: is_post_overview ( $pagenow ) || WPSEO_Metabox :: is_post_edit ( $pagenow ) ) {
$this -> admin_features [ 'primary_category' ] = new WPSEO_Primary_Term_Admin ();
}
2021-09-21 15:01:08 +02:00
$integrations [] = new WPSEO_Yoast_Columns ();
$integrations [] = new WPSEO_Statistic_Integration ();
$integrations [] = new WPSEO_Capability_Manager_Integration ( WPSEO_Capability_Manager_Factory :: get () );
2021-09-21 15:05:30 +02:00
$integrations [] = new WPSEO_Admin_Gutenberg_Compatibility_Notification ();
$integrations [] = new WPSEO_Expose_Shortlinks ();
$integrations [] = new WPSEO_MyYoast_Proxy ();
$integrations [] = new WPSEO_Schema_Person_Upgrade_Notification ();
$integrations [] = new WPSEO_Tracking ( 'https://tracking.yoast.com/stats' , ( WEEK_IN_SECONDS * 2 ) );
$integrations [] = new WPSEO_Admin_Settings_Changed_Listener ();
$integrations = array_merge (
$integrations ,
$this -> get_admin_features (),
$this -> initialize_cornerstone_content ()
);
2021-09-21 15:01:08 +02:00
foreach ( $integrations as $integration ) {
$integration -> register_hooks ();
}
}
/**
* Schedules a rewrite flush to happen at shutdown .
*/
public function schedule_rewrite_flush () {
2021-09-21 15:05:30 +02:00
// Bail if this is a multisite installation and the site has been switched.
if ( is_multisite () && ms_is_switched () ) {
return ;
}
2021-09-21 15:01:08 +02:00
add_action ( 'shutdown' , 'flush_rewrite_rules' );
}
/**
* Returns all the classes for the admin features .
*
* @ return array
*/
public function get_admin_features () {
return $this -> admin_features ;
}
/**
* Register assets needed on admin pages .
*/
public function enqueue_assets () {
2021-09-21 15:05:30 +02:00
if ( filter_input ( INPUT_GET , 'page' ) === 'wpseo_licenses' ) {
2021-09-21 15:01:08 +02:00
$asset_manager = new WPSEO_Admin_Asset_Manager ();
$asset_manager -> enqueue_style ( 'extensions' );
}
}
/**
* Returns the manage_options capability .
*
* @ return string The capability to use .
*/
public function get_manage_options_cap () {
/**
* Filter : 'wpseo_manage_options_capability' - Allow changing the capability users need to view the settings pages .
*
* @ api string unsigned The capability .
*/
return apply_filters ( 'wpseo_manage_options_capability' , 'wpseo_manage_options' );
}
/**
* Maps the manage_options cap on saving an options page to wpseo_manage_options .
*/
public function map_manage_options_cap () {
2021-09-21 15:05:30 +02:00
// phpcs:ignore WordPress.Security -- The variable is only used in strpos and thus safe to not unslash or sanitize.
$option_page = ! empty ( $_POST [ 'option_page' ] ) ? $_POST [ 'option_page' ] : '' ;
2021-09-21 15:01:08 +02:00
if ( strpos ( $option_page , 'yoast_wpseo' ) === 0 ) {
2021-09-21 15:05:30 +02:00
add_filter ( 'option_page_capability_' . $option_page , [ $this , 'get_manage_options_cap' ] );
2021-09-21 15:01:08 +02:00
}
}
/**
* Adds the ability to choose how many posts are displayed per page
* on the bulk edit pages .
*/
public function bulk_edit_options () {
$option = 'per_page' ;
2021-09-21 15:05:30 +02:00
$args = [
2021-09-21 15:01:08 +02:00
'label' => __ ( 'Posts' , 'wordpress-seo' ),
'default' => 10 ,
'option' => 'wpseo_posts_per_page' ,
2021-09-21 15:05:30 +02:00
];
2021-09-21 15:01:08 +02:00
add_screen_option ( $option , $args );
}
/**
* Saves the posts per page limit for bulk edit pages .
*
* @ param int $status Status value to pass through .
* @ param string $option Option name .
* @ param int $value Count value to check .
*
* @ return int
*/
public function save_bulk_edit_options ( $status , $option , $value ) {
2021-09-21 15:05:30 +02:00
if ( $option && ( $value > 0 && $value < 1000 ) === 'wpseo_posts_per_page' ) {
2021-09-21 15:01:08 +02:00
return $value ;
}
return $status ;
}
/**
* Adds links to Premium Support and FAQ under the plugin in the plugin overview page .
*
* @ param array $links Array of links for the plugins , adapted when the current plugin is found .
* @ param string $file The filename for the current plugin , which the filter loops through .
*
2021-09-21 15:05:30 +02:00
* @ return array
2021-09-21 15:01:08 +02:00
*/
public function add_action_link ( $links , $file ) {
2021-09-21 15:05:30 +02:00
if ( $file === WPSEO_BASENAME && WPSEO_Capability_Utils :: current_user_can ( 'wpseo_manage_options' ) ) {
if ( is_network_admin () ) {
$settings_url = network_admin_url ( 'admin.php?page=' . self :: PAGE_IDENTIFIER );
}
else {
$settings_url = admin_url ( 'admin.php?page=' . self :: PAGE_IDENTIFIER );
}
$settings_link = '<a href="' . esc_url ( $settings_url ) . '">' . __ ( 'Settings' , 'wordpress-seo' ) . '</a>' ;
2021-09-21 15:01:08 +02:00
array_unshift ( $links , $settings_link );
}
2021-09-21 15:05:30 +02:00
// Add link to docs.
$faq_link = '<a href="' . esc_url ( WPSEO_Shortlinker :: get ( 'https://yoa.st/1yc' ) ) . '" target="_blank">' . __ ( 'FAQ' , 'wordpress-seo' ) . '</a>' ;
array_unshift ( $links , $faq_link );
$addon_manager = new WPSEO_Addon_Manager ();
if ( YoastSEO () -> helpers -> product -> is_premium () ) {
// Remove Free 'deactivate' link if Premium is active as well. We don't want users to deactivate Free when Premium is active.
unset ( $links [ 'deactivate' ] );
$no_deactivation_explanation = '<span style="color: #32373c">' . sprintf (
/* translators: %s expands to Yoast SEO Premium. */
__ ( 'Required by %s' , 'wordpress-seo' ),
'Yoast SEO Premium'
) . '</span>' ;
2021-09-21 15:01:08 +02:00
2021-09-21 15:05:30 +02:00
array_unshift ( $links , $no_deactivation_explanation );
if ( $addon_manager -> has_valid_subscription ( WPSEO_Addon_Manager :: PREMIUM_SLUG ) ) {
2021-09-21 15:01:08 +02:00
return $links ;
}
2021-09-21 15:05:30 +02:00
// Add link to where premium can be activated.
$activation_link = '<a style="font-weight: bold;" href="' . esc_url ( WPSEO_Shortlinker :: get ( 'https://yoa.st/activate-my-yoast' ) ) . '" target="_blank">' . __ ( 'Activate your subscription' , 'wordpress-seo' ) . '</a>' ;
array_unshift ( $links , $activation_link );
return $links ;
2021-09-21 15:01:08 +02:00
}
2021-09-21 15:05:30 +02:00
// Add link to premium landing page.
$premium_link = '<a style="font-weight: bold;" href="' . esc_url ( WPSEO_Shortlinker :: get ( 'https://yoa.st/1yb' ) ) . '" target="_blank">' . __ ( 'Get Premium' , 'wordpress-seo' ) . '</a>' ;
2021-09-21 15:01:08 +02:00
array_unshift ( $links , $premium_link );
return $links ;
}
/**
* Enqueues the ( tiny ) global JS needed for the plugin .
*/
public function config_page_scripts () {
$asset_manager = new WPSEO_Admin_Asset_Manager ();
2021-09-21 15:05:30 +02:00
$asset_manager -> enqueue_script ( 'admin-global' );
$asset_manager -> localize_script ( 'admin-global' , 'wpseoAdminGlobalL10n' , $this -> localize_admin_global_script () );
2021-09-21 15:01:08 +02:00
}
/**
* Enqueues the ( tiny ) global stylesheet needed for the plugin .
*/
public function enqueue_global_style () {
$asset_manager = new WPSEO_Admin_Asset_Manager ();
$asset_manager -> enqueue_style ( 'admin-global' );
}
/**
2021-09-21 15:05:30 +02:00
* Filter the $contactmethods array and add a set of social profiles .
2021-09-21 15:01:08 +02:00
*
* These are used with the Facebook author , rel = " author " and Twitter cards implementation .
*
* @ param array $contactmethods Currently set contactmethods .
*
2021-09-21 15:05:30 +02:00
* @ return array Contactmethods with added contactmethods .
2021-09-21 15:01:08 +02:00
*/
public function update_contactmethods ( $contactmethods ) {
2021-09-21 15:05:30 +02:00
$contactmethods [ 'facebook' ] = __ ( 'Facebook profile URL' , 'wordpress-seo' );
$contactmethods [ 'instagram' ] = __ ( 'Instagram profile URL' , 'wordpress-seo' );
$contactmethods [ 'linkedin' ] = __ ( 'LinkedIn profile URL' , 'wordpress-seo' );
$contactmethods [ 'myspace' ] = __ ( 'MySpace profile URL' , 'wordpress-seo' );
$contactmethods [ 'pinterest' ] = __ ( 'Pinterest profile URL' , 'wordpress-seo' );
$contactmethods [ 'soundcloud' ] = __ ( 'SoundCloud profile URL' , 'wordpress-seo' );
$contactmethods [ 'tumblr' ] = __ ( 'Tumblr profile URL' , 'wordpress-seo' );
$contactmethods [ 'twitter' ] = __ ( 'Twitter username (without @)' , 'wordpress-seo' );
$contactmethods [ 'youtube' ] = __ ( 'YouTube profile URL' , 'wordpress-seo' );
$contactmethods [ 'wikipedia' ] = __ ( 'Wikipedia page about you' , 'wordpress-seo' ) . '<br/><small>' . __ ( '(if one exists)' , 'wordpress-seo' ) . '</small>' ;
2021-09-21 15:01:08 +02:00
return $contactmethods ;
}
/**
* Log the updated timestamp for user profiles when theme is changed .
*/
public function switch_theme () {
2021-09-21 15:05:30 +02:00
$users = get_users ( [ 'who' => 'authors' ] );
if ( is_array ( $users ) && $users !== [] ) {
2021-09-21 15:01:08 +02:00
foreach ( $users as $user ) {
update_user_meta ( $user -> ID , '_yoast_wpseo_profile_updated' , time () );
}
}
}
/**
* Localization for the dismiss urls .
*
* @ return array
*/
private function localize_admin_global_script () {
2021-09-21 15:05:30 +02:00
return [
'isRtl' => is_rtl (),
'variable_warning' => sprintf (
/* translators: %1$s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template, %2$s: expands to 'HelpScout beacon' */
__ ( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.' , 'wordpress-seo' ),
'<code>%s</code>' ,
'HelpScout beacon'
),
/* translators: %s: expends to Yoast SEO */
'help_video_iframe_title' => sprintf ( __ ( '%s video tutorial' , 'wordpress-seo' ), 'Yoast SEO' ),
2021-09-21 15:01:08 +02:00
'scrollable_table_hint' => __ ( 'Scroll to see the table content.' , 'wordpress-seo' ),
2021-09-21 15:05:30 +02:00
];
2021-09-21 15:01:08 +02:00
}
/**
* Sets the upsell notice .
*/
protected function set_upsell_notice () {
$upsell = new WPSEO_Product_Upsell_Notice ();
$upsell -> dismiss_notice_listener ();
$upsell -> initialize ();
}
/**
* Whether we are on the admin dashboard page .
*
2021-09-21 15:05:30 +02:00
* @ return bool
2021-09-21 15:01:08 +02:00
*/
protected function on_dashboard_page () {
2021-09-21 15:05:30 +02:00
return $GLOBALS [ 'pagenow' ] === 'index.php' ;
2021-09-21 15:01:08 +02:00
}
/**
* Loads the cornerstone filter .
2021-09-21 15:05:30 +02:00
*
* @ return WPSEO_WordPress_Integration [] The integrations to initialize .
2021-09-21 15:01:08 +02:00
*/
protected function initialize_cornerstone_content () {
if ( ! WPSEO_Options :: get ( 'enable_cornerstone_content' ) ) {
2021-09-21 15:05:30 +02:00
return [];
2021-09-21 15:01:08 +02:00
}
2021-09-21 15:05:30 +02:00
return [
'cornerstone_filter' => new WPSEO_Cornerstone_Filter (),
];
2021-09-21 15:01:08 +02:00
}
}