PDF rausgenommen
This commit is contained in:
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class handles the data for the option where the Ryte data is stored.
|
||||
*/
|
||||
class WPSEO_OnPage_Option {
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const NOT_FETCHED = 99;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const IS_INDEXABLE = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const IS_NOT_INDEXABLE = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const CANNOT_FETCH = -1;
|
||||
|
||||
/**
|
||||
* The name of the option where data will be stored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const OPTION_NAME = 'wpseo_onpage';
|
||||
|
||||
/**
|
||||
* The key of the status in the option.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const STATUS = 'status';
|
||||
|
||||
/**
|
||||
* The key of the last fetch date in the option.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const LAST_FETCH = 'last_fetch';
|
||||
|
||||
/**
|
||||
* The limit for fetching the status manually.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FETCH_LIMIT = 15;
|
||||
|
||||
/**
|
||||
* The Ryte option stored in the database.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $onpage_option;
|
||||
|
||||
/**
|
||||
* Setting the object by setting the properties.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->onpage_option = $this->get_option();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the status from the option.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_status() {
|
||||
if ( array_key_exists( self::STATUS, $this->onpage_option ) ) {
|
||||
return $this->onpage_option[ self::STATUS ];
|
||||
}
|
||||
|
||||
return self::CANNOT_FETCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving the status to the options.
|
||||
*
|
||||
* @param string $status The status to save.
|
||||
*/
|
||||
public function set_status( $status ) {
|
||||
$this->onpage_option[ self::STATUS ] = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving the last fetch timestamp to the options.
|
||||
*
|
||||
* @param integer $timestamp Timestamp with the new value.
|
||||
*/
|
||||
public function set_last_fetch( $timestamp ) {
|
||||
$this->onpage_option[ self::LAST_FETCH ] = $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the last fetch is within the time of 60 minutes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_be_fetched() {
|
||||
return ( ( time() - $this->onpage_option[ self::LAST_FETCH ] ) > self::FETCH_LIMIT );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving the option with the current data.
|
||||
*/
|
||||
public function save_option() {
|
||||
update_option( self::OPTION_NAME, $this->onpage_option );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the onpage_enabled status.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
return WPSEO_Options::get( 'onpage_indexability' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the option with the Ryte data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_option() {
|
||||
$default = array(
|
||||
self::STATUS => self::NOT_FETCHED,
|
||||
self::LAST_FETCH => 0,
|
||||
);
|
||||
|
||||
return get_option( self::OPTION_NAME, $default );
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class will fetch a new status from Ryte and if it's necessary it will
|
||||
* notify the site admin by email and remove the current meta value to hide the
|
||||
* notice for all admin users.
|
||||
*/
|
||||
class WPSEO_OnPage_Request {
|
||||
|
||||
/**
|
||||
* @var string The endpoint where the request will be send to.
|
||||
*/
|
||||
private $onpage_endpoint = 'https://indexability.yoast.onpage.org/';
|
||||
|
||||
/**
|
||||
* Doing the remote get and returns the body.
|
||||
*
|
||||
* @param string $target_url The home url.
|
||||
* @param array $parameters Array of extra parameters to send to Ryte.
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception The error message that can be used to show to the user.
|
||||
*/
|
||||
protected function get_remote( $target_url, $parameters = array() ) {
|
||||
$defaults = array(
|
||||
'url' => $target_url,
|
||||
'wp_version' => $GLOBALS['wp_version'],
|
||||
'yseo_version' => WPSEO_VERSION,
|
||||
);
|
||||
$parameters = array_merge( $defaults, $parameters );
|
||||
|
||||
$url = add_query_arg( $parameters, $this->onpage_endpoint );
|
||||
|
||||
$response = wp_remote_get( $url );
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
|
||||
// When the request is successful, the response code will be 200.
|
||||
if ( $response_code === 200 ) {
|
||||
$response_body = wp_remote_retrieve_body( $response );
|
||||
|
||||
return json_decode( $response_body, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sending a request to Ryte to check if the $home_url is indexable.
|
||||
*
|
||||
* @param string $target_url The URL that will be send to the API.
|
||||
* @param array $parameters Array of extra parameters to send to Ryte.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function do_request( $target_url, $parameters = array() ) {
|
||||
$json_body = $this->get_remote( $target_url, $parameters );
|
||||
|
||||
// Ryte recognized a redirect, fetch the data of that URL by calling this method with the value from Ryte.
|
||||
if ( ! empty( $json_body['passes_juice_to'] ) ) {
|
||||
return $this->do_request( $json_body['passes_juice_to'], $parameters );
|
||||
}
|
||||
|
||||
return $json_body;
|
||||
}
|
||||
}
|
@ -0,0 +1,298 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles the request for getting the Ryte status.
|
||||
*/
|
||||
class WPSEO_OnPage implements WPSEO_WordPress_Integration {
|
||||
|
||||
/**
|
||||
* The name of the user meta key for storing the dismissed status.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const USER_META_KEY = 'wpseo_dismiss_onpage';
|
||||
|
||||
/**
|
||||
* Is the request started by pressing the fetch button.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_manual_request = false;
|
||||
|
||||
/**
|
||||
* Constructs the object.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->catch_redo_listener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
// Adds admin notice if necessary.
|
||||
add_filter( 'admin_init', array( $this, 'show_notice' ) );
|
||||
|
||||
if ( ! self::is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Adds weekly schedule to the cron job schedules.
|
||||
add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) );
|
||||
|
||||
// Sets the action for the Ryte fetch.
|
||||
add_action( 'wpseo_onpage_fetch', array( $this, 'fetch_from_onpage' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a notice when the website is not indexable.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function show_notice() {
|
||||
$notification = $this->get_indexability_notification();
|
||||
$notification_center = Yoast_Notification_Center::get();
|
||||
|
||||
if ( $this->should_show_notice() ) {
|
||||
$notification_center->add_notification( $notification );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$notification_center->remove_notification( $notification );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if we can use the functionality.
|
||||
*
|
||||
* @return bool True if this functionality can be used.
|
||||
*/
|
||||
public static function is_active() {
|
||||
if ( wp_doing_ajax() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! WPSEO_Options::get( 'onpage_indexability' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks to run on plugin activation.
|
||||
*/
|
||||
public function activate_hooks() {
|
||||
if ( $this->get_option()->is_enabled() ) {
|
||||
$this->schedule_cron();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->unschedule_cron();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a weekly cron schedule.
|
||||
*
|
||||
* @param array $schedules Currently scheduled items.
|
||||
*
|
||||
* @return array Enriched list of schedules.
|
||||
*/
|
||||
public function add_weekly_schedule( $schedules ) {
|
||||
if ( ! is_array( $schedules ) ) {
|
||||
$schedules = array();
|
||||
}
|
||||
|
||||
$schedules['weekly'] = array(
|
||||
'interval' => WEEK_IN_SECONDS,
|
||||
'display' => __( 'Once Weekly', 'wordpress-seo' ),
|
||||
);
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data from Ryte.
|
||||
*
|
||||
* @return bool True if this has been run.
|
||||
*/
|
||||
public function fetch_from_onpage() {
|
||||
$onpage_option = $this->get_option();
|
||||
if ( ! $onpage_option->should_be_fetched() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$new_status = $this->request_indexability();
|
||||
if ( false === $new_status ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Updates the timestamp in the option.
|
||||
$onpage_option->set_last_fetch( time() );
|
||||
|
||||
// The currently indexability status.
|
||||
$old_status = $onpage_option->get_status();
|
||||
|
||||
$onpage_option->set_status( $new_status );
|
||||
$onpage_option->save_option();
|
||||
|
||||
// Check if the status has been changed.
|
||||
if ( $old_status !== $new_status && $new_status !== WPSEO_OnPage_Option::CANNOT_FETCH ) {
|
||||
$this->notify_admins();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the option to use.
|
||||
*
|
||||
* @return WPSEO_OnPage_Option The option.
|
||||
*/
|
||||
protected function get_option() {
|
||||
return new WPSEO_OnPage_Option();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the indexability notification.
|
||||
*
|
||||
* @return Yoast_Notification The notification.
|
||||
*/
|
||||
private function get_indexability_notification() {
|
||||
$notice = sprintf(
|
||||
/* translators: 1: opens a link to a related knowledge base article. 2: closes the link */
|
||||
__( '%1$sYour homepage cannot be indexed by search engines%2$s. This is very bad for SEO and should be fixed.', 'wordpress-seo' ),
|
||||
'<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/onpageindexerror' ) . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
return new Yoast_Notification(
|
||||
$notice,
|
||||
array(
|
||||
'type' => Yoast_Notification::ERROR,
|
||||
'id' => 'wpseo-dismiss-onpageorg',
|
||||
'capabilities' => 'wpseo_manage_options',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to Ryte to get the indexability.
|
||||
*
|
||||
* @return int|bool The indexability value.
|
||||
*/
|
||||
protected function request_indexability() {
|
||||
$parameters = array();
|
||||
if ( $this->wordfence_protection_enabled() ) {
|
||||
$parameters['wf_strict'] = 1;
|
||||
}
|
||||
|
||||
$request = new WPSEO_OnPage_Request();
|
||||
$response = $request->do_request( get_option( 'home' ), $parameters );
|
||||
|
||||
if ( isset( $response['is_indexable'] ) ) {
|
||||
return (int) $response['is_indexable'];
|
||||
}
|
||||
|
||||
return WPSEO_OnPage_Option::CANNOT_FETCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the notice being given?
|
||||
*
|
||||
* @return bool True if a notice should be shown.
|
||||
*/
|
||||
protected function should_show_notice() {
|
||||
if ( ! $this->get_option()->is_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If development mode is on or the blog is not public, just don't show this notice.
|
||||
if ( WPSEO_Utils::is_development_mode() || ( '0' === get_option( 'blog_public' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->get_option()->get_status() === WPSEO_OnPage_Option::IS_NOT_INDEXABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the admins.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function notify_admins() {
|
||||
/*
|
||||
* Let's start showing the notices to all admins by removing the hide-notice meta data for each admin resulting
|
||||
* in popping up the notice again.
|
||||
*/
|
||||
delete_metadata( 'user', 0, self::USER_META_KEY, '', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the cronjob to get the new indexibility status.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function schedule_cron() {
|
||||
if ( wp_next_scheduled( 'wpseo_onpage_fetch' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_schedule_event( time(), 'weekly', 'wpseo_onpage_fetch' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unschedules the cronjob to get the new indexibility status.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function unschedule_cron() {
|
||||
if ( ! wp_next_scheduled( 'wpseo_onpage_fetch' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_clear_scheduled_hook( 'wpseo_onpage_fetch' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redo the fetch request for Ryte.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function catch_redo_listener() {
|
||||
if ( ! self::is_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( filter_input( INPUT_GET, 'wpseo-redo-onpage' ) === '1' ) {
|
||||
$this->is_manual_request = true;
|
||||
|
||||
add_action( 'admin_init', array( $this, 'fetch_from_onpage' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if WordFence protects the site against 'fake' Google crawlers.
|
||||
*
|
||||
* @return boolean True if WordFence protects the site.
|
||||
*/
|
||||
private function wordfence_protection_enabled() {
|
||||
if ( ! class_exists( 'wfConfig' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! method_exists( 'wfConfig', 'get' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) wfConfig::get( 'blockFakeBots' );
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Admin\OnPage
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the service to be used by the WPSEO_Endpoint_Ryte endpoint.
|
||||
*/
|
||||
class WPSEO_Ryte_Service {
|
||||
|
||||
/**
|
||||
* @var WPSEO_OnPage_Option
|
||||
*/
|
||||
protected $option;
|
||||
|
||||
/**
|
||||
* Constructs the WPSEO_Ryte_Service class.
|
||||
*
|
||||
* @param WPSEO_OnPage_Option $option The option to retrieve data from.
|
||||
*/
|
||||
public function __construct( WPSEO_OnPage_Option $option ) {
|
||||
$this->option = $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches statistics via REST request.
|
||||
*
|
||||
* @return WP_REST_Response The response object.
|
||||
*/
|
||||
public function get_statistics() {
|
||||
// Switch to the user locale with fallback to the site locale.
|
||||
switch_to_locale( WPSEO_Language_Utils::get_user_locale() );
|
||||
|
||||
$result = false;
|
||||
|
||||
if ( $this->option->is_enabled() ) {
|
||||
$result = $this->get_score( $this->option->get_status(), $this->option->should_be_fetched() );
|
||||
}
|
||||
|
||||
return new WP_REST_Response( array( 'ryte' => $result ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an the results of the Ryte option based on the passed status.
|
||||
*
|
||||
* @param string $status The option's status.
|
||||
* @param bool $fetch Whether or not the data should be fetched.
|
||||
*
|
||||
* @return array The results, contains a score and label.
|
||||
*/
|
||||
private function get_score( $status, $fetch = false ) {
|
||||
if ( $status === WPSEO_OnPage_Option::IS_INDEXABLE ) {
|
||||
return array(
|
||||
'score' => 'good',
|
||||
'label' => __( 'Your homepage can be indexed by search engines.', 'wordpress-seo' ),
|
||||
'can_fetch' => $fetch,
|
||||
);
|
||||
}
|
||||
|
||||
if ( $status === WPSEO_OnPage_Option::IS_NOT_INDEXABLE ) {
|
||||
/* translators: %1$s: opens a link to a related knowledge base article. %2$s: closes the link. */
|
||||
$label = __( '%1$sYour homepage cannot be indexed by search engines%2$s. This is very bad for SEO and should be fixed.', 'wordpress-seo' );
|
||||
$label = sprintf(
|
||||
$label,
|
||||
'<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/onpageindexerror' ) . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
return array(
|
||||
'score' => 'bad',
|
||||
'label' => $label,
|
||||
'can_fetch' => $fetch,
|
||||
);
|
||||
}
|
||||
|
||||
if ( $status === WPSEO_OnPage_Option::CANNOT_FETCH ) {
|
||||
/* translators: %1$s: opens a link to a related knowledge base article, %2$s: expands to Yoast SEO, %3$s: closes the link, %4$s: expands to Ryte. */
|
||||
$label = __( '%1$s%2$s has not been able to fetch your site\'s indexability status%3$s from %4$s', 'wordpress-seo' );
|
||||
$label = sprintf(
|
||||
$label,
|
||||
'<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/onpagerequestfailed' ) . '" target="_blank">',
|
||||
'Yoast SEO',
|
||||
'</a>',
|
||||
'Ryte'
|
||||
);
|
||||
|
||||
return array(
|
||||
'score' => 'na',
|
||||
'label' => $label,
|
||||
'can_fetch' => $fetch,
|
||||
);
|
||||
}
|
||||
|
||||
if ( $status === WPSEO_OnPage_Option::NOT_FETCHED ) {
|
||||
/* translators: %1$s: expands to Yoast SEO, %2$s: expands to Ryte. */
|
||||
$label = __( '%1$s has not fetched your site\'s indexability status yet from %2$s', 'wordpress-seo' );
|
||||
$label = sprintf( $label, 'Yoast SEO', 'Ryte' );
|
||||
|
||||
return array(
|
||||
'score' => 'na',
|
||||
'label' => esc_html( $label ),
|
||||
'can_fetch' => $fetch,
|
||||
);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user