Yoast SEO - Version 7.9

Version Description

Download this release

Release Info

Developer atimmer
Plugin Icon 128x128 Yoast SEO
Version 7.9
Comparing to
See all releases

Code changes from version 7.8 to 7.9

Files changed (103) hide show
  1. admin/class-admin-asset-manager.php +2 -2
  2. admin/class-admin-asset-yoast-components-l10n.php +2 -2
  3. admin/class-admin-editor-specific-replace-vars.php +225 -0
  4. admin/class-admin-init.php +27 -0
  5. admin/class-admin-media-purge-notification.php +4 -3
  6. admin/class-admin-recommended-replace-vars.php +11 -11
  7. admin/class-admin.php +0 -1
  8. admin/class-config.php +9 -5
  9. admin/class-help-center.php +1 -1
  10. admin/class-option-tabs-formatter.php +2 -1
  11. admin/class-paper-presenter.php +116 -0
  12. admin/class-yoast-dashboard-widget.php +1 -1
  13. admin/class-yoast-notification-center.php +25 -2
  14. admin/class-yoast-plugin-conflict.php +1 -5
  15. admin/config-ui/class-configuration-page.php +1 -1
  16. admin/formatter/class-metabox-formatter.php +1 -0
  17. admin/menu/class-network-admin-menu.php +2 -1
  18. admin/menu/class-replacevar-editor.php +75 -36
  19. admin/menu/class-replacevar-field.php +23 -14
  20. admin/metabox/class-metabox.php +2 -2
  21. admin/notifiers/class-post-type-archive-notification-handler.php +268 -0
  22. admin/notifiers/interface-notification-handler.php +21 -0
  23. admin/taxonomy/class-taxonomy.php +17 -19
  24. admin/views/class-view-utils.php +16 -23
  25. admin/views/paper-collapsible.php +45 -0
  26. admin/views/tabs/metas/archives.php +31 -128
  27. admin/views/tabs/metas/archives/help.php +34 -0
  28. admin/views/tabs/metas/breadcrumbs.php +4 -105
  29. admin/views/tabs/metas/general.php +6 -9
  30. admin/views/tabs/metas/media.php +11 -32
  31. admin/views/tabs/metas/paper-content/author-archive-settings.php +77 -0
  32. admin/views/tabs/metas/paper-content/breadcrumbs-content.php +108 -0
  33. admin/views/tabs/metas/paper-content/date-archives-settings.php +57 -0
  34. admin/views/tabs/metas/paper-content/general-content.php +12 -0
  35. admin/views/tabs/metas/{general → paper-content/general}/force-rewrite-title.php +0 -0
  36. admin/views/tabs/metas/{general → paper-content/general}/homepage.php +10 -1
  37. admin/views/tabs/metas/{general → paper-content/general}/knowledge-graph.php +1 -1
  38. admin/views/tabs/metas/{general → paper-content/general}/title-separator.php +0 -0
  39. admin/views/tabs/metas/paper-content/media-content.php +52 -0
  40. admin/views/tabs/metas/paper-content/post-type-content.php +73 -0
  41. admin/views/tabs/metas/paper-content/post_type/post-type.php +45 -0
  42. admin/views/tabs/metas/paper-content/post_type/woocommerce-shop-page.php +23 -0
  43. admin/views/tabs/metas/paper-content/rss-content.php +52 -0
  44. admin/views/tabs/metas/paper-content/special-pages.php +27 -0
  45. admin/views/tabs/metas/paper-content/taxonomy-content.php +62 -0
  46. admin/views/tabs/metas/post-types.php +25 -92
  47. admin/views/tabs/metas/rss.php +12 -55
  48. admin/views/tabs/metas/taxonomies.php +31 -74
  49. admin/views/tabs/metas/taxonomies/category-url.php +28 -0
  50. admin/watchers/class-slug-change-watcher.php +7 -2
  51. css/dist/{admin-global-780-rtl.min.css → admin-global-790-rtl.min.css} +0 -0
  52. css/dist/{admin-global-780.min.css → admin-global-790.min.css} +0 -0
  53. css/dist/{adminbar-780-rtl.min.css → adminbar-790-rtl.min.css} +0 -0
  54. css/dist/{adminbar-780.min.css → adminbar-790.min.css} +0 -0
  55. css/dist/{alerts-780-rtl.min.css → alerts-790-rtl.min.css} +0 -0
  56. css/dist/{alerts-780.min.css → alerts-790.min.css} +0 -0
  57. css/dist/{dashboard-780-rtl.min.css → dashboard-790-rtl.min.css} +0 -0
  58. css/dist/{dashboard-780.min.css → dashboard-790.min.css} +0 -0
  59. css/dist/{edit-page-780-rtl.min.css → edit-page-790-rtl.min.css} +0 -0
  60. css/dist/{edit-page-780.min.css → edit-page-790.min.css} +0 -0
  61. css/dist/{featured-image-780-rtl.min.css → featured-image-790-rtl.min.css} +0 -0
  62. css/dist/{featured-image-780.min.css → featured-image-790.min.css} +0 -0
  63. css/dist/{filter-explanation-780-rtl.min.css → filter-explanation-790-rtl.min.css} +0 -0
  64. css/dist/{filter-explanation-780.min.css → filter-explanation-790.min.css} +0 -0
  65. css/dist/{inside-editor-780-rtl.min.css → inside-editor-790-rtl.min.css} +0 -0
  66. css/dist/{inside-editor-780.min.css → inside-editor-790.min.css} +0 -0
  67. css/dist/{metabox-780-rtl.min.css → metabox-790-rtl.min.css} +1 -1
  68. css/dist/{metabox-780.min.css → metabox-790.min.css} +1 -1
  69. css/dist/{metabox-primary-category-780-rtl.min.css → metabox-primary-category-790-rtl.min.css} +0 -0
  70. css/dist/{metabox-primary-category-780.min.css → metabox-primary-category-790.min.css} +0 -0
  71. css/dist/{search-appearance-780-rtl.min.css → search-appearance-790-rtl.min.css} +0 -0
  72. css/dist/{search-appearance-780.min.css → search-appearance-790.min.css} +0 -0
  73. css/dist/{snippet-780-rtl.min.css → snippet-790-rtl.min.css} +0 -0
  74. css/dist/{snippet-780.min.css → snippet-790.min.css} +0 -0
  75. css/dist/{toggle-switch-780-rtl.min.css → toggle-switch-790-rtl.min.css} +0 -0
  76. css/dist/{toggle-switch-780.min.css → toggle-switch-790.min.css} +0 -0
  77. css/dist/{wpseo-dismissible-780-rtl.min.css → wpseo-dismissible-790-rtl.min.css} +0 -0
  78. css/dist/{wpseo-dismissible-780.min.css → wpseo-dismissible-790.min.css} +0 -0
  79. css/dist/{yoast-components-780-rtl.min.css → yoast-components-790-rtl.min.css} +0 -0
  80. css/dist/{yoast-components-780.min.css → yoast-components-790.min.css} +0 -0
  81. css/dist/{yoast-extensions-780-rtl.min.css → yoast-extensions-790-rtl.min.css} +0 -0
  82. css/dist/{yoast-extensions-780.min.css → yoast-extensions-790.min.css} +0 -0
  83. css/dist/yst_plugin_tools-780-rtl.min.css +0 -1
  84. css/dist/yst_plugin_tools-780.min.css +0 -1
  85. css/dist/yst_plugin_tools-790-rtl.min.css +1 -0
  86. css/dist/yst_plugin_tools-790.min.css +1 -0
  87. css/dist/{yst_seo_score-780-rtl.min.css → yst_seo_score-790-rtl.min.css} +0 -0
  88. css/dist/{yst_seo_score-780.min.css → yst_seo_score-790.min.css} +0 -0
  89. frontend/class-breadcrumbs.php +1 -1
  90. frontend/class-frontend.php +18 -0
  91. frontend/class-opengraph.php +3 -3
  92. images/Yoast_icon_kader.svg +1 -0
  93. inc/class-post-type.php +16 -1
  94. inc/class-rewrite.php +65 -5
  95. inc/class-upgrade.php +2 -6
  96. inc/class-wpseo-content-images.php +3 -3
  97. inc/class-wpseo-custom-fields.php +65 -0
  98. inc/class-wpseo-custom-taxonomies.php +69 -0
  99. inc/class-wpseo-replace-vars.php +11 -10
  100. inc/options/class-wpseo-option-titles.php +2 -2
  101. inc/options/class-wpseo-taxonomy-meta.php +3 -1
  102. js/dist/{commons-780.min.js → commons-790.min.js} +7 -7
  103. js/dist/configuration-wizard-780.min.js +0 -12
admin/class-admin-asset-manager.php CHANGED
@@ -222,7 +222,7 @@ class WPSEO_Admin_Asset_Manager {
222
  ),
223
  array(
224
  'name' => 'search-appearance',
225
- 'src' => 'search-appearance-' . $flat_version,
226
  'deps' => 'react-dependencies',
227
  ),
228
  array(
@@ -527,7 +527,7 @@ class WPSEO_Admin_Asset_Manager {
527
  ),
528
  array(
529
  'name' => 'search-appearance',
530
- 'src' => 'search-appearance-' . $flat_version,
531
  ),
532
  );
533
  }
222
  ),
223
  array(
224
  'name' => 'search-appearance',
225
+ 'src' => 'search-appearance-' . $flat_version,
226
  'deps' => 'react-dependencies',
227
  ),
