<?php
namespace Yoast\WP\SEO\Integrations\Watchers;
use Yoast\WP\SEO\Conditionals\No_Conditionals;
use Yoast\WP\SEO\Helpers\Capability_Helper;
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
use Yoast\WP\SEO\Helpers\Notification_Helper;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Integrations\Integration_Interface;
use Yoast\WP\SEO\Presenters\Admin\Search_Engines_Discouraged_Presenter;
use Yoast_Notification;
use Yoast_Notification_Center;
/**
* Shows a notification for users who have access for robots disabled.
*/
class Search_Engines_Discouraged_Watcher implements Integration_Interface {
use No_Conditionals;
/**
* The notification ID.
*/
public const NOTIFICATION_ID = 'wpseo-search-engines-discouraged';
/**
* The Yoast notification center.
*
* @var Yoast_Notification_Center
*/
protected $notification_center;
/**
* The notification helper.
*
* @var Notification_Helper
*/
protected $notification_helper;
/**
* The search engines discouraged presenter.
*
* @var Search_Engines_Discouraged_Presenter
*/
protected $presenter;
/**
* The current page helper.
*
* @var Current_Page_Helper
*/
protected $current_page_helper;
/**
* The options helper.
*
* @var Options_Helper
*/
protected $options_helper;
/**
* The capability helper.
*
* @var Capability_Helper
*/
protected $capability_helper;
/**
* Search_Engines_Discouraged_Watcher constructor.
*
* @param Yoast_Notification_Center $notification_center The notification center.
* @param Notification_Helper $notification_helper The notification helper.
* @param Current_Page_Helper $current_page_helper The current page helper.
* @param Options_Helper $options_helper The options helper.
* @param Capability_Helper $capability_helper The capability helper.
*/
public function __construct(
Yoast_Notification_Center $notification_center,
Notification_Helper $notification_helper,
Current_Page_Helper $current_page_helper,
Options_Helper $options_helper,
Capability_Helper $capability_helper
) {
$this->notification_center = $notification_center;
$this->notification_helper = $notification_helper;
$this->current_page_helper = $current_page_helper;
$this->options_helper = $options_helper;
$this->capability_helper = $capability_helper;
$this->presenter = new Search_Engines_Discouraged_Presenter();
}
/**
* Initializes the integration.
*
* On admin_init, it is checked whether the notification about search engines being discouraged should be shown.
* On admin_notices, the notice about the search engines being discouraged will be shown when necessary.
*
* @return void
*/
public function register_hooks() {
\add_action( 'admin_init', [ $this, 'manage_search_engines_discouraged_notification' ] );
\add_action( 'update_option_blog_public', [ $this, 'restore_ignore_option' ] );
/*
* The `admin_notices` hook fires on single site admin pages vs.
* `network_admin_notices` which fires on multisite admin pages and
* `user_admin_notices` which fires on multisite user admin pages.
*/
\add_action( 'admin_notices', [ $this, 'maybe_show_search_engines_discouraged_notice' ] );
}
/**
* Manage the search engines discouraged notification.
*
* Shows the notification if needed and deletes it if needed.
*
* @return void
*/
public function manage_search_engines_discouraged_notification() {
if ( ! $this->should_show_search_engines_discouraged_notification() ) {
$this->remove_search_engines_discouraged_notification_if_exists();
}
else {
$this->maybe_add_search_engines_discouraged_notification();
}
}
/**
* Show the search engine discouraged notice when needed.
*
* @return void
*/
public function maybe_show_search_engines_discouraged_notice() {
if ( ! $this->should_show_search_engines_discouraged_notice() ) {
return;
}
$this->show_search_engines_discouraged_notice();
}
/**
* Whether the search engines discouraged notification should be shown.
*
* @return bool
*/
protected function should_show_search_engines_discouraged_notification() {
return $this->search_engines_are_discouraged() && $this->options_helper->get( 'ignore_search_engines_discouraged_notice', false ) === false;
}
/**
* Remove the search engines discouraged notification if it exists.
*
* @return void
*/
protected function remove_search_engines_discouraged_notification_if_exists() {
$this->notification_center->remove_notification_by_id( self::NOTIFICATION_ID );
}
/**
* Add the search engines discouraged notification if it does not exist yet.
*
* @return void
*/
protected function maybe_add_search_engines_discouraged_notification() {
if ( ! $this->notification_center->get_notification_by_id( self::NOTIFICATION_ID ) ) {
$notification = $this->notification();
$this->notification_helper->restore_notification( $notification );
$this->notification_center->add_notification( $notification );
}
}
/**
* Checks whether search engines are discouraged from indexing the site.
*
* @return bool Whether search engines are discouraged from indexing the site.
*/
protected function search_engines_are_discouraged() {
return (string) \get_option( 'blog_public' ) === '0';
}
/**
* Whether the search engines notice should be shown.
*
* @return bool
*/
protected function should_show_search_engines_discouraged_notice() {
$pages_to_show_notice = [
'index.php',
'plugins.php',
'update-core.php',
];
return (
$this->search_engines_are_discouraged()
&& $this->capability_helper->current_user_can( 'manage_options' )
&& $this->options_helper->get( 'ignore_search_engines_discouraged_notice', false ) === false
&& (
$this->current_page_helper->is_yoast_seo_page()
|| \in_array( $this->current_page_helper->get_current_admin_page(), $pages_to_show_notice, true )
)
&& $this->current_page_helper->get_current_yoast_seo_page() !== 'wpseo_dashboard'
);
}
/**
* Show the search engines discouraged notice.
*
* @return void
*/
protected function show_search_engines_discouraged_notice() {
\printf(
'<div id="robotsmessage" class="notice notice-error">%1$s</div>',
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output from present() is considered safe.
$this->presenter->present()
);
}
/**
* Returns an instance of the notification.
*
* @return Yoast_Notification The notification to show.
*/
protected function notification() {
return new Yoast_Notification(
$this->presenter->present(),
[
'type' => Yoast_Notification::ERROR,
'id' => self::NOTIFICATION_ID,
'capabilities' => 'wpseo_manage_options',
'priority' => 1,
]
);
}
/**
* Should restore the ignore option for the search engines discouraged notice.
*
* @return void
*/
public function restore_ignore_option() {
if ( ! $this->search_engines_are_discouraged() ) {
$this->options_helper->set( 'ignore_search_engines_discouraged_notice', false );
}
}
}