rebase on oct-10-2023
This commit is contained in:
@@ -4,11 +4,11 @@ namespace Yoast\WP\SEO\Integrations;
|
||||
|
||||
use WPSEO_Addon_Manager;
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use Yoast\WP\SEO\Helpers\Short_Link_Helper;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\User_Can_Manage_Wpseo_Options_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Product_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Short_Link_Helper;
|
||||
|
||||
/**
|
||||
* Class Academy_Integration.
|
||||
@@ -46,7 +46,7 @@ class Academy_Integration implements Integration_Interface {
|
||||
private $shortlink_helper;
|
||||
|
||||
/**
|
||||
* Constructs Settings_Integration.
|
||||
* Constructs Academy_Integration.
|
||||
*
|
||||
* @param WPSEO_Admin_Asset_Manager $asset_manager The WPSEO_Admin_Asset_Manager.
|
||||
* @param Current_Page_Helper $current_page_helper The Current_Page_Helper.
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Admin;
|
||||
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
||||
use Yoast\WP\SEO\Conditionals\No_Conditionals;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
|
||||
/**
|
||||
* This integration registers a run of the cleanup routine whenever the plugin is activated.
|
||||
@@ -38,7 +38,7 @@ class Activation_Cleanup_Integration implements Integration_Interface {
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
add_action( 'wpseo_activate', [ $this, 'register_cleanup_routine' ], 11 );
|
||||
\add_action( 'wpseo_activate', [ $this, 'register_cleanup_routine' ], 11 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,9 +49,9 @@ class Activation_Cleanup_Integration implements Integration_Interface {
|
||||
public function register_cleanup_routine() {
|
||||
$first_activated_on = $this->options_helper->get( 'first_activated_on', false );
|
||||
|
||||
if ( ! $first_activated_on || time() > ( $first_activated_on + ( MINUTE_IN_SECONDS * 5 ) ) ) {
|
||||
if ( ! $first_activated_on || \time() > ( $first_activated_on + ( \MINUTE_IN_SECONDS * 5 ) ) ) {
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
\wp_schedule_single_event( ( time() + DAY_IN_SECONDS ), Cleanup_Integration::START_HOOK );
|
||||
\wp_schedule_single_event( ( \time() + \DAY_IN_SECONDS ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,9 @@ class Admin_Columns_Cache_Integration implements Integration_Interface {
|
||||
$indexables = $this->indexable_repository->find_by_multiple_ids_and_type( $post_ids, 'post', false );
|
||||
|
||||
foreach ( $indexables as $indexable ) {
|
||||
$this->indexable_cache[ $indexable->object_id ] = $indexable;
|
||||
if ( $indexable instanceof Indexable ) {
|
||||
$this->indexable_cache[ $indexable->object_id ] = $indexable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +170,7 @@ class Admin_Columns_Cache_Integration implements Integration_Interface {
|
||||
$pages_map[ $page->ID ] = $page;
|
||||
}
|
||||
|
||||
$pages = &$top_level_pages;
|
||||
$pages = $top_level_pages;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
@@ -11,7 +11,9 @@ use Yoast\WP\SEO\Actions\Indexing\Post_Link_Indexing_Action;
|
||||
use Yoast\WP\SEO\Actions\Indexing\Term_Link_Indexing_Action;
|
||||
use Yoast\WP\SEO\Conditionals\Get_Request_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Migrations_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\WP_CRON_Enabled_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Yoast_Admin_And_Dashboard_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Indexable_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Indexing_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
|
||||
@@ -78,6 +80,34 @@ class Background_Indexing_Integration implements Integration_Interface {
|
||||
*/
|
||||
protected $indexing_helper;
|
||||
|
||||
/**
|
||||
* An object that checks if we are on the Yoast admin or on the dashboard page.
|
||||
*
|
||||
* @var Yoast_Admin_And_Dashboard_Conditional
|
||||
*/
|
||||
protected $yoast_admin_and_dashboard_conditional;
|
||||
|
||||
/**
|
||||
* An object that checks if we are handling a GET request.
|
||||
*
|
||||
* @var Get_Request_Conditional
|
||||
*/
|
||||
private $get_request_conditional;
|
||||
|
||||
/**
|
||||
* An object that checks if WP_CRON is enabled.
|
||||
*
|
||||
* @var WP_CRON_Enabled_Conditional
|
||||
*/
|
||||
private $wp_cron_enabled_conditional;
|
||||
|
||||
/**
|
||||
* The indexable helper
|
||||
*
|
||||
* @var Indexable_Helper
|
||||
*/
|
||||
private $indexable_helper;
|
||||
|
||||
/**
|
||||
* Returns the conditionals based on which this integration should be active.
|
||||
*
|
||||
@@ -85,23 +115,25 @@ class Background_Indexing_Integration implements Integration_Interface {
|
||||
*/
|
||||
public static function get_conditionals() {
|
||||
return [
|
||||
Yoast_Admin_And_Dashboard_Conditional::class,
|
||||
Migrations_Conditional::class,
|
||||
Get_Request_Conditional::class,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown_Indexing_Integration constructor.
|
||||
*
|
||||
* @param Indexable_Post_Indexation_Action $post_indexation The post indexing action.
|
||||
* @param Indexable_Term_Indexation_Action $term_indexation The term indexing action.
|
||||
* @param Indexable_Post_Type_Archive_Indexation_Action $post_type_archive_indexation The post type archive indexing action.
|
||||
* @param Indexable_General_Indexation_Action $general_indexation The general indexing action.
|
||||
* @param Indexable_Indexing_Complete_Action $complete_indexation_action The complete indexing action.
|
||||
* @param Post_Link_Indexing_Action $post_link_indexing_action The post indexing action.
|
||||
* @param Term_Link_Indexing_Action $term_link_indexing_action The term indexing action.
|
||||
* @param Indexing_Helper $indexing_helper The indexing helper.
|
||||
* @param Indexable_Post_Indexation_Action $post_indexation The post indexing action.
|
||||
* @param Indexable_Term_Indexation_Action $term_indexation The term indexing action.
|
||||
* @param Indexable_Post_Type_Archive_Indexation_Action $post_type_archive_indexation The post type archive indexing action.
|
||||
* @param Indexable_General_Indexation_Action $general_indexation The general indexing action.
|
||||
* @param Indexable_Indexing_Complete_Action $complete_indexation_action The complete indexing action.
|
||||
* @param Post_Link_Indexing_Action $post_link_indexing_action The post indexing action.
|
||||
* @param Term_Link_Indexing_Action $term_link_indexing_action The term indexing action.
|
||||
* @param Indexing_Helper $indexing_helper The indexing helper.
|
||||
* @param Indexable_Helper $indexable_helper The indexable helper.
|
||||
* @param Yoast_Admin_And_Dashboard_Conditional $yoast_admin_and_dashboard_conditional An object that checks if we are on the Yoast admin or on the dashboard page.
|
||||
* @param Get_Request_Conditional $get_request_conditional An object that checks if we are handling a GET request.
|
||||
* @param WP_CRON_Enabled_Conditional $wp_cron_enabled_conditional An object that checks if WP_CRON is enabled.
|
||||
*/
|
||||
public function __construct(
|
||||
Indexable_Post_Indexation_Action $post_indexation,
|
||||
@@ -111,23 +143,50 @@ class Background_Indexing_Integration implements Integration_Interface {
|
||||
Indexable_Indexing_Complete_Action $complete_indexation_action,
|
||||
Post_Link_Indexing_Action $post_link_indexing_action,
|
||||
Term_Link_Indexing_Action $term_link_indexing_action,
|
||||
Indexing_Helper $indexing_helper
|
||||
Indexing_Helper $indexing_helper,
|
||||
Indexable_Helper $indexable_helper,
|
||||
Yoast_Admin_And_Dashboard_Conditional $yoast_admin_and_dashboard_conditional,
|
||||
Get_Request_Conditional $get_request_conditional,
|
||||
WP_CRON_Enabled_Conditional $wp_cron_enabled_conditional
|
||||
) {
|
||||
$this->post_indexation = $post_indexation;
|
||||
$this->term_indexation = $term_indexation;
|
||||
$this->post_type_archive_indexation = $post_type_archive_indexation;
|
||||
$this->general_indexation = $general_indexation;
|
||||
$this->complete_indexation_action = $complete_indexation_action;
|
||||
$this->post_link_indexing_action = $post_link_indexing_action;
|
||||
$this->term_link_indexing_action = $term_link_indexing_action;
|
||||
$this->indexing_helper = $indexing_helper;
|
||||
$this->post_indexation = $post_indexation;
|
||||
$this->term_indexation = $term_indexation;
|
||||
$this->post_type_archive_indexation = $post_type_archive_indexation;
|
||||
$this->general_indexation = $general_indexation;
|
||||
$this->complete_indexation_action = $complete_indexation_action;
|
||||
$this->post_link_indexing_action = $post_link_indexing_action;
|
||||
$this->term_link_indexing_action = $term_link_indexing_action;
|
||||
$this->indexing_helper = $indexing_helper;
|
||||
$this->indexable_helper = $indexable_helper;
|
||||
$this->yoast_admin_and_dashboard_conditional = $yoast_admin_and_dashboard_conditional;
|
||||
$this->get_request_conditional = $get_request_conditional;
|
||||
$this->wp_cron_enabled_conditional = $wp_cron_enabled_conditional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*/
|
||||
public function register_hooks() {
|
||||
\add_action( 'admin_init', [ $this, 'register_shutdown_indexing' ], 10 );
|
||||
\add_action( 'admin_init', [ $this, 'register_shutdown_indexing' ] );
|
||||
\add_action( 'wpseo_indexable_index_batch', [ $this, 'index' ] );
|
||||
// phpcs:ignore WordPress.WP.CronInterval -- The sniff doesn't understand values with parentheses. https://github.com/WordPress/WordPress-Coding-Standards/issues/2025
|
||||
\add_filter( 'cron_schedules', [ $this, 'add_cron_schedule' ] );
|
||||
\add_action( 'admin_init', [ $this, 'schedule_cron_indexing' ], 11 );
|
||||
|
||||
$this->add_limit_filters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the filters that change the indexing limits.
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
public function add_limit_filters() {
|
||||
\add_filter( 'wpseo_post_indexation_limit', [ $this, 'throttle_cron_indexing' ] );
|
||||
\add_filter( 'wpseo_post_type_archive_indexation_limit', [ $this, 'throttle_cron_indexing' ] );
|
||||
\add_filter( 'wpseo_term_indexation_limit', [ $this, 'throttle_cron_indexing' ] );
|
||||
\add_filter( 'wpseo_prominent_words_indexation_limit', [ $this, 'throttle_cron_indexing' ] );
|
||||
\add_filter( 'wpseo_link_indexing_limit', [ $this, 'throttle_cron_link_indexing' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +196,7 @@ class Background_Indexing_Integration implements Integration_Interface {
|
||||
*/
|
||||
public function register_shutdown_indexing() {
|
||||
if ( $this->should_index_on_shutdown( $this->get_shutdown_limit() ) ) {
|
||||
\register_shutdown_function( [ $this, 'index' ] );
|
||||
$this->register_shutdown_function( 'index' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,13 +206,152 @@ class Background_Indexing_Integration implements Integration_Interface {
|
||||
* @return void
|
||||
*/
|
||||
public function index() {
|
||||
if ( \wp_doing_cron() && ! $this->should_index_on_cron() ) {
|
||||
$this->unschedule_cron_indexing();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->post_indexation->index();
|
||||
$this->term_indexation->index();
|
||||
$this->general_indexation->index();
|
||||
$this->post_type_archive_indexation->index();
|
||||
$this->post_link_indexing_action->index();
|
||||
$this->term_link_indexing_action->index();
|
||||
$this->complete_indexation_action->complete();
|
||||
|
||||
if ( $this->indexing_helper->get_limited_filtered_unindexed_count_background( 1 ) === 0 ) {
|
||||
// We set this as complete, even though prominent words might not be complete. But that's the way we always treated that.
|
||||
$this->complete_indexation_action->complete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the 'Every fifteen minutes' cron schedule to WP-Cron.
|
||||
*
|
||||
* @param array $schedules The existing schedules.
|
||||
*
|
||||
* @return array The schedules containing the fifteen_minutes schedule.
|
||||
*/
|
||||
public function add_cron_schedule( $schedules ) {
|
||||
if ( ! \is_array( $schedules ) ) {
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
$schedules['fifteen_minutes'] = [
|
||||
'interval' => ( 15 * MINUTE_IN_SECONDS ),
|
||||
'display' => \esc_html__( 'Every fifteen minutes', 'wordpress-seo' ),
|
||||
];
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule background indexing every 15 minutes if the index isn't already up to date.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function schedule_cron_indexing() {
|
||||
/**
|
||||
* Filter: 'wpseo_unindexed_count_queries_ran' - Informs whether the expensive unindexed count queries have been ran already.
|
||||
*
|
||||
* @internal
|
||||
* @api bool
|
||||
*/
|
||||
$have_queries_ran = \apply_filters( 'wpseo_unindexed_count_queries_ran', false );
|
||||
|
||||
if ( ( ! $this->yoast_admin_and_dashboard_conditional->is_met() || ! $this->get_request_conditional->is_met() ) && ! $have_queries_ran ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! \wp_next_scheduled( 'wpseo_indexable_index_batch' ) && $this->should_index_on_cron() ) {
|
||||
\wp_schedule_event( ( \time() + \HOUR_IN_SECONDS ), 'fifteen_minutes', 'wpseo_indexable_index_batch' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit cron indexing to 15 indexables per batch instead of 25.
|
||||
*
|
||||
* @param int $indexation_limit The current limit (filter input).
|
||||
*
|
||||
* @return int The new batch limit.
|
||||
*/
|
||||
public function throttle_cron_indexing( $indexation_limit ) {
|
||||
if ( \wp_doing_cron() ) {
|
||||
/**
|
||||
* Filter: 'wpseo_cron_indexing_limit_size' - Adds the possibility to limit the number of items that are indexed when in cron action.
|
||||
*
|
||||
* @api int $limit Maximum number of indexables to be indexed per indexing action.
|
||||
*/
|
||||
return \apply_filters( 'wpseo_cron_indexing_limit_size', 15 );
|
||||
}
|
||||
|
||||
return $indexation_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit cron indexing to 3 links per batch instead of 5.
|
||||
*
|
||||
* @param int $link_indexation_limit The current limit (filter input).
|
||||
*
|
||||
* @return int The new batch limit.
|
||||
*/
|
||||
public function throttle_cron_link_indexing( $link_indexation_limit ) {
|
||||
if ( \wp_doing_cron() ) {
|
||||
/**
|
||||
* Filter: 'wpseo_cron_link_indexing_limit_size' - Adds the possibility to limit the number of links that are indexed when in cron action.
|
||||
*
|
||||
* @api int $limit Maximum number of link indexables to be indexed per link indexing action.
|
||||
*/
|
||||
return \apply_filters( 'wpseo_cron_link_indexing_limit_size', 3 );
|
||||
}
|
||||
|
||||
return $link_indexation_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether cron indexation should be performed.
|
||||
*
|
||||
* @return bool Should cron indexation be performed.
|
||||
*/
|
||||
protected function should_index_on_cron() {
|
||||
if ( ! $this->indexable_helper->should_index_indexables() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The filter supersedes everything when preventing cron indexation.
|
||||
if ( \apply_filters( 'Yoast\WP\SEO\enable_cron_indexing', true ) !== true ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->indexing_helper->get_limited_filtered_unindexed_count_background( 1 ) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether background indexation should be performed.
|
||||
*
|
||||
* @param int $shutdown_limit The shutdown limit used to determine whether indexation should be run.
|
||||
*
|
||||
* @return bool Should background indexation be performed.
|
||||
*/
|
||||
protected function should_index_on_shutdown( $shutdown_limit ) {
|
||||
if ( ! $this->yoast_admin_and_dashboard_conditional->is_met() || ! $this->get_request_conditional->is_met() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->indexable_helper->should_index_indexables() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->wp_cron_enabled_conditional->is_met() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$total_unindexed = $this->indexing_helper->get_limited_filtered_unindexed_count_background( $shutdown_limit );
|
||||
if ( $total_unindexed === 0 || $total_unindexed > $shutdown_limit ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,15 +369,26 @@ class Background_Indexing_Integration implements Integration_Interface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether background indexation should be performed.
|
||||
* Removes the cron indexing job from the scheduled event queue.
|
||||
*
|
||||
* @param int $shutdown_limit The shutdown limit used to determine whether indexation should be run.
|
||||
*
|
||||
* @return bool Should background indexation be performed.
|
||||
* @return void
|
||||
*/
|
||||
public function should_index_on_shutdown( $shutdown_limit ) {
|
||||
$total = $this->indexing_helper->get_limited_filtered_unindexed_count( $shutdown_limit );
|
||||
protected function unschedule_cron_indexing() {
|
||||
$scheduled = \wp_next_scheduled( 'wpseo_indexable_index_batch' );
|
||||
if ( $scheduled ) {
|
||||
\wp_unschedule_event( $scheduled, 'wpseo_indexable_index_batch' );
|
||||
}
|
||||
}
|
||||
|
||||
return ( $total > 0 && $total < $shutdown_limit );
|
||||
/**
|
||||
* Registers a method to be executed on shutdown.
|
||||
* This wrapper mostly exists for making this class more unittestable.
|
||||
*
|
||||
* @param string $method_name The name of the method on the current instance to register.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function register_shutdown_function( $method_name ) {
|
||||
\register_shutdown_function( [ $this, $method_name ] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
* Enqueue the workouts app.
|
||||
*/
|
||||
public function enqueue_assets() {
|
||||
if ( ! is_network_admin() ) {
|
||||
if ( ! \is_network_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
$this->unused_resources_settings = [
|
||||
'remove_emoji_scripts' => \__( 'Emoji scripts', 'wordpress-seo' ),
|
||||
'deny_wp_json_crawling' => \__( 'Prevent search engines from crawling /wp-json/', 'wordpress-seo' ),
|
||||
'deny_adsbot_crawling' => \__( 'Prevent Google AdsBot from crawling', 'wordpress-seo' ),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -166,8 +167,8 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
* @param Yoast_Form $yform The yoast form object.
|
||||
*/
|
||||
public function add_crawl_settings_tab_content( $yform ) {
|
||||
_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
|
||||
$this->add_crawl_settings( $yform, false );
|
||||
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
|
||||
$this->add_crawl_settings( $yform );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,13 +177,13 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
* @param Yoast_Form $yform The yoast form object.
|
||||
*/
|
||||
public function add_crawl_settings_tab_content_network( $yform ) {
|
||||
$this->add_crawl_settings( $yform, true );
|
||||
$this->add_crawl_settings( $yform );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the settings sections.
|
||||
*
|
||||
* @param Yoast_Form $yform The Yoast form class.
|
||||
* @param Yoast_Form $yform The Yoast form class.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -213,7 +214,6 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
'</a>'
|
||||
);
|
||||
|
||||
|
||||
$this->print_toggles( $this->permalink_cleanup_settings, $yform, \__( 'Permalink cleanup settings', 'wordpress-seo' ), [], $permalink_warning );
|
||||
|
||||
// Add the original option as hidden, so as not to lose any values if it's disabled and the form is saved.
|
||||
@@ -223,11 +223,11 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
/**
|
||||
* Prints a list of toggles for an array of settings with labels.
|
||||
*
|
||||
* @param array $settings The settings being displayed.
|
||||
* @param Yoast_Form $yform The Yoast form class.
|
||||
* @param string $title Optional title for the settings being displayed.
|
||||
* @param array $toggles Optional naming of the toggle buttons.
|
||||
* @param string $warning Optional warning to be displayed above the toggles.
|
||||
* @param array $settings The settings being displayed.
|
||||
* @param Yoast_Form $yform The Yoast form class.
|
||||
* @param string $title Optional title for the settings being displayed.
|
||||
* @param array $toggles Optional naming of the toggle buttons.
|
||||
* @param string $warning Optional warning to be displayed above the toggles.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -324,7 +324,7 @@ class Crawl_Settings_Integration implements Integration_Interface {
|
||||
*/
|
||||
protected function should_feature_be_disabled_multisite( $setting ) {
|
||||
return (
|
||||
\in_array( $setting, [ 'deny_search_crawling', 'deny_wp_json_crawling' ], true )
|
||||
\in_array( $setting, [ 'deny_search_crawling', 'deny_wp_json_crawling', 'deny_adsbot_crawling' ], true )
|
||||
&& \is_multisite()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ use WPSEO_Addon_Manager;
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use WPSEO_Option_Tab;
|
||||
use WPSEO_Shortlinker;
|
||||
use WPSEO_Utils;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Context\Meta_Tags_Context;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
@@ -140,8 +139,8 @@ class First_Time_Configuration_Integration implements Integration_Interface {
|
||||
|
||||
$this->admin_asset_manager->enqueue_script( 'indexation' );
|
||||
$this->admin_asset_manager->enqueue_script( 'first-time-configuration' );
|
||||
$this->admin_asset_manager->enqueue_style( 'first-time-configuration' );
|
||||
$this->admin_asset_manager->enqueue_style( 'admin-css' );
|
||||
$this->admin_asset_manager->enqueue_style( 'tailwind' );
|
||||
$this->admin_asset_manager->enqueue_style( 'monorepo' );
|
||||
|
||||
$data = [
|
||||
@@ -185,78 +184,44 @@ class First_Time_Configuration_Integration implements Integration_Interface {
|
||||
$selected_option_label = $selected_option['label'];
|
||||
}
|
||||
|
||||
$this->admin_asset_manager->add_inline_script(
|
||||
'first-time-configuration',
|
||||
\sprintf(
|
||||
'window.wpseoFirstTimeConfigurationData = {
|
||||
"canEditUser": %d,
|
||||
"companyOrPerson": "%s",
|
||||
"companyOrPersonLabel": "%s",
|
||||
"companyName": "%s",
|
||||
"fallbackCompanyName": "%s",
|
||||
"websiteName": "%s",
|
||||
"fallbackWebsiteName": "%s",
|
||||
"companyLogo": "%s",
|
||||
"companyLogoFallback": "%s",
|
||||
"companyLogoId": %d,
|
||||
"finishedSteps": %s,
|
||||
"personId": %d,
|
||||
"personName": "%s",
|
||||
"personLogo": "%s",
|
||||
"personLogoFallback": "%s",
|
||||
"personLogoId": %d,
|
||||
"siteTagline": "%s",
|
||||
"socialProfiles": {
|
||||
"facebookUrl": "%s",
|
||||
"twitterUsername": "%s",
|
||||
"otherSocialUrls": %s,
|
||||
},
|
||||
"isPremium": %d,
|
||||
"tracking": %d,
|
||||
"isTrackingAllowedMultisite": %d,
|
||||
"isMainSite": %d,
|
||||
"companyOrPersonOptions": %s,
|
||||
"shouldForceCompany": %d,
|
||||
"knowledgeGraphMessage": "%s",
|
||||
"shortlinks": {
|
||||
"gdpr": "%s",
|
||||
"configIndexables": "%s",
|
||||
"configIndexablesBenefits": "%s",
|
||||
},
|
||||
};',
|
||||
$this->can_edit_profile( $person_id ),
|
||||
$this->is_company_or_person(),
|
||||
$selected_option_label,
|
||||
$this->get_company_name(),
|
||||
$this->get_fallback_company_name( $this->get_company_name() ),
|
||||
$this->get_website_name(),
|
||||
$this->get_fallback_website_name( $this->get_website_name() ),
|
||||
$this->get_company_logo(),
|
||||
$this->get_company_fallback_logo( $this->get_company_logo() ),
|
||||
$this->get_company_logo_id(),
|
||||
WPSEO_Utils::format_json_encode( $finished_steps ),
|
||||
$person_id,
|
||||
$this->get_person_name(),
|
||||
$this->get_person_logo(),
|
||||
$this->get_person_fallback_logo( $this->get_person_logo() ),
|
||||
$this->get_person_logo_id(),
|
||||
$this->get_site_tagline(),
|
||||
$social_profiles['facebook_site'],
|
||||
$social_profiles['twitter_site'],
|
||||
WPSEO_Utils::format_json_encode( $social_profiles['other_social_urls'] ),
|
||||
$this->product_helper->is_premium(),
|
||||
$this->has_tracking_enabled(),
|
||||
$this->is_tracking_enabled_multisite(),
|
||||
$this->is_main_site(),
|
||||
WPSEO_Utils::format_json_encode( $options ),
|
||||
$this->should_force_company(),
|
||||
$knowledge_graph_message,
|
||||
$this->shortlinker->build_shortlink( 'https://yoa.st/gdpr-config-workout' ),
|
||||
$this->shortlinker->build_shortlink( 'https://yoa.st/config-indexables' ),
|
||||
$this->shortlinker->build_shortlink( 'https://yoa.st/config-indexables-benefits' )
|
||||
),
|
||||
'before'
|
||||
);
|
||||
$data_ftc = [
|
||||
'canEditUser' => $this->can_edit_profile( $person_id ),
|
||||
'companyOrPerson' => $this->is_company_or_person(),
|
||||
'companyOrPersonLabel' => $selected_option_label,
|
||||
'companyName' => $this->get_company_name(),
|
||||
'fallbackCompanyName' => $this->get_fallback_company_name( $this->get_company_name() ),
|
||||
'websiteName' => $this->get_website_name(),
|
||||
'fallbackWebsiteName' => $this->get_fallback_website_name( $this->get_website_name() ),
|
||||
'companyLogo' => $this->get_company_logo(),
|
||||
'companyLogoFallback' => $this->get_company_fallback_logo( $this->get_company_logo() ),
|
||||
'companyLogoId' => $this->get_person_logo_id(),
|
||||
'finishedSteps' => $finished_steps,
|
||||
'personId' => (int) $person_id,
|
||||
'personName' => $this->get_person_name(),
|
||||
'personLogo' => $this->get_person_logo(),
|
||||
'personLogoFallback' => $this->get_person_fallback_logo( $this->get_person_logo() ),
|
||||
'personLogoId' => $this->get_person_logo_id(),
|
||||
'siteTagline' => $this->get_site_tagline(),
|
||||
'socialProfiles' => [
|
||||
'facebookUrl' => $social_profiles['facebook_site'],
|
||||
'twitterUsername' => $social_profiles['twitter_site'],
|
||||
'otherSocialUrls' => $social_profiles['other_social_urls'],
|
||||
],
|
||||
'isPremium' => $this->product_helper->is_premium(),
|
||||
'tracking' => $this->has_tracking_enabled(),
|
||||
'isTrackingAllowedMultisite' => $this->is_tracking_enabled_multisite(),
|
||||
'isMainSite' => $this->is_main_site(),
|
||||
'companyOrPersonOptions' => $options,
|
||||
'shouldForceCompany' => $this->should_force_company(),
|
||||
'knowledgeGraphMessage' => $knowledge_graph_message,
|
||||
'shortlinks' => [
|
||||
'gdpr' => $this->shortlinker->build_shortlink( 'https://yoa.st/gdpr-config-workout' ),
|
||||
'configIndexables' => $this->shortlinker->build_shortlink( 'https://yoa.st/config-indexables' ),
|
||||
'configIndexablesBenefits' => $this->shortlinker->build_shortlink( 'https://yoa.st/config-indexables-benefits' ),
|
||||
],
|
||||
];
|
||||
|
||||
$this->admin_asset_manager->localize_script( 'first-time-configuration', 'wpseoFirstTimeConfigurationData', $data_ftc );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,10 +4,10 @@ namespace Yoast\WP\SEO\Integrations\Admin;
|
||||
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\First_Time_Configuration_Notice_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast\WP\SEO\Presenters\Admin\Notice_Presenter;
|
||||
use Yoast\WP\SEO\Helpers\First_Time_Configuration_Notice_Helper;
|
||||
|
||||
/**
|
||||
* First_Time_Configuration_Notice_Integration class
|
||||
@@ -31,7 +31,7 @@ class First_Time_Configuration_Notice_Integration implements Integration_Interfa
|
||||
/**
|
||||
* The first time configuration notice helper.
|
||||
*
|
||||
* @var \Yoast\WP\SEO\Helpers\First_Time_Configuration_Notice_Helper
|
||||
* @var First_Time_Configuration_Notice_Helper
|
||||
*/
|
||||
private $first_time_configuration_notice_helper;
|
||||
|
||||
@@ -45,9 +45,9 @@ class First_Time_Configuration_Notice_Integration implements Integration_Interfa
|
||||
/**
|
||||
* First_Time_Configuration_Notice_Integration constructor.
|
||||
*
|
||||
* @param Options_Helper $options_helper The options helper.
|
||||
* @param First_Time_Configuration_Notice_Helper $first_time_configuration_notice_helper The first time configuration notice helper.
|
||||
* @param WPSEO_Admin_Asset_Manager $admin_asset_manager The admin asset manager.
|
||||
* @param Options_Helper $options_helper The options helper.
|
||||
* @param First_Time_Configuration_Notice_Helper $first_time_configuration_notice_helper The first time configuration notice helper.
|
||||
* @param WPSEO_Admin_Asset_Manager $admin_asset_manager The admin asset manager.
|
||||
*/
|
||||
public function __construct(
|
||||
Options_Helper $options_helper,
|
||||
|
||||
@@ -9,9 +9,10 @@ use WPSEO_Utils;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Config\Migration_Status;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Academy_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast\WP\SEO\Integrations\Settings_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Academy_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Support_Integration;
|
||||
|
||||
/**
|
||||
* Class WPSEO_HelpScout
|
||||
@@ -69,6 +70,7 @@ class HelpScout_Beacon implements Integration_Interface {
|
||||
'wpseo_dashboard',
|
||||
Settings_Integration::PAGE,
|
||||
Academy_Integration::PAGE,
|
||||
Support_Integration::PAGE,
|
||||
'wpseo_search_console',
|
||||
'wpseo_tools',
|
||||
'wpseo_licenses',
|
||||
|
||||
@@ -199,6 +199,9 @@ class Indexing_Notification_Integration implements Integration_Interface {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're about to perform expensive queries, let's inform.
|
||||
\add_filter( 'wpseo_unindexed_count_queries_ran', '__return_true' );
|
||||
|
||||
// Never show a notification when nothing should be indexed.
|
||||
return $this->indexing_helper->get_limited_filtered_unindexed_count( 1 ) > 0;
|
||||
}
|
||||
|
||||
@@ -2,14 +2,18 @@
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Admin;
|
||||
|
||||
use Easy_Digital_Downloads;
|
||||
use SeriouslySimplePodcasting\Integrations\Yoast\Schema\PodcastEpisode;
|
||||
use TEC\Events\Integrations\Plugins\WordPress_SEO\Events_Schema;
|
||||
use WP_Recipe_Maker;
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use WPSEO_Plugin_Availability;
|
||||
use WPSEO_Shortlinker;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Jetpack_Boost_Active_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Jetpack_Boost_Not_Premium_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Jetpack_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Elementor_Activated_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Jetpack_Boost_Active_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Jetpack_Boost_Not_Premium_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\WooCommerce_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
@@ -111,7 +115,7 @@ class Integrations_Page implements Integration_Interface {
|
||||
$algolia_file = 'wp-search-with-algolia/algolia.php';
|
||||
$old_algolia_file = 'search-by-algolia-instant-relevant-results/algolia.php';
|
||||
|
||||
$host = YoastSEO()->helpers->url->get_url_host( get_site_url() );
|
||||
$host = \YoastSEO()->helpers->url->get_url_host( \get_site_url() );
|
||||
|
||||
$wpseo_plugin_availability_checker = new WPSEO_Plugin_Availability();
|
||||
$woocommerce_seo_installed = \file_exists( \WP_PLUGIN_DIR . '/' . $woocommerce_seo_file );
|
||||
@@ -123,13 +127,13 @@ class Integrations_Page implements Integration_Interface {
|
||||
$acf_seo_github_active = $wpseo_plugin_availability_checker->is_active( $acf_seo_file_github );
|
||||
$acf_active = \class_exists( 'acf' );
|
||||
$algolia_active = $wpseo_plugin_availability_checker->is_active( $algolia_file );
|
||||
$edd_active = \class_exists( \Easy_Digital_Downloads::class );
|
||||
$edd_active = \class_exists( Easy_Digital_Downloads::class );
|
||||
$jetpack_boost_active = $jetpack_boost_active_conditional->is_met();
|
||||
$jetpack_boost_premium = ( ! $jetpack_boost_not_premium_conditional->is_met() );
|
||||
$old_algolia_active = $wpseo_plugin_availability_checker->is_active( $old_algolia_file );
|
||||
$tec_active = \class_exists( \TEC\Events\Integrations\Plugins\WordPress_SEO\Events_Schema::class );
|
||||
$ssp_active = \class_exists( \SeriouslySimplePodcasting\Integrations\Yoast\Schema\PodcastEpisode::class );
|
||||
$wp_recipe_maker_active = \class_exists( \WP_Recipe_Maker::class );
|
||||
$tec_active = \class_exists( Events_Schema::class );
|
||||
$ssp_active = \class_exists( PodcastEpisode::class );
|
||||
$wp_recipe_maker_active = \class_exists( WP_Recipe_Maker::class );
|
||||
$mastodon_active = $this->is_mastodon_active();
|
||||
|
||||
$woocommerce_seo_activate_url = \wp_nonce_url(
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Admin;
|
||||
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Capability_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Product_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast\WP\SEO\Presenters\Admin\Notice_Presenter;
|
||||
|
||||
/**
|
||||
* Old_Premium_Integration class
|
||||
*/
|
||||
class Old_Premium_Integration implements Integration_Interface {
|
||||
|
||||
/**
|
||||
* The minimum Premium version.
|
||||
*/
|
||||
const MINIMUM_PREMIUM_VERSION = '20.1-RC0';
|
||||
|
||||
/**
|
||||
* The options' helper.
|
||||
*
|
||||
* @var Options_Helper
|
||||
*/
|
||||
private $options_helper;
|
||||
|
||||
/**
|
||||
* The product helper.
|
||||
*
|
||||
* @var Product_Helper
|
||||
*/
|
||||
private $product_helper;
|
||||
|
||||
/**
|
||||
* The capability helper.
|
||||
*
|
||||
* @var Capability_Helper
|
||||
*/
|
||||
private $capability_helper;
|
||||
|
||||
/**
|
||||
* The admin asset manager.
|
||||
*
|
||||
* @var WPSEO_Admin_Asset_Manager
|
||||
*/
|
||||
private $admin_asset_manager;
|
||||
|
||||
/**
|
||||
* The Current_Page_Helper.
|
||||
*
|
||||
* @var Current_Page_Helper
|
||||
*/
|
||||
private $current_page_helper;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function get_conditionals() {
|
||||
return [ Admin_Conditional::class ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Old_Premium_Integration constructor.
|
||||
*
|
||||
* @param Options_Helper $options_helper The options helper.
|
||||
* @param Product_Helper $product_helper The product helper.
|
||||
* @param Capability_Helper $capability_helper The capability helper.
|
||||
* @param WPSEO_Admin_Asset_Manager $admin_asset_manager The admin asset manager.
|
||||
* @param Current_Page_Helper $current_page_helper The Current_Page_Helper.
|
||||
*/
|
||||
public function __construct(
|
||||
Options_Helper $options_helper,
|
||||
Product_Helper $product_helper,
|
||||
Capability_Helper $capability_helper,
|
||||
WPSEO_Admin_Asset_Manager $admin_asset_manager,
|
||||
Current_Page_Helper $current_page_helper
|
||||
) {
|
||||
$this->options_helper = $options_helper;
|
||||
$this->product_helper = $product_helper;
|
||||
$this->capability_helper = $capability_helper;
|
||||
$this->admin_asset_manager = $admin_asset_manager;
|
||||
$this->current_page_helper = $current_page_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function register_hooks() {
|
||||
\add_action( 'admin_notices', [ $this, 'old_premium_notice' ] );
|
||||
\add_action( 'wp_ajax_dismiss_old_premium_notice', [ $this, 'dismiss_old_premium_notice' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a notice if Premium is older than 20.0-RC1 so Settings might be missing from the UI.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function old_premium_notice() {
|
||||
global $pagenow;
|
||||
if ( $pagenow === 'update.php' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->notice_was_dismissed_after_current_min_premium_version() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $this->capability_helper->current_user_can( 'wpseo_manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->premium_is_old() ) {
|
||||
$this->admin_asset_manager->enqueue_style( 'monorepo' );
|
||||
|
||||
$is_plugins_page = $this->current_page_helper->get_current_admin_page() === 'plugins.php';
|
||||
$content = \sprintf(
|
||||
/* translators: 1: Yoast SEO Premium, 2 and 3: opening and closing anchor tag. */
|
||||
\esc_html__( 'Please %2$supdate %1$s to the latest version%3$s to ensure you can fully use all Premium settings and features.', 'wordpress-seo' ),
|
||||
'Yoast SEO Premium',
|
||||
( $is_plugins_page ) ? '' : '<a href="' . \esc_url( \self_admin_url( 'plugins.php' ) ) . '">',
|
||||
( $is_plugins_page ) ? '' : '</a>'
|
||||
);
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Output of the title escaped in the Notice_Presenter.
|
||||
echo new Notice_Presenter(
|
||||
/* translators: 1: Yoast SEO Premium */
|
||||
\sprintf( \__( 'Update to the latest version of %1$s!', 'wordpress-seo' ), 'Yoast SEO Premium' ),
|
||||
$content,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
'yoast-old-premium-notice'
|
||||
);
|
||||
// phpcs:enable
|
||||
|
||||
// Enable permanently dismissing the notice.
|
||||
echo "<script>
|
||||
function dismiss_old_premium_notice(){
|
||||
var data = {
|
||||
'action': 'dismiss_old_premium_notice',
|
||||
};
|
||||
|
||||
jQuery.post( ajaxurl, data, function( response ) {
|
||||
jQuery( '#yoast-old-premium-notice' ).hide();
|
||||
});
|
||||
}
|
||||
|
||||
jQuery( document ).ready( function() {
|
||||
jQuery( 'body' ).on( 'click', '#yoast-old-premium-notice .notice-dismiss', function() {
|
||||
dismiss_old_premium_notice();
|
||||
} );
|
||||
} );
|
||||
</script>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the old premium notice.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function dismiss_old_premium_notice() {
|
||||
return $this->options_helper->set( 'dismiss_old_premium_version_notice', self::MINIMUM_PREMIUM_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Premium is installed but older than the minimum premium version.
|
||||
*
|
||||
* @return bool Whether premium is installed but older than minimum premium version.
|
||||
*/
|
||||
protected function premium_is_old() {
|
||||
$premium_version = $this->product_helper->get_premium_version();
|
||||
if ( ! \is_null( $premium_version ) ) {
|
||||
return \version_compare( $premium_version, self::MINIMUM_PREMIUM_VERSION, '<' );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the notification was dismissed in a version later than the minimum premium version.
|
||||
*
|
||||
* @return bool Whether the notification was dismissed in a version later than the minimum premium version.
|
||||
*/
|
||||
protected function notice_was_dismissed_after_current_min_premium_version() {
|
||||
$dismissed_notification_version = $this->options_helper->get( 'dismiss_old_premium_version_notice', '' );
|
||||
if ( ! empty( $dismissed_notification_version ) ) {
|
||||
return \version_compare( $dismissed_notification_version, self::MINIMUM_PREMIUM_VERSION, '>=' );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,7 @@ class Workouts_Integration implements Integration_Interface {
|
||||
$notice = new Notice_Presenter(
|
||||
$title,
|
||||
$copy,
|
||||
'Assistent_Time_bubble_500x570.png',
|
||||
null,
|
||||
$button
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Alerts;
|
||||
|
||||
/**
|
||||
* Black_Friday_Product_Editor_Checklist_Notification class.
|
||||
* @phpcs:disable Yoast.NamingConventions.ObjectNameDepth.MaxExceeded
|
||||
*/
|
||||
class Black_Friday_Product_Editor_Checklist_Notification extends Abstract_Dismissable_Alert {
|
||||
|
||||
/**
|
||||
* Holds the alert identifier.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $alert_identifier = 'black-friday-2023-product-editor-checklist';
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Alerts;
|
||||
|
||||
/**
|
||||
* Black_Friday_Promo_Notification class.
|
||||
*/
|
||||
class Black_Friday_Promo_Notification extends Abstract_Dismissable_Alert {
|
||||
|
||||
/**
|
||||
* Holds the alert identifier.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $alert_identifier = 'black-friday-promo-notification';
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Alerts;
|
||||
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Jetpack_Boost_Not_Premium_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Premium_Inactive_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Jetpack_Boost_Not_Premium_Conditional;
|
||||
|
||||
/**
|
||||
* Jetpack_Boost_Pre_Publish class.
|
||||
|
||||
@@ -173,6 +173,100 @@ class Structured_Data_Blocks implements Integration_Interface {
|
||||
return $this->optimize_images( $attributes['questions'], 'answer', $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the durations into a translated string containing the count, and either singular or plural unit.
|
||||
* For example (in en-US): If 'days' is 1, it returns "1 day". If 'days' is 2, it returns "2 days".
|
||||
* If a number value is 0, we don't output the string.
|
||||
*
|
||||
* @param number $days Number of days.
|
||||
* @param number $hours Number of hours.
|
||||
* @param number $minutes Number of minutes.
|
||||
* @return array Array of pluralized durations.
|
||||
*/
|
||||
private function transform_duration_to_string( $days, $hours, $minutes ) {
|
||||
$strings = [];
|
||||
if ( $days ) {
|
||||
$strings[] = \sprintf(
|
||||
/* translators: %d expands to the number of day/days. */
|
||||
\_n( '%d day', '%d days', $days, 'wordpress-seo' ),
|
||||
$days
|
||||
);
|
||||
}
|
||||
if ( $hours ) {
|
||||
$strings[] = \sprintf(
|
||||
/* translators: %d expands to the number of hour/hours. */
|
||||
\_n( '%d hour', '%d hours', $hours, 'wordpress-seo' ),
|
||||
$hours
|
||||
);
|
||||
}
|
||||
if ( $minutes ) {
|
||||
$strings[] = \sprintf(
|
||||
/* translators: %d expands to the number of minute/minutes. */
|
||||
\_n( '%d minute', '%d minutes', $minutes, 'wordpress-seo' ),
|
||||
$minutes
|
||||
);
|
||||
}
|
||||
return $strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the durations into a translated string.
|
||||
*
|
||||
* @param array $attributes The attributes.
|
||||
* @return string The formatted duration.
|
||||
*/
|
||||
private function build_duration_string( $attributes ) {
|
||||
$days = ( $attributes['days'] ?? 0 );
|
||||
$hours = ( $attributes['hours'] ?? 0 );
|
||||
$minutes = ( $attributes['minutes'] ?? 0 );
|
||||
$elements = $this->transform_duration_to_string( $days, $hours, $minutes );
|
||||
$elements_length = count( $elements );
|
||||
|
||||
switch ( $elements_length ) {
|
||||
case 1:
|
||||
return $elements[0];
|
||||
case 2:
|
||||
return \sprintf(
|
||||
/* translators: %s expands to a unit of time (e.g. 1 day). */
|
||||
\__( '%1$s and %2$s', 'wordpress-seo' ),
|
||||
...$elements
|
||||
);
|
||||
case 3:
|
||||
return \sprintf(
|
||||
/* translators: %s expands to a unit of time (e.g. 1 day). */
|
||||
\__( '%1$s, %2$s and %3$s', 'wordpress-seo' ),
|
||||
...$elements
|
||||
);
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Presents the duration text of the How-To block in the site language.
|
||||
*
|
||||
* @param array $attributes The attributes.
|
||||
* @param string $content The content.
|
||||
*
|
||||
* @return string The content with the duration text in the site language.
|
||||
*/
|
||||
public function present_duration_text( $attributes, $content ) {
|
||||
$duration = $this->build_duration_string( $attributes );
|
||||
// 'Time needed:' is the default duration text that will be shown if a user doesn't add one.
|
||||
$duration_text = \__( 'Time needed:', 'wordpress-seo' );
|
||||
|
||||
if ( isset( $attributes['durationText'] ) && $attributes['durationText'] !== '' ) {
|
||||
$duration_text = $attributes['durationText'];
|
||||
}
|
||||
|
||||
return \preg_replace(
|
||||
'/(<p class="schema-how-to-total-time">)(<span class="schema-how-to-duration-time-text">.*<\/span>)(.[^\/p>]*)(<\/p>)/',
|
||||
'<p class="schema-how-to-total-time"><span class="schema-how-to-duration-time-text">' . $duration_text . ' </span>' . $duration . '</p>',
|
||||
$content,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimizes images in the How-To blocks.
|
||||
*
|
||||
@@ -186,6 +280,8 @@ class Structured_Data_Blocks implements Integration_Interface {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$content = $this->present_duration_text( $attributes, $content );
|
||||
|
||||
return $this->optimize_images( $attributes['steps'], 'text', $content );
|
||||
}
|
||||
|
||||
@@ -346,7 +442,7 @@ class Structured_Data_Blocks implements Integration_Interface {
|
||||
if ( ! isset( $element[ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( isset( $element[ $key ] ) && is_array( $element[ $key ] ) ) {
|
||||
if ( isset( $element[ $key ] ) && \is_array( $element[ $key ] ) ) {
|
||||
foreach ( $element[ $key ] as $part ) {
|
||||
if ( ! \is_array( $part ) || ! isset( $part['type'] ) || $part['type'] !== 'img' ) {
|
||||
continue;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Yoast\WP\SEO\Integrations;
|
||||
|
||||
use Closure;
|
||||
use Yoast\WP\Lib\Model;
|
||||
use Yoast\WP\SEO\Repositories\Indexable_Cleanup_Repository;
|
||||
|
||||
/**
|
||||
@@ -36,7 +35,7 @@ class Cleanup_Integration implements Integration_Interface {
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param Indexable_Cleanup_Repository $cleanup_repository The cleanup repository.
|
||||
* @param Indexable_Cleanup_Repository $cleanup_repository The cleanup repository.
|
||||
*/
|
||||
public function __construct( Indexable_Cleanup_Repository $cleanup_repository ) {
|
||||
$this->cleanup_repository = $cleanup_repository;
|
||||
@@ -126,7 +125,7 @@ class Cleanup_Integration implements Integration_Interface {
|
||||
return $this->cleanup_repository->update_indexables_author_to_reassigned( $limit );
|
||||
},
|
||||
'clean_orphaned_user_indexables_without_wp_user' => function ( $limit ) {
|
||||
return $this->cleanup_repository->clean_indexables_for_object_type_and_source_table( 'users', 'ID', 'user', $limit );
|
||||
return $this->cleanup_repository->clean_indexables_for_orphaned_users( $limit );
|
||||
},
|
||||
'clean_orphaned_user_indexables_without_wp_post' => function ( $limit ) {
|
||||
return $this->cleanup_repository->clean_indexables_for_object_type_and_source_table( 'posts', 'ID', 'post', $limit );
|
||||
@@ -286,4 +285,3 @@ class Cleanup_Integration implements Integration_Interface {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations;
|
||||
|
||||
use WP_HTML_Tag_Processor;
|
||||
use WPSEO_Replace_Vars;
|
||||
use Yoast\WP\SEO\Conditionals\Front_End_Conditional;
|
||||
use Yoast\WP\SEO\Context\Meta_Tags_Context;
|
||||
@@ -175,6 +176,20 @@ class Front_End_Integration implements Integration_Interface {
|
||||
'Schema',
|
||||
];
|
||||
|
||||
/**
|
||||
* The next output.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $next;
|
||||
|
||||
/**
|
||||
* The prev output.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prev;
|
||||
|
||||
/**
|
||||
* Returns the conditionals based on which this loadable should be active.
|
||||
*
|
||||
@@ -219,6 +234,8 @@ class Front_End_Integration implements Integration_Interface {
|
||||
* to avoid duplicate and/or mismatched metadata.
|
||||
*/
|
||||
public function register_hooks() {
|
||||
\add_filter( 'render_block', [ $this, 'query_loop_next_prev' ], 1, 2 );
|
||||
|
||||
\add_action( 'wp_head', [ $this, 'call_wpseo_head' ], 1 );
|
||||
// Filter the title for compatibility with other plugins and themes.
|
||||
\add_filter( 'wp_title', [ $this, 'filter_title' ], 15 );
|
||||
@@ -262,6 +279,72 @@ class Front_End_Integration implements Integration_Interface {
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the next and prev links in the query loop block.
|
||||
*
|
||||
* @param string $html The HTML output.
|
||||
* @param array $block The block.
|
||||
* @return string The filtered HTML output.
|
||||
*/
|
||||
public function query_loop_next_prev( $html, $block ) {
|
||||
if ( $block['blockName'] === 'core/query' ) {
|
||||
// Check that the query does not inherit the main query.
|
||||
if ( isset( $block['attrs']['query']['inherit'] ) && ! $block['attrs']['query']['inherit'] ) {
|
||||
\add_filter( 'wpseo_adjacent_rel_url', [ $this, 'adjacent_rel_url' ], 1, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $block['blockName'] === 'core/query-pagination-next' ) {
|
||||
$this->next = $html;
|
||||
}
|
||||
|
||||
if ( $block['blockName'] === 'core/query-pagination-previous' ) {
|
||||
$this->prev = $html;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns correct adjacent pages when QUery loop block does not inherit query from template.
|
||||
*
|
||||
* @param string $link The current link.
|
||||
* @param string $rel Link relationship, prev or next.
|
||||
* @param Indexable_Presentation|null $presentation The indexable presentation.
|
||||
*
|
||||
* @return string The correct link.
|
||||
*/
|
||||
public function adjacent_rel_url( $link, $rel, $presentation = null ) {
|
||||
if ( $link === \home_url( '/' ) ) {
|
||||
return $link;
|
||||
}
|
||||
|
||||
if ( $rel === 'next' || $rel === 'prev' ) {
|
||||
|
||||
// WP_HTML_Tag_Processor was introduced in WordPress 6.2.
|
||||
if ( \class_exists( WP_HTML_Tag_Processor::class ) ) {
|
||||
$processor = new WP_HTML_Tag_Processor( $this->$rel );
|
||||
while ( $processor->next_tag( [ 'tag_name' => 'a' ] ) ) {
|
||||
$href = $processor->get_attribute( 'href' );
|
||||
if ( $href ) {
|
||||
return $presentation->permalink . substr( $href, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove else when dropping support for WordPress 6.1 and lower.
|
||||
else {
|
||||
$pattern = '/"(.*?)"/';
|
||||
// Find all matches of the pattern in the HTML string.
|
||||
\preg_match_all( $pattern, $this->$rel, $matches );
|
||||
if ( isset( $matches[1] ) && isset( $matches[1][0] ) && $matches[1][0] ) {
|
||||
return $presentation->permalink . \substr( $matches[1][0], 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters our robots presenter, but only when wp_robots is attached to the wp_head action.
|
||||
*
|
||||
@@ -435,6 +518,11 @@ class Front_End_Integration implements Integration_Interface {
|
||||
$presenters = \array_diff( $presenters, $this->singular_presenters );
|
||||
}
|
||||
|
||||
// Filter out `twitter:data` presenters for static home pages.
|
||||
if ( $page_type === 'Static_Home_Page' ) {
|
||||
$presenters = \array_diff( $presenters, $this->slack_presenters );
|
||||
}
|
||||
|
||||
return $presenters;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace Yoast\WP\SEO\Integrations\Front_End;
|
||||
use WP_Query;
|
||||
use Yoast\WP\SEO\Conditionals\Front_End_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast\WP\SEO\Helpers\Redirect_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
|
||||
/**
|
||||
* Class Crawl_Cleanup_Searches.
|
||||
|
||||
@@ -95,7 +95,6 @@ class Open_Graph_OEmbed implements Integration_Interface {
|
||||
$this->set_image();
|
||||
}
|
||||
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
@@ -127,7 +126,7 @@ class Open_Graph_OEmbed implements Integration_Interface {
|
||||
protected function set_image() {
|
||||
$images = $this->post_meta->open_graph_images;
|
||||
|
||||
if ( ! is_array( $images ) ) {
|
||||
if ( ! \is_array( $images ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ class Robots_Txt_Integration implements Integration_Interface {
|
||||
if ( $this->options_helper->get( 'deny_wp_json_crawling' ) && ! \is_multisite() ) {
|
||||
\add_action( 'Yoast\WP\SEO\register_robots_rules', [ $this, 'add_disallow_wp_json_to_robots' ], 10, 1 );
|
||||
}
|
||||
if ( $this->options_helper->get( 'deny_adsbot_crawling' ) && ! \is_multisite() ) {
|
||||
\add_action( 'Yoast\WP\SEO\register_robots_rules', [ $this, 'add_disallow_adsbot' ], 10, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,6 +119,7 @@ class Robots_Txt_Integration implements Integration_Interface {
|
||||
*/
|
||||
public function add_disallow_search_to_robots( Robots_Txt_Helper $robots_txt_helper ) {
|
||||
$robots_txt_helper->add_disallow( '*', '/?s=' );
|
||||
$robots_txt_helper->add_disallow( '*', '/page/*/?s=' );
|
||||
$robots_txt_helper->add_disallow( '*', '/search/' );
|
||||
}
|
||||
|
||||
@@ -131,6 +135,17 @@ class Robots_Txt_Integration implements Integration_Interface {
|
||||
$robots_txt_helper->add_disallow( '*', '/?rest_route=' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a disallow rule for AdsBot agents to robots.txt.
|
||||
*
|
||||
* @param Robots_Txt_Helper $robots_txt_helper The robots txt helper.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_disallow_adsbot( Robots_Txt_Helper $robots_txt_helper ) {
|
||||
$robots_txt_helper->add_disallow( 'AdsBot', '/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the default WordPress robots.txt output.
|
||||
*
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations;
|
||||
|
||||
use Exception;
|
||||
use WP_Post_Type;
|
||||
use WP_Taxonomy;
|
||||
use WP_User;
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use WPSEO_Admin_Editor_Specific_Replace_Vars;
|
||||
use WPSEO_Admin_Recommended_Replace_Vars;
|
||||
@@ -23,7 +23,8 @@ use Yoast\WP\SEO\Helpers\Schema\Article_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
|
||||
use Yoast\WP\SEO\Helpers\User_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Woocommerce_Helper;
|
||||
use Yoast_Notification_Center;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Content_Type_Visibility\Application\Content_Type_Visibility_Dismiss_Notifications;
|
||||
|
||||
/**
|
||||
* Class Settings_Integration.
|
||||
@@ -67,6 +68,9 @@ class Settings_Integration implements Integration_Interface {
|
||||
'most_linked_ignore_list',
|
||||
'least_linked_ignore_list',
|
||||
'indexables_page_reading_list',
|
||||
'show_new_content_type_notification',
|
||||
'new_post_types',
|
||||
'new_taxonomies',
|
||||
],
|
||||
'wpseo_titles' => [
|
||||
'company_logo_meta',
|
||||
@@ -83,6 +87,7 @@ class Settings_Integration implements Integration_Interface {
|
||||
'wpseo' => [
|
||||
'deny_search_crawling',
|
||||
'deny_wp_json_crawling',
|
||||
'deny_adsbot_crawling',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -163,20 +168,36 @@ class Settings_Integration implements Integration_Interface {
|
||||
*/
|
||||
protected $user_helper;
|
||||
|
||||
/**
|
||||
* Holds the Options_Helper instance.
|
||||
*
|
||||
* @var Options_Helper
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Holds the Content_Type_Visibility_Dismiss_Notifications instance.
|
||||
*
|
||||
* @var Content_Type_Visibility_Dismiss_Notifications
|
||||
*/
|
||||
protected $content_type_visibility;
|
||||
|
||||
/**
|
||||
* Constructs Settings_Integration.
|
||||
*
|
||||
* @param WPSEO_Admin_Asset_Manager $asset_manager The WPSEO_Admin_Asset_Manager.
|
||||
* @param WPSEO_Replace_Vars $replace_vars The WPSEO_Replace_Vars.
|
||||
* @param Schema_Types $schema_types The Schema_Types.
|
||||
* @param Current_Page_Helper $current_page_helper The Current_Page_Helper.
|
||||
* @param Post_Type_Helper $post_type_helper The Post_Type_Helper.
|
||||
* @param Language_Helper $language_helper The Language_Helper.
|
||||
* @param Taxonomy_Helper $taxonomy_helper The Taxonomy_Helper.
|
||||
* @param Product_Helper $product_helper The Product_Helper.
|
||||
* @param Woocommerce_Helper $woocommerce_helper The Woocommerce_Helper.
|
||||
* @param Article_Helper $article_helper The Article_Helper.
|
||||
* @param User_Helper $user_helper The User_Helper.
|
||||
* @param WPSEO_Admin_Asset_Manager $asset_manager The WPSEO_Admin_Asset_Manager.
|
||||
* @param WPSEO_Replace_Vars $replace_vars The WPSEO_Replace_Vars.
|
||||
* @param Schema_Types $schema_types The Schema_Types.
|
||||
* @param Current_Page_Helper $current_page_helper The Current_Page_Helper.
|
||||
* @param Post_Type_Helper $post_type_helper The Post_Type_Helper.
|
||||
* @param Language_Helper $language_helper The Language_Helper.
|
||||
* @param Taxonomy_Helper $taxonomy_helper The Taxonomy_Helper.
|
||||
* @param Product_Helper $product_helper The Product_Helper.
|
||||
* @param Woocommerce_Helper $woocommerce_helper The Woocommerce_Helper.
|
||||
* @param Article_Helper $article_helper The Article_Helper.
|
||||
* @param User_Helper $user_helper The User_Helper.
|
||||
* @param Options_Helper $options The options helper.
|
||||
* @param Content_Type_Visibility_Dismiss_Notifications $content_type_visibility The Content_Type_Visibility_Dismiss_Notifications instance.
|
||||
*/
|
||||
public function __construct(
|
||||
WPSEO_Admin_Asset_Manager $asset_manager,
|
||||
@@ -189,19 +210,23 @@ class Settings_Integration implements Integration_Interface {
|
||||
Product_Helper $product_helper,
|
||||
Woocommerce_Helper $woocommerce_helper,
|
||||
Article_Helper $article_helper,
|
||||
User_Helper $user_helper
|
||||
User_Helper $user_helper,
|
||||
Options_Helper $options,
|
||||
Content_Type_Visibility_Dismiss_Notifications $content_type_visibility
|
||||
) {
|
||||
$this->asset_manager = $asset_manager;
|
||||
$this->replace_vars = $replace_vars;
|
||||
$this->schema_types = $schema_types;
|
||||
$this->current_page_helper = $current_page_helper;
|
||||
$this->taxonomy_helper = $taxonomy_helper;
|
||||
$this->post_type_helper = $post_type_helper;
|
||||
$this->language_helper = $language_helper;
|
||||
$this->product_helper = $product_helper;
|
||||
$this->woocommerce_helper = $woocommerce_helper;
|
||||
$this->article_helper = $article_helper;
|
||||
$this->user_helper = $user_helper;
|
||||
$this->asset_manager = $asset_manager;
|
||||
$this->replace_vars = $replace_vars;
|
||||
$this->schema_types = $schema_types;
|
||||
$this->current_page_helper = $current_page_helper;
|
||||
$this->taxonomy_helper = $taxonomy_helper;
|
||||
$this->post_type_helper = $post_type_helper;
|
||||
$this->language_helper = $language_helper;
|
||||
$this->product_helper = $product_helper;
|
||||
$this->woocommerce_helper = $woocommerce_helper;
|
||||
$this->article_helper = $article_helper;
|
||||
$this->user_helper = $user_helper;
|
||||
$this->options = $options;
|
||||
$this->content_type_visibility = $content_type_visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,9 +271,6 @@ class Settings_Integration implements Integration_Interface {
|
||||
\add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
|
||||
\add_action( 'in_admin_header', [ $this, 'remove_notices' ], \PHP_INT_MAX );
|
||||
|
||||
// Remove the post types and taxonomies made public notifications (if any).
|
||||
$this->remove_post_types_made_public_notification();
|
||||
$this->remove_taxonomies_made_public_notification();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,20 +410,24 @@ class Settings_Integration implements Integration_Interface {
|
||||
$transformed_post_types = $this->transform_post_types( $post_types );
|
||||
$transformed_taxonomies = $this->transform_taxonomies( $taxonomies, \array_keys( $transformed_post_types ) );
|
||||
|
||||
// Check if there is a new content type to show notification only once in the settings.
|
||||
$show_new_content_type_notification = $this->content_type_visibility->maybe_add_settings_notification();
|
||||
|
||||
return [
|
||||
'settings' => $this->transform_settings( $settings ),
|
||||
'defaultSettingValues' => $default_setting_values,
|
||||
'disabledSettings' => $this->get_disabled_settings( $settings ),
|
||||
'endpoint' => \admin_url( 'options.php' ),
|
||||
'nonce' => \wp_create_nonce( self::PAGE . '-options' ),
|
||||
'separators' => WPSEO_Option_Titles::get_instance()->get_separator_options_for_display(),
|
||||
'replacementVariables' => $this->get_replacement_variables(),
|
||||
'schema' => $this->get_schema( $transformed_post_types ),
|
||||
'preferences' => $this->get_preferences( $settings ),
|
||||
'linkParams' => WPSEO_Shortlinker::get_query_params(),
|
||||
'postTypes' => $transformed_post_types,
|
||||
'taxonomies' => $transformed_taxonomies,
|
||||
'fallbacks' => $this->get_fallbacks(),
|
||||
'settings' => $this->transform_settings( $settings ),
|
||||
'defaultSettingValues' => $default_setting_values,
|
||||
'disabledSettings' => $this->get_disabled_settings( $settings ),
|
||||
'endpoint' => \admin_url( 'options.php' ),
|
||||
'nonce' => \wp_create_nonce( self::PAGE . '-options' ),
|
||||
'separators' => WPSEO_Option_Titles::get_instance()->get_separator_options_for_display(),
|
||||
'replacementVariables' => $this->get_replacement_variables(),
|
||||
'schema' => $this->get_schema( $transformed_post_types ),
|
||||
'preferences' => $this->get_preferences( $settings ),
|
||||
'linkParams' => WPSEO_Shortlinker::get_query_params(),
|
||||
'postTypes' => $transformed_post_types,
|
||||
'taxonomies' => $transformed_taxonomies,
|
||||
'fallbacks' => $this->get_fallbacks(),
|
||||
'showNewContentTypeNotification' => $show_new_content_type_notification,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -440,12 +466,14 @@ class Settings_Integration implements Integration_Interface {
|
||||
'homepagePageEditUrl' => \get_edit_post_link( $page_on_front, 'js' ),
|
||||
'homepagePostsEditUrl' => \get_edit_post_link( $page_for_posts, 'js' ),
|
||||
'createUserUrl' => \admin_url( 'user-new.php' ),
|
||||
'createPageUrl' => \admin_url( 'post-new.php?post_type=page' ),
|
||||
'editUserUrl' => \admin_url( 'user-edit.php' ),
|
||||
'editTaxonomyUrl' => \admin_url( 'edit-tags.php' ),
|
||||
'generalSettingsUrl' => \admin_url( 'options-general.php' ),
|
||||
'companyOrPersonMessage' => \apply_filters( 'wpseo_knowledge_graph_setting_msg', '' ),
|
||||
'currentUserId' => \get_current_user_id(),
|
||||
'canCreateUsers' => \current_user_can( 'create_users' ),
|
||||
'canCreatePages' => \current_user_can( 'edit_pages' ),
|
||||
'canEditUsers' => \current_user_can( 'edit_users' ),
|
||||
'canManageOptions' => \current_user_can( 'manage_options' ),
|
||||
'userLocale' => \str_replace( '_', '-', \get_user_locale() ),
|
||||
@@ -453,6 +481,7 @@ class Settings_Integration implements Integration_Interface {
|
||||
'showForceRewriteTitlesSetting' => ! \current_theme_supports( 'title-tag' ) && ! ( \function_exists( 'wp_is_block_theme' ) && \wp_is_block_theme() ),
|
||||
'upsellSettings' => $this->get_upsell_settings(),
|
||||
'siteRepresentsPerson' => $this->get_site_represents_person( $settings ),
|
||||
'siteBasicsPolicies' => $this->get_site_basics_policies( $settings ),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -472,7 +501,7 @@ class Settings_Integration implements Integration_Interface {
|
||||
if ( isset( $settings['wpseo_titles']['company_or_person_user_id'] ) ) {
|
||||
$person['id'] = $settings['wpseo_titles']['company_or_person_user_id'];
|
||||
$user = \get_userdata( $person['id'] );
|
||||
if ( $user instanceof \WP_User ) {
|
||||
if ( $user instanceof WP_User ) {
|
||||
$person['name'] = $user->get( 'display_name' );
|
||||
}
|
||||
}
|
||||
@@ -480,6 +509,59 @@ class Settings_Integration implements Integration_Interface {
|
||||
return $person;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site policy data.
|
||||
*
|
||||
* @param array $settings The settings.
|
||||
*
|
||||
* @return array The policy data.
|
||||
*/
|
||||
private function get_site_basics_policies( $settings ) {
|
||||
$policies = [];
|
||||
|
||||
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['publishing_principles_id'], 'publishing_principles_id' );
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['ownership_funding_info_id'], 'ownership_funding_info_id' );
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['actionable_feedback_policy_id'], 'actionable_feedback_policy_id' );
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['corrections_policy_id'], 'corrections_policy_id' );
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['ethics_policy_id'], 'ethics_policy_id' );
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['diversity_policy_id'], 'diversity_policy_id' );
|
||||
$policies = $this->maybe_add_policy( $policies, $settings['wpseo_titles']['diversity_staffing_report_id'], 'diversity_staffing_report_id' );
|
||||
|
||||
return $policies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds policy data if it is present.
|
||||
*
|
||||
* @param array $policies The existing policy data.
|
||||
* @param int $policy The policy id to check.
|
||||
* @param string $key The option key name.
|
||||
*
|
||||
* @return array The policy data.
|
||||
*/
|
||||
private function maybe_add_policy( $policies, $policy, $key ) {
|
||||
$policy_array = [
|
||||
'id' => 0,
|
||||
'name' => \__( 'None', 'wordpress-seo' ),
|
||||
];
|
||||
|
||||
if ( isset( $policy ) && \is_int( $policy ) ) {
|
||||
$policy_array['id'] = $policy;
|
||||
$post = \get_post( $policy );
|
||||
if ( $post instanceof \WP_Post ) {
|
||||
if ( $post->post_status !== 'publish' || $post->post_password !== '' ) {
|
||||
return $policies;
|
||||
}
|
||||
$policy_array['name'] = $post->post_title;
|
||||
}
|
||||
}
|
||||
|
||||
$policies[ $key ] = $policy_array;
|
||||
|
||||
return $policies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns settings for the Call to Buy (CTB) buttons.
|
||||
*
|
||||
@@ -694,7 +776,8 @@ class Settings_Integration implements Integration_Interface {
|
||||
* @return array The post types.
|
||||
*/
|
||||
protected function transform_post_types( $post_types ) {
|
||||
$transformed = [];
|
||||
$transformed = [];
|
||||
$new_post_types = $this->options->get( 'new_post_types', [] );
|
||||
foreach ( $post_types as $post_type ) {
|
||||
$transformed[ $post_type->name ] = [
|
||||
'name' => $post_type->name,
|
||||
@@ -704,6 +787,7 @@ class Settings_Integration implements Integration_Interface {
|
||||
'hasArchive' => $this->post_type_helper->has_archive( $post_type ),
|
||||
'hasSchemaArticleType' => $this->article_helper->is_article_post_type( $post_type->name ),
|
||||
'menuPosition' => $post_type->menu_position,
|
||||
'isNew' => \in_array( $post_type->name, $new_post_types, true ),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -745,7 +829,8 @@ class Settings_Integration implements Integration_Interface {
|
||||
* @return array The taxonomies.
|
||||
*/
|
||||
protected function transform_taxonomies( $taxonomies, $post_type_names ) {
|
||||
$transformed = [];
|
||||
$transformed = [];
|
||||
$new_taxonomies = $this->options->get( 'new_taxonomies', [] );
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
$transformed[ $taxonomy->name ] = [
|
||||
'name' => $taxonomy->name,
|
||||
@@ -759,6 +844,7 @@ class Settings_Integration implements Integration_Interface {
|
||||
return \in_array( $object_type, $post_type_names, true );
|
||||
}
|
||||
),
|
||||
'isNew' => \in_array( $taxonomy->name, $new_taxonomies, true ),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -815,24 +901,4 @@ class Settings_Integration implements Integration_Interface {
|
||||
'siteLogoId' => $site_logo_id,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the notification related to the post types which have been made public.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function remove_post_types_made_public_notification() {
|
||||
$notification_center = Yoast_Notification_Center::get();
|
||||
$notification_center->remove_notification_by_id( 'post-types-made-public' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the notification related to the taxonomies which have been made public.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function remove_taxonomies_made_public_notification() {
|
||||
$notification_center = Yoast_Notification_Center::get();
|
||||
$notification_center->remove_notification_by_id( 'taxonomies-made-public' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations;
|
||||
|
||||
use WPSEO_Admin_Asset_Manager;
|
||||
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\User_Can_Manage_Wpseo_Options_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Product_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Short_Link_Helper;
|
||||
|
||||
/**
|
||||
* Class Support_Integration.
|
||||
*/
|
||||
class Support_Integration implements Integration_Interface {
|
||||
|
||||
const PAGE = 'wpseo_page_support';
|
||||
|
||||
const CAPABILITY = 'wpseo_manage_options';
|
||||
|
||||
/**
|
||||
* Holds the WPSEO_Admin_Asset_Manager.
|
||||
*
|
||||
* @var WPSEO_Admin_Asset_Manager
|
||||
*/
|
||||
private $asset_manager;
|
||||
|
||||
/**
|
||||
* Holds the Current_Page_Helper.
|
||||
*
|
||||
* @var Current_Page_Helper
|
||||
*/
|
||||
private $current_page_helper;
|
||||
|
||||
/**
|
||||
* Holds the Product_Helper.
|
||||
*
|
||||
* @var Product_Helper
|
||||
*/
|
||||
private $product_helper;
|
||||
|
||||
/**
|
||||
* Holds the Short_Link_Helper.
|
||||
*
|
||||
* @var Short_Link_Helper
|
||||
*/
|
||||
private $shortlink_helper;
|
||||
|
||||
/**
|
||||
* Constructs Support_Integration.
|
||||
*
|
||||
* @param WPSEO_Admin_Asset_Manager $asset_manager The WPSEO_Admin_Asset_Manager.
|
||||
* @param Current_Page_Helper $current_page_helper The Current_Page_Helper.
|
||||
* @param Product_Helper $product_helper The Product_Helper.
|
||||
* @param Short_Link_Helper $shortlink_helper The Short_Link_Helper.
|
||||
*/
|
||||
public function __construct(
|
||||
WPSEO_Admin_Asset_Manager $asset_manager,
|
||||
Current_Page_Helper $current_page_helper,
|
||||
Product_Helper $product_helper,
|
||||
Short_Link_Helper $shortlink_helper
|
||||
) {
|
||||
$this->asset_manager = $asset_manager;
|
||||
$this->current_page_helper = $current_page_helper;
|
||||
$this->product_helper = $product_helper;
|
||||
$this->shortlink_helper = $shortlink_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the conditionals based on which this loadable should be active.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_conditionals() {
|
||||
return [ Admin_Conditional::class, User_Can_Manage_Wpseo_Options_Conditional::class ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the integration.
|
||||
*
|
||||
* This is the place to register hooks and filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
// Add page.
|
||||
\add_filter( 'wpseo_submenu_pages', [ $this, 'add_page' ], \PHP_INT_MAX );
|
||||
|
||||
// Are we on the settings page?
|
||||
if ( $this->current_page_helper->get_current_yoast_seo_page() === self::PAGE ) {
|
||||
\add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
|
||||
\add_action( 'in_admin_header', [ $this, 'remove_notices' ], \PHP_INT_MAX );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the page.
|
||||
*
|
||||
* @param array $pages The pages.
|
||||
*
|
||||
* @return array The pages.
|
||||
*/
|
||||
public function add_page( $pages ) {
|
||||
$pages[] = [
|
||||
'wpseo_dashboard',
|
||||
'',
|
||||
\__( 'Support', 'wordpress-seo' ),
|
||||
self::CAPABILITY,
|
||||
self::PAGE,
|
||||
[ $this, 'display_page' ],
|
||||
];
|
||||
|
||||
return $pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the page.
|
||||
*/
|
||||
public function display_page() {
|
||||
echo '<div id="yoast-seo-support"></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the assets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_assets() {
|
||||
// Remove the emoji script as it is incompatible with both React and any contenteditable fields.
|
||||
\remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
||||
$this->asset_manager->enqueue_script( 'support' );
|
||||
$this->asset_manager->enqueue_style( 'support' );
|
||||
$this->asset_manager->localize_script( 'support', 'wpseoScriptData', $this->get_script_data() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all current WP notices.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove_notices() {
|
||||
\remove_all_actions( 'admin_notices' );
|
||||
\remove_all_actions( 'user_admin_notices' );
|
||||
\remove_all_actions( 'network_admin_notices' );
|
||||
\remove_all_actions( 'all_admin_notices' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the script data.
|
||||
*
|
||||
* @return array The script data.
|
||||
*/
|
||||
public function get_script_data() {
|
||||
return [
|
||||
'preferences' => [
|
||||
'isPremium' => $this->product_helper->is_premium(),
|
||||
'isRtl' => \is_rtl(),
|
||||
'pluginUrl' => \plugins_url( '', \WPSEO_FILE ),
|
||||
'upsellSettings' => [
|
||||
'actionId' => 'load-nfd-ctb',
|
||||
'premiumCtbId' => 'f6a84663-465f-4cb5-8ba5-f7a6d72224b2',
|
||||
],
|
||||
],
|
||||
'linkParams' => $this->shortlink_helper->get_query_params(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,9 @@ use WPSEO_Admin_Asset_Manager;
|
||||
use WPSEO_Admin_Recommended_Replace_Vars;
|
||||
use WPSEO_Language_Utils;
|
||||
use WPSEO_Meta;
|
||||
use WPSEO_Metabox_Analysis_Inclusive_Language;
|
||||
use WPSEO_Metabox_Analysis_Readability;
|
||||
use WPSEO_Metabox_Analysis_SEO;
|
||||
use WPSEO_Metabox_Analysis_Inclusive_Language;
|
||||
use WPSEO_Metabox_Formatter;
|
||||
use WPSEO_Post_Metabox_Formatter;
|
||||
use WPSEO_Replace_Vars;
|
||||
@@ -20,10 +20,13 @@ use WPSEO_Shortlinker;
|
||||
use WPSEO_Utils;
|
||||
use Yoast\WP\SEO\Actions\Alert_Dismissal_Action;
|
||||
use Yoast\WP\SEO\Conditionals\Third_Party\Elementor_Edit_Conditional;
|
||||
use Yoast\WP\SEO\Conditionals\WooCommerce_Conditional;
|
||||
use Yoast\WP\SEO\Helpers\Capability_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast\WP\SEO\Introductions\Infrastructure\Wistia_Embed_Permission_Repository;
|
||||
use Yoast\WP\SEO\Presenters\Admin\Meta_Fields_Presenter;
|
||||
use Yoast\WP\SEO\Promotions\Application\Promotion_Manager_Interface;
|
||||
|
||||
/**
|
||||
* Integrates the Yoast SEO metabox in the Elementor editor.
|
||||
@@ -98,6 +101,13 @@ class Elementor implements Integration_Interface {
|
||||
*/
|
||||
protected $inclusive_language_analysis;
|
||||
|
||||
/**
|
||||
* The promotions manager.
|
||||
*
|
||||
* @var Promotion_Manager_Interface
|
||||
*/
|
||||
private $promotion_manager;
|
||||
|
||||
/**
|
||||
* Returns the conditionals based in which this loadable should be active.
|
||||
*
|
||||
@@ -110,18 +120,21 @@ class Elementor implements Integration_Interface {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param WPSEO_Admin_Asset_Manager $asset_manager The asset manager.
|
||||
* @param Options_Helper $options The options helper.
|
||||
* @param Capability_Helper $capability The capability helper.
|
||||
* @param WPSEO_Admin_Asset_Manager $asset_manager The asset manager.
|
||||
* @param Options_Helper $options The options helper.
|
||||
* @param Capability_Helper $capability The capability helper.
|
||||
* @param Promotion_Manager_Interface $promotion_manager The promotions manager.
|
||||
*/
|
||||
public function __construct(
|
||||
WPSEO_Admin_Asset_Manager $asset_manager,
|
||||
Options_Helper $options,
|
||||
Capability_Helper $capability
|
||||
Capability_Helper $capability,
|
||||
Promotion_Manager_Interface $promotion_manager
|
||||
) {
|
||||
$this->asset_manager = $asset_manager;
|
||||
$this->options = $options;
|
||||
$this->capability = $capability;
|
||||
$this->asset_manager = $asset_manager;
|
||||
$this->options = $options;
|
||||
$this->capability = $capability;
|
||||
$this->promotion_manager = $promotion_manager;
|
||||
|
||||
$this->seo_analysis = new WPSEO_Metabox_Analysis_SEO();
|
||||
$this->readability_analysis = new WPSEO_Metabox_Analysis_Readability();
|
||||
@@ -146,9 +159,11 @@ class Elementor implements Integration_Interface {
|
||||
|
||||
/**
|
||||
* Registers our Elementor hooks.
|
||||
* This is done for pages with metabox on page load and not on ajax request.
|
||||
*/
|
||||
public function register_elementor_hooks() {
|
||||
if ( ! $this->display_metabox( $this->get_metabox_post()->post_type ) ) {
|
||||
|
||||
if ( $this->get_metabox_post() === null || ! $this->display_metabox( $this->get_metabox_post()->post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -399,6 +414,7 @@ class Elementor implements Integration_Interface {
|
||||
$this->asset_manager->enqueue_style( 'scoring' );
|
||||
$this->asset_manager->enqueue_style( 'monorepo' );
|
||||
$this->asset_manager->enqueue_style( 'admin-css' );
|
||||
$this->asset_manager->enqueue_style( 'ai-generator' );
|
||||
$this->asset_manager->enqueue_style( 'elementor' );
|
||||
|
||||
$this->asset_manager->enqueue_script( 'admin-global' );
|
||||
@@ -432,24 +448,31 @@ class Elementor implements Integration_Interface {
|
||||
'enabled_features' => WPSEO_Utils::retrieve_enabled_features(),
|
||||
];
|
||||
|
||||
$alert_dismissal_action = \YoastSEO()->classes->get( Alert_Dismissal_Action::class );
|
||||
$dismissed_alerts = $alert_dismissal_action->all_dismissed();
|
||||
$alert_dismissal_action = \YoastSEO()->classes->get( Alert_Dismissal_Action::class );
|
||||
$dismissed_alerts = $alert_dismissal_action->all_dismissed();
|
||||
$woocommerce_conditional = new WooCommerce_Conditional();
|
||||
|
||||
$script_data = [
|
||||
'media' => [ 'choose_image' => \__( 'Use Image', 'wordpress-seo' ) ],
|
||||
'metabox' => $this->get_metabox_script_data(),
|
||||
'userLanguageCode' => WPSEO_Language_Utils::get_language( \get_user_locale() ),
|
||||
'isPost' => true,
|
||||
'isBlockEditor' => WP_Screen::get()->is_block_editor(),
|
||||
'isElementorEditor' => true,
|
||||
'postStatus' => \get_post_status( $post_id ),
|
||||
'analysis' => [
|
||||
'media' => [ 'choose_image' => \__( 'Use Image', 'wordpress-seo' ) ],
|
||||
'metabox' => $this->get_metabox_script_data(),
|
||||
'userLanguageCode' => WPSEO_Language_Utils::get_language( \get_user_locale() ),
|
||||
'isPost' => true,
|
||||
'isBlockEditor' => WP_Screen::get()->is_block_editor(),
|
||||
'isElementorEditor' => true,
|
||||
'isWooCommerceActive' => $woocommerce_conditional->is_met(),
|
||||
'postStatus' => \get_post_status( $post_id ),
|
||||
'postType' => \get_post_type( $post_id ),
|
||||
'analysis' => [
|
||||
'plugins' => $plugins_script_data,
|
||||
'worker' => $worker_script_data,
|
||||
],
|
||||
'dismissedAlerts' => $dismissed_alerts,
|
||||
'webinarIntroElementorUrl' => WPSEO_Shortlinker::get( 'https://yoa.st/webinar-intro-elementor' ),
|
||||
'usedKeywordsNonce' => \wp_create_nonce( 'wpseo-keyword-usage-and-post-types' ),
|
||||
'dismissedAlerts' => $dismissed_alerts,
|
||||
'webinarIntroElementorUrl' => WPSEO_Shortlinker::get( 'https://yoa.st/webinar-intro-elementor' ),
|
||||
'blackFridayBlockEditorUrl' => ( $this->promotion_manager->is( 'black_friday_2023_checklist' ) ) ? WPSEO_Shortlinker::get( 'https://yoa.st/black-friday-checklist' ) : '',
|
||||
'usedKeywordsNonce' => \wp_create_nonce( 'wpseo-keyword-usage-and-post-types' ),
|
||||
'linkParams' => WPSEO_Shortlinker::get_query_params(),
|
||||
'pluginUrl' => \plugins_url( '', \WPSEO_FILE ),
|
||||
'wistiaEmbedPermission' => \YoastSEO()->classes->get( Wistia_Embed_Permission_Repository::class )->get_value_for_user( \get_current_user_id() ),
|
||||
];
|
||||
|
||||
if ( \post_type_supports( $this->get_metabox_post()->post_type, 'thumbnail' ) ) {
|
||||
@@ -545,7 +568,7 @@ class Elementor implements Integration_Interface {
|
||||
|
||||
$post = null;
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
|
||||
if ( isset( $_GET['post'] ) && \is_string( $_GET['post'] ) ) {
|
||||
if ( isset( $_GET['post'] ) && \is_numeric( $_GET['post'] ) ) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended -- Reason: No sanitization needed because we cast to an integer,We are not processing form information.
|
||||
$post = (int) \wp_unslash( $_GET['post'] );
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class Wincher implements Integration_Interface {
|
||||
* @param Yoast_Feature_Toggle $integration The integration toggle class.
|
||||
*/
|
||||
public function after_integration_toggle( $integration ) {
|
||||
_deprecated_function( __METHOD__, 'Yoast SEO 20.3' );
|
||||
\_deprecated_function( __METHOD__, 'Yoast SEO 20.3' );
|
||||
if ( $integration->setting === 'wincher_integration_active' ) {
|
||||
if ( \is_multisite() ) {
|
||||
$this->get_disabled_note();
|
||||
|
||||
@@ -117,7 +117,7 @@ class Wordproof_Integration_Toggle implements Integration_Interface {
|
||||
* @param Yoast_Feature_Toggle $integration The integration toggle class.
|
||||
*/
|
||||
public function after_integration_toggle( $integration ) {
|
||||
_deprecated_function( __METHOD__, 'Yoast SEO 20.3' );
|
||||
\_deprecated_function( __METHOD__, 'Yoast SEO 20.3' );
|
||||
if ( $integration->setting === 'wordproof_integration_active' ) {
|
||||
if ( $integration->disabled ) {
|
||||
|
||||
|
||||
@@ -129,7 +129,6 @@ class Indexable_Ancestor_Watcher implements Integration_Interface {
|
||||
$child_indexables_for_term = $this->get_children_for_term( $indexable->object_id, $child_indexables );
|
||||
|
||||
\array_walk( $child_indexables_for_term, [ $this, 'update_hierarchy_and_permalink' ] );
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Yoast\WP\SEO\Integrations\Watchers;
|
||||
|
||||
use Yoast_Notification_Center;
|
||||
use Yoast\WP\SEO\Actions\Indexing\Indexable_Post_Indexation_Action;
|
||||
use Yoast\WP\SEO\Conditionals\Migrations_Conditional;
|
||||
use Yoast\WP\SEO\Config\Indexing_Reasons;
|
||||
@@ -10,6 +9,7 @@ use Yoast\WP\SEO\Helpers\Attachment_Cleanup_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Indexing_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast_Notification_Center;
|
||||
|
||||
/**
|
||||
* Watches the disable-attachment key in wpseo_titles, in order to clear the permalink of the category indexables.
|
||||
@@ -116,7 +116,7 @@ class Indexable_Attachment_Watcher implements Integration_Interface {
|
||||
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
// This just schedules the cleanup routine cron again.
|
||||
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
\wp_schedule_single_event( ( \time() + ( \MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Post_Type_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast_Notification;
|
||||
use Yoast_Notification_Center;
|
||||
|
||||
/**
|
||||
@@ -100,7 +99,8 @@ class Indexable_Post_Type_Change_Watcher implements Integration_Interface {
|
||||
return;
|
||||
}
|
||||
|
||||
$public_post_types = \array_keys( $this->post_type_helper->get_public_post_types() );
|
||||
$public_post_types = $this->post_type_helper->get_indexable_post_types();
|
||||
|
||||
$last_known_public_post_types = $this->options->get( 'last_known_public_post_types', [] );
|
||||
|
||||
// Initializing the option on the first run.
|
||||
@@ -109,6 +109,7 @@ class Indexable_Post_Type_Change_Watcher implements Integration_Interface {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// We look for new public post types.
|
||||
$newly_made_public_post_types = \array_diff( $public_post_types, $last_known_public_post_types );
|
||||
// We look for post types that from public have been made private.
|
||||
@@ -123,7 +124,7 @@ class Indexable_Post_Type_Change_Watcher implements Integration_Interface {
|
||||
$this->options->set( 'last_known_public_post_types', $public_post_types );
|
||||
|
||||
// There are new post types that have been made public.
|
||||
if ( ! empty( $newly_made_public_post_types ) ) {
|
||||
if ( $newly_made_public_post_types ) {
|
||||
|
||||
// Force a notification requesting to start the SEO data optimization.
|
||||
\delete_transient( Indexable_Post_Indexation_Action::UNINDEXED_COUNT_TRANSIENT );
|
||||
@@ -131,54 +132,18 @@ class Indexable_Post_Type_Change_Watcher implements Integration_Interface {
|
||||
|
||||
$this->indexing_helper->set_reason( Indexing_Reasons::REASON_POST_TYPE_MADE_PUBLIC );
|
||||
|
||||
$this->maybe_add_notification();
|
||||
do_action( 'new_public_post_type_notifications', $newly_made_public_post_types );
|
||||
}
|
||||
|
||||
// There are post types that have been made private.
|
||||
if ( ! empty( $newly_made_non_public_post_types ) ) {
|
||||
if ( $newly_made_non_public_post_types ) {
|
||||
// Schedule a cron job to remove all the posts whose post type has been made private.
|
||||
$cleanup_not_yet_scheduled = ! \wp_next_scheduled( Cleanup_Integration::START_HOOK );
|
||||
if ( $cleanup_not_yet_scheduled ) {
|
||||
\wp_schedule_single_event( ( \time() + ( \MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
|
||||
do_action( 'clean_new_public_post_type_notifications', $newly_made_non_public_post_types );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if a notification should be added in the notification center.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function maybe_add_notification() {
|
||||
$notification = $this->notification_center->get_notification_by_id( 'post-types-made-public' );
|
||||
if ( \is_null( $notification ) ) {
|
||||
$this->add_notification();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a notification to be shown on the next page request since posts are updated in an ajax request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_notification() {
|
||||
$message = \sprintf(
|
||||
/* translators: 1: Opening tag of the link to the Search appearance settings page, 2: Link closing tag. */
|
||||
\esc_html__( 'It looks like you\'ve added a new type of content to your website. We recommend that you review your %1$sSettings%2$s under Content types.', 'wordpress-seo' ),
|
||||
'<a href="' . \esc_url( \admin_url( 'admin.php?page=wpseo_page_settings' ) ) . '">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$notification = new Yoast_Notification(
|
||||
$message,
|
||||
[
|
||||
'type' => Yoast_Notification::WARNING,
|
||||
'id' => 'post-types-made-public',
|
||||
'capabilities' => 'wpseo_manage_options',
|
||||
'priority' => 0.8,
|
||||
]
|
||||
);
|
||||
|
||||
$this->notification_center->add_notification( $notification );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ use Yoast\WP\SEO\Helpers\Options_Helper;
|
||||
use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Integration_Interface;
|
||||
use Yoast_Notification;
|
||||
use Yoast_Notification_Center;
|
||||
|
||||
/**
|
||||
@@ -102,7 +101,8 @@ class Indexable_Taxonomy_Change_Watcher implements Integration_Interface {
|
||||
return;
|
||||
}
|
||||
|
||||
$public_taxonomies = \array_keys( $this->taxonomy_helper->get_public_taxonomies() );
|
||||
$public_taxonomies = $this->taxonomy_helper->get_indexable_taxonomies();
|
||||
|
||||
$last_known_public_taxonomies = $this->options->get( 'last_known_public_taxonomies', [] );
|
||||
|
||||
// Initializing the option on the first run.
|
||||
@@ -113,6 +113,7 @@ class Indexable_Taxonomy_Change_Watcher implements Integration_Interface {
|
||||
|
||||
// We look for new public taxonomies.
|
||||
$newly_made_public_taxonomies = \array_diff( $public_taxonomies, $last_known_public_taxonomies );
|
||||
|
||||
// We look fortaxonomies that from public have been made private.
|
||||
$newly_made_non_public_taxonomies = \array_diff( $last_known_public_taxonomies, $public_taxonomies );
|
||||
|
||||
@@ -132,8 +133,7 @@ class Indexable_Taxonomy_Change_Watcher implements Integration_Interface {
|
||||
\delete_transient( Indexable_Term_Indexation_Action::UNINDEXED_LIMITED_COUNT_TRANSIENT );
|
||||
|
||||
$this->indexing_helper->set_reason( Indexing_Reasons::REASON_TAXONOMY_MADE_PUBLIC );
|
||||
|
||||
$this->maybe_add_notification();
|
||||
do_action( 'new_public_taxonomy_notifications', $newly_made_public_taxonomies );
|
||||
}
|
||||
|
||||
// There are taxonomies that have been made private.
|
||||
@@ -143,44 +143,8 @@ class Indexable_Taxonomy_Change_Watcher implements Integration_Interface {
|
||||
if ( $cleanup_not_yet_scheduled ) {
|
||||
\wp_schedule_single_event( ( \time() + ( \MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
|
||||
do_action( 'clean_new_public_taxonomy_notifications', $newly_made_non_public_taxonomies );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if a notification should be added in the notification center.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function maybe_add_notification() {
|
||||
$notification = $this->notification_center->get_notification_by_id( 'taxonomies-made-public' );
|
||||
if ( \is_null( $notification ) ) {
|
||||
$this->add_notification();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a notification to be shown on the next page request since posts are updated in an ajax request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_notification() {
|
||||
$message = \sprintf(
|
||||
/* translators: 1: Opening tag of the link to the Search appearance settings page, 2: Link closing tag. */
|
||||
\esc_html__( 'It looks like you\'ve added a new taxonomy to your website. We recommend that you review your %1$sSettings%2$s under Categories & tags.', 'wordpress-seo' ),
|
||||
'<a href="' . \esc_url( \admin_url( 'admin.php?page=wpseo_page_settings' ) ) . '">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$notification = new Yoast_Notification(
|
||||
$message,
|
||||
[
|
||||
'type' => Yoast_Notification::WARNING,
|
||||
'id' => 'taxonomies-made-public',
|
||||
'capabilities' => 'wpseo_manage_options',
|
||||
'priority' => 0.8,
|
||||
]
|
||||
);
|
||||
|
||||
$this->notification_center->add_notification( $notification );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user