PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.5
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
← All changes | admin/class-admin.php +58 -52 18.128.5 View file →
@@ -4,9 +4,9 @@
4 4 *
5 5 * @package WPSEO\Admin
6 6 */
7 7
8 -use Yoast\WP\SEO\Helpers\Wordpress_Helper;
8 +use Yoast\WP\SEO\Integrations\Settings_Integration;
9 9
10 10 /**
11 11 * Class that holds most of the admin functionality for Yoast SEO.
12 12 */
@@ -18,9 +18,9 @@
18 18 * !DO NOT CHANGE THIS!
19 19 *
20 20 * @var string
21 21 */
22 - const PAGE_IDENTIFIER = 'wpseo_dashboard';
22 + public const PAGE_IDENTIFIER = 'wpseo_dashboard';
23 23
24 24 /**
25 25 * Array of classes that add admin functionality.
26 26 *
@@ -42,17 +42,13 @@
42 42 if ( is_multisite() ) {
43 43 WPSEO_Options::maybe_set_multisite_defaults( false );
44 44 }
45 45
46 - if ( WPSEO_Options::get( 'stripcategorybase' ) === true ) {
47 - add_action( 'created_category', [ $this, 'schedule_rewrite_flush' ] );
48 - add_action( 'edited_category', [ $this, 'schedule_rewrite_flush' ] );
49 - add_action( 'delete_category', [ $this, 'schedule_rewrite_flush' ] );
50 - }
46 + add_action( 'created_category', [ $this, 'schedule_rewrite_flush' ] );
47 + add_action( 'edited_category', [ $this, 'schedule_rewrite_flush' ] );
48 + add_action( 'delete_category', [ $this, 'schedule_rewrite_flush' ] );
51 49
52 - if ( WPSEO_Options::get( 'disable-attachment' ) === true ) {
53 - add_filter( 'wpseo_accessible_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] );
54 - }
50 + add_filter( 'wpseo_accessible_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] );
55 51
56 52 add_filter( 'plugin_action_links_' . WPSEO_BASENAME, [ $this, 'add_action_link' ], 10, 2 );
57 53 add_filter( 'network_admin_plugin_action_links_' . WPSEO_BASENAME, [ $this, 'add_action_link' ], 10, 2 );
58 54
@@ -58,10 +54,8 @@
58 54
59 55 add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] );
60 56 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_global_style' ] );
61 57
62 - add_filter( 'user_contactmethods', [ $this, 'update_contactmethods' ], 10, 1 );
63 -
64 58 add_action( 'after_switch_theme', [ $this, 'switch_theme' ] );
65 59 add_action( 'switch_theme', [ $this, 'switch_theme' ] );
66 60
67 61 add_filter( 'set-screen-option', [ $this, 'save_bulk_edit_options' ], 10, 3 );
@@ -72,14 +66,8 @@
72 66
73 67 WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' );
74 68 WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'home' );
75 69
76 - if ( YoastSEO()->helpers->current_page->is_yoast_seo_page() ) {
77 - add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
78 - }
79 -
80 - $this->set_upsell_notice();
81 -
82 70 $this->initialize_cornerstone_content();
83 71
84 72 if ( WPSEO_Utils::is_plugin_network_active() ) {
85 73 $integrations[] = new Yoast_Network_Admin();
@@ -85,9 +73,10 @@
85 73 $integrations[] = new Yoast_Network_Admin();
86 74 }
87 75
88 76 $this->admin_features = [
89 - 'dashboard_widget' => new Yoast_Dashboard_Widget(),
77 + 'dashboard_widget' => new Yoast_Dashboard_Widget(),
78 + 'wincher_dashboard_widget' => new Wincher_Dashboard_Widget(),
90 79 ];
91 80
92 81 if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) {
93 82 $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin();
@@ -105,9 +94,9 @@
105 94
106 95 $integrations = array_merge(
107 96 $integrations,
108 97 $this->get_admin_features(),
109 - $this->initialize_cornerstone_content()
98 + $this->initialize_cornerstone_content(),
110 99 );
111 100
112 101 foreach ( $integrations as $integration ) {
113 102 $integration->register_hooks();
@@ -115,10 +104,16 @@
115 104 }
116 105
117 106 /**
118 107 * Schedules a rewrite flush to happen at shutdown.
108 + *
109 + * @return void
119 110 */
120 111 public function schedule_rewrite_flush() {
112 + if ( WPSEO_Options::get( 'stripcategorybase' ) !== true ) {
113 + return;
114 + }
115 +
121 116 // Bail if this is a multisite installation and the site has been switched.
122 117 if ( is_multisite() && ms_is_switched() ) {
123 118 return;
124 119 }
@@ -136,14 +131,16 @@
136 131 }
137 132
138 133 /**
139 134 * Register assets needed on admin pages.
135 + *
136 + * @deprecated 25.5
137 + * @codeCoverageIgnore
138 + *
139 + * @return void
140 140 */
141 141 public function enqueue_assets() {
142 - if ( filter_input( INPUT_GET, 'page' ) === 'wpseo_licenses' ) {
143 - $asset_manager = new WPSEO_Admin_Asset_Manager();
144 - $asset_manager->enqueue_style( 'extensions' );
145 - }
142 + _deprecated_function( __METHOD__, 'Yoast SEO 25.5' );
146 143 }
147 144
148 145 /**
149 146 * Returns the manage_options capability.
@@ -153,9 +150,9 @@
153 150 public function get_manage_options_cap() {
154 151 /**
155 152 * Filter: 'wpseo_manage_options_capability' - Allow changing the capability users need to view the settings pages.
156 153 *
157 - * @api string unsigned The capability.
154 + * @param string $capability The capability.
158 155 */
159 156 return apply_filters( 'wpseo_manage_options_capability', 'wpseo_manage_options' );
160 157 }
161 158
@@ -160,14 +157,16 @@
160 157 }
161 158
162 159 /**
163 160 * Maps the manage_options cap on saving an options page to wpseo_manage_options.
161 + *
162 + * @return void
164 163 */
165 164 public function map_manage_options_cap() {
166 165 // phpcs:ignore WordPress.Security -- The variable is only used in strpos and thus safe to not unslash or sanitize.
167 166 $option_page = ! empty( $_POST['option_page'] ) ? $_POST['option_page'] : '';
168 167
169 - if ( strpos( $option_page, 'yoast_wpseo' ) === 0 ) {
168 + if ( strpos( $option_page, 'yoast_wpseo' ) === 0 || strpos( $option_page, Settings_Integration::PAGE ) === 0 ) {
170 169 add_filter( 'option_page_capability_' . $option_page, [ $this, 'get_manage_options_cap' ] );
171 170 }
172 171 }
173 172
@@ -173,8 +172,10 @@
173 172
174 173 /**
175 174 * Adds the ability to choose how many posts are displayed per page
176 175 * on the bulk edit pages.
176 + *
177 + * @return void
177 178 */
178 179 public function bulk_edit_options() {
179 180 $option = 'per_page';
180 181 $args = [
@@ -210,8 +211,10 @@
210 211 *
211 212 * @return array
212 213 */
213 214 public function add_action_link( $links, $file ) {
215 + $first_time_configuration_notice_helper = YoastSEO()->helpers->first_time_configuration_notice;
216 +
214 217 if ( $file === WPSEO_BASENAME && WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) {
215 218 if ( is_network_admin() ) {
216 219 $settings_url = network_admin_url( 'admin.php?page=' . self::PAGE_IDENTIFIER );
217 220 }
@@ -225,8 +228,17 @@
225 228 // Add link to docs.
226 229 $faq_link = '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yc' ) ) . '" target="_blank">' . __( 'FAQ', 'wordpress-seo' ) . '</a>';
227 230 array_unshift( $links, $faq_link );
228 231
232 + if ( $first_time_configuration_notice_helper->first_time_configuration_not_finished() && ! is_network_admin() ) {
233 + $configuration_title = ( ! $first_time_configuration_notice_helper->should_show_alternate_message() ) ? 'first-time configuration' : 'SEO configuration';
234 + /* translators: CTA to finish the first time configuration. %s: Either first-time SEO configuration or SEO configuration. */
235 + $message = sprintf( __( 'Finish your %s', 'wordpress-seo' ), $configuration_title );
236 + $ftc_page = 'admin.php?page=wpseo_dashboard#/first-time-configuration';
237 + $ftc_link = '<a href="' . esc_url( admin_url( $ftc_page ) ) . '" target="_blank">' . $message . '</a>';
238 + array_unshift( $links, $ftc_link );
239 + }
240 +
229 241 $addon_manager = new WPSEO_Addon_Manager();
230 242 if ( YoastSEO()->helpers->product->is_premium() ) {
231 243
232 244 // Remove Free 'deactivate' link if Premium is active as well. We don't want users to deactivate Free when Premium is active.
@@ -233,9 +245,9 @@
233 245 unset( $links['deactivate'] );
234 246 $no_deactivation_explanation = '<span style="color: #32373c">' . sprintf(
235 247 /* translators: %s expands to Yoast SEO Premium. */
236 248 __( 'Required by %s', 'wordpress-seo' ),
237 - 'Yoast SEO Premium'
249 + 'Yoast SEO Premium',
238 250 ) . '</span>';
239 251
240 252 array_unshift( $links, $no_deactivation_explanation );
241 253
@@ -250,9 +262,9 @@
250 262 return $links;
251 263 }
252 264
253 265 // Add link to premium landing page.
254 - $premium_link = '<a style="font-weight: bold;" href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yb' ) ) . '" target="_blank">' . __( 'Get Premium', 'wordpress-seo' ) . '</a>';
266 + $premium_link = '<a style="font-weight: bold;" href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yb' ) ) . '" target="_blank" data-action="load-nfd-ctb" data-ctb-id="f6a84663-465f-4cb5-8ba5-f7a6d72224b2">' . __( 'Get Premium', 'wordpress-seo' ) . '</a>';
255 267 array_unshift( $links, $premium_link );
256 268
257 269 return $links;
258 270 }
@@ -258,8 +270,10 @@
258 270 }
259 271
260 272 /**
261 273 * Enqueues the (tiny) global JS needed for the plugin.
274 + *
275 + * @return void
262 276 */
263 277 public function config_page_scripts() {
264 278 $asset_manager = new WPSEO_Admin_Asset_Manager();
265 279 $asset_manager->enqueue_script( 'admin-global' );
@@ -267,8 +281,10 @@
267 281 }
268 282
269 283 /**
270 284 * Enqueues the (tiny) global stylesheet needed for the plugin.
285 + *
286 + * @return void
271 287 */
272 288 public function enqueue_global_style() {
273 289 $asset_manager = new WPSEO_Admin_Asset_Manager();
274 290 $asset_manager->enqueue_style( 'admin-global' );
@@ -278,13 +294,18 @@
278 294 * Filter the $contactmethods array and add a set of social profiles.
279 295 *
280 296 * These are used with the Facebook author, rel="author" and Twitter cards implementation.
281 297 *
282 - * @param array $contactmethods Currently set contactmethods.
298 + * @deprecated 22.6
299 + * @codeCoverageIgnore
283 300 *
284 - * @return array Contactmethods with added contactmethods.
301 + * @param array<string, string> $contactmethods Currently set contactmethods.
302 + *
303 + * @return array<string, string> Contactmethods with added contactmethods.
285 304 */
286 305 public function update_contactmethods( $contactmethods ) {
306 + _deprecated_function( __METHOD__, 'Yoast SEO 22.6' );
307 +
287 308 $contactmethods['facebook'] = __( 'Facebook profile URL', 'wordpress-seo' );
288 309 $contactmethods['instagram'] = __( 'Instagram profile URL', 'wordpress-seo' );
289 310 $contactmethods['linkedin'] = __( 'LinkedIn profile URL', 'wordpress-seo' );
290 311 $contactmethods['myspace'] = __( 'MySpace profile URL', 'wordpress-seo' );
@@ -290,9 +311,9 @@
290 311 $contactmethods['myspace'] = __( 'MySpace profile URL', 'wordpress-seo' );
291 312 $contactmethods['pinterest'] = __( 'Pinterest profile URL', 'wordpress-seo' );
292 313 $contactmethods['soundcloud'] = __( 'SoundCloud profile URL', 'wordpress-seo' );
293 314 $contactmethods['tumblr'] = __( 'Tumblr profile URL', 'wordpress-seo' );
294 - $contactmethods['twitter'] = __( 'Twitter username (without @)', 'wordpress-seo' );
315 + $contactmethods['twitter'] = __( 'X username (without @)', 'wordpress-seo' );
295 316 $contactmethods['youtube'] = __( 'YouTube profile URL', 'wordpress-seo' );
296 317 $contactmethods['wikipedia'] = __( 'Wikipedia page about you', 'wordpress-seo' ) . '<br/><small>' . __( '(if one exists)', 'wordpress-seo' ) . '</small>';
297 318
298 319 return $contactmethods;
@@ -299,20 +320,14 @@
299 320 }
300 321
301 322 /**
302 323 * Log the updated timestamp for user profiles when theme is changed.
324 + *
325 + * @return void
303 326 */
304 327 public function switch_theme() {
305 - $wordpress_helper = new Wordpress_Helper();
306 - $wordpress_version = $wordpress_helper->get_wordpress_version();
307 328
308 - // Capability queries were only introduced in WP 5.9.
309 - if ( version_compare( $wordpress_version, '5.8.99', '<' ) ) {
310 - $users = get_users( [ 'who' => 'authors' ] );
311 - }
312 - else {
313 - $users = get_users( [ 'capability' => [ 'edit_posts' ] ] );
314 - }
329 + $users = get_users( [ 'capability' => [ 'edit_posts' ] ] );
315 330
316 331 if ( is_array( $users ) && $users !== [] ) {
317 332 foreach ( $users as $user ) {
318 333 update_user_meta( $user->ID, '_yoast_wpseo_profile_updated', time() );
@@ -329,12 +344,12 @@
329 344 return array_merge(
330 345 [
331 346 'isRtl' => is_rtl(),
332 347 'variable_warning' => sprintf(
333 - /* translators: %1$s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template, %2$s: expands to 'HelpScout beacon' */
348 + /* translators: %1$s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template, %2$s: expands to 'HelpScout beacon' */
334 349 __( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.', 'wordpress-seo' ),
335 350 '<code>%s</code>',
336 - 'HelpScout beacon'
351 + 'HelpScout beacon',
337 352 ),
338 353 /* translators: %s: expends to Yoast SEO */
339 354 'help_video_iframe_title' => sprintf( __( '%s video tutorial', 'wordpress-seo' ), 'Yoast SEO' ),
340 355 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ),
@@ -339,19 +354,10 @@
339 354 'help_video_iframe_title' => sprintf( __( '%s video tutorial', 'wordpress-seo' ), 'Yoast SEO' ),
340 355 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ),
341 356 'wincher_is_logged_in' => WPSEO_Options::get( 'wincher_integration_active', true ) ? YoastSEO()->helpers->wincher->login_status() : false,
342 357 ],
343 - YoastSEO()->helpers->wincher->get_admin_global_links()
358 + YoastSEO()->helpers->wincher->get_admin_global_links(),
344 359 );
345 - }
346 -
347 - /**
348 - * Sets the upsell notice.
349 - */
350 - protected function set_upsell_notice() {
351 - $upsell = new WPSEO_Product_Upsell_Notice();
352 - $upsell->dismiss_notice_listener();
353 - $upsell->initialize();
354 360 }
355 361
356 362 /**
357 363 * Whether we are on the admin dashboard page.