228
  array(
527
  ),
528
  array(
529
  'name' => 'search-appearance',
530
+ 'src' => 'search-appearance-' . $flat_version,
531
  ),
532
  );
533
  }
admin/class-admin-asset-yoast-components-l10n.php CHANGED
@@ -6,7 +6,7 @@
6
  /**
7
  * Localizes JavaScript files.
8
  */
9
- final class WPSEO_Admin_Asset_Yoast_Components_l10n {
10
  /**
11
  * Localizes the given script with the JavaScript translations.
12
  *
@@ -17,7 +17,7 @@ final class WPSEO_Admin_Asset_Yoast_Components_l10n {
17
  public function localize_script( $script_handle ) {
18
  wp_localize_script( $script_handle, 'wpseoYoastJSL10n', array(
19
  'yoast-components' => $this->get_translations( 'yoast-components' ),
20
- 'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
21
  ) );
22
  }
23
 
6
  /**
7
  * Localizes JavaScript files.
8
  */
9
+ final class WPSEO_Admin_Asset_Yoast_Components_L10n {
10
  /**
11
  * Localizes the given script with the JavaScript translations.
12
  *
17
  public function localize_script( $script_handle ) {
18
  wp_localize_script( $script_handle, 'wpseoYoastJSL10n', array(
19
  'yoast-components' => $this->get_translations( 'yoast-components' ),
20
+ 'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
21
  ) );
22
  }
23
 
admin/class-admin-editor-specific-replace-vars.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPSEO plugin file.
4
+ *
5
+ * @package WPSEO\Admin
6
+ */
7
+
8
+ /**
9
+ * Determines the editor specific replacement variables.
10
+ */
11
+ class WPSEO_Admin_Editor_Specific_Replace_Vars {
12
+
13
+ /**
14
+ * @var array The editor specific replacement variables.
15
+ */
16
+ protected $replacement_variables = array(
17
+ // Posts types.
18
+ 'page' => array( 'id', 'pt_single', 'pt_plural', 'parent_title' ),
19
+ 'post' => array( 'id', 'term404', 'pt_single', 'pt_plural' ),
20
+ // Custom post type.
21
+ 'custom_post_type' => array( 'id', 'term404', 'pt_single', 'pt_plural', 'parent_title' ),
22
+ // Settings - archive pages.
23
+ 'custom-post-type_archive' => array( 'pt_single', 'pt_plural' ),
24
+
25
+ // Taxonomies.
26
+ 'category' => array( 'term_title', 'term_description', 'category_description', 'parent_title' ),
27
+ 'post_tag' => array( 'term_title', 'term_description', 'tag_description' ),
28
+ 'post_format' => array(),
29
+ // Custom taxonomy.
30
+ 'term-in-custom-taxonomy' => array( 'term_title', 'term_description', 'category_description', 'parent_title' ),
31
+
32
+ // Settings - special pages.
33
+ 'search' => array( 'searchphrase' ),
34
+ );
35
+
36
+ /**
37
+ * WPSEO_Admin_Editor_Specific_Replace_Vars constructor.
38
+ */
39
+ public function __construct() {
40
+ $this->add_for_page_types(
41
+ array( 'page', 'post', 'custom_post_type' ),
42
+ WPSEO_Custom_Fields::get_custom_fields()
43
+ );
44
+
45
+ $this->add_for_page_types(
46
+ array( 'post', 'term-in-custom-taxonomies' ),
47
+ WPSEO_Custom_Taxonomies::get_custom_taxonomies()
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Retrieves the editor specific replacement variables.
53
+ *
54
+ * @return array The editor specific replacement variables.
55
+ */
56
+ public function get() {
57
+ /**
58
+ * Filter: Adds the possibility to add extra editor specific replacement variables.
59
+ *
60
+ * @api array $replacement_variables Empty array to add the editor specific replace vars to.
61
+ */
62
+ $replacement_variables = apply_filters(
63
+ 'wpseo_editor_specific_replace_vars',
64
+ $this->replacement_variables
65
+ );
66
+
67
+ if ( ! is_array( $replacement_variables ) ) {
68
+ $replacement_variables = $this->replacement_variables;
69
+ }
70
+
71
+ return array_filter( $replacement_variables, 'is_array' );
72
+ }
73
+
74
+ /**
75
+ * Retrieves the generic replacement variable names.
76
+ *
77
+ * Which are the replacement variables without the editor specific ones.
78
+ *
79
+ * @param array $replacement_variables Possibly generic replacement variables.
80
+ *
81
+ * @return array The generic replacement variable names.
82
+ */
83
+ public function get_generic( $replacement_variables ) {
84
+ $shared_variables = array_diff(
85
+ $this->extract_names( $replacement_variables ),
86
+ $this->get_unique_replacement_variables()
87
+ );
88
+
89
+ return array_values( $shared_variables );
90
+ }
91
+
92
+ /**
93
+ * Determines the page type of the current term.
94
+ *
95
+ * @param string $taxonomy The taxonomy name.
96
+ *
97
+ * @return string The page type.
98
+ */
99
+ public function determine_for_term( $taxonomy ) {
100
+ $replacement_variables = $this->get();
101
+ if ( array_key_exists( $taxonomy, $replacement_variables ) ) {
102
+ return $taxonomy;
103
+ }
104
+
105
+ return 'term-in-custom-taxonomy';
106
+ }
107
+
108
+ /**
109
+ * Determines the page type of the current post.
110
+ *
111
+ * @param WP_Post $post A WordPress post instance.
112
+ *
113
+ * @return string The page type.
114
+ */
115
+ public function determine_for_post( $post ) {
116
+ if ( $post instanceof WP_Post === false ) {
117
+ return 'post';
118
+ }
119
+
120
+ $replacement_variables = $this->get();
121
+ if ( array_key_exists( $post->post_type, $replacement_variables ) ) {
122
+ return $post->post_type;
123
+ }
124
+
125
+ return 'custom_post_type';
126
+ }
127
+
128
+ /**
129
+ * Determines the page type for a post type.
130
+ *
131
+ * @param string $post_type The name of the post_type.
132
+ * @param string $fallback The page type to fall back to.
133
+ *
134
+ * @return string The page type.
135
+ */
136
+ public function determine_for_post_type( $post_type, $fallback = 'custom_post_type' ) {
137
+ if ( ! $this->has_for_page_type( $post_type ) ) {
138
+ return $fallback;
139
+ }
140
+
141
+ return $post_type;
142
+ }
143
+
144
+ /**
145
+ * Determines the page type for an archive page.
146
+ *
147
+ * @param string $name The name of the archive.
148
+ * @param string $fallback The page type to fall back to.
149
+ *
150
+ * @return string The page type.
151
+ */
152
+ public function determine_for_archive( $name, $fallback = 'custom-post-type_archive' ) {
153
+ $page_type = $name . '_archive';
154
+
155
+ if ( ! $this->has_for_page_type( $page_type ) ) {
156
+ return $fallback;
157
+ }
158
+
159
+ return $page_type;
160
+ }
161
+
162
+ /**
163
+ * Adds the replavement variables for the given page types.
164
+ *
165
+ * @param array $page_types Page types to add variables for.
166
+ * @param array $replacement_variables_to_add The variables to add.
167
+ *
168
+ * @return void
169
+ */
170
+ protected function add_for_page_types( array $page_types, array $replacement_variables_to_add ) {
171
+ if ( empty( $replacement_variables_to_add ) ) {
172
+ return;
173
+ }
174
+
175
+ $replacement_variables_to_add = array_fill_keys( $page_types, $replacement_variables_to_add );
176
+ $replacement_variables = $this->replacement_variables;
177
+
178
+ $this->replacement_variables = array_merge_recursive( $replacement_variables, $replacement_variables_to_add );
179
+ }
180
+
181
+ /**
182
+ * Extracts the names from the given replacements variables.
183
+ *
184
+ * @param array $replacement_variables Replacement variables to extract the name from.
185
+ *
186
+ * @return array Extracted names.
187
+ */
188
+ protected function extract_names( $replacement_variables ) {
189
+ $extracted_names = array();
190
+
191
+ foreach ( $replacement_variables as $replacement_variable ) {
192
+ if ( empty( $replacement_variable['name'] ) ) {
193
+ continue;
194
+ }
195
+
196
+ $extracted_names[] = $replacement_variable['name'];
197
+ }
198
+
199
+ return $extracted_names;
200
+ }
201
+
202
+ /**
203
+ * Returns whether the given page type has editor specific replace vars.
204
+ *
205
+ * @param string $page_type The page type to check.
206
+ *
207
+ * @return bool True if there are associated editor specific replace vars.
208
+ */
209
+ protected function has_for_page_type( $page_type ) {
210
+ $replacement_variables = $this->get();
211
+
212
+ return ( ! empty( $replacement_variables[ $page_type ] ) && is_array( $replacement_variables[ $page_type ] ) );
213
+ }
214
+
215
+ /**
216
+ * Merges all editor specific replacement variables into one array and removes duplicates.
217
+ *
218
+ * @return array The list of unique editor specific replacement variables.
219
+ */
220
+ protected function get_unique_replacement_variables() {
221
+ $merged_replacement_variables = call_user_func_array( 'array_merge', $this->get() );
222
+
223
+ return array_unique( $merged_replacement_variables );
224
+ }
225
+ }
admin/class-admin-init.php CHANGED
@@ -47,6 +47,15 @@ class WPSEO_Admin_Init {
47
  add_action( 'admin_init', array( $this->asset_manager, 'register_assets' ) );
48
  add_action( 'admin_init', array( $this, 'show_hook_deprecation_warnings' ) );
49
  add_action( 'admin_init', array( 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ) );
 
 
 
 
 
 
 
 
 
50
 
51
  $this->load_meta_boxes();
52
  $this->load_taxonomy_class();
@@ -56,6 +65,24 @@ class WPSEO_Admin_Init {
56
  $this->load_plugin_suggestions();
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  /**
60
  * Enqueue our styling for dismissible yoast notifications.
61
  */
47
  add_action( 'admin_init', array( $this->asset_manager, 'register_assets' ) );
48
  add_action( 'admin_init', array( $this, 'show_hook_deprecation_warnings' ) );
49
  add_action( 'admin_init', array( 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ) );
50
+ add_action( 'admin_init', array( $this, 'handle_notifications' ), 15 );
51
+
52
+ $listeners = array();
53
+ $listeners[] = new WPSEO_Post_Type_Archive_Notification_Handler();
54
+
55
+ /** @var WPSEO_Listener $listener */
56
+ foreach ( $listeners as $listener ) {
57
+ $listener->listen();
58
+ }
59
 
60
  $this->load_meta_boxes();
61
  $this->load_taxonomy_class();
65
  $this->load_plugin_suggestions();
66
  }
67
 
68
+ /**
69
+ * Handles the notifiers for the dashboard page.
70
+ *
71
+ * @return void
72
+ */
73
+ public function handle_notifications() {
74
+ /**
75
+ * @var WPSEO_Notification_Handler[] $handlers
76
+ */
77
+ $handlers = array();
78
+ $handlers[] = new WPSEO_Post_Type_Archive_Notification_Handler();
79
+
80
+ $notification_center = Yoast_Notification_Center::get();
81
+ foreach ( $handlers as $handler ) {
82
+ $handler->handle( $notification_center );
83
+ }
84
+ }
85
+
86
  /**
87
  * Enqueue our styling for dismissible yoast notifications.
88
  */
admin/class-admin-media-purge-notification.php CHANGED
@@ -65,16 +65,17 @@ class WPSEO_Admin_Media_Purge_Notification implements WPSEO_WordPress_Integratio
65
  */
66
  private function get_notification() {
67
  $content = sprintf(
68
- /* translators: %1$s expands to the link to the article, %2$s closes the link tag. */
69
  __( 'Your site\'s settings currently allow attachment URLs on your site to exist. Please read %1$sthis post about a potential issue%2$s with attachment URLs and check whether you have the correct setting for your site.', 'wordpress-seo' ),
70
- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/2r8' ) ) . '" rel="nofollow noreferer" target="_blank">',
71
  '</a>'
72
  );
73
 
74
  $content .= '<br><br>';
75
  $content .= sprintf(
 
76
  __( 'If you know what this means and you do not want to see this message anymore, you can %1$sdismiss this message%2$s.', 'wordpress-seo' ),
77
- '<a href="' . admin_url( 'admin.php?page=wpseo_dashboard&dismiss=' . $this->notification_id ) . '">',
78
  '</a>'
79
  );
80
 
65
  */
66
  private function get_notification() {
67
  $content = sprintf(
68
+ /* translators: %1$s expands to the link to the article, %2$s closes the link tag. */
69
  __( 'Your site\'s settings currently allow attachment URLs on your site to exist. Please read %1$sthis post about a potential issue%2$s with attachment URLs and check whether you have the correct setting for your site.', 'wordpress-seo' ),
70
+ '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/2r8' ) ) . '" rel="noopener noreferrer" target="_blank">',
71
  '</a>'
72
  );
73
 
74
  $content .= '<br><br>';
75
  $content .= sprintf(
76
+ /* translators: %1$s dismiss link open tag, %2$s closes the link tag. */
77
  __( 'If you know what this means and you do not want to see this message anymore, you can %1$sdismiss this message%2$s.', 'wordpress-seo' ),
78
+ '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_dashboard&dismiss=' . $this->notification_id ) ) . '">',
79
  '</a>'
80
  );
81
 
admin/class-admin-recommended-replace-vars.php CHANGED
@@ -15,20 +15,20 @@ class WPSEO_Admin_Recommended_Replace_Vars {
15
  */
16
  protected $recommended_replace_vars = array(
17
  // Posts types.
18
- 'page' => array( 'sitename', 'title', 'sep', 'primary_category' ),
19
- 'post' => array( 'sitename', 'title', 'sep', 'primary_category' ),
20
  // Homepage.
21
- 'homepage' => array( 'sitename', 'sitedesc', 'sep' ),
22
  // Custom post type.
23
- 'custom_post_type' => array( 'sitename', 'title', 'sep' ),
24
 
25
  // Taxonomies.
26
- 'category' => array( 'sitename', 'term_title', 'sep' ),
27
- 'post_tag' => array( 'sitename', 'term_title', 'sep' ),
28
- 'post_format' => array( 'sitename', 'term_title', 'sep', 'page' ),
29
 
30
  // Custom taxonomy.
31
- 'term-in-custom-taxomomy' => array( 'sitename', 'term_title', 'sep' ),
32
 
33
  // Settings - archive pages.
34
  'author_archive' => array( 'sitename', 'title', 'sep', 'page' ),
@@ -36,8 +36,8 @@ class WPSEO_Admin_Recommended_Replace_Vars {
36
  'custom-post-type_archive' => array( 'sitename', 'title', 'sep', 'page' ),
37
 
38
  // Settings - special pages.
39
- 'search' => array( 'sitename', 'searchphrase', 'sep', 'page' ),
40
- '404' => array( 'sitename', 'sep' ),
41
  );
42
 
43
  /**
@@ -59,7 +59,7 @@ class WPSEO_Admin_Recommended_Replace_Vars {
59
  /**
60
  * Determines the page type of the current post.
61
  *
62
- * @param WP_Post $post The WordPress global post object.
63
  *
64
  * @return string The page type.
65
  */
15
  */
16
  protected $recommended_replace_vars = array(
17
  // Posts types.
18
+ 'page' => array( 'sitename', 'title', 'sep', 'primary_category' ),
19
+ 'post' => array( 'sitename', 'title', 'sep', 'primary_category' ),
20
  // Homepage.
21
+ 'homepage' => array( 'sitename', 'sitedesc', 'sep' ),
22
  // Custom post type.
23
+ 'custom_post_type' => array( 'sitename', 'title', 'sep' ),
24
 
25
  // Taxonomies.
26
+ 'category' => array( 'sitename', 'term_title', 'sep' ),
27
+ 'post_tag' => array( 'sitename', 'term_title', 'sep' ),
28
+ 'post_format' => array( 'sitename', 'term_title', 'sep', 'page' ),
29
 
30
  // Custom taxonomy.
31
+ 'term-in-custom-taxomomy' => array( 'sitename', 'term_title', 'sep' ),
32
 
33
  // Settings - archive pages.
34
  'author_archive' => array( 'sitename', 'title', 'sep', 'page' ),
36
  'custom-post-type_archive' => array( 'sitename', 'title', 'sep', 'page' ),
37
 
38
  // Settings - special pages.
39
+ 'search' => array( 'sitename', 'searchphrase', 'sep', 'page' ),
40
+ '404' => array( 'sitename', 'sep' ),
41
  );
42
 
43
  /**
59
  /**
60
  * Determines the page type of the current post.
61
  *
62
+ * @param WP_Post $post A WordPress post instance.
63
  *
64
  * @return string The page type.
65
  */
admin/class-admin.php CHANGED
@@ -103,7 +103,6 @@ class WPSEO_Admin {
103
  foreach ( $integrations as $integration ) {
104
  $integration->register_hooks();
105
  }
106
-
107
  }
108
 
109
  /**
103
  foreach ( $integrations as $integration ) {
104
  $integration->register_hooks();
105
  }
 
106
  }
107
 
108
  /**
admin/class-config.php CHANGED
@@ -93,7 +93,7 @@ class WPSEO_Admin_Pages {
93
  */
94
  remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
95
 
96
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
97
  $yoast_components_l10n->localize_script( 'search-appearance' );
98
  }
99
 
@@ -131,12 +131,16 @@ class WPSEO_Admin_Pages {
131
  * @return array The replacement and recommended replacement variables.
132
  */
133
  public function localize_replace_vars_script() {
134
- $replace_vars = new WPSEO_Replace_Vars();
135
- $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
 
 
136
 
137
  return array(
138
- 'replace_vars' => $replace_vars->get_replacement_variables_list(),
139
- 'recommended_replace_vars' => $recommended_replace_vars->get_recommended_replacevars(),
 
 
140
  );
141
  }
142
 
93
  */
94
  remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
95
 
96
+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
97
  $yoast_components_l10n->localize_script( 'search-appearance' );
98
  }
99
 
131
  * @return array The replacement and recommended replacement variables.
132
  */
133
  public function localize_replace_vars_script() {
134
+ $replace_vars = new WPSEO_Replace_Vars();
135
+ $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
136
+ $editor_specific_replace_vars = new WPSEO_Admin_Editor_Specific_Replace_Vars();
137
+ $replace_vars_list = $replace_vars->get_replacement_variables_list();
138
 
139
  return array(
140
+ 'replace_vars' => $replace_vars_list,
141
+ 'recommended_replace_vars' => $recommended_replace_vars->get_recommended_replacevars(),
142
+ 'editor_specific_replace_vars' => $editor_specific_replace_vars->get(),
143
+ 'shared_replace_vars' => $editor_specific_replace_vars->get_generic( $replace_vars_list ),
144
  );
145
  }
146
 
admin/class-help-center.php CHANGED
@@ -181,7 +181,7 @@ class WPSEO_Help_Center {
181
  protected function enqueue_localized_data( $data ) {
182
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'help-center', 'wpseoHelpCenterData', $data );
183
 
184
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
185
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'help-center' );
186
  }
187
 
181
  protected function enqueue_localized_data( $data ) {
182
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'help-center', 'wpseoHelpCenterData', $data );
183
 
184
+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
185
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'help-center' );
186
  }
187
 
admin/class-option-tabs-formatter.php CHANGED
@@ -66,9 +66,10 @@ class WPSEO_Option_Tabs_Formatter {
66
  if ( empty( $option_tab_content ) ) {
67
  // Output the settings view for all tabs.
68
  $tab_view = $this->get_tab_view( $option_tabs, $tab );
 
69
  if ( is_file( $tab_view ) ) {
70
  $yform = Yoast_Form::get_instance();
71
- require_once $tab_view;
72
  }
73
  }
74
 
66
  if ( empty( $option_tab_content ) ) {
67
  // Output the settings view for all tabs.
68
  $tab_view = $this->get_tab_view( $option_tabs, $tab );
69
+
70
  if ( is_file( $tab_view ) ) {
71
  $yform = Yoast_Form::get_instance();
72
+ require $tab_view;
73
  }
74
  }
75
 
admin/class-paper-presenter.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPSEO plugin file.
4
+ *
5
+ * @package WPSEO\Admin
6
+ */
7
+
8
+ /**
9
+ * Class WPSEO_presenter_paper
10
+ */
11
+ class WPSEO_Paper_Presenter {
12
+ /**
13
+ * @var string Title of the paper
14
+ */
15
+ private $title;
16
+
17
+ /**
18
+ * @var array The view variables.
19
+ */
20
+ private $settings;
21
+
22
+ /**
23
+ * @var string The path to the view file.
24
+ */
25
+ private $view_file;
26
+
27
+ /**
28
+ * WPSEO_presenter_paper constructor.
29
+ *
30
+ * @param string $title The title of the paper.
31
+ * @param string $view_file The path to the view file.
32
+ * @param array $settings Optional. Settings for the paper.
33
+ */
34
+ public function __construct( $title, $view_file, array $settings = array() ) {
35
+ $defaults = array(
36
+ 'paper_id' => null,
37
+ 'collapsible' => false,
38
+ 'expanded' => false,
39
+ 'help_text' => '',
40
+ 'title_after' => '',
41
+ 'view_data' => array(),
42
+ );
43
+
44
+ $this->settings = wp_parse_args( $settings, $defaults );
45
+ $this->title = $title;
46
+ $this->view_file = $view_file;
47
+ }
48
+
49
+ /**
50
+ * Renders the collapsible paper and returns it as a string.
51
+ *
52
+ * @return string The rendered paper.
53
+ */
54
+ public function get_output() {
55
+ extract( $this->get_view_variables(), EXTR_SKIP );
56
+
57
+ ob_start();
58
+ require WPSEO_PATH . 'admin/views/paper-collapsible.php' ;
59
+ $rendered_output = ob_get_clean();
60
+
61
+ return $rendered_output;
62
+ }
63
+
64
+ /**
65
+ * Retrieves the view variables.
66
+ *
67
+ * @return array The view variables.
68
+ */
69
+ private function get_view_variables() {
70
+ if ( $this->settings['help_text'] instanceof WPSEO_Admin_Help_Panel === false ) {
71
+ $this->settings['help_text'] = new WPSEO_Admin_Help_Panel( '', '', '' );
72
+ }
73
+
74
+ $view_variables = array(
75
+ 'collapsible' => $this->settings['collapsible'],
76
+ 'collapsible_config' => $this->collapsible_config(),
77
+ 'title_after' => $this->settings['title_after'],
78
+ 'help_text' => $this->settings['help_text'],
79
+ 'view_file' => $this->view_file,
80
+ 'title' => $this->title,
81
+ 'paper_id' => $this->settings['paper_id'],
82
+ 'yform' => Yoast_Form::get_instance(),
83
+ );
84
+
85
+ return array_merge( $this->settings['view_data'], $view_variables );
86
+ }
87
+
88
+ /**
89
+ * Retrieves the collapsible config based on the settings.
90
+ *
91
+ * @return array The config.
92
+ */
93
+ protected function collapsible_config() {
94
+ if ( empty( $this->settings['collapsible'] ) ) {
95
+ return array(
96
+ 'toggle_icon' => '',
97
+ 'class' => '',
98
+ 'expanded' => '',
99
+ );
100
+ }
101
+
102
+ if ( ! empty( $this->settings['expanded'] ) ) {
103
+ return array(
104
+ 'toggle_icon' => 'dashicons-arrow-up-alt2',
105
+ 'class' => 'toggleable-container',
106
+ 'expanded' => 'true',
107
+ );
108
+ }
109
+
110
+ return array(
111
+ 'toggle_icon' => 'dashicons-arrow-down-alt2',
112
+ 'class' => 'toggleable-container toggleable-container-hidden',
113
+ 'expanded' => 'false',
114
+ );
115
+ }
116
+ }
admin/class-yoast-dashboard-widget.php CHANGED
@@ -102,7 +102,7 @@ class Yoast_Dashboard_Widget {
102
  }
103
 
104
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'dashboard-widget', 'wpseoDashboardWidgetL10n', $this->localize_dashboard_script() );
105
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
106
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'dashboard-widget' );
107
  $this->asset_manager->enqueue_script( 'dashboard-widget' );
