Version Description
Release Date: September 1st, 2020
Yoast SEO 14.9 comes with a new round of improvements, plus a new language-based enhancement: improved keyphrase recognition for Hebrew. Read more about those changes in our release post!
Bugfixes:
- Fixes a bug where a JavaScript console warning was thrown on category edit pages.
- Fixes a bug where the page number was not shown in the breadcrumb for paginated series.
- Fixes a bug where the
robots.txt
and.htaccess
file editor would not work due toget_home_path()
not being a writable path. Props to druesome. - Fixes a bug where port numbers in the indexable permalinks were missing (when applicable).
- Fixes a bug where the indexables table would contain incorrect permalinks for posts if the term slug had been changed and the post permalink contains the term slug.
- Fixes a bug where the indexables table would contain incorrect permalinks for pages if the slug of the parent page had been changed.
- Fixes a bug where a warning would occur when a query was unsuccessful while indexing post type archives. Props to Sekiphp.
- Fixes a bug where closing parentheses would always be regarded as sentence endings in RTL languages.
- Fixes a bug where closing parentheses would always be regarded as sentence endings when followed by an upper-case letter.
Enhancements:
- Adds an update notification for major and minor releases.
- Improves the SQL performance by not performing unnecessary update queries when updating a posts public status.
- Optimizes performance by preventing regular database queries.
- Improves keyphrase recognition in Polish by filtering more function words.
- Improves the feedback string in the Keyphrase in Subheadings assessment by making it more explicit.
- Improves all keyphrase-based assessments for Hebrew by filtering function words and allowing keyphrases to be recognized in the text when preceded by a prefix (e.g., or ).
- We already had a filter available to change the default Schema Article type (
wpseo_schema_article_post_types
), but it wasn't called anywhere. Now it is.
Other:
- Adds the weekly cron schedule to the
cron_schedules
filter to prevent overwriting the one WordPress adds. Props to peter-webbird. - Merges the googlebot and bingbot meta tag values into the robots meta tag value and deprecates the
Googlebot_Presenter
andBingbot_Presenter
.
Download this release
Release Info
Developer | Yoast |
Plugin | Yoast SEO |
Version | 14.9 |
Comparing to | |
See all releases |
Code changes from version 14.8.1 to 14.9
- admin/admin-settings-changed-listener.php +1 -1
- admin/ajax.php +0 -6
- admin/ajax/class-recalculate-scores-ajax.php +0 -123
- admin/class-admin-asset-manager.php +30 -24
- admin/class-admin-init.php +99 -0
- admin/class-admin-media-purge-notification.php +1 -1
- admin/class-admin.php +1 -42
- admin/class-license-page-manager.php +4 -13
- admin/class-meta-columns.php +25 -31
- admin/class-meta-storage.php +0 -126
- admin/class-meta-table-accessible.php +0 -103
- admin/class-recalculate-scores.php +0 -54
- admin/class-yoast-notification-center.php +10 -2
- admin/links/class-link-cleanup-transient.php +0 -35
- admin/links/class-link-column-count.php +0 -93
- admin/links/class-link-content-processor.php +0 -143
- admin/links/class-link-extractor.php +0 -52
- admin/links/class-link-factory.php +0 -94
- admin/links/class-link-filter.php +0 -61
- admin/links/class-link-installer.php +0 -56
- admin/links/class-link-internal-lookup.php +0 -25
- admin/links/class-link-notifier.php +0 -125
- admin/links/class-link-query.php +0 -160
- admin/links/class-link-reindex-dashboard.php +0 -207
- admin/links/class-link-reindex-post-endpoint.php +0 -71
- admin/links/class-link-reindex-post-service.php +0 -95
- admin/links/class-link-storage.php +0 -158
- admin/links/class-link-table-accessible.php +0 -103
- admin/links/class-link-type-classifier.php +0 -103
- admin/links/class-link-utils.php +0 -30
- admin/links/class-link-watcher-loader.php +0 -25
- admin/links/class-link-watcher.php +0 -149
- admin/links/class-link.php +0 -87
- admin/metabox/class-metabox.php +3 -1
- admin/pages/tools.php +0 -2
- admin/recalculate/class-recalculate-posts.php +0 -151
- admin/recalculate/class-recalculate-terms.php +0 -151
- admin/recalculate/class-recalculate.php +0 -104
- admin/ryte/class-ryte.php +9 -11
- admin/views/licenses.php +4 -4
- admin/views/tabs/metas/paper-content/post_type/woocommerce-shop-page.php +3 -4
- admin/views/tool-file-editor.php +10 -4
- cli/class-cli-redirect-upsell-command-namespace.php +0 -15
- cli/class-cli-yoast-command-namespace.php +0 -15
- css/dist/{admin-global-1481-rtl.css → admin-global-1490-rtl.css} +0 -0
- css/dist/{admin-global-1481.css → admin-global-1490.css} +0 -0
- css/dist/{adminbar-1481-rtl.css → adminbar-1490-rtl.css} +0 -0
- css/dist/{adminbar-1481.css → adminbar-1490.css} +0 -0
- css/dist/{alerts-1481-rtl.css → alerts-1490-rtl.css} +0 -0
- css/dist/{alerts-1481.css → alerts-1490.css} +0 -0
- css/dist/{dashboard-1481-rtl.css → dashboard-1490-rtl.css} +0 -0
- css/dist/{dashboard-1481.css → dashboard-1490.css} +0 -0
- css/dist/{edit-page-1481-rtl.css → edit-page-1490-rtl.css} +0 -0
- css/dist/{edit-page-1481.css → edit-page-1490.css} +0 -0
- css/dist/{featured-image-1481-rtl.css → featured-image-1490-rtl.css} +0 -0
- css/dist/{featured-image-1481.css → featured-image-1490.css} +0 -0
- css/dist/{filter-explanation-1481-rtl.css → filter-explanation-1490-rtl.css} +0 -0
- css/dist/{filter-explanation-1481.css → filter-explanation-1490.css} +0 -0
- css/dist/{icons-1481-rtl.css → icons-1490-rtl.css} +0 -0
- css/dist/{icons-1481.css → icons-1490.css} +0 -0
- css/dist/{inside-editor-1481-rtl.css → inside-editor-1490-rtl.css} +0 -0
- css/dist/{inside-editor-1481.css → inside-editor-1490.css} +0 -0
- css/dist/metabox-1481-rtl.css +0 -1
- css/dist/metabox-1490-rtl.css +1 -0
- css/dist/{metabox-1481.css → metabox-1490.css} +1 -1
- css/dist/{metabox-primary-category-1481-rtl.css → metabox-primary-category-1490-rtl.css} +0 -0
- css/dist/{metabox-primary-category-1481.css → metabox-primary-category-1490.css} +0 -0
- css/dist/modal-1490-rtl.css +1 -0
- css/dist/modal-1490.css +1 -0
- css/dist/monorepo-1481-rtl.css +0 -1
- css/dist/monorepo-1481.css +0 -1
- css/dist/monorepo-1490-rtl.css +1 -0
- css/dist/monorepo-1490.css +1 -0
- css/dist/{notifications-1481-rtl.css → notifications-1490-rtl.css} +0 -0
- css/dist/{notifications-1481.css → notifications-1490.css} +0 -0
- css/dist/{score_icon-1481-rtl.css → score_icon-1490-rtl.css} +0 -0
- css/dist/{score_icon-1481.css → score_icon-1490.css} +0 -0
- css/dist/{search-appearance-1481-rtl.css → search-appearance-1490-rtl.css} +0 -0
- css/dist/{search-appearance-1481.css → search-appearance-1490.css} +0 -0
- css/dist/{structured-data-blocks-1481-rtl.css → structured-data-blocks-1490-rtl.css} +0 -0
- css/dist/{structured-data-blocks-1481.css → structured-data-blocks-1490.css} +0 -0
- css/dist/{toggle-switch-1481-rtl.css → toggle-switch-1490-rtl.css} +0 -0
- css/dist/{toggle-switch-1481.css → toggle-switch-1490.css} +0 -0
- css/dist/{wpseo-dismissible-1481-rtl.css → wpseo-dismissible-1490-rtl.css} +0 -0
- css/dist/{wpseo-dismissible-1481.css → wpseo-dismissible-1490.css} +0 -0
- css/dist/{yoast-components-1481-rtl.css → yoast-components-1490-rtl.css} +0 -0
- css/dist/{yoast-components-1481.css → yoast-components-1490.css} +0 -0
- css/dist/{yoast-extensions-1481-rtl.css → yoast-extensions-1490-rtl.css} +0 -0
- css/dist/{yoast-extensions-1481.css → yoast-extensions-1490.css} +0 -0
- css/dist/{yst_plugin_tools-1481-rtl.css → yst_plugin_tools-1490-rtl.css} +0 -0
- css/dist/{yst_plugin_tools-1481.css → yst_plugin_tools-1490.css} +0 -0
- css/dist/{yst_seo_score-1481-rtl.css → yst_seo_score-1490-rtl.css} +0 -0
- css/dist/{yst_seo_score-1481.css → yst_seo_score-1490.css} +0 -0
- css/src/metabox.css +1 -0
- css/src/modal.css +375 -0
- deprecated/admin/ajax/class-recalculate-scores-ajax.php +63 -0
- deprecated/admin/class-recalculate-scores.php +47 -0
- deprecated/admin/recalculate/class-recalculate-posts.php +71 -0
- deprecated/admin/recalculate/class-recalculate-terms.php +71 -0
- deprecated/admin/recalculate/class-recalculate.php +64 -0
- {frontend → deprecated/frontend}/class-frontend-page-type.php +33 -18
- deprecated/frontend/class-woocommerce-shop-page.php +61 -0
- frontend/class-woocommerce-shop-page.php +0 -86
- frontend/index.php +0 -4
- inc/class-post-type.php +3 -22
- inc/class-upgrade.php +10 -59
- inc/class-wpseo-replace-vars.php +1 -1
- inc/class-wpseo-utils.php +4 -33
- inc/health-check-links-table-not-accessible.php +3 -10
- inc/indexables/class-post-indexable.php +0 -5
- inc/options/class-wpseo-option-titles.php +1 -1
- inc/options/class-wpseo-option-wpseo.php +6 -5
- inc/sitemaps/class-post-type-sitemap-provider.php +20 -14
- inc/sitemaps/class-sitemap-image-parser.php +1 -1
- js/dist/{admin-global-1481.js → admin-global-1490.js} +1 -1
- js/dist/analysis-1481.js +0 -21
admin/admin-settings-changed-listener.php
CHANGED
@@ -32,7 +32,7 @@ class WPSEO_Admin_Settings_Changed_Listener implements WPSEO_WordPress_Integrati
|
|
32 |
public function intercept_save_update_notification() {
|
33 |
global $pagenow;
|
34 |
|
35 |
-
if ( $pagenow !== 'admin.php' || !
|
36 |
return;
|
37 |
}
|
38 |
|
32 |
public function intercept_save_update_notification() {
|
33 |
global $pagenow;
|
34 |
|
35 |
+
if ( $pagenow !== 'admin.php' || ! YoastSEO()->helpers->current_page->is_yoast_seo_page() ) {
|
36 |
return;
|
37 |
}
|
38 |
|
admin/ajax.php
CHANGED
@@ -331,16 +331,10 @@ function wpseo_register_ajax_integrations() {
|
|
331 |
|
332 |
wpseo_register_ajax_integrations();
|
333 |
|
334 |
-
// SEO Score Recalculations.
|
335 |
-
new WPSEO_Recalculate_Scores_Ajax();
|
336 |
-
|
337 |
new WPSEO_Shortcode_Filter();
|
338 |
|
339 |
new WPSEO_Taxonomy_Columns();
|
340 |
|
341 |
-
// Setting the notice for the recalculate the posts.
|
342 |
-
new Yoast_Dismissable_Notice_Ajax( 'recalculate', Yoast_Dismissable_Notice_Ajax::FOR_SITE );
|
343 |
-
|
344 |
/* ********************* DEPRECATED FUNCTIONS ********************* */
|
345 |
|
346 |
/**
|
331 |
|
332 |
wpseo_register_ajax_integrations();
|
333 |
|
|
|
|
|
|
|
334 |
new WPSEO_Shortcode_Filter();
|
335 |
|
336 |
new WPSEO_Taxonomy_Columns();
|
337 |
|
|
|
|
|
|
|
338 |
/* ********************* DEPRECATED FUNCTIONS ********************* */
|
339 |
|
340 |
/**
|
admin/ajax/class-recalculate-scores-ajax.php
DELETED
@@ -1,123 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Ajax
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class WPSEO_Recalculate_Scores.
|
10 |
-
*
|
11 |
-
* This class handles the SEO score recalculation for all posts with a filled focus keyword.
|
12 |
-
*/
|
13 |
-
class WPSEO_Recalculate_Scores_Ajax {
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Initialize the AJAX hooks.
|
17 |
-
*/
|
18 |
-
public function __construct() {
|
19 |
-
add_action( 'wp_ajax_wpseo_recalculate_scores', [ $this, 'recalculate_scores' ] );
|
20 |
-
add_action( 'wp_ajax_wpseo_update_score', [ $this, 'save_score' ] );
|
21 |
-
add_action( 'wp_ajax_wpseo_recalculate_total', [ $this, 'get_total' ] );
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Get the totals for the posts and the terms.
|
26 |
-
*/
|
27 |
-
public function get_total() {
|
28 |
-
check_ajax_referer( 'wpseo_recalculate', 'nonce' );
|
29 |
-
|
30 |
-
wp_die(
|
31 |
-
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: WPSEO_Utils::format_json_encode is considered safe.
|
32 |
-
WPSEO_Utils::format_json_encode(
|
33 |
-
[
|
34 |
-
'posts' => $this->calculate_posts(),
|
35 |
-
'terms' => $this->calculate_terms(),
|
36 |
-
]
|
37 |
-
)
|
38 |
-
);
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Start recalculation.
|
43 |
-
*/
|
44 |
-
public function recalculate_scores() {
|
45 |
-
check_ajax_referer( 'wpseo_recalculate', 'nonce' );
|
46 |
-
|
47 |
-
$fetch_object = $this->get_fetch_object();
|
48 |
-
if ( ! empty( $fetch_object ) ) {
|
49 |
-
$paged = filter_input( INPUT_POST, 'paged', FILTER_VALIDATE_INT );
|
50 |
-
$response = $fetch_object->get_items_to_recalculate( $paged );
|
51 |
-
|
52 |
-
if ( ! empty( $response ) ) {
|
53 |
-
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: WPSEO_Utils::format_json_encode is considered safe.
|
54 |
-
wp_die( WPSEO_Utils::format_json_encode( $response ) );
|
55 |
-
}
|
56 |
-
}
|
57 |
-
|
58 |
-
wp_die( '' );
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Saves the new linkdex score for given post.
|
63 |
-
*/
|
64 |
-
public function save_score() {
|
65 |
-
check_ajax_referer( 'wpseo_recalculate', 'nonce' );
|
66 |
-
|
67 |
-
$fetch_object = $this->get_fetch_object();
|
68 |
-
if ( ! empty( $fetch_object ) ) {
|
69 |
-
$scores = filter_input( INPUT_POST, 'scores', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
|
70 |
-
$fetch_object->save_scores( $scores );
|
71 |
-
}
|
72 |
-
|
73 |
-
wp_die();
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Returns the needed object for recalculating scores.
|
78 |
-
*
|
79 |
-
* @return WPSEO_Recalculate_Posts|WPSEO_Recalculate_Terms
|
80 |
-
*/
|
81 |
-
private function get_fetch_object() {
|
82 |
-
switch ( filter_input( INPUT_POST, 'type' ) ) {
|
83 |
-
case 'post':
|
84 |
-
return new WPSEO_Recalculate_Posts();
|
85 |
-
case 'term':
|
86 |
-
return new WPSEO_Recalculate_Terms();
|
87 |
-
}
|
88 |
-
|
89 |
-
return null;
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Gets the total number of posts.
|
94 |
-
*
|
95 |
-
* @return int
|
96 |
-
*/
|
97 |
-
private function calculate_posts() {
|
98 |
-
$count_posts_query = new WP_Query(
|
99 |
-
[
|
100 |
-
'post_type' => 'any',
|
101 |
-
'meta_key' => '_yoast_wpseo_focuskw',
|
102 |
-
'posts_per_page' => 1,
|
103 |
-
'fields' => 'ids',
|
104 |
-
]
|
105 |
-
);
|
106 |
-
|
107 |
-
return $count_posts_query->found_posts;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Get the total number of terms.
|
112 |
-
*
|
113 |
-
* @return int
|
114 |
-
*/
|
115 |
-
private function calculate_terms() {
|
116 |
-
$total = 0;
|
117 |
-
foreach ( get_taxonomies( [], 'objects' ) as $taxonomy ) {
|
118 |
-
$total += wp_count_terms( $taxonomy->name, [ 'hide_empty' => false ] );
|
119 |
-
}
|
120 |
-
|
121 |
-
return $total;
|
122 |
-
}
|
123 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/class-admin-asset-manager.php
CHANGED
@@ -270,28 +270,48 @@ class WPSEO_Admin_Asset_Manager {
|
|
270 |
],
|
271 |
'in_footer' => false,
|
272 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
[
|
274 |
'name' => 'post-edit',
|
275 |
'src' => 'post-edit-' . $flat_version,
|
276 |
'deps' => [
|
277 |
'jquery',
|
278 |
-
'wp-annotations',
|
279 |
'wp-api',
|
280 |
'wp-api-fetch',
|
281 |
-
'wp-blocks',
|
282 |
-
'wp-components',
|
283 |
-
'wp-compose',
|
284 |
'wp-data',
|
285 |
-
'wp-element',
|
286 |
'wp-i18n',
|
287 |
'wp-is-shallow-equal',
|
288 |
'wp-sanitize',
|
289 |
'wp-url',
|
290 |
'wp-util',
|
291 |
-
self::PREFIX . 'redux',
|
292 |
self::PREFIX . 'analysis',
|
293 |
-
self::PREFIX . '
|
294 |
self::PREFIX . 'commons',
|
|
|
295 |
self::PREFIX . 'select2',
|
296 |
self::PREFIX . 'select2-translations',
|
297 |
],
|
@@ -304,19 +324,16 @@ class WPSEO_Admin_Asset_Manager {
|
|
304 |
'jquery',
|
305 |
'wp-api',
|
306 |
'wp-api-fetch',
|
307 |
-
'wp-components',
|
308 |
-
'wp-compose',
|
309 |
'wp-data',
|
310 |
-
'wp-element',
|
311 |
'wp-i18n',
|
312 |
'wp-is-shallow-equal',
|
313 |
'wp-sanitize',
|
314 |
'wp-url',
|
315 |
'wp-util',
|
316 |
-
self::PREFIX . 'redux',
|
317 |
self::PREFIX . 'analysis',
|
318 |
-
self::PREFIX . '
|
319 |
self::PREFIX . 'commons',
|
|
|
320 |
self::PREFIX . 'select2',
|
321 |
self::PREFIX . 'select2-translations',
|
322 |
],
|
@@ -338,23 +355,12 @@ class WPSEO_Admin_Asset_Manager {
|
|
338 |
self::PREFIX . 'redux',
|
339 |
self::PREFIX . 'analysis',
|
340 |
self::PREFIX . 'components',
|
|
|
341 |
self::PREFIX . 'commons',
|
342 |
self::PREFIX . 'select2',
|
343 |
self::PREFIX . 'select2-translations',
|
344 |
],
|
345 |
],
|
346 |
-
[
|
347 |
-
'name' => 'recalculate',
|
348 |
-
'src' => 'recalculate-' . $flat_version,
|
349 |
-
'deps' => [
|
350 |
-
'jquery',
|
351 |
-
'jquery-ui-core',
|
352 |
-
'jquery-ui-progressbar',
|
353 |
-
self::PREFIX . 'jed',
|
354 |
-
self::PREFIX . 'analysis',
|
355 |
-
self::PREFIX . 'commons',
|
356 |
-
],
|
357 |
-
],
|
358 |
[
|
359 |
'name' => 'select2',
|
360 |
'src' => 'select2/select2.full',
|
270 |
],
|
271 |
'in_footer' => false,
|
272 |
],
|
273 |
+
[
|
274 |
+
'name' => 'block-editor',
|
275 |
+
'src' => 'block-editor-' . $flat_version,
|
276 |
+
'deps' => [
|
277 |
+
'wp-annotations',
|
278 |
+
'wp-blocks',
|
279 |
+
'wp-components',
|
280 |
+
'wp-compose',
|
281 |
+
'wp-edit-post',
|
282 |
+
'wp-element',
|
283 |
+
self::PREFIX . 'components',
|
284 |
+
],
|
285 |
+
'in_footer' => false,
|
286 |
+
],
|
287 |
+
[
|
288 |
+
'name' => 'classic-editor',
|
289 |
+
'src' => 'classic-editor-' . $flat_version,
|
290 |
+
'deps' => [
|
291 |
+
'wp-components',
|
292 |
+
'wp-compose',
|
293 |
+
'wp-element',
|
294 |
+
self::PREFIX . 'components',
|
295 |
+
],
|
296 |
+
'in_footer' => false,
|
297 |
+
],
|
298 |
[
|
299 |
'name' => 'post-edit',
|
300 |
'src' => 'post-edit-' . $flat_version,
|
301 |
'deps' => [
|
302 |
'jquery',
|
|
|
303 |
'wp-api',
|
304 |
'wp-api-fetch',
|
|
|
|
|
|
|
305 |
'wp-data',
|
|
|
306 |
'wp-i18n',
|
307 |
'wp-is-shallow-equal',
|
308 |
'wp-sanitize',
|
309 |
'wp-url',
|
310 |
'wp-util',
|
|
|
311 |
self::PREFIX . 'analysis',
|
312 |
+
self::PREFIX . 'block-editor',
|
313 |
self::PREFIX . 'commons',
|
314 |
+
self::PREFIX . 'redux',
|
315 |
self::PREFIX . 'select2',
|
316 |
self::PREFIX . 'select2-translations',
|
317 |
],
|
324 |
'jquery',
|
325 |
'wp-api',
|
326 |
'wp-api-fetch',
|
|
|
|
|
327 |
'wp-data',
|
|
|
328 |
'wp-i18n',
|
329 |
'wp-is-shallow-equal',
|
330 |
'wp-sanitize',
|
331 |
'wp-url',
|
332 |
'wp-util',
|
|
|
333 |
self::PREFIX . 'analysis',
|
334 |
+
self::PREFIX . 'classic-editor',
|
335 |
self::PREFIX . 'commons',
|
336 |
+
self::PREFIX . 'redux',
|
337 |
self::PREFIX . 'select2',
|
338 |
self::PREFIX . 'select2-translations',
|
339 |
],
|
355 |
self::PREFIX . 'redux',
|
356 |
self::PREFIX . 'analysis',
|
357 |
self::PREFIX . 'components',
|
358 |
+
self::PREFIX . 'classic-editor',
|
359 |
self::PREFIX . 'commons',
|
360 |
self::PREFIX . 'select2',
|
361 |
self::PREFIX . 'select2-translations',
|
362 |
],
|
363 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
364 |
[
|
365 |
'name' => 'select2',
|
366 |
'src' => 'select2/select2.full',
|
admin/class-admin-init.php
CHANGED
@@ -36,6 +36,7 @@ class WPSEO_Admin_Init {
|
|
36 |
|
37 |
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dismissible' ] );
|
38 |
add_action( 'admin_init', [ $this, 'yoast_plugin_suggestions_notification' ], 15 );
|
|
|
39 |
add_action( 'admin_init', [ $this, 'unsupported_php_notice' ], 15 );
|
40 |
add_action( 'admin_init', [ $this->asset_manager, 'register_assets' ] );
|
41 |
add_action( 'admin_init', [ $this, 'show_hook_deprecation_warnings' ] );
|
@@ -130,6 +131,104 @@ class WPSEO_Admin_Init {
|
|
130 |
);
|
131 |
}
|
132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
/**
|
134 |
* Creates an unsupported PHP version notification in the notification center.
|
135 |
*
|
36 |
|
37 |
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dismissible' ] );
|
38 |
add_action( 'admin_init', [ $this, 'yoast_plugin_suggestions_notification' ], 15 );
|
39 |
+
add_action( 'admin_init', [ $this, 'yoast_plugin_update_notification' ] );
|
40 |
add_action( 'admin_init', [ $this, 'unsupported_php_notice' ], 15 );
|
41 |
add_action( 'admin_init', [ $this->asset_manager, 'register_assets' ] );
|
42 |
add_action( 'admin_init', [ $this, 'show_hook_deprecation_warnings' ] );
|
131 |
);
|
132 |
}
|
133 |
|
134 |
+
/**
|
135 |
+
* Determines whether a update notification needs to be displayed.
|
136 |
+
*
|
137 |
+
* @return void
|
138 |
+
*/
|
139 |
+
public function yoast_plugin_update_notification() {
|
140 |
+
$notification_center = Yoast_Notification_Center::get();
|
141 |
+
$current_minor_version = $this->get_major_minor_version( WPSEO_Options::get( 'version', WPSEO_VERSION ) );
|
142 |
+
$file = plugin_dir_path( WPSEO_FILE ) . 'release-info.json';
|
143 |
+
|
144 |
+
// Remove if file is not present.
|
145 |
+
if ( ! file_exists( $file ) ) {
|
146 |
+
$notification_center->remove_notification_by_id( 'wpseo-plugin-updated' );
|
147 |
+
return;
|
148 |
+
}
|
149 |
+
|
150 |
+
$release_json = file_get_contents( $file );
|
151 |
+
/**
|
152 |
+
* Filter: 'wpseo_update_notice_content' - Allow filtering of the content
|
153 |
+
* of the update notice read from the release-info.json file.
|
154 |
+
*
|
155 |
+
* @api object The object from the release-info.json file.
|
156 |
+
*/
|
157 |
+
$release_info = apply_filters( 'wpseo_update_notice_content', json_decode( $release_json ) );
|
158 |
+
|
159 |
+
// Remove if file is malformed or for a different version.
|
160 |
+
if ( is_null( $release_info )
|
161 |
+
|| empty( $release_info->version )
|
162 |
+
|| version_compare( $this->get_major_minor_version( $release_info->version ), $current_minor_version, '!=' )
|
163 |
+
|| empty( $release_info->release_description )
|
164 |
+
) {
|
165 |
+
$notification_center->remove_notification_by_id( 'wpseo-plugin-updated' );
|
166 |
+
return;
|
167 |
+
}
|
168 |
+
|
169 |
+
$notification = $this->get_yoast_seo_update_notification( $release_info );
|
170 |
+
|
171 |
+
// Restore notification if it was dismissed in a previous minor version.
|
172 |
+
$last_dismissed_version = get_user_option( $notification->get_dismissal_key() );
|
173 |
+
if ( ! $last_dismissed_version
|
174 |
+
|| version_compare( $this->get_major_minor_version( $last_dismissed_version ), $current_minor_version, '<' )
|
175 |
+
) {
|
176 |
+
Yoast_Notification_Center::restore_notification( $notification );
|
177 |
+
}
|
178 |
+
$notification_center->add_notification( $notification );
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Helper to truncate the version string up to the minor number
|
183 |
+
*
|
184 |
+
* @param string $version The version string to extract the major.minor number from.
|
185 |
+
* @return string The version string up to the minor number.
|
186 |
+
*/
|
187 |
+
private function get_major_minor_version( $version ) {
|
188 |
+
$version_parts = preg_split( '/[^0-9]+/', $version, 3 );
|
189 |
+
return join( '.', array_slice( $version_parts, 0, 2 ) );
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Builds Yoast SEO update notification.
|
194 |
+
*
|
195 |
+
* @param object $release_info The release information.
|
196 |
+
*
|
197 |
+
* @return Yoast_Notification The notification for the present version
|
198 |
+
*/
|
199 |
+
private function get_yoast_seo_update_notification( $release_info ) {
|
200 |
+
$info_message = '<strong>' .
|
201 |
+
sprintf(
|
202 |
+
/* translators: %1$s expands to Yoast SEO, %2$s expands to the plugin version. */
|
203 |
+
__( 'New in %1$s %2$s: ', 'wordpress-seo' ),
|
204 |
+
'Yoast SEO',
|
205 |
+
$release_info->version
|
206 |
+
) .
|
207 |
+
'</strong>' .
|
208 |
+
$release_info->release_description;
|
209 |
+
|
210 |
+
if ( ! empty( $release_info->shortlink ) ) {
|
211 |
+
$link = esc_url( WPSEO_Shortlinker::get( $release_info->shortlink ) );
|
212 |
+
$info_message .= ' <a href="' . esc_url( $link ) . '" target="_blank">' .
|
213 |
+
sprintf(
|
214 |
+
/* translators: %s expands to the plugin version. */
|
215 |
+
__( 'Read all about version %s here', 'wordpress-seo' ),
|
216 |
+
$release_info->version
|
217 |
+
) .
|
218 |
+
'</a>';
|
219 |
+
}
|
220 |
+
|
221 |
+
return new Yoast_Notification(
|
222 |
+
$info_message,
|
223 |
+
[
|
224 |
+
'id' => 'wpseo-plugin-updated',
|
225 |
+
'type' => Yoast_Notification::UPDATED,
|
226 |
+
'data_json' => [ 'dismiss_value' => WPSEO_Options::get( 'version', WPSEO_VERSION ) ],
|
227 |
+
'dismissal_key' => 'wpseo-plugin-updated',
|
228 |
+
]
|
229 |
+
);
|
230 |
+
}
|
231 |
+
|
232 |
/**
|
233 |
* Creates an unsupported PHP version notification in the notification center.
|
234 |
*
|
admin/class-admin-media-purge-notification.php
CHANGED
@@ -27,7 +27,7 @@ class WPSEO_Admin_Media_Purge_Notification implements WPSEO_WordPress_Integratio
|
|
27 |
add_filter( 'wpseo_option_tab-metas_media', [ $this, 'output_hidden_setting' ] );
|
28 |
|
29 |
// Dismissing is just setting the relevancy to false, which cancels out any functionality.
|
30 |
-
if (
|
31 |
WPSEO_Options::set( 'is-media-purge-relevant', false );
|
32 |
}
|
33 |
}
|
27 |
add_filter( 'wpseo_option_tab-metas_media', [ $this, 'output_hidden_setting' ] );
|
28 |
|
29 |
// Dismissing is just setting the relevancy to false, which cancels out any functionality.
|
30 |
+
if ( YoastSEO()->helpers->current_page->is_yoast_seo_page() && filter_input( INPUT_GET, 'dismiss' ) === $this->notification_id ) {
|
31 |
WPSEO_Options::set( 'is-media-purge-relevant', false );
|
32 |
}
|
33 |
}
|
admin/class-admin.php
CHANGED
@@ -51,10 +51,6 @@ class WPSEO_Admin {
|
|
51 |
add_filter( 'wpseo_accessible_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] );
|
52 |
}
|
53 |
|
54 |
-
if ( filter_input( INPUT_GET, 'page' ) === 'wpseo_tools' && filter_input( INPUT_GET, 'tool' ) === null ) {
|
55 |
-
new WPSEO_Recalculate_Scores();
|
56 |
-
}
|
57 |
-
|
58 |
add_filter( 'plugin_action_links_' . WPSEO_BASENAME, [ $this, 'add_action_link' ], 10, 2 );
|
59 |
|
60 |
add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] );
|
@@ -74,7 +70,7 @@ class WPSEO_Admin {
|
|
74 |
WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' );
|
75 |
WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'home' );
|
76 |
|
77 |
-
if (
|
78 |
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
|
79 |
}
|
80 |
|
@@ -117,7 +113,6 @@ class WPSEO_Admin {
|
|
117 |
$integrations = array_merge(
|
118 |
$integrations,
|
119 |
$this->get_admin_features(),
|
120 |
-
$this->initialize_seo_links(),
|
121 |
$this->initialize_cornerstone_content()
|
122 |
);
|
123 |
|
@@ -369,42 +364,6 @@ class WPSEO_Admin {
|
|
369 |
];
|
370 |
}
|
371 |
|
372 |
-
/**
|
373 |
-
* Initializes the seo link watcher.
|
374 |
-
*
|
375 |
-
* @returns WPSEO_WordPress_Integration[]
|
376 |
-
*/
|
377 |
-
protected function initialize_seo_links() {
|
378 |
-
$integrations = [];
|
379 |
-
|
380 |
-
if ( ! WPSEO_Options::get( 'enable_text_link_counter' ) ) {
|
381 |
-
return $integrations;
|
382 |
-
}
|
383 |
-
|
384 |
-
$integrations[] = new WPSEO_Link_Cleanup_Transient();
|
385 |
-
|
386 |
-
if ( ! WPSEO_Link_Table_Accessible::is_accessible() ) {
|
387 |
-
WPSEO_Link_Table_Accessible::cleanup();
|
388 |
-
}
|
389 |
-
|
390 |
-
if ( ! WPSEO_Meta_Table_Accessible::is_accessible() ) {
|
391 |
-
WPSEO_Meta_Table_Accessible::cleanup();
|
392 |
-
}
|
393 |
-
|
394 |
-
if ( ! WPSEO_Link_Table_Accessible::is_accessible() || ! WPSEO_Meta_Table_Accessible::is_accessible() ) {
|
395 |
-
return $integrations;
|
396 |
-
}
|
397 |
-
|
398 |
-
$integrations[] = new WPSEO_Link_Columns( new WPSEO_Meta_Storage() );
|
399 |
-
$integrations[] = new WPSEO_Link_Reindex_Dashboard();
|
400 |
-
$integrations[] = new WPSEO_Link_Notifier();
|
401 |
-
|
402 |
-
// Adds a filter to exclude the attachments from the link count.
|
403 |
-
add_filter( 'wpseo_link_count_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] );
|
404 |
-
|
405 |
-
return $integrations;
|
406 |
-
}
|
407 |
-
|
408 |
/**
|
409 |
* Retrieves an instance of the HelpScout beacon class for Yoast SEO.
|
410 |
*
|
51 |
add_filter( 'wpseo_accessible_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] );
|
52 |
}
|
53 |
|
|
|
|
|
|
|
|
|
54 |
add_filter( 'plugin_action_links_' . WPSEO_BASENAME, [ $this, 'add_action_link' ], 10, 2 );
|
55 |
|
56 |
add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] );
|
70 |
WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' );
|
71 |
WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'home' );
|
72 |
|
73 |
+
if ( YoastSEO()->helpers->current_page->is_yoast_seo_page() ) {
|
74 |
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
|
75 |
}
|
76 |
|
113 |
$integrations = array_merge(
|
114 |
$integrations,
|
115 |
$this->get_admin_features(),
|
|
|
116 |
$this->initialize_cornerstone_content()
|
117 |
);
|
118 |
|
364 |
];
|
365 |
}
|
366 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
367 |
/**
|
368 |
* Retrieves an instance of the HelpScout beacon class for Yoast SEO.
|
369 |
*
|
admin/class-license-page-manager.php
CHANGED
@@ -10,13 +10,6 @@
|
|
10 |
*/
|
11 |
class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
12 |
|
13 |
-
/**
|
14 |
-
* Version number for License Page Manager.
|
15 |
-
*
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
const VERSION_LEGACY = '1';
|
19 |
-
|
20 |
/**
|
21 |
* Version number for License Page Manager.
|
22 |
*
|
@@ -124,7 +117,7 @@ class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
|
124 |
* @return int The version number
|
125 |
*/
|
126 |
protected function get_version() {
|
127 |
-
return
|
128 |
}
|
129 |
|
130 |
/**
|
@@ -133,7 +126,7 @@ class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
|
133 |
* @return string The option name.
|
134 |
*/
|
135 |
protected function get_option_name() {
|
136 |
-
return '
|
137 |
}
|
138 |
|
139 |
/**
|
@@ -153,7 +146,7 @@ class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
|
153 |
* @param string $server_version The version number to save.
|
154 |
*/
|
155 |
protected function set_version( $server_version ) {
|
156 |
-
|
157 |
}
|
158 |
|
159 |
/**
|
@@ -200,7 +193,7 @@ class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
|
200 |
'capabilities' => 'wpseo_manage_options',
|
201 |
];
|
202 |
|
203 |
-
|
204 |
sprintf(
|
205 |
/* translators: %1$s expands to the product name. %2$s expands to a link to My Yoast */
|
206 |
__( 'You are not receiving updates or support! Fix this problem by adding this site and enabling %1$s for it in %2$s.', 'wordpress-seo' ),
|
@@ -209,7 +202,5 @@ class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
|
209 |
),
|
210 |
$notification_options
|
211 |
);
|
212 |
-
|
213 |
-
return $notification;
|
214 |
}
|
215 |
}
|
10 |
*/
|
11 |
class WPSEO_License_Page_Manager implements WPSEO_WordPress_Integration {
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* Version number for License Page Manager.
|
15 |
*
|
117 |
* @return int The version number
|
118 |
*/
|
119 |
protected function get_version() {
|
120 |
+
return WPSEO_Options::get( $this->get_option_name(), self::VERSION_BACKWARDS_COMPATIBILITY );
|
121 |
}
|
122 |
|
123 |
/**
|
126 |
* @return string The option name.
|
127 |
*/
|
128 |
protected function get_option_name() {
|
129 |
+
return 'license_server_version';
|
130 |
}
|
131 |
|
132 |
/**
|
146 |
* @param string $server_version The version number to save.
|
147 |
*/
|
148 |
protected function set_version( $server_version ) {
|
149 |
+
WPSEO_Options::set( $this->get_option_name(), $server_version );
|
150 |
}
|
151 |
|
152 |
/**
|
193 |
'capabilities' => 'wpseo_manage_options',
|
194 |
];
|
195 |
|
196 |
+
return new Yoast_Notification(
|
197 |
sprintf(
|
198 |
/* translators: %1$s expands to the product name. %2$s expands to a link to My Yoast */
|
199 |
__( 'You are not receiving updates or support! Fix this problem by adding this site and enabling %1$s for it in %2$s.', 'wordpress-seo' ),
|
202 |
),
|
203 |
$notification_options
|
204 |
);
|
|
|
|
|
205 |
}
|
206 |
}
|
admin/class-meta-columns.php
CHANGED
@@ -6,6 +6,8 @@
|
|
6 |
*/
|
7 |
|
8 |
use Yoast\WP\SEO\Context\Meta_Tags_Context;
|
|
|
|
|
9 |
|
10 |
/**
|
11 |
* Class WPSEO_Meta_Columns.
|
@@ -33,6 +35,13 @@ class WPSEO_Meta_Columns {
|
|
33 |
*/
|
34 |
private $analysis_readability;
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
/**
|
37 |
* When page analysis is enabled, just initialize the hooks.
|
38 |
*/
|
@@ -43,6 +52,7 @@ class WPSEO_Meta_Columns {
|
|
43 |
|
44 |
$this->analysis_seo = new WPSEO_Metabox_Analysis_SEO();
|
45 |
$this->analysis_readability = new WPSEO_Metabox_Analysis_Readability();
|
|
|
46 |
}
|
47 |
|
48 |
/**
|
@@ -60,35 +70,6 @@ class WPSEO_Meta_Columns {
|
|
60 |
}
|
61 |
|
62 |
add_filter( 'request', [ $this, 'column_sort_orderby' ] );
|
63 |
-
|
64 |
-
// Hook into tablenav to get the indexable context, at this point we can get the post ids.
|
65 |
-
add_action( 'manage_posts_extra_tablenav', [ $this, 'get_post_ids_and_set_context' ] );
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Retrieves the post ids and sets the context objects for all the indexables belonging
|
70 |
-
* to the post ids.
|
71 |
-
*
|
72 |
-
* @param string $target Extra table navigation location which is triggered.
|
73 |
-
*/
|
74 |
-
public function get_post_ids_and_set_context( $target ) {
|
75 |
-
if ( $target !== 'top' ) {
|
76 |
-
return;
|
77 |
-
}
|
78 |
-
|
79 |
-
global $wp_query;
|
80 |
-
|
81 |
-
$posts = empty( $wp_query->posts ) ? $wp_query->get_posts() : $wp_query->posts;
|
82 |
-
$post_ids = [];
|
83 |
-
|
84 |
-
// Post lists return a list of objects.
|
85 |
-
if ( isset( $posts[0] ) && is_object( $posts[0] ) ) {
|
86 |
-
$post_ids = wp_list_pluck( $posts, 'ID' );
|
87 |
-
}
|
88 |
-
elseif ( ! empty( $posts ) ) {
|
89 |
-
// Page list returns an array of post IDs.
|
90 |
-
$post_ids = array_keys( $posts );
|
91 |
-
}
|
92 |
}
|
93 |
|
94 |
/**
|
@@ -146,11 +127,11 @@ class WPSEO_Meta_Columns {
|
|
146 |
return;
|
147 |
|
148 |
case 'wpseo-title':
|
149 |
-
echo esc_html(
|
150 |
return;
|
151 |
|
152 |
case 'wpseo-metadesc':
|
153 |
-
$metadesc_val =
|
154 |
|
155 |
if ( $metadesc_val === '' ) {
|
156 |
echo '<span aria-hidden="true">—</span><span class="screen-reader-text">',
|
@@ -290,6 +271,19 @@ class WPSEO_Meta_Columns {
|
|
290 |
return '<option ' . $selected . ' value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
|
291 |
}
|
292 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
293 |
/**
|
294 |
* Determines the SEO score filter to be later used in the meta query, based on the passed SEO filter.
|
295 |
*
|
6 |
*/
|
7 |
|
8 |
use Yoast\WP\SEO\Context\Meta_Tags_Context;
|
9 |
+
use Yoast\WP\SEO\Integrations\Admin\Admin_Columns_Cache_Integration;
|
10 |
+
use Yoast\WP\SEO\Surfaces\Values\Meta;
|
11 |
|
12 |
/**
|
13 |
* Class WPSEO_Meta_Columns.
|
35 |
*/
|
36 |
private $analysis_readability;
|
37 |
|
38 |
+
/**
|
39 |
+
* Admin columns cache.
|
40 |
+
*
|
41 |
+
* @var Admin_Columns_Cache_Integration
|
42 |
+
*/
|
43 |
+
private $admin_columns_cache;
|
44 |
+
|
45 |
/**
|
46 |
* When page analysis is enabled, just initialize the hooks.
|
47 |
*/
|
52 |
|
53 |
$this->analysis_seo = new WPSEO_Metabox_Analysis_SEO();
|
54 |
$this->analysis_readability = new WPSEO_Metabox_Analysis_Readability();
|
55 |
+
$this->admin_columns_cache = YoastSEO()->classes->get( Admin_Columns_Cache_Integration::class );
|
56 |
}
|
57 |
|
58 |
/**
|
70 |
}
|
71 |
|
72 |
add_filter( 'request', [ $this, 'column_sort_orderby' ] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
/**
|
127 |
return;
|
128 |
|
129 |
case 'wpseo-title':
|
130 |
+
echo esc_html( $this->get_meta( $post_id )->title );
|
131 |
return;
|
132 |
|
133 |
case 'wpseo-metadesc':
|
134 |
+
$metadesc_val = $this->get_meta( $post_id )->meta_description;
|
135 |
|
136 |
if ( $metadesc_val === '' ) {
|
137 |
echo '<span aria-hidden="true">—</span><span class="screen-reader-text">',
|
271 |
return '<option ' . $selected . ' value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
|
272 |
}
|
273 |
|
274 |
+
/**
|
275 |
+
* Returns the meta object for a given post ID.
|
276 |
+
*
|
277 |
+
* @param int $post_id The post ID.
|
278 |
+
*
|
279 |
+
* @return Meta The meta object.
|
280 |
+
*/
|
281 |
+
protected function get_meta( $post_id ) {
|
282 |
+
$indexable = $this->admin_columns_cache->get_indexable( $post_id );
|
283 |
+
|
284 |
+
return YoastSEO()->meta->for_indexable( $indexable, 'Post_Type' );
|
285 |
+
}
|
286 |
+
|
287 |
/**
|
288 |
* Determines the SEO score filter to be later used in the meta query, based on the passed SEO filter.
|
289 |
*
|
admin/class-meta-storage.php
DELETED
@@ -1,126 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the link count storage.
|
10 |
-
*/
|
11 |
-
class WPSEO_Meta_Storage implements WPSEO_Installable {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Table name for the meta storage.
|
15 |
-
*
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
const TABLE_NAME = 'yoast_seo_meta';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Holds the database's proxy.
|
22 |
-
*
|
23 |
-
* @var WPSEO_Database_Proxy
|
24 |
-
*/
|
25 |
-
protected $database_proxy;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Holds the prefix of the table.
|
29 |
-
*
|
30 |
-
* @deprecated 7.4
|
31 |
-
*
|
32 |
-
* @var null|string
|
33 |
-
*/
|
34 |
-
protected $table_prefix;
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Initializes the database table.
|
38 |
-
*
|
39 |
-
* @param string $table_prefix Optional. Deprecated argument.
|
40 |
-
*/
|
41 |
-
public function __construct( $table_prefix = null ) {
|
42 |
-
if ( $table_prefix !== null ) {
|
43 |
-
_deprecated_argument( __METHOD__, 'WPSEO 7.4' );
|
44 |
-
}
|
45 |
-
|
46 |
-
$this->database_proxy = new WPSEO_Database_Proxy( $GLOBALS['wpdb'], self::TABLE_NAME, true );
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Returns the table name to use.
|
51 |
-
*
|
52 |
-
* @return string The table name.
|
53 |
-
*/
|
54 |
-
public function get_table_name() {
|
55 |
-
return $this->database_proxy->get_table_name();
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Creates the database table.
|
60 |
-
*
|
61 |
-
* @return boolean True if the table was created, false if something went wrong.
|
62 |
-
*/
|
63 |
-
public function install() {
|
64 |
-
return $this->database_proxy->create_table(
|
65 |
-
[
|
66 |
-
'object_id bigint(20) UNSIGNED NOT NULL',
|
67 |
-
'internal_link_count int(10) UNSIGNED NULL DEFAULT NULL',
|
68 |
-
'incoming_link_count int(10) UNSIGNED NULL DEFAULT NULL',
|
69 |
-
],
|
70 |
-
[
|
71 |
-
'UNIQUE KEY object_id (object_id)',
|
72 |
-
]
|
73 |
-
);
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Saves the link count to the database.
|
78 |
-
*
|
79 |
-
* @param int $meta_id The id to save the link count for.
|
80 |
-
* @param array $meta_data The total amount of links.
|
81 |
-
*/
|
82 |
-
public function save_meta_data( $meta_id, array $meta_data ) {
|
83 |
-
$where = [ 'object_id' => $meta_id ];
|
84 |
-
|
85 |
-
$saved = $this->database_proxy->upsert(
|
86 |
-
array_merge( $where, $meta_data ),
|
87 |
-
$where
|
88 |
-
);
|
89 |
-
|
90 |
-
if ( $saved === false ) {
|
91 |
-
WPSEO_Meta_Table_Accessible::set_inaccessible();
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Updates the incoming link count.
|
97 |
-
*
|
98 |
-
* @param array $post_ids The posts to update the incoming link count for.
|
99 |
-
* @param WPSEO_Link_Storage $storage The link storage object.
|
100 |
-
*/
|
101 |
-
public function update_incoming_link_count( array $post_ids, WPSEO_Link_Storage $storage ) {
|
102 |
-
global $wpdb;
|
103 |
-
|
104 |
-
$query = $wpdb->prepare(
|
105 |
-
'
|
106 |
-
SELECT COUNT( id ) AS incoming, target_post_id AS post_id
|
107 |
-
FROM ' . $storage->get_table_name() . '
|
108 |
-
WHERE target_post_id IN(' . implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) . ')
|
109 |
-
GROUP BY target_post_id',
|
110 |
-
$post_ids
|
111 |
-
);
|
112 |
-
|
113 |
-
$results = $wpdb->get_results( $query );
|
114 |
-
|
115 |
-
$post_ids_non_zero = [];
|
116 |
-
foreach ( $results as $result ) {
|
117 |
-
$this->save_meta_data( $result->post_id, [ 'incoming_link_count' => $result->incoming ] );
|
118 |
-
$post_ids_non_zero[] = $result->post_id;
|
119 |
-
}
|
120 |
-
|
121 |
-
$post_ids_zero = array_diff( $post_ids, $post_ids_non_zero );
|
122 |
-
foreach ( $post_ids_zero as $post_id ) {
|
123 |
-
$this->save_meta_data( $post_id, [ 'incoming_link_count' => 0 ] );
|
124 |
-
}
|
125 |
-
}
|
126 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/class-meta-table-accessible.php
DELETED
@@ -1,103 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the state of the table being accessible.
|
10 |
-
*/
|
11 |
-
class WPSEO_Meta_Table_Accessible {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Indicates that the table is accessible.
|
15 |
-
*
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
const ACCESSIBLE = '0';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Indicates that the table is inaccessible.
|
22 |
-
*
|
23 |
-
* @var string
|
24 |
-
*/
|
25 |
-
const INACCESSBILE = '1';
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Checks if the given table name exists.
|
29 |
-
*
|
30 |
-
* @return bool True when table is accessible.
|
31 |
-
*/
|
32 |
-
public static function is_accessible() {
|
33 |
-
$value = get_transient( self::transient_name() );
|
34 |
-
|
35 |
-
// If the value is not set, check the table.
|
36 |
-
if ( $value === false ) {
|
37 |
-
return self::check_table();
|
38 |
-
}
|
39 |
-
|
40 |
-
return $value === self::ACCESSIBLE;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Sets the transient value to 1, to indicate the table is not accessible.
|
45 |
-
*
|
46 |
-
* @return void
|
47 |
-
*/
|
48 |
-
public static function set_inaccessible() {
|
49 |
-
set_transient( self::transient_name(), self::INACCESSBILE, HOUR_IN_SECONDS );
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Removes the transient.
|
54 |
-
*
|
55 |
-
* @return void
|
56 |
-
*/
|
57 |
-
public static function cleanup() {
|
58 |
-
delete_transient( self::transient_name() );
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Sets the transient value to 0, to indicate the table is accessible.
|
63 |
-
*
|
64 |
-
* @return void
|
65 |
-
*/
|
66 |
-
protected static function set_accessible() {
|
67 |
-
/*
|
68 |
-
* Prefer to set a 0 timeout, but if the timeout was set before WordPress will not delete the transient
|
69 |
-
* correctly when overridden with a zero value.
|
70 |
-
*
|
71 |
-
* Setting a YEAR_IN_SECONDS instead.
|
72 |
-
*/
|
73 |
-
set_transient( self::transient_name(), self::ACCESSIBLE, YEAR_IN_SECONDS );
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Checks if the table exists if not, set the transient to indicate the inaccessible table.
|
78 |
-
*
|
79 |
-
* @return bool True if table is accessible.
|
80 |
-
*/
|
81 |
-
protected static function check_table() {
|
82 |
-
global $wpdb;
|
83 |
-
|
84 |
-
$storage = new WPSEO_Meta_Storage();
|
85 |
-
$query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $storage->get_table_name() );
|
86 |
-
if ( $wpdb->get_var( $query ) !== $storage->get_table_name() ) {
|
87 |
-
self::set_inaccessible();
|
88 |
-
return false;
|
89 |
-
}
|
90 |
-
|
91 |
-
self::set_accessible();
|
92 |
-
return true;
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Returns the name of the transient.
|
97 |
-
*
|
98 |
-
* @return string The name of the transient to use.
|
99 |
-
*/
|
100 |
-
protected static function transient_name() {
|
101 |
-
return 'wpseo_meta_table_inaccessible';
|
102 |
-
}
|
103 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/class-recalculate-scores.php
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class WPSEO_Recalculate_Scores.
|
10 |
-
*
|
11 |
-
* This class handles the SEO score recalculation for all posts with a filled focus keyword.
|
12 |
-
*/
|
13 |
-
class WPSEO_Recalculate_Scores {
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Constructing the object by modalbox, the localization and the totals.
|
17 |
-
*/
|
18 |
-
public function __construct() {
|
19 |
-
add_action( 'admin_enqueue_scripts', [ $this, 'recalculate_assets' ] );
|
20 |
-
add_action( 'admin_footer', [ $this, 'modal_box' ], 20 );
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Run the localize script.
|
25 |
-
*/
|
26 |
-
public function recalculate_assets() {
|
27 |
-
$asset_manager = new WPSEO_Admin_Asset_Manager();
|
28 |
-
$asset_manager->enqueue_script( 'recalculate' );
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Initialize the modal box to be displayed when needed.
|
33 |
-
*/
|
34 |
-
public function modal_box() {
|
35 |
-
// Adding the thickbox.
|
36 |
-
add_thickbox();
|
37 |
-
|
38 |
-
$progress = sprintf(
|
39 |
-
/* translators: 1: expands to a <span> containing the number of posts recalculated. 2: expands to a <strong> containing the total number of posts. */
|
40 |
-
esc_html__( '%1$s of %2$s done.', 'wordpress-seo' ),
|
41 |
-
'<span id="wpseo_count">0</span>',
|
42 |
-
'<strong id="wpseo_count_total">0</strong>'
|
43 |
-
);
|
44 |
-
|
45 |
-
?>
|
46 |
-
<div id="wpseo_recalculate" class="hidden">
|
47 |
-
<p><?php esc_html_e( 'Recalculating SEO scores for all pieces of content with a focus keyphrase.', 'wordpress-seo' ); ?></p>
|
48 |
-
|
49 |
-
<div id="wpseo_progressbar"></div>
|
50 |
-
<p><?php echo $progress; ?></p>
|
51 |
-
</div>
|
52 |
-
<?php
|
53 |
-
}
|
54 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/class-yoast-notification-center.php
CHANGED
@@ -164,8 +164,9 @@ class Yoast_Notification_Center {
|
|
164 |
return true;
|
165 |
}
|
166 |
|
167 |
-
$dismissal_key
|
168 |
-
$notification_id
|
|
|
169 |
|
170 |
$is_dismissing = ( $dismissal_key === self::get_user_input( 'notification' ) );
|
171 |
if ( ! $is_dismissing ) {
|
@@ -186,6 +187,13 @@ class Yoast_Notification_Center {
|
|
186 |
return false;
|
187 |
}
|
188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
return self::dismiss_notification( $notification, $meta_value );
|
190 |
}
|
191 |
|
164 |
return true;
|
165 |
}
|
166 |
|
167 |
+
$dismissal_key = $notification->get_dismissal_key();
|
168 |
+
$notification_id = $notification->get_id();
|
169 |
+
$notification_json = $notification->get_json();
|
170 |
|
171 |
$is_dismissing = ( $dismissal_key === self::get_user_input( 'notification' ) );
|
172 |
if ( ! $is_dismissing ) {
|
187 |
return false;
|
188 |
}
|
189 |
|
190 |
+
if ( ! empty( $notification_json ) ) {
|
191 |
+
$notification_data = json_decode( $notification_json );
|
192 |
+
if ( ! is_null( $notification_data ) && isset( $notification_data->dismiss_value ) ) {
|
193 |
+
$meta_value = $notification_data->dismiss_value;
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
return self::dismiss_notification( $notification, $meta_value );
|
198 |
}
|
199 |
|
admin/links/class-link-cleanup-transient.php
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the cleanup logic when the text link counter features has been disabled.
|
10 |
-
*/
|
11 |
-
class WPSEO_Link_Cleanup_Transient implements WPSEO_WordPress_Integration {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Registers the hooks.
|
15 |
-
*/
|
16 |
-
public function register_hooks() {
|
17 |
-
add_action( 'update_option_wpseo', [ $this, 'remove_transients_on_updated_option' ], 10, 2 );
|
18 |
-
}
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Removes the transient when the option is updated.
|
22 |
-
*
|
23 |
-
* @param mixed $old_value The old value.
|
24 |
-
* @param mixed $value The new value.
|
25 |
-
*
|
26 |
-
* @return void
|
27 |
-
*/
|
28 |
-
public function remove_transients_on_updated_option( $old_value, $value ) {
|
29 |
-
$option_name = 'enable_text_link_counter';
|
30 |
-
if ( $value[ $option_name ] === false && $old_value[ $option_name ] !== $value[ $option_name ] ) {
|
31 |
-
WPSEO_Link_Table_Accessible::cleanup();
|
32 |
-
WPSEO_Meta_Table_Accessible::cleanup();
|
33 |
-
}
|
34 |
-
}
|
35 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/links/class-link-column-count.php
DELETED
@@ -1,93 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the link column count. This class contains the count for each post id on the current page.
|
10 |
-
*/
|
11 |
-
class WPSEO_Link_Column_Count {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* The link counts for each post id on the current page.
|
15 |
-
*
|
16 |
-
* @var array
|
17 |
-
*/
|
18 |
-
protected $count = [];
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Sets the counts for the set target field.
|
22 |
-
*
|
23 |
-
* @param array $post_ids The posts to get the count for.
|
24 |
-
*/
|
25 |
-
public function set( $post_ids ) {
|
26 |
-
if ( empty( $post_ids ) ) {
|
27 |
-
return;
|
28 |
-
}
|
29 |
-
|
30 |
-
$this->count = $this->get_results( $post_ids );
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Gets the link count for given post id.
|
35 |
-
*
|
36 |
-
* @param int $post_id The post id.
|
37 |
-
* @param string $target_field The field to show.
|
38 |
-
*
|
39 |
-
* @return int|null The total amount of links or null if the target field
|
40 |
-
* does not exist for the given post id.
|
41 |
-
*/
|
42 |
-
public function get( $post_id, $target_field = 'internal_link_count' ) {
|
43 |
-
if ( array_key_exists( $post_id, $this->count ) && array_key_exists( $target_field, $this->count[ $post_id ] ) ) {
|
44 |
-
return $this->count[ $post_id ][ $target_field ];
|
45 |
-
}
|
46 |
-
|
47 |
-
return null;
|
48 |
-
}
|
49 |
-
|
50 |
-
/**
|
51 |
-
* Gets the link count for the given post ids.
|
52 |
-
*
|
53 |
-
* @param array $post_ids Array with post_ids.
|
54 |
-
*
|
55 |
-
* @return array
|
56 |
-
*/
|
57 |
-
protected function get_results( $post_ids ) {
|
58 |
-
global $wpdb;
|
59 |
-
|
60 |
-
$storage = new WPSEO_Meta_Storage();
|
61 |
-
|
62 |
-
$results = $wpdb->get_results(
|
63 |
-
$wpdb->prepare(
|
64 |
-
'
|
65 |
-
SELECT internal_link_count, incoming_link_count, object_id
|
66 |
-
FROM ' . $storage->get_table_name() . '
|
67 |
-
WHERE object_id IN (' . implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) . ')',
|
68 |
-
$post_ids
|
69 |
-
),
|
70 |
-
ARRAY_A
|
71 |
-
);
|
72 |
-
|
73 |
-
$output = [];
|
74 |
-
foreach ( $results as $result ) {
|
75 |
-
$output[ (int) $result['object_id'] ] = [
|
76 |
-
'internal_link_count' => $result['internal_link_count'],
|
77 |
-
'incoming_link_count' => (int) $result['incoming_link_count'],
|
78 |
-
];
|
79 |
-
}
|
80 |
-
|
81 |
-
// Set unfound items to zero.
|
82 |
-
foreach ( $post_ids as $post_id ) {
|
83 |
-
if ( ! array_key_exists( $post_id, $output ) ) {
|
84 |
-
$output[ $post_id ] = [
|
85 |
-
'internal_link_count' => null,
|
86 |
-
'incoming_link_count' => 0,
|
87 |
-
];
|
88 |
-
}
|
89 |
-
}
|
90 |
-
|
91 |
-
return $output;
|
92 |
-
}
|
93 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/links/class-link-content-processor.php
DELETED
@@ -1,143 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the content processor. It will extract links from the content and
|
10 |
-
* saves them for the given post id.
|
11 |
-
*/
|
12 |
-
class WPSEO_Link_Content_Processor {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Holds the link storage instance.
|
16 |
-
*
|
17 |
-
* @var WPSEO_Link_Storage
|
18 |
-
*/
|
19 |
-
protected $storage;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Holds the meta storage instance.
|
23 |
-
*
|
24 |
-
* @var WPSEO_Meta_Storage
|
25 |
-
*/
|
26 |
-
private $count_storage;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Sets an instance of a storage object.
|
30 |
-
*
|
31 |
-
* @param WPSEO_Link_Storage $storage The storage object to use.
|
32 |
-
* @param WPSEO_Meta_Storage $count_storage The storage object for the link
|
33 |
-
* counts.
|
34 |
-
*/
|
35 |
-
public function __construct( WPSEO_Link_Storage $storage, WPSEO_Meta_Storage $count_storage ) {
|
36 |
-
$this->storage = $storage;
|
37 |
-
$this->count_storage = $count_storage;
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Process the content for the given post id.
|
42 |
-
*
|
43 |
-
* @param int $post_id The post id.
|
44 |
-
* @param string $content The content to process.
|
45 |
-
*/
|
46 |
-
public function process( $post_id, $content ) {
|
47 |
-
$link_extractor = new WPSEO_Link_Extractor( $content );
|
48 |
-
$link_processor = new WPSEO_Link_Factory(
|
49 |
-
new WPSEO_Link_Type_Classifier( home_url() ),
|
50 |
-
new WPSEO_Link_Internal_Lookup(),
|
51 |
-
new WPSEO_Link_Filter( get_permalink( $post_id ) )
|
52 |
-
);
|
53 |
-
|
54 |
-
$extracted_links = $link_extractor->extract();
|
55 |
-
$links = $link_processor->build( $extracted_links );
|
56 |
-
|
57 |
-
$internal_links = array_filter( $links, [ $this, 'filter_internal_link' ] );
|
58 |
-
|
59 |
-
$stored_links = $this->get_stored_internal_links( $post_id );
|
60 |
-
|
61 |
-
$this->storage->cleanup( $post_id );
|
62 |
-
$this->storage->save_links( $post_id, $links );
|
63 |
-
|
64 |
-
$this->update_link_counts( $post_id, count( $internal_links ), array_merge( $stored_links, $internal_links ) );
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Updates the link counts for the post and referenced posts.
|
69 |
-
*
|
70 |
-
* @param int $post_id Post to update link counts for.
|
71 |
-
* @param int|null $count Number of internal links.
|
72 |
-
* @param array $links Links to process for incoming link count update.
|
73 |
-
*/
|
74 |
-
public function update_link_counts( $post_id, $count, array $links ) {
|
75 |
-
$this->store_internal_link_count( $post_id, $count );
|
76 |
-
$this->update_incoming_links( $post_id, $links );
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Retrieves the stored internal links for the supplied post.
|
81 |
-
*
|
82 |
-
* @param int $post_id The post to fetch links for.
|
83 |
-
*
|
84 |
-
* @return WPSEO_Link[] List of internal links connected to the post.
|
85 |
-
*/
|
86 |
-
public function get_stored_internal_links( $post_id ) {
|
87 |
-
$links = $this->storage->get_links( $post_id );
|
88 |
-
return array_filter( $links, [ $this, 'filter_internal_link' ] );
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Filters on INTERNAL links.
|
93 |
-
*
|
94 |
-
* @param WPSEO_Link $link Link to test type of.
|
95 |
-
*
|
96 |
-
* @return bool True for internal link, false for external link.
|
97 |
-
*/
|
98 |
-
protected function filter_internal_link( WPSEO_Link $link ) {
|
99 |
-
return $link->get_type() === WPSEO_Link::TYPE_INTERNAL;
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Stores the total links for the post.
|
104 |
-
*
|
105 |
-
* @param int $post_id The post id.
|
106 |
-
* @param int $internal_link_count Total amount of links in the post.
|
107 |
-
*
|
108 |
-
* @return void
|
109 |
-
*/
|
110 |
-
protected function store_internal_link_count( $post_id, $internal_link_count ) {
|
111 |
-
$this->count_storage->save_meta_data( $post_id, [ 'internal_link_count' => $internal_link_count ] );
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Updates the incoming link count.
|
116 |
-
*
|
117 |
-
* @param int $post_id Post which is processed, this needs to be recalculated too.
|
118 |
-
* @param WPSEO_Link[] $links Links to update the incoming link count of.
|
119 |
-
*
|
120 |
-
* @return void
|
121 |
-
*/
|
122 |
-
protected function update_incoming_links( $post_id, $links ) {
|
123 |
-
$post_ids = $this->get_internal_post_ids( $links );
|
124 |
-
$post_ids = array_merge( [ $post_id ], $post_ids );
|
125 |
-
$this->count_storage->update_incoming_link_count( $post_ids, $this->storage );
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Extract the post IDs from the links.
|
130 |
-
*
|
131 |
-
* @param WPSEO_Link[] $links Links to update the incoming link count of.
|
132 |
-
*
|
133 |
-
* @return int[] List of post IDs.
|
134 |
-
*/
|
135 |
-
protected function get_internal_post_ids( $links ) {
|
136 |
-
$post_ids = [];
|
137 |
-
foreach ( $links as $link ) {
|
138 |
-
$post_ids[] = $link->get_target_post_id();
|
139 |
-
}
|
140 |
-
|
141 |
-
return array_filter( $post_ids );
|
142 |
-
}
|
143 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/links/class-link-extractor.php
DELETED
@@ -1,52 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the link extractor.
|
10 |
-
*/
|
11 |
-
class WPSEO_Link_Extractor {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* The content to extract the links from.
|
15 |
-
*
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
protected $content;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Sets the content.
|
22 |
-
*
|
23 |
-
* @param string $content The content to extract the links from.
|
24 |
-
*/
|
25 |
-
public function __construct( $content ) {
|
26 |
-
$this->content = $content;
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Extracts the hrefs from the content and returns them as an array.
|
31 |
-
*
|
32 |
-
* @return array All the extracted links
|
33 |
-
*/
|
34 |
-
public function extract() {
|
35 |
-
$links = [];
|
36 |
-
|
37 |
-
if ( strpos( $this->content, 'href' ) === false ) {
|
38 |
-
return $links;
|
39 |
-
}
|
40 |
-
|
41 |
-
$regexp = '<a\s[^>]*href=("??)([^" >]*?)\\1[^>]*>';
|
42 |
-
|
43 |
-
// Used modifiers iU to match case insensitive and make greedy quantifiers lazy.
|
44 |
-
if ( preg_match_all( "/$regexp/iU", $this->content, $matches, PREG_SET_ORDER ) ) {
|
45 |
-
foreach ( $matches as $match ) {
|
46 |
-
$links[] = trim( $match[2], "'" );
|
47 |
-
}
|
48 |
-
}
|
49 |
-
|
50 |
-
return $links;
|
51 |
-
}
|
52 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/links/class-link-factory.php
DELETED
@@ -1,94 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Links
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the conversion from array with string links into WPSEO_Link objects.
|
10 |
-
*/
|
11 |
-
class WPSEO_Link_Factory {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Represents the classifier for a link. Determines of a link is an outbound or internal one.
|
15 |
-
*
|
16 |
-
* @var WPSEO_Link_Type_Classifier
|
17 |
-
*/
|
18 |
-
protected $classifier;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Represents the internal link lookup. This class tries get the postid for a given internal link.
|
22 |
-
*
|
23 |
-
* @var WPSEO_Link_Internal_Lookup
|
24 |
-
*/
|
25 |
-
protected $internal_lookup;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Represents the filter for filtering links.
|
29 |
-
*
|
30 |
-
* @var WPSEO_Link_Filter
|
31 |
-
*/
|
32 |
-
protected $filter;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Sets the dependencies for this object.
|
36 |
-
*
|
37 |
-
* @param WPSEO_Link_Type_Classifier $classifier The classifier to use.
|
38 |
-
* @param WPSEO_Link_Internal_Lookup $internal_lookup The internal lookup to use.
|
39 |
-
* @param WPSEO_Link_Filter $filter The link filter.
|
40 |
-
*/
|
41 |
-
public function __construct( WPSEO_Link_Type_Classifier $classifier, WPSEO_Link_Internal_Lookup $internal_lookup, WPSEO_Link_Filter $filter ) {
|
42 |
-
$this->classifier = $classifier;
|
43 |
-
$this->internal_lookup = $internal_lookup;
|
44 |
-
$this->filter = $filter;
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Formats an array of links to WPSEO_Link object.
|
49 |
-
*
|
50 |
-
* @param array $extracted_links The links for format.
|
51 |
-
*
|
52 |
-
* @return WPSEO_Link[] The formatted links.
|
53 |
-
*/
|
54 |
-
public function build( array $extracted_links ) {
|
55 |
-
$extracted_links = array_map( [ $this, 'build_link' ], $extracted_links );
|
56 |
-
$filtered_links = array_filter(
|
57 |
-
$extracted_links,
|
58 |
-
[ $this->filter, 'internal_link_with_fragment_filter' ]
|
59 |
-
);
|
60 |
-
|
61 |
-
return $filtered_links;
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Builds the link.
|
66 |
-
*
|
67 |
-
* @param string $link The link to build.
|
68 |
-
*
|
69 |
-
* @return WPSEO_Link The built link.
|
70 |
-
*/
|
71 |
-
public function build_link( $link ) {
|
72 |
-
$link_type = $this->classifier->classify( $link );
|
73 |
-
|
74 |
-
$target_post_id = 0;
|
75 |
-
if ( $link_type === WPSEO_Link::TYPE_INTERNAL ) {
|
76 |
-
$target_post_id = $this->internal_lookup->lookup( $link );
|
77 |
-
}
|
78 |
-
|
79 |
-
return self::get_link( $link, $target_post_id, $link_type );
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Returns the link object.
|
84 |
-
*
|
85 |
-
* @param string $url The URL of the link.
|
86 |
-
* @param int $target_post_id The target post ID.
|
87 |
-
* @param string $type The link type.
|
88 |
-
*
|
89 |
-
* @return WPSEO_Link Generated link object.
|
90 |
-
*/
|
91 |
-
public static function get_link( $url, $target_post_id, $type ) {
|
92 |
-
return new WPSEO_Link( $url, $target_post_id, $type );
|
93 |
-
}
|
94 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|