108
  $this->asset_manager->enqueue_style( 'wp-dashboard' );
102
  }
103
 
104
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'dashboard-widget', 'wpseoDashboardWidgetL10n', $this->localize_dashboard_script() );
105
+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
106
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'dashboard-widget' );
107
  $this->asset_manager->enqueue_script( 'dashboard-widget' );
108
  $this->asset_manager->enqueue_style( 'wp-dashboard' );
admin/class-yoast-notification-center.php CHANGED
@@ -82,7 +82,7 @@ class Yoast_Notification_Center {
82
  ) );
83
  }
84
 
85
- if ( $notification_center->maybe_dismiss_notification( $notification ) ) {
86
  die( '1' );
87
  }
88
 
@@ -332,13 +332,18 @@ class Yoast_Notification_Center {
332
 
333
  array_walk( $notifications, array( $this, 'remove_notification' ) );
334
 
 
335
  if ( $echo_as_json ) {
336
  $notification_json = array();
 
 
 
 
337
  foreach ( $notifications as $notification ) {
338
  $notification_json[] = $notification->render();
339
  }
340
 
341
- echo json_encode( $notification_json );
342
 
343
  return;
344
  }
@@ -390,6 +395,24 @@ class Yoast_Notification_Center {
390
  $this->notifications = array_values( $this->notifications );
391
  }
392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  /**
394
  * Get the notification count
395
  *
82
  ) );
83
  }
84
 
85
+ if ( self::maybe_dismiss_notification( $notification ) ) {
86
  die( '1' );
87
  }
88
 
332
 
333
  array_walk( $notifications, array( $this, 'remove_notification' ) );
334
 
335
+ $notifications = array_unique( $notifications );
336
  if ( $echo_as_json ) {
337
  $notification_json = array();
338
+
339
+ /**
340
+ * @var Yoast_Notification[] $notifications
341
+ */
342
  foreach ( $notifications as $notification ) {
343
  $notification_json[] = $notification->render();
344
  }
345
 
346
+ echo wp_json_encode( $notification_json );
347
 
348
  return;
349
  }
395
  $this->notifications = array_values( $this->notifications );
396
  }
397
 
398
+ /**
399
+ * Removes a notification by its ID.
400
+ *
401
+ * @param string $notification_id The notification id.
402
+ * @param bool $resolve Resolve as fixed.
403
+ *
404
+ * @return void
405
+ */
406
+ public function remove_notification_by_id( $notification_id, $resolve = true ) {
407
+ $notification = $this->get_notification_by_id( $notification_id );
408
+
409
+ if ( $notification === null ) {
410
+ return;
411
+ }
412
+
413
+ $this->remove_notification( $notification, $resolve );
414
+ }
415
+
416
  /**
417
  * Get the notification count
418
  *
admin/class-yoast-plugin-conflict.php CHANGED
@@ -228,11 +228,7 @@ class Yoast_Plugin_Conflict {
228
  $identifier = $this->get_notification_identifier( $plugin_file );
229
 
230
  $notification_center = Yoast_Notification_Center::get();
231
- $notification = $notification_center->get_notification_by_id( 'wpseo-conflict-' . $identifier );
232
-
233
- if ( $notification ) {
234
- $notification_center->remove_notification( $notification );
235
- }
236
  }
237
 
238
  /**
228
  $identifier = $this->get_notification_identifier( $plugin_file );
229
 
230
  $notification_center = Yoast_Notification_Center::get();
231
+ $notification_center->remove_notification_by_id( 'wpseo-conflict-' . $identifier );
 
 
 
 
232
  }
233
 
234
  /**
admin/config-ui/class-configuration-page.php CHANGED
@@ -88,7 +88,7 @@ class WPSEO_Configuration_Page {
88
 
89
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard', 'yoastWizardConfig', $config );
90
 
91
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
92
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard' );
93
  }
94
 
88
 
89
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard', 'yoastWizardConfig', $config );
90
 
91
+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
92
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'configuration-wizard' );
93
  }
94
 
admin/formatter/class-metabox-formatter.php CHANGED
@@ -65,6 +65,7 @@ class WPSEO_Metabox_Formatter {
65
  'keywordAnalysisActive' => $analysis_seo->is_enabled() ? 1 : 0,
66
  'intl' => $this->get_content_analysis_component_translations(),
67
  'isRtl' => is_rtl(),
 
68
 
69
  /**
70
  * Filter to determine if the markers should be enabled or not.
65
  'keywordAnalysisActive' => $analysis_seo->is_enabled() ? 1 : 0,
66
  'intl' => $this->get_content_analysis_component_translations(),
67
  'isRtl' => is_rtl(),
68
+ 'gutenbergSidebar' => defined( 'YOAST_FEATURE_GUTENBERG_SIDEBAR' ) && YOAST_FEATURE_GUTENBERG_SIDEBAR,
69
 
70
  /**
71
  * Filter to determine if the markers should be enabled or not.
admin/menu/class-network-admin-menu.php CHANGED
@@ -57,7 +57,8 @@ class WPSEO_Network_Admin_Menu implements WPSEO_WordPress_Integration {
57
  $this->menu->get_page_identifier(),
58
  'Yoast SEO: ' . __( 'Edit Files', 'wordpress-seo' ),
59
  __( 'Edit Files', 'wordpress-seo' ),
60
- 'delete_users', 'wpseo_files',
 
61
  $page_callback
62
  );
63
  }
57
  $this->menu->get_page_identifier(),
58
  'Yoast SEO: ' . __( 'Edit Files', 'wordpress-seo' ),
59
  __( 'Edit Files', 'wordpress-seo' ),
60
+ 'delete_users',
61
+ 'wpseo_files',
62
  $page_callback
63
  );
64
  }
admin/menu/class-replacevar-editor.php CHANGED
@@ -15,40 +15,50 @@ class WPSEO_Replacevar_Editor {
15
  private $yform;
16
 
17
  /**
18
- * @var string The id for the hidden title field.
19
- */
20
- private $title;
21
-
22
- /**
23
- * @var string The id for the hidden description field.
24
- */
25
- private $description;
26
-
27
- /**
28
- * @var string The page type for context.
29
- */
30
- private $page_type;
31
-
32
- /**
33
- * @var bool Whether the editor has paper style.
34
  */
35
- private $paper_style;
36
 
37
  /**
38
  * Constructs the object.
39
  *
40
- * @param Yoast_Form $yform Yoast forms.
41
- * @param string $title The title field id.
42
- * @param string $description The description field id.
43
- * @param string $page_type The page type for context.
44
- * @param bool $paper_style Whether the editor has paper style.
 
 
 
 
 
45
  */
46
- public function __construct( Yoast_Form $yform, $title, $description, $page_type, $paper_style = true ) {
47
- $this->yform = $yform;
48
- $this->title = (string) $title;
49
- $this->description = (string) $description;
50
- $this->page_type = (string) $page_type;
51
- $this->paper_style = (bool) $paper_style;
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
  /**
@@ -59,19 +69,48 @@ class WPSEO_Replacevar_Editor {
59
  * @return void
60
  */
61
  public function render() {
62
- $this->yform->hidden( $this->title, $this->title );
63
- $this->yform->hidden( $this->description, $this->description );
64
 
65
  printf( '<div
66
  data-react-replacevar-editor
67
  data-react-replacevar-title-field-id="%1$s"
68
  data-react-replacevar-metadesc-field-id="%2$s"
69
- data-react-replacevar-page-type="%3$s"
70
- data-react-replacevar-paper-style="%4$s"></div>',
71
- esc_attr( $this->title ),
72
- esc_attr( $this->description ),
73
- esc_attr( $this->page_type ),
74
- esc_attr( $this->paper_style )
 
 
75
  );
76
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
15
  private $yform;
16
 
17
  /**
18
+ * @var array {
19
+ * The arguments required for the div to render.
20
+ *
21
+ * @type string $title The title field id.
22
+ * @type string $description The description field id.
23
+ * @type string $page_type_recommended The page type for the context of the recommended replace vars.
24
+ * @type string $page_type_specific The page type for the context of the editor specific replace vars.
25
+ * @type bool $paper_style Optional. Whether the editor has paper style.
26
+ * }
 
 
 
 
 
 
 
27
  */
28
+ private $arguments;
29
 
30
  /**
31
  * Constructs the object.
32
  *
33
+ * @param Yoast_Form $yform Yoast forms.
34
+ * @param array $arguments {
35
+ * The arguments that can be given.
36
+ *
37
+ * @type string $title The title field id.
38
+ * @type string $description The description field id.
39
+ * @type string $page_type_recommended The page type for the context of the recommended replace vars.
40
+ * @type string $page_type_specific The page type for the context of the editor specific replace vars.
41
+ * @type bool $paper_style Optional. Whether the editor has paper style.
42
+ * }
43
  */
44
+ public function __construct( Yoast_Form $yform, $arguments ) {
45
+ $arguments = wp_parse_args(
46
+ $arguments,
47
+ array(
48
+ 'paper_style' => true,
49
+ )
50
+ );
51
+
52
+ $this->validate_arguments( $arguments );
53
+
54
+ $this->yform = $yform;
55
+ $this->arguments = array(
56
+ 'title' => (string) $arguments['title'],
57
+ 'description' => (string) $arguments['description'],
58
+ 'page_type_recommended' => (string) $arguments['page_type_recommended'],
59
+ 'page_type_specific' => (string) $arguments['page_type_specific'],
60
+ 'paper_style' => (bool) $arguments['paper_style'],
61
+ );
62
  }
63
 
64
  /**
69
  * @return void
70
  */
71
  public function render() {
72
+ $this->yform->hidden( $this->arguments['title'], $this->arguments['title'] );
73
+ $this->yform->hidden( $this->arguments['description'], $this->arguments['description'] );
74
 
75
  printf( '<div
76
  data-react-replacevar-editor
77
  data-react-replacevar-title-field-id="%1$s"
78
  data-react-replacevar-metadesc-field-id="%2$s"
79
+ data-react-replacevar-page-type-recommended="%3$s"
80
+ data-react-replacevar-page-type-specific="%4$s"
81
+ data-react-replacevar-paper-style="%5$s"></div>',
82
+ esc_attr( $this->arguments['title'] ),
83
+ esc_attr( $this->arguments['description'] ),
84
+ esc_attr( $this->arguments['page_type_recommended'] ),
85
+ esc_attr( $this->arguments['page_type_specific'] ),
86
+ esc_attr( $this->arguments['paper_style'] )
87
  );
88
  }
89
+
90
+ /**
91
+ * @param array $arguments The arguments to validate.
92
+ *
93
+ * @throws InvalidArgumentException Thrown when not all required arguments are present.
94
+ */
95
+ protected function validate_arguments( array $arguments ) {
96
+ $required_arguments = array(
97
+ 'title',
98
+ 'description',
99
+ 'page_type_recommended',
100
+ 'page_type_specific',
101
+ 'paper_style',
102
+ );
103
+
104
+ foreach ( $required_arguments as $field_name ) {
105
+ if ( ! array_key_exists( $field_name, $arguments ) ) {
106
+ throw new InvalidArgumentException(
107
+ sprintf(
108
+ /* translators: %1$s expands to the missing field name. */
109
+ __( 'Not all required fields are given. Missing field %1$s', 'wordpress-seo' ),
110
+ $field_name
111
+ )
112
+ );
113
+ }
114
+ }
115
+ }
116
  }
admin/menu/class-replacevar-field.php CHANGED
@@ -25,23 +25,30 @@ class WPSEO_Replacevar_Field {
25
  private $label;
26
 
27
  /**
28
- * @var string The page type for context.
29
  */
30
- private $page_type;
 
 
 
 
 
31
 
32
  /**
33
  * Constructs the object.
34
  *
35
- * @param Yoast_Form $yform Yoast forms.
36
- * @param string $field_id The field id.
37
- * @param string $label The field label.
38
- * @param string $page_type The page type for context.
 
39
  */
40
- public function __construct( Yoast_Form $yform, $field_id, $label, $page_type ) {
41
- $this->yform = $yform;
42
- $this->field_id = $field_id;
43
- $this->label = $label;
44
- $this->page_type = $page_type;
 
45
  }
46
 
47
  /**
@@ -57,11 +64,13 @@ class WPSEO_Replacevar_Field {
57
  printf( '<div
58
  data-react-replacevar-field
59
  data-react-replacevar-field-id="%1$s"
60
- data-react-replacevar-field-label="%2$s",
61
- data-react-replacevar-page-type="%3$s"></div>',
 
62
  esc_attr( $this->field_id ),
63
  esc_attr( $this->label ),
64
- esc_attr( $this->page_type )
 
65
  );
66
  }
67
  }
25
  private $label;
26
 
27
  /**
28
+ * @var string The page type for the context of the recommended replace vars.
29
  */
30
+ private $page_type_recommended;
31
+
32
+ /**
33
+ * @var string The page type for the context of the editor specific replace vars.
34
+ */
35
+ private $page_type_specific;
36
 
37
  /**
38
  * Constructs the object.
39
  *
40
+ * @param Yoast_Form $yform Yoast forms.
41
+ * @param string $field_id The field id.
42
+ * @param string $label The field label.
43
+ * @param string $page_type_recommended The page type for the context of the recommended replace vars.
44
+ * @param string $page_type_specific The page type for the context of the editor specific replace vars.
45
  */
46
+ public function __construct( Yoast_Form $yform, $field_id, $label, $page_type_recommended, $page_type_specific ) {
47
+ $this->yform = $yform;
48
+ $this->field_id = $field_id;
49
+ $this->label = $label;
50
+ $this->page_type_recommended = $page_type_recommended;
51
+ $this->page_type_specific = $page_type_specific;
52
  }
53
 
54
  /**
64
  printf( '<div
65
  data-react-replacevar-field
66
  data-react-replacevar-field-id="%1$s"
67
+ data-react-replacevar-field-label="%2$s"
68
+ data-react-replacevar-page-type-recommended="%3$s"
69
+ data-react-replacevar-page-type-specific="%4$s"></div>',
70
  esc_attr( $this->field_id ),
71
  esc_attr( $this->label ),
72
+ esc_attr( $this->page_type_recommended ),
73
+ esc_attr( $this->page_type_specific )
74
  );
75
  }
76
  }
admin/metabox/class-metabox.php CHANGED
@@ -904,7 +904,7 @@ class WPSEO_Metabox extends WPSEO_Meta {
904
 
905
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-media', 'wpseoMediaL10n', $this->localize_media_script() );
906
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'post-scraper', 'wpseoPostScraperL10n', $this->localize_post_scraper_script() );
907
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
908
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'post-scraper' );
909
  /**
910
  * Remove the emoji script as it is incompatible with both React and any
@@ -1010,7 +1010,7 @@ class WPSEO_Metabox extends WPSEO_Meta {
1010
  * @return array Recommended replacement variables.
1011
  */
1012
  private function get_recommended_replace_vars() {
1013
- $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
1014
  $post = $this->get_metabox_post();
1015
 
1016
  // What is recommended depends on the current context.
904
 
905
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-media', 'wpseoMediaL10n', $this->localize_media_script() );
906
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'post-scraper', 'wpseoPostScraperL10n', $this->localize_post_scraper_script() );
907
+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
908
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'post-scraper' );
909
  /**
910
  * Remove the emoji script as it is incompatible with both React and any
1010
  * @return array Recommended replacement variables.
1011
  */
1012
  private function get_recommended_replace_vars() {
1013
+ $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
1014
  $post = $this->get_metabox_post();
1015
 
1016
  // What is recommended depends on the current context.
admin/notifiers/class-post-type-archive-notification-handler.php ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPSEO plugin file.
4
+ *
5
+ * @package WPSEO\Admin\Notifiers
6
+ */
7
+
8
+ /**
9
+ * Represents the logic for showing the post type archive notification.
10
+ */
11
+ class WPSEO_Post_Type_Archive_Notification_Handler implements WPSEO_Listener, WPSEO_Notification_Handler {
12
+
13
+ /**
14
+ * The identifier for the notification.
15
+ *
16
+ * @var string
17
+ */
18
+ protected $notification_identifier = 'post-type-archive-notification';
19
+
20
+ /**
21
+ * Defaults for the title option.
22
+ *
23
+ * @var array
24
+ */
25
+ protected $option_defaults = array();
26
+
27
+ /**
28
+ * Listens to an argument in the request URL and triggers an action.
29
+ *
30
+ * @return void
31
+ */
32
+ public function listen() {
33
+ if ( $this->get_listener_value() !== $this->notification_identifier ) {
34
+ return;
35
+ }
36
+
37
+ $this->set_dismissal_state();
38
+ $this->redirect_to_dashboard();
39
+ }
40
+
41
+ /**
42
+ * Adds the notification if applicable, otherwise removes it.
43
+ *
44
+ * @param Yoast_Notification_Center $notification_center The notification center object.
45
+ *
46
+ * @return void
47
+ */
48
+ public function handle( Yoast_Notification_Center $notification_center ) {
49
+ if ( ! $this->is_applicable() ) {
50
+ $notification_center->remove_notification_by_id( 'wpseo-' . $this->notification_identifier );
51
+
52
+ return;
53
+ }
54
+
55
+ $notification = $this->get_notification( $this->get_post_types() );
56
+ $notification_center->add_notification( $notification );
57
+ }
58
+
59
+ /**
60
+ * Retrevies the value where listener is listening for.
61
+ *
62
+ * @return string The listener value.
63
+ *
64
+ * @coveCoverageIgnore
65
+ */
66
+ protected function get_listener_value() {
67
+ return filter_input( INPUT_GET, 'yoast_dismiss' );
68
+ }
69
+
70
+ /**
71
+ * Redirects the user back to the dashboard.
72
+ *
73
+ * @return void
74
+ *
75
+ * @coveCoverageIgnore
76
+ */
77
+ protected function redirect_to_dashboard() {
78
+ wp_safe_redirect( admin_url( 'admin.php?page=wpseo_dashboard' ) );
79
+ exit;
80
+ }
81
+
82
+ /**
83
+ * Returns the notification.
84
+ *
85
+ * @param array $post_types The post types that needs an other check.
86
+ *
87
+ * @return Yoast_Notification The notification for the notification center.
88
+ *
89
+ * @codeCoverageIgnore
90
+ */
91
+ protected function get_notification( array $post_types ) {
92
+ $message = esc_html__(
93
+ 'We\'ve recently improved the functionality of the Search Appearance settings. Unfortunately, we\'ve discovered that for some edge-cases, saving the settings for specific post type archives might have gone wrong.',
94
+ 'wordpress-seo'
95
+ );
96
+ $message .= PHP_EOL . PHP_EOL;
97
+ $message .= sprintf(
98
+ _n(
99
+ /* translators: %1$s is the archive template link start tag, %2$s is the link closing tag, %3$s is a comma separated string with content types. */
100
+ 'Please check the %1$sarchive template%2$s for the following content type: %3$s.',
101
+ ' Please check the %1$sarchive templates%2$s for the following content types: %3$s.',
102
+ count( $post_types ),
103
+ 'wordpress-seo'
104
+ ),
105
+ '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_titles#top#post-types' ) ) . '">',
106
+ '</a>',
107
+ implode( ', ', $post_types )
108
+ );
109
+ $message .= PHP_EOL . PHP_EOL;
110
+ $message .= sprintf(
111
+ /* translators: %1$s is the notification dismissal link start tag, %2$s is the link closing tag. */
112
+ __( '%1$sRemove this message%2$s', 'wordpress-seo' ),
113
+ '<a class="button" href="' . admin_url( '?page=' . WPSEO_Admin::PAGE_IDENTIFIER . '&yoast_dismiss=' . $this->notification_identifier ) . '">',
114
+ '</a>'
115
+ );
116
+
117
+ $notification_options = array(
118
+ 'type' => Yoast_Notification::WARNING,
119
+ 'id' => 'wpseo-' . $this->notification_identifier,
120
+ 'priority' => 1.0,
121
+ 'capabilities' => 'wpseo_manage_options',
122
+ );
123
+
124
+ return new Yoast_Notification( $message, $notification_options );
125
+ }
126
+
127
+ /**
128
+ * Checks if the noticiation should be shown.
129
+ *
130
+ * @return bool True when applicable.
131
+ */
132
+ protected function is_applicable() {
133
+ if ( $this->is_notice_dismissed() ) {
134
+ return false;
135
+ }
136
+
137
+ if ( $this->is_new_install() ) {
138
+ return false;
139
+ }
140
+
141
+ return $this->get_post_types() !== array();
142
+ }
143
+
144
+ /**
145
+ * Checks whether the notification has been dismissed.
146
+ *
147
+ * @return bool True when notification is dismissed.
148
+ *
149
+ * @codeCoverageIgnore
150
+ */
151
+ protected function is_notice_dismissed() {
152
+ return get_user_meta( get_current_user_id(), 'wpseo-remove-' . $this->notification_identifier, true ) === '1';
153
+ }
154
+
155
+ /**
156
+ * Dismisses the notification.
157
+ *
158
+ * @return void
159
+ *
160
+ * @codeCoverageIgnore
161
+ */
162
+ protected function set_dismissal_state() {
163
+ update_user_meta( get_current_user_id(), 'wpseo-remove-' . $this->notification_identifier, true );
164
+ }
165
+
166
+ /**
167
+ * Checks if the first activation is done before the release of 7.9.
168
+ *
169
+ * @return bool True whether the install is 'new'.
170
+ *
171
+ * @codeCoverageIgnore
172
+ */
173
+ protected function is_new_install() {
174
+ return WPSEO_Options::get( 'first_activated_on' ) >= strtotime( '2018-07-24' );
175
+ }
176
+
177
+ /**
178
+ * Returns all the post types which might have wrong archive settings.
179
+ *
180
+ * @return array The post types.
181
+ *
182
+ * @codeCoverageIgnore
183
+ */
184
+ protected function get_post_types() {
185
+ static $post_types;
186
+
187
+ if ( $post_types === null ) {
188
+ $this->option_defaults = WPSEO_Option_Titles::get_instance()->get_defaults();
189
+
190
+ $post_types = get_post_types( array( 'public' => true ) );
191
+ $post_types = WPSEO_Post_Type::filter_attachment_post_type( $post_types );
192
+ $post_types = $this->filter_woocommerce_product_type( $post_types );
193
+ $post_types = array_filter( $post_types, array( $this, 'has_custom_archive_slug' ) );
194
+ $post_types = array_filter( $post_types, array( $this, 'has_default_templates_set' ) );
195
+ }
196
+
197
+ return $post_types;
198
+ }
199
+
200
+ /**
201
+ * Filters the WooCommerce product, when Woocommerce is active.
202
+ *
203
+ * @param array $post_types The post types to filter.
204
+ *
205
+ * @return array The filtere post types.
206
+ *
207
+ * @codeCoverageIgnore
208
+ */
209
+ public function filter_woocommerce_product_type( $post_types ) {
210
+ if ( WPSEO_Utils::is_woocommerce_active() ) {
211
+ unset( $post_types['product'] );
212
+ }
213
+
214
+ return $post_types;
215
+ }
216
+
217
+ /**
218
+ * Checks if the archive slug for the post type is overridden.
219
+ *
220
+ * @param string $post_type_name The post type's name.
221
+ *
222
+ * @return bool True whether the archive slug is overridden.
223
+ *
224
+ * @codeCoverageIgnore
225
+ */
226
+ protected function has_custom_archive_slug( $post_type_name ) {
227
+ $post_type = get_post_type_object( $post_type_name );
228
+ if ( $post_type === null || ! WPSEO_Post_Type::has_archive( $post_type ) ) {
229
+ return false;
230
+ }
231
+
232
+ // When the archive value is not TRUE it will be a custom archive slug.
233
+ return ( $post_type->has_archive !== true );
234
+ }
235
+
236
+ /**
237
+ * Checks if the default templates are set for given post type.
238
+ *
239
+ * @param string $post_type_name The post type name.
240
+ *
241
+ * @return bool True whether the default templates are set.
242
+ *
243
+ * @codeCoverageIgnore
244
+ */
245
+ protected function has_default_templates_set( $post_type_name ) {
246
+ $title_option_name = 'title-ptarchive-' . $post_type_name;
247
+ $metadesc_option_name = 'metadesc-ptarchive-' . $post_type_name;
248
+
249
+ return ( $this->is_equal_to_default( $title_option_name ) && $this->is_equal_to_default( $metadesc_option_name ) );
250
+ }
251
+
252
+ /**
253
+ * Checks if value for given option name is equal to the default value.
254
+ *
255
+ * @param string $option_name The option name to check.
256
+ *
257
+ * @return bool True whethere the option value is equal to the default value.
258
+ *
259
+ * @codeCoverageIgnore
260
+ */
261
+ protected function is_equal_to_default( $option_name ) {
262
+ if ( ! isset( $this->option_defaults[ $option_name ] ) ) {
263
+ return false;
264
+ }
265
+
266
+ return ( WPSEO_Options::get( $option_name ) === $this->option_defaults[ $option_name ] );
267
+ }
268
+ }
admin/notifiers/interface-notification-handler.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPSEO plugin file.
4
+ *
5
+ * @package WPSEO\Admin\Notifiers
6
+ */
7
+
8
+ /**
9
+ * Dictates the required methods for a Notification Handler implementation.
10
+ */
11
+ interface WPSEO_Notification_Handler {
12
+
13
+ /**
14
+ * Handles the notification object.
15
+ *
16
+ * @param Yoast_Notification_Center $notification_center The notification center object.
17
+ *
18
+ * @return void
19
+ */
20
+ public function handle( Yoast_Notification_Center $notification_center );
21
+ }
admin/taxonomy/class-taxonomy.php CHANGED
@@ -57,8 +57,6 @@ class WPSEO_Taxonomy {
57
 
58
  $this->insert_description_field_editor();
59
 
60
- add_filter( 'category_description', array( $this, 'custom_category_descriptions_add_shortcode_support' ) );
61
-
62
  add_action( sanitize_text_field( $this->taxonomy ) . '_edit_form', array( $this, 'term_metabox' ), 90, 1 );
63
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
64
  }
@@ -108,7 +106,7 @@ class WPSEO_Taxonomy {
108
  $asset_manager->enqueue_script( 'term-scraper' );
109
 
110
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'term-scraper', 'wpseoTermScraperL10n', $this->localize_term_scraper_script() );
111
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
112
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'term-scraper' );
113
  /**
114
  * Remove the emoji script as it is incompatible with both React and any
@@ -201,22 +199,6 @@ class WPSEO_Taxonomy {
201
  wp_editor( '', 'description' );
202
  }
203
 
204
- /**
205
- * Adds shortcode support to category descriptions.
206
- *
207
- * @param string $desc String to add shortcodes in.
208
- *
209
- * @return string
210
- */
211
- public function custom_category_descriptions_add_shortcode_support( $desc ) {
212
- // Wrap in output buffering to prevent shortcodes that echo stuff instead of return from breaking things.
213
- ob_start();
214
- $desc = do_shortcode( $desc );
215
- ob_end_clean();
216
-
217
- return $desc;
218
- }
219
-
220
  /**
221
  * Pass variables to js for use with the term-scraper.
222
  *
@@ -368,4 +350,20 @@ class WPSEO_Taxonomy {
368
 
369
  add_action( "{$this->taxonomy}_term_edit_form_top", array( $this, 'custom_category_description_editor' ) );
370
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  }
57
 
58
  $this->insert_description_field_editor();
59
 
 
 
60
  add_action( sanitize_text_field( $this->taxonomy ) . '_edit_form', array( $this, 'term_metabox' ), 90, 1 );
61
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
62
  }
106
  $asset_manager->enqueue_script( 'term-scraper' );
107
 
108
  wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'term-scraper', 'wpseoTermScraperL10n', $this->localize_term_scraper_script() );
109
+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
110
  $yoast_components_l10n->localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'term-scraper' );
111
  /**
112
  * Remove the emoji script as it is incompatible with both React and any
199
  wp_editor( '', 'description' );
200
  }
201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  /**
203
  * Pass variables to js for use with the term-scraper.
204
  *
350
 
351
  add_action( "{$this->taxonomy}_term_edit_form_top", array( $this, 'custom_category_description_editor' ) );
352
  }
353
+
354
+ /**
355
+ * Adds shortcode support to category descriptions.
356
+ *
357
+ * @deprecated 7.9.0
358
+ *
359
+ * @param string $desc String to add shortcodes in.
360
+ *
361
+ * @return string Content with shortcodes filtered out.
362
+ */
363
+ public function custom_category_descriptions_add_shortcode_support( $desc ) {
364
+ _deprecated_function( __FUNCTION__, 'WPSEO 7.9.0', 'WPSEO_Frontend::custom_category_descriptions_add_shortcode_support' );
365
+
366
+ $frontend = WPSEO_Frontend::get_instance();
367
+ return $frontend->custom_category_descriptions_add_shortcode_support( $desc );
368
+ }
369
  }
admin/views/class-view-utils.php CHANGED
@@ -62,11 +62,12 @@ class Yoast_View_Utils {
62
  /**
63
  * Shows the search appearance settings for a post type.
64
  *
65
- * @param string|object $post_type The post type to show the search appearance settings for.
 
66
  *
67
  * @return void
68
  */
69
- public function show_post_type_settings( $post_type ) {
70
  if ( ! is_object( $post_type ) ) {
71
  $post_type = get_post_type_object( $post_type );
72
  }
@@ -74,23 +75,6 @@ class Yoast_View_Utils {
74
  $show_post_type_help = $this->search_results_setting_help( $post_type );
75
  $noindex_option_name = 'noindex-' . $post_type->name;
76
 
77
- if ( WPSEO_Options::get( 'is-media-purge-relevant' ) ) {
78
- if ( $post_type->name === 'attachment' && WPSEO_Options::get( $noindex_option_name ) === false ) {
79
- $description = sprintf(
80
- /* translators: %1$s expands to the link to the article, %2$s closes the link to the article */
81
- esc_html( __( 'By enabling this option, attachment URLs become visible to both your visitors and Google.
82
- To add value to your website, they should contain useful information, or they might have a
83
- negative impact on your ranking. Please carefully consider this and %1$sread this post%2$s if
84
- you want more information about the impact of showing media in search results.', 'wordpress-seo'
85
- ) ),
86
- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/2r8' ) ) . '" rel="noopener nofollow" target="_blank">',
87
- '</a>'
88
- );
89
-
90
- echo '<div style="clear:both; background-color: #ffeb3b; color: #000000; padding: 16px; max-width: 450px; margin-bottom: 32px;">' . $description . '</div>';
91
- }
92
- }
93
-
94
  $this->form->index_switch(
95
  $noindex_option_name,
96
  $post_type->labels->name,
@@ -108,10 +92,19 @@ you want more information about the impact of showing media in search results.',
108
  sprintf( __( '%1$s Meta Box', 'wordpress-seo' ), 'Yoast SEO' )
109
  );
110
 
111
- $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
112
- $page_type = $recommended_replace_vars->determine_for_post_type( $post_type->name );
113
-
114
- $editor = new WPSEO_Replacevar_Editor( $this->form, 'title-' . $post_type->name, 'metadesc-' . $post_type->name, $page_type, false );
 
 
 
 
 
 
 
 
 
115
  $editor->render();
116
  }
117
  }
62
  /**
63
  * Shows the search appearance settings for a post type.
64
  *
65
+ * @param string|object $post_type The post type to show the search appearance settings for.
66
+ * @param bool $paper_style Whether or not the paper style should be shown.
67
  *
68
  * @return void
69
  */
70
+ public function show_post_type_settings( $post_type, $paper_style = false ) {
71
  if ( ! is_object( $post_type ) ) {
72
  $post_type = get_post_type_object( $post_type );
73
  }
75
  $show_post_type_help = $this->search_results_setting_help( $post_type );
76
  $noindex_option_name = 'noindex-' . $post_type->name;
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  $this->form->index_switch(
79
  $noindex_option_name,
80
  $post_type->labels->name,
92
  sprintf( __( '%1$s Meta Box', 'wordpress-seo' ), 'Yoast SEO' )
93
  );
94
 
95
+ $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
96
+ $editor_specific_replace_vars = new WPSEO_Admin_Editor_Specific_Replace_Vars();
97
+
98
+ $editor = new WPSEO_Replacevar_Editor(
99
+ $this->form,
100
+ array(
101
+ 'title' => 'title-' . $post_type->name,
102
+ 'description' => 'metadesc-' . $post_type->name,
103
+ 'page_type_recommended' => $recommended_replace_vars->determine_for_post_type( $post_type->name ),
104
+ 'page_type_specific' => $editor_specific_replace_vars->determine_for_post_type( $post_type->name ),
105
+ 'paper_style' => $paper_style,
106
+ )
107
+ );
108
  $editor->render();
109
  }
110
  }
admin/views/paper-collapsible.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPSEO plugin file.
4
+ *
5
+ * @package WPSEO\Admin\Views
6
+ *
7
+ * @var string $paper_id The id of the paper.
8
+ * @var bool $collapsible Whether the collapsible should be rendered.
9
+ * @var array $collapsible_config Configuration for the collapsible.
10
+ * @var string $title The title
11
+ * @var string $title_after Additional content to render after the title.
12
+ * @var string $view_file Path to the view file.
13
+ * @var WPSEO_Admin_Help_Panel $help_text The help text.
14
+ */
15
+
16
+ if ( ! defined( 'WPSEO_VERSION' ) ) {
17
+ header( 'Status: 403 Forbidden' );
18
+ header( 'HTTP/1.1 403 Forbidden' );
19
+ exit();
20
+ }
21
+ ?>
22
+ <div class="paper tab-block" id="<?php echo esc_attr( $paper_id ); ?>">
23
+
24
+ <?php
25
+ if ( ! empty( $title ) ) {
26
+ if ( ! empty( $collapsible ) ) {
27
+ printf(
28
+ '<h2 class="help-button-inline" id="%1$s"><button type="button" class="toggleable-container-trigger" aria-expanded="%4$s">%2$s <span class="toggleable-container-icon dashicons %3$s" aria-hidden="true"></span></button></h2>',
29
+ esc_attr( $title ),
30
+ esc_html( $title ) . $title_after . $help_text->get_button_html(),
31
+ $collapsible_config['toggle_icon'],
32
+ $collapsible_config['expanded']
33
+ );
34
+ }
35
+ else {
36
+ printf( '<h2 class="help-button-inline">' . esc_html( $title ) . $title_after . $help_text->get_button_html() . '</h2>' );
37
+ }
38
+ }
39
+ ?>
40
+ <?php echo $help_text->get_panel_html(); ?>
41
+ <div class="<?php echo esc_attr( $collapsible_config['class'] ); ?>">
42
+ <?php require $view_file; ?>
43
+ </div>
44
+
45
+ </div>
admin/views/tabs/metas/archives.php CHANGED
@@ -5,143 +5,46 @@
5
  * @package WPSEO\Admin\Views
6
  */
7
 
8
- /**
9
- * @var Yoast_Form $yform
10
- */
11
-
12
  if ( ! defined( 'WPSEO_VERSION' ) ) {
13
  header( 'Status: 403 Forbidden' );
14
  header( 'HTTP/1.1 403 Forbidden' );
15
  exit();
16
  }
17
 
18
- $archives_help_01 = sprintf(
19
- /* translators: %1$s / %2$s: links to an article about duplicate content on yoast.com */
20
- esc_html__( 'If you\'re running a one author blog, the author archive will be exactly the same as your homepage. This is what\'s called a %1$sduplicate content problem%2$s.', 'wordpress-seo' ),
21
- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/duplicate-content' ) ) . '">',
22
- '</a>'
23
- );
24
-
25
- $archives_help_02 = sprintf(
26
- /* translators: %s expands to <code>noindex, follow</code> */
27
- esc_html__( 'If this is the case on your site, you can choose to either disable it (which makes it redirect to the homepage), or to add %s to it so it doesn\'t show up in the search results.', 'wordpress-seo' ),
28
- '<code>noindex,follow</code>'
29
- );
30
-
31
- $archives_help_03 = esc_html__( 'Note that links to archives might be still output by your theme and you would need to remove them separately.', 'wordpress-seo' );
32
-
33
- $archives_help_04 = esc_html__( 'Date-based archives could in some cases also be seen as duplicate content.', 'wordpress-seo' );
34
-
35
- $archives_help = new WPSEO_Admin_Help_Panel(
36
- 'search-appearance-archives',
37
- __( 'Learn more about the archives setting', 'wordpress-seo' ),
38
- $archives_help_01 . ' ' . $archives_help_02 . ' ' . $archives_help_03 . ' ' . $archives_help_04,
39
- 'has-wrapper'
40
- );
41
-
42
- echo '<p class="help-button-inline"><strong>' . esc_html__( 'Archives settings help', 'wordpress-seo' ) . $archives_help->get_button_html() . '</strong><p>';
43
- echo $archives_help->get_panel_html();
44
-
45
- echo '<div class="tab-block" id="author-archives-titles-metas">';
46
- echo '<h2>' . esc_html__( 'Author archives settings', 'wordpress-seo' ) . '</h2>';
47
- $yform->toggle_switch( 'disable-author', array(
48
- 'off' => __( 'Enabled', 'wordpress-seo' ),
49
- 'on' => __( 'Disabled', 'wordpress-seo' ),
50
- ), __( 'Author archives', 'wordpress-seo' ) );
51
-
52
- echo "<div id='author-archives-titles-metas-content' class='archives-titles-metas-content'>";
53
-
54
- $author_archives_help = new WPSEO_Admin_Help_Panel(
55
- 'noindex-author-wpseo',
56
- esc_html__( 'Help on the author archives search results setting', 'wordpress-seo' ),
57
- sprintf(
58
- /* translators: 1: expands to <code>noindex</code>; 2: link open tag; 3: link close tag. */
59
- esc_html__( 'Not showing the archive for authors in the search results technically means those will have a %1$s robots meta and will be excluded from XML sitemaps. %2$sMore info on the search results settings%3$s.', 'wordpress-seo' ),
60
- '<code>noindex</code>',
61
- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/show-x' ) ) . '" target="_blank" rel="noopener noreferrer">',
62
- '</a>'
63
- )
64
- );
65
-
66
- $yform->index_switch(
67
- 'noindex-author-wpseo',
68
- __( 'author archives', 'wordpress-seo' ),
69
- $author_archives_help->get_button_html() . $author_archives_help->get_panel_html()
70
- );
71
-
72
- $author_archives_no_posts_help = new WPSEO_Admin_Help_Panel(
73
- 'noindex-author-noposts-wpseo',
74
- esc_html__( 'Help on the authors without posts archive search results setting', 'wordpress-seo' ),
75
- sprintf(
76
- /* translators: 1: expands to <code>noindex</code>; 2: link open tag; 3: link close tag. */
77
- esc_html__( 'Not showing the archives for authors without posts in the search results technically means those will have a %1$s robots meta and will be excluded from XML sitemaps. %2$sMore info on the search results settings%3$s.', 'wordpress-seo' ),
78
- '<code>noindex</code>',
79
- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/show-x' ) ) . '" target="_blank" rel="noopener noreferrer">',
80
- '</a>'
81
- )
82
- );
83
-
84
- $yform->index_switch(
85
- 'noindex-author-noposts-wpseo',
86
- __( 'archives for authors without posts', 'wordpress-seo' ),
87
- $author_archives_no_posts_help->get_button_html() . $author_archives_no_posts_help->get_panel_html()
88
- );
89
-
90
- $editor = new WPSEO_Replacevar_Editor( $yform, 'title-author-wpseo', 'metadesc-author-wpseo', 'author_archive' );
91
- $editor->render();
92
- echo '</div>';
93
- echo '</div>';
94
-
95
- echo '<div class="tab-block" id="date-archives-titles-metas">';
96
- echo '<h2>' . esc_html__( 'Date archives settings', 'wordpress-seo' ) . '</h2>';
97
- $yform->toggle_switch( 'disable-date', array(
98
- 'off' => __( 'Enabled', 'wordpress-seo' ),
99
- 'on' => __( 'Disabled', 'wordpress-seo' ),
100
- ), __( 'Date archives', 'wordpress-seo' ) );
101
-
102
- echo "<div id='date-archives-titles-metas-content' class='archives-titles-metas-content'>";
103
 
104
- $date_archives_help = new WPSEO_Admin_Help_Panel(
105
- 'noindex-archive-wpseo',
106
- esc_html__( 'Help on the date archives search results setting', 'wordpress-seo' ),
107
- sprintf(
108
- /* translators: 1: expands to <code>noindex</code>; 2: link open tag; 3: link close tag. */
109
- esc_html__( 'Not showing the date archives in the search results technically means those will have a %1$s robots meta and will be excluded from XML sitemaps. %2$sMore info on the search results settings%3$s.', 'wordpress-seo' ),
110
- '<code>noindex</code>',
111
-