Yoast SEO - Version 7.0

Version Description

Download this release

Release Info

Developer jipmoors
Plugin Icon 128x128 Yoast SEO
Version 7.0
Comparing to
See all releases

Version 7.0

Files changed (275) hide show
  1. admin/ajax.php +390 -0
  2. admin/ajax/class-recalculate-scores-ajax.php +119 -0
  3. admin/ajax/class-shortcode-filter.php +39 -0
  4. admin/ajax/class-yoast-dismissable-notice.php +80 -0
  5. admin/ajax/class-yoast-onpage-ajax.php +38 -0
  6. admin/ajax/class-yoast-plugin-conflict-ajax.php +105 -0
  7. admin/banner/class-admin-banner-renderer.php +48 -0
  8. admin/banner/class-admin-banner-sidebar-renderer.php +60 -0
  9. admin/banner/class-admin-banner-sidebar.php +388 -0
  10. admin/banner/class-admin-banner-spot-renderer.php +37 -0
  11. admin/banner/class-admin-banner-spot.php +118 -0
  12. admin/banner/class-admin-banner.php +87 -0
  13. admin/capabilities/class-abstract-capability-manager.php +82 -0
  14. admin/capabilities/class-capability-manager-factory.php +30 -0
  15. admin/capabilities/class-capability-manager-integration.php +113 -0
  16. admin/capabilities/class-capability-manager-vip.php +70 -0
  17. admin/capabilities/class-capability-manager-wp.php +48 -0
  18. admin/capabilities/class-capability-manager.php +35 -0
  19. admin/capabilities/class-capability-utils.php +52 -0
  20. admin/capabilities/class-register-capabilities.php +40 -0
  21. admin/class-admin-asset-dev-server-location.php +80 -0
  22. admin/class-admin-asset-location.php +20 -0
  23. admin/class-admin-asset-manager.php +493 -0
  24. admin/class-admin-asset-seo-location.php +95 -0
  25. admin/class-admin-help-panel.php +92 -0
  26. admin/class-admin-init.php +665 -0
  27. admin/class-admin-user-profile.php +86 -0
  28. admin/class-admin-utils.php +68 -0
  29. admin/class-admin.php +539 -0
  30. admin/class-asset.php +170 -0
  31. admin/class-bulk-description-editor-list-table.php +75 -0
  32. admin/class-bulk-editor-list-table.php +1019 -0
  33. admin/class-bulk-title-editor-list-table.php +85 -0
  34. admin/class-collector.php +46 -0
  35. admin/class-config.php +145 -0
  36. admin/class-cornerstone-field.php +55 -0
  37. admin/class-cornerstone.php +90 -0
  38. admin/class-customizer.php +253 -0
  39. admin/class-database-proxy.php +191 -0
  40. admin/class-export.php +285 -0
  41. admin/class-extension-manager.php +138 -0
  42. admin/class-extension.php +81 -0
  43. admin/class-extensions.php +106 -0
  44. admin/class-help-center-item.php +94 -0
  45. admin/class-help-center.php +254 -0
  46. admin/class-import-aioseo.php +107 -0
  47. admin/class-import-external.php +113 -0
  48. admin/class-import-jetpack.php +31 -0
  49. admin/class-import-seopressor.php +189 -0
  50. admin/class-import-ultimate-seo.php +54 -0
  51. admin/class-import-woothemes-seo.php +149 -0
  52. admin/class-import-wpseo.php +208 -0
  53. admin/class-import.php +205 -0
  54. admin/class-license-page-manager.php +209 -0
  55. admin/class-meta-columns.php +752 -0
  56. admin/class-meta-storage.php +109 -0
  57. admin/class-meta-table-accessible.php +101 -0
  58. admin/class-option-tab.php +89 -0
  59. admin/class-option-tabs-formatter.php +57 -0
  60. admin/class-option-tabs.php +105 -0
  61. admin/class-plugin-availability.php +342 -0
  62. admin/class-plugin-compatibility.php +107 -0
  63. admin/class-plugin-conflict.php +161 -0
  64. admin/class-premium-popup.php +97 -0
  65. admin/class-premium-upsell-admin-block.php +144 -0
  66. admin/class-primary-term-admin.php +232 -0
  67. admin/class-product-upsell-notice.php +201 -0
  68. admin/class-recalculate-scores.php +52 -0
  69. admin/class-remote-request.php +128 -0
  70. admin/class-social-admin.php +241 -0
  71. admin/class-social-facebook-form.php +273 -0
  72. admin/class-social-facebook.php +211 -0
  73. admin/class-suggested-plugins.php +157 -0
  74. admin/class-yoast-alerts.php +258 -0
  75. admin/class-yoast-columns.php +42 -0
  76. admin/class-yoast-dashboard-widget.php +153 -0
  77. admin/class-yoast-form.php +669 -0
  78. admin/class-yoast-notification-center.php +598 -0
  79. admin/class-yoast-notification.php +330 -0
  80. admin/class-yoast-plugin-conflict.php +334 -0
  81. admin/config-ui/class-configuration-components.php +71 -0
  82. admin/config-ui/class-configuration-endpoint.php +78 -0
  83. admin/config-ui/class-configuration-options-adapter.php +197 -0
  84. admin/config-ui/class-configuration-page.php +262 -0
  85. admin/config-ui/class-configuration-service.php +160 -0
  86. admin/config-ui/class-configuration-storage.php +198 -0
  87. admin/config-ui/class-configuration-structure.php +99 -0
  88. admin/config-ui/class-configuration-translations.php +53 -0
  89. admin/config-ui/components/class-component-configuration-choices.php +96 -0
  90. admin/config-ui/components/class-component-connect-google-search-console.php +149 -0
  91. admin/config-ui/components/class-component-mailchimp-signup.php +79 -0
  92. admin/config-ui/components/class-component-suggestions.php +106 -0
  93. admin/config-ui/components/interface-component.php +33 -0
  94. admin/config-ui/factories/class-factory-post-type.php +68 -0
  95. admin/config-ui/fields/class-field-choice-post-type.php +79 -0
  96. admin/config-ui/fields/class-field-choice.php +40 -0
  97. admin/config-ui/fields/class-field-company-logo.php +28 -0
  98. admin/config-ui/fields/class-field-company-name.php +28 -0
  99. admin/config-ui/fields/class-field-company-or-person.php +32 -0
  100. admin/config-ui/fields/class-field-configuration-choices.php +41 -0
  101. admin/config-ui/fields/class-field-connect-google-search-console.php +28 -0
  102. admin/config-ui/fields/class-field-environment.php +90 -0
  103. admin/config-ui/fields/class-field-google-search-console-intro.php +35 -0
  104. admin/config-ui/fields/class-field-mailchimp-signup.php +58 -0
  105. admin/config-ui/fields/class-field-multiple-authors.php +83 -0
  106. admin/config-ui/fields/class-field-person-name.php +28 -0
  107. admin/config-ui/fields/class-field-post-type-visibility.php +25 -0
  108. admin/config-ui/fields/class-field-profile-url-facebook.php +29 -0
  109. admin/config-ui/fields/class-field-profile-url-googleplus.php +29 -0
  110. admin/config-ui/fields/class-field-profile-url-instagram.php +29 -0
  111. admin/config-ui/fields/class-field-profile-url-linkedin.php +29 -0
  112. admin/config-ui/fields/class-field-profile-url-myspace.php +29 -0
  113. admin/config-ui/fields/class-field-profile-url-pinterest.php +29 -0
  114. admin/config-ui/fields/class-field-profile-url-twitter.php +28 -0
  115. admin/config-ui/fields/class-field-profile-url-youtube.php +29 -0
  116. admin/config-ui/fields/class-field-separator.php +43 -0
  117. admin/config-ui/fields/class-field-site-name.php +58 -0
  118. admin/config-ui/fields/class-field-site-type.php +37 -0
  119. admin/config-ui/fields/class-field-social-profiles-intro.php +31 -0
  120. admin/config-ui/fields/class-field-success-message.php +35 -0
  121. admin/config-ui/fields/class-field-suggestions.php +42 -0
  122. admin/config-ui/fields/class-field-title-intro.php +27 -0
  123. admin/config-ui/fields/class-field-upsell-configuration-service.php +43 -0
  124. admin/config-ui/fields/class-field-upsell-site-review.php +36 -0
  125. admin/config-ui/fields/class-field.php +134 -0
  126. admin/endpoints/class-endpoint-ryte.php +54 -0
  127. admin/endpoints/class-endpoint-statistics.php +54 -0
  128. admin/endpoints/class-endpoint.php +24 -0
  129. admin/filters/class-abstract-post-filter.php +178 -0
  130. admin/filters/class-cornerstone-filter.php +104 -0
  131. admin/formatter/class-metabox-formatter.php +203 -0
  132. admin/formatter/class-post-metabox-formatter.php +211 -0
  133. admin/formatter/class-term-metabox-formatter.php +136 -0
  134. admin/formatter/interface-metabox-formatter.php +18 -0
  135. admin/google_search_console/class-gsc-ajax.php +108 -0
  136. admin/google_search_console/class-gsc-bulk-action.php +96 -0
  137. admin/google_search_console/class-gsc-category-filters.php +199 -0
  138. admin/google_search_console/class-gsc-config.php +22 -0
  139. admin/google_search_console/class-gsc-count.php +227 -0
  140. admin/google_search_console/class-gsc-issue.php +89 -0
  141. admin/google_search_console/class-gsc-issues.php +175 -0
  142. admin/google_search_console/class-gsc-mapper.php +119 -0
  143. admin/google_search_console/class-gsc-marker.php +143 -0
  144. admin/google_search_console/class-gsc-modal.php +56 -0
  145. admin/google_search_console/class-gsc-platform-tabs.php +95 -0
  146. admin/google_search_console/class-gsc-service.php +193 -0
  147. admin/google_search_console/class-gsc-settings.php +102 -0
  148. admin/google_search_console/class-gsc-table.php +368 -0
  149. admin/google_search_console/class-gsc.php +311 -0
  150. admin/google_search_console/views/gsc-display.php +147 -0
  151. admin/google_search_console/views/gsc-redirect-nopremium.php +23 -0
  152. admin/import/class-import-aioseo-hooks.php +40 -0
  153. admin/import/class-import-hooks.php +89 -0
  154. admin/import/class-import-wpseo-hooks.php +40 -0
  155. admin/index.php +4 -0
  156. admin/interface-collection.php +18 -0
  157. admin/interface-installable.php +17 -0
  158. admin/links/class-link-cleanup-transient.php +33 -0
  159. admin/links/class-link-column-count.php +86 -0
  160. admin/links/class-link-columns.php +253 -0
  161. admin/links/class-link-compatibility-notifier.php +56 -0
  162. admin/links/class-link-content-processor.php +133 -0
  163. admin/links/class-link-extractor.php +46 -0
  164. admin/links/class-link-factory.php +81 -0
  165. admin/links/class-link-filter.php +55 -0
  166. admin/links/class-link-installer.php +50 -0
  167. admin/links/class-link-internal-lookup.php +23 -0
  168. admin/links/class-link-notifier.php +125 -0
  169. admin/links/class-link-query.php +158 -0
  170. admin/links/class-link-reindex-dashboard.php +222 -0
  171. admin/links/class-link-reindex-post-endpoint.php +54 -0
  172. admin/links/class-link-reindex-post-service.php +93 -0
  173. admin/links/class-link-storage.php +150 -0
  174. admin/links/class-link-table-accessible-notifier.php +54 -0
  175. admin/links/class-link-table-accessible.php +101 -0
  176. admin/links/class-link-type-classifier.php +93 -0
  177. admin/links/class-link-utils.php +39 -0
  178. admin/links/class-link-watcher-loader.php +23 -0
  179. admin/links/class-link-watcher.php +119 -0
  180. admin/links/class-link.php +62 -0
  181. admin/listeners/class-listener.php +17 -0
  182. admin/menu/class-admin-menu.php +270 -0
  183. admin/menu/class-menu.php +89 -0
  184. admin/menu/class-network-admin-menu.php +82 -0
  185. admin/menu/class-submenu-capability-normalize.php +39 -0
  186. admin/metabox/class-metabox-add-keyword-tab.php +67 -0
  187. admin/metabox/class-metabox-addon-section.php +37 -0
  188. admin/metabox/class-metabox-analysis-readability.php +37 -0
  189. admin/metabox/class-metabox-analysis-seo.php +37 -0
  190. admin/metabox/class-metabox-editor.php +65 -0
  191. admin/metabox/class-metabox-form-tab.php +117 -0
  192. admin/metabox/class-metabox-tab-section.php +147 -0
  193. admin/metabox/class-metabox.php +1184 -0
  194. admin/metabox/interface-metabox-analysis.php +31 -0
  195. admin/metabox/interface-metabox-section.php +20 -0
  196. admin/metabox/interface-metabox-tab.php +24 -0
  197. admin/notifiers/class-configuration-notifier.php +154 -0
  198. admin/onpage/class-onpage-option.php +117 -0
  199. admin/onpage/class-onpage-request.php +65 -0
  200. admin/onpage/class-onpage.php +237 -0
  201. admin/onpage/class-ryte-service.php +100 -0
  202. admin/pages/dashboard.php +65 -0
  203. admin/pages/licenses.php +15 -0
  204. admin/pages/metas.php +79 -0
  205. admin/pages/network.php +153 -0
  206. admin/pages/social.php +23 -0
  207. admin/pages/tools.php +84 -0
  208. admin/recalculate/class-recalculate-posts.php +149 -0
  209. admin/recalculate/class-recalculate-terms.php +149 -0
  210. admin/recalculate/class-recalculate.php +101 -0
  211. admin/roles/class-abstract-role-manager.php +143 -0
  212. admin/roles/class-register-roles.php +30 -0
  213. admin/roles/class-role-manager-factory.php +30 -0
  214. admin/roles/class-role-manager-vip.php +50 -0
  215. admin/roles/class-role-manager-wp.php +60 -0
  216. admin/roles/class-role-manager.php +41 -0
  217. admin/statistics/class-statistics-integration.php +28 -0
  218. admin/statistics/class-statistics-service.php +232 -0
  219. admin/taxonomy/class-taxonomy-columns.php +247 -0
  220. admin/taxonomy/class-taxonomy-content-fields.php +76 -0
  221. admin/taxonomy/class-taxonomy-fields-presenter.php +234 -0
  222. admin/taxonomy/class-taxonomy-fields.php +73 -0
  223. admin/taxonomy/class-taxonomy-metabox.php +417 -0
  224. admin/taxonomy/class-taxonomy-settings-fields.php +106 -0
  225. admin/taxonomy/class-taxonomy-social-fields.php +141 -0
  226. admin/taxonomy/class-taxonomy.php +344 -0
  227. admin/tracking/class-tracking-default-data.php +38 -0
  228. admin/tracking/class-tracking-plugin-data.php +58 -0
  229. admin/tracking/class-tracking-server-data.php +83 -0
  230. admin/tracking/class-tracking-theme-data.php +47 -0
  231. admin/tracking/class-tracking.php +93 -0
  232. admin/views/class-view-utils.php +103 -0
  233. admin/views/class-yoast-form-fieldset.php +168 -0
  234. admin/views/class-yoast-input-select.php +128 -0
  235. admin/views/form/fieldset.php +24 -0
  236. admin/views/form/select.php +24 -0
  237. admin/views/interface-yoast-form-element.php +17 -0
  238. admin/views/js-templates-primary-term.php +47 -0
  239. admin/views/licenses.php +271 -0
  240. admin/views/partial-alerts-errors.php +20 -0
  241. admin/views/partial-alerts-template.php +69 -0
  242. admin/views/partial-alerts-warnings.php +20 -0
  243. admin/views/tabs/dashboard/dashboard.php +51 -0
  244. admin/views/tabs/dashboard/features.php +154 -0
  245. admin/views/tabs/dashboard/site-analysis.php +21 -0
  246. admin/views/tabs/dashboard/webmaster-tools.php +67 -0
  247. admin/views/tabs/metas/archives.php +146 -0
  248. admin/views/tabs/metas/breadcrumbs.php +111 -0
  249. admin/views/tabs/metas/general.php +20 -0
  250. admin/views/tabs/metas/general/force-rewrite-title.php +23 -0
  251. admin/views/tabs/metas/general/homepage.php +46 -0
  252. admin/views/tabs/metas/general/knowledge-graph.php +41 -0
  253. admin/views/tabs/metas/general/title-separator.php +23 -0
  254. admin/views/tabs/metas/media.php +46 -0
  255. admin/views/tabs/metas/post-types.php +82 -0
  256. admin/views/tabs/metas/rss.php +69 -0
  257. admin/views/tabs/metas/taxonomies.php +85 -0
  258. admin/views/tabs/social/accounts.php +36 -0
  259. admin/views/tabs/social/facebook.php +82 -0
  260. admin/views/tabs/social/google.php +25 -0
  261. admin/views/tabs/social/pinterest.php +38 -0
  262. admin/views/tabs/social/twitterbox.php +28 -0
  263. admin/views/tabs/tool/import-seo.php +52 -0
  264. admin/views/tabs/tool/wpseo-export.php +34 -0
  265. admin/views/tabs/tool/wpseo-import.php +39 -0
  266. admin/views/tool-bulk-editor.php +86 -0
  267. admin/views/tool-file-editor.php +239 -0
  268. admin/views/tool-import-export.php +152 -0
  269. admin/views/user-profile.php +53 -0
  270. admin/watchers/class-slug-change-watcher.php +116 -0
  271. css/dist/admin-global-700-rtl.min.css +1 -0
  272. css/dist/admin-global-700.min.css +1 -0
  273. css/dist/adminbar-700-rtl.min.css +1 -0
  274. css/dist/adminbar-700.min.css +1 -0
  275. css/dist/alerts-700-rtl.min.css +1 -0
admin/ajax.php ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\Admin
4
+ */
5
+
6
+ if ( ! defined( 'WPSEO_VERSION' ) ) {
7
+ header( 'Status: 403 Forbidden' );
8
+ header( 'HTTP/1.1 403 Forbidden' );
9
+ exit();
10
+ }
11
+
12
+ /**
13
+ * @todo this whole thing should probably be a proper class.
14
+ */
15
+
16
+ /**
17
+ * Convenience function to JSON encode and echo results and then die
18
+ *
19
+ * @param array $results Results array for encoding.
20
+ */
21
+ function wpseo_ajax_json_echo_die( $results ) {
22
+ echo wp_json_encode( $results );
23
+ die();
24
+ }
25
+
26
+ /**
27
+ * Function used from AJAX calls, takes it variables from $_POST, dies on exit.
28
+ */
29
+ function wpseo_set_option() {
30
+ if ( ! current_user_can( 'manage_options' ) ) {
31
+ die( '-1' );
32
+ }
33
+
34
+ check_ajax_referer( 'wpseo-setoption' );
35
+
36
+ $option = sanitize_text_field( filter_input( INPUT_POST, 'option' ) );
37
+ if ( $option !== 'page_comments' ) {
38
+ die( '-1' );
39
+ }
40
+
41
+ update_option( $option, 0 );
42
+ die( '1' );
43
+ }
44
+
45
+ add_action( 'wp_ajax_wpseo_set_option', 'wpseo_set_option' );
46
+
47
+ /**
48
+ * Since 3.2 Notifications are dismissed in the Notification Center.
49
+ */
50
+ add_action( 'wp_ajax_yoast_dismiss_notification', array( 'Yoast_Notification_Center', 'ajax_dismiss_notification' ) );
51
+
52
+ /**
53
+ * Function used to remove the admin notices for several purposes, dies on exit.
54
+ */
55
+ function wpseo_set_ignore() {
56
+ if ( ! current_user_can( 'manage_options' ) ) {
57
+ die( '-1' );
58
+ }
59
+
60
+ check_ajax_referer( 'wpseo-ignore' );
61
+
62
+ $ignore_key = sanitize_text_field( filter_input( INPUT_POST, 'option' ) );
63
+ WPSEO_Options::set( 'ignore_' . $ignore_key, true );
64
+
65
+ die( '1' );
66
+ }
67
+
68
+ add_action( 'wp_ajax_wpseo_set_ignore', 'wpseo_set_ignore' );
69
+
70
+ /**
71
+ * Hides the default tagline notice for a specific user.
72
+ */
73
+ function wpseo_dismiss_tagline_notice() {
74
+ if ( ! current_user_can( 'manage_options' ) ) {
75
+ die( '-1' );
76
+ }
77
+
78
+ check_ajax_referer( 'wpseo-dismiss-tagline-notice' );
79
+
80
+ update_user_meta( get_current_user_id(), 'wpseo_seen_tagline_notice', 'seen' );
81
+
82
+ die( '1' );
83
+ }
84
+
85
+ add_action( 'wp_ajax_wpseo_dismiss_tagline_notice', 'wpseo_dismiss_tagline_notice' );
86
+
87
+ /**
88
+ * Used in the editor to replace vars for the snippet preview
89
+ */
90
+ function wpseo_ajax_replace_vars() {
91
+ global $post;
92
+ check_ajax_referer( 'wpseo-replace-vars' );
93
+
94
+ $post = get_post( intval( filter_input( INPUT_POST, 'post_id' ) ) );
95
+ global $wp_query;
96
+ $wp_query->queried_object = $post;
97
+ $wp_query->queried_object_id = $post->ID;
98
+
99
+ $omit = array( 'excerpt', 'excerpt_only', 'title' );
100
+ echo wpseo_replace_vars( stripslashes( filter_input( INPUT_POST, 'string' ) ), $post, $omit );
101
+ die;
102
+ }
103
+
104
+ add_action( 'wp_ajax_wpseo_replace_vars', 'wpseo_ajax_replace_vars' );
105
+
106
+ /**
107
+ * Save an individual SEO title from the Bulk Editor.
108
+ */
109
+ function wpseo_save_title() {
110
+ wpseo_save_what( 'title' );
111
+ }
112
+
113
+ add_action( 'wp_ajax_wpseo_save_title', 'wpseo_save_title' );
114
+
115
+ /**
116
+ * Save an individual meta description from the Bulk Editor.
117
+ */
118
+ function wpseo_save_description() {
119
+ wpseo_save_what( 'metadesc' );
120
+ }
121
+
122
+ add_action( 'wp_ajax_wpseo_save_metadesc', 'wpseo_save_description' );
123
+
124
+ /**
125
+ * Save titles & descriptions
126
+ *
127
+ * @param string $what Type of item to save (title, description).
128
+ */
129
+ function wpseo_save_what( $what ) {
130
+ check_ajax_referer( 'wpseo-bulk-editor' );
131
+
132
+ $new = filter_input( INPUT_POST, 'new_value' );
133
+ $post_id = intval( filter_input( INPUT_POST, 'wpseo_post_id' ) );
134
+ $original = filter_input( INPUT_POST, 'existing_value' );
135
+
136
+ $results = wpseo_upsert_new( $what, $post_id, $new, $original );
137
+
138
+ wpseo_ajax_json_echo_die( $results );
139
+ }
140
+
141
+ /**
142
+ * Helper function to update a post's meta data, returning relevant information
143
+ * about the information updated and the results or the meta update.
144
+ *
145
+ * @param int $post_id Post ID.
146
+ * @param string $new_meta_value New meta value to record.
147
+ * @param string $orig_meta_value Original meta value.
148
+ * @param string $meta_key Meta key string.
149
+ * @param string $return_key Return key string to use in results.
150
+ *
151
+ * @return string
152
+ */
153
+ function wpseo_upsert_meta( $post_id, $new_meta_value, $orig_meta_value, $meta_key, $return_key ) {
154
+
155
+ $post_id = intval( $post_id );
156
+ $sanitized_new_meta_value = wp_strip_all_tags( $new_meta_value );
157
+ $orig_meta_value = wp_strip_all_tags( $orig_meta_value );
158
+
159
+ $upsert_results = array(
160
+ 'status' => 'success',
161
+ 'post_id' => $post_id,
162
+ "new_{$return_key}" => $sanitized_new_meta_value,
163
+ "original_{$return_key}" => $orig_meta_value,
164
+ );
165
+
166
+ $the_post = get_post( $post_id );
167
+ if ( empty( $the_post ) ) {
168
+
169
+ $upsert_results['status'] = 'failure';
170
+ $upsert_results['results'] = __( 'Post doesn\'t exist.', 'wordpress-seo' );
171
+
172
+ return $upsert_results;
173
+ }
174
+
175
+ $post_type_object = get_post_type_object( $the_post->post_type );
176
+ if ( ! $post_type_object ) {
177
+
178
+ $upsert_results['status'] = 'failure';
179
+ $upsert_results['results'] = sprintf(
180
+ /* translators: %s expands to post type. */
181
+ __( 'Post has an invalid Post Type: %s.', 'wordpress-seo' ),
182
+ $the_post->post_type
183
+ );
184
+
185
+ return $upsert_results;
186
+ }
187
+
188
+ if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) {
189
+
190
+ $upsert_results['status'] = 'failure';
191
+ $upsert_results['results'] = sprintf(
192
+ /* translators: %s expands to post type name. */
193
+ __( 'You can\'t edit %s.', 'wordpress-seo' ),
194
+ $post_type_object->label
195
+ );
196
+
197
+ return $upsert_results;
198
+ }
199
+
200
+ if ( ! current_user_can( $post_type_object->cap->edit_others_posts ) && (int) $the_post->post_author !== get_current_user_id() ) {
201
+
202
+ $upsert_results['status'] = 'failure';
203
+ $upsert_results['results'] = sprintf(
204
+ /* translators: %s expands to the name of a post type (plural). */
205
+ __( 'You can\'t edit %s that aren\'t yours.', 'wordpress-seo' ),
206
+ $post_type_object->label
207
+ );
208
+
209
+ return $upsert_results;
210
+
211
+ }
212
+
213
+ if ( $sanitized_new_meta_value === $orig_meta_value && $sanitized_new_meta_value !== $new_meta_value ) {
214
+ $upsert_results['status'] = 'failure';
215
+ $upsert_results['results'] = __( 'You have used HTML in your value which is not allowed.', 'wordpress-seo' );
216
+
217
+ return $upsert_results;
218
+ }
219
+
220
+ $res = update_post_meta( $post_id, $meta_key, $sanitized_new_meta_value );
221
+
222
+ $upsert_results['status'] = ( $res !== false ) ? 'success' : 'failure';
223
+ $upsert_results['results'] = $res;
224
+
225
+ return $upsert_results;
226
+ }
227
+
228
+ /**
229
+ * Save all titles sent from the Bulk Editor.
230
+ */
231
+ function wpseo_save_all_titles() {
232
+ wpseo_save_all( 'title' );
233
+ }
234
+
235
+ add_action( 'wp_ajax_wpseo_save_all_titles', 'wpseo_save_all_titles' );
236
+
237
+ /**
238
+ * Save all description sent from the Bulk Editor.
239
+ */
240
+ function wpseo_save_all_descriptions() {
241
+ wpseo_save_all( 'metadesc' );
242
+ }
243
+
244
+ add_action( 'wp_ajax_wpseo_save_all_descriptions', 'wpseo_save_all_descriptions' );
245
+
246
+ /**
247
+ * Utility function to save values
248
+ *
249
+ * @param string $what Type of item so save.
250
+ */
251
+ function wpseo_save_all( $what ) {
252
+ check_ajax_referer( 'wpseo-bulk-editor' );
253
+
254
+ // @todo the WPSEO Utils class can't filter arrays in POST yet.
255
+ $new_values = $_POST['items'];
256
+ $original_values = $_POST['existing_items'];
257
+
258
+ $results = array();
259
+
260
+ if ( is_array( $new_values ) && $new_values !== array() ) {
261
+ foreach ( $new_values as $post_id => $new_value ) {
262
+ $original_value = $original_values[ $post_id ];
263
+ $results[] = wpseo_upsert_new( $what, $post_id, $new_value, $original_value );
264
+ }
265
+ }
266
+ wpseo_ajax_json_echo_die( $results );
267
+ }
268
+
269
+ /**
270
+ * Insert a new value
271
+ *
272
+ * @param string $what Item type (such as title).
273
+ * @param int $post_id Post ID.
274
+ * @param string $new New value to record.
275
+ * @param string $original Original value.
276
+ *
277
+ * @return string
278
+ */
279
+ function wpseo_upsert_new( $what, $post_id, $new, $original ) {
280
+ $meta_key = WPSEO_Meta::$meta_prefix . $what;
281
+
282
+ return wpseo_upsert_meta( $post_id, $new, $original, $meta_key, $what );
283
+ }
284
+
285
+ /**
286
+ * Handles the posting of a new FB admin.
287
+ */
288
+ function wpseo_add_fb_admin() {
289
+ check_ajax_referer( 'wpseo_fb_admin_nonce' );
290
+
291
+ if ( ! current_user_can( 'manage_options' ) ) {
292
+ die( '-1' );
293
+ }
294
+
295
+ $facebook_social = new Yoast_Social_Facebook();
296
+
297
+ wp_die( $facebook_social->add_admin( filter_input( INPUT_POST, 'admin_name' ), filter_input( INPUT_POST, 'admin_id' ) ) );
298
+ }
299
+
300
+ add_action( 'wp_ajax_wpseo_add_fb_admin', 'wpseo_add_fb_admin' );
301
+
302
+ /**
303
+ * Retrieves the keyword for the keyword doubles.
304
+ */
305
+ function ajax_get_keyword_usage() {
306
+ $post_id = filter_input( INPUT_POST, 'post_id' );
307
+ $keyword = filter_input( INPUT_POST, 'keyword' );
308
+
309
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
310
+ die( '-1' );
311
+ }
312
+
313
+ wp_die(
314
+ wp_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) )
315
+ );
316
+ }
317
+
318
+ add_action( 'wp_ajax_get_focus_keyword_usage', 'ajax_get_keyword_usage' );
319
+
320
+ /**
321
+ * Retrieves the keyword for the keyword doubles of the termpages.
322
+ */
323
+ function ajax_get_term_keyword_usage() {
324
+ $post_id = filter_input( INPUT_POST, 'post_id' );
325
+ $keyword = filter_input( INPUT_POST, 'keyword' );
326
+ $taxonomy_name = filter_input( INPUT_POST, 'taxonomy' );
327
+
328
+ $taxonomy = get_taxonomy( $taxonomy_name );
329
+
330
+ if ( ! $taxonomy ) {
331
+ wp_die( 0 );
332
+ }
333
+
334
+ if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
335
+ wp_die( -1 );
336
+ }
337
+
338
+ $usage = WPSEO_Taxonomy_Meta::get_keyword_usage( $keyword, $post_id, $taxonomy_name );
339
+
340
+ // Normalize the result so it it the same as the post keyword usage AJAX request.
341
+ $usage = $usage[ $keyword ];
342
+
343
+ wp_die(
344
+ wp_json_encode( $usage )
345
+ );
346
+ }
347
+
348
+ add_action( 'wp_ajax_get_term_keyword_usage', 'ajax_get_term_keyword_usage' );
349
+
350
+ // Crawl Issue Manager AJAX hooks.
351
+ new WPSEO_GSC_Ajax();
352
+
353
+ // SEO Score Recalculations.
354
+ new WPSEO_Recalculate_Scores_Ajax();
355
+
356
+ new Yoast_OnPage_Ajax();
357
+
358
+ new WPSEO_Shortcode_Filter();
359
+
360
+ new WPSEO_Taxonomy_Columns();
361
+
362
+ // Setting the notice for the recalculate the posts.
363
+ new Yoast_Dismissable_Notice_Ajax( 'recalculate', Yoast_Dismissable_Notice_Ajax::FOR_SITE );
364
+
365
+ /********************** DEPRECATED METHODS **********************/
366
+
367
+
368
+ /**
369
+ * Removes stopword from the sample permalink that is generated in an AJAX request
370
+ *
371
+ * @deprecated 6.3
372
+ * @codeCoverageIgnore
373
+ */
374
+ function wpseo_remove_stopwords_sample_permalink() {
375
+ _deprecated_function( __FUNCTION__, 'WPSEO 6.3', 'This method is deprecated.' );
376
+
377
+ wpseo_ajax_json_echo_die( '' );
378
+ }
379
+
380
+ /**
381
+ * Function used to delete blocking files, dies on exit.
382
+ *
383
+ * @deprecated 7.0
384
+ * @codeCoverageIgnore
385
+ */
386
+ function wpseo_kill_blocking_files() {
387
+ _deprecated_function( __FUNCTION__, 'WPSEO 7.0', 'This method is deprecated.' );
388
+
389
+ wpseo_ajax_json_echo_die( '' );
390
+ }
admin/ajax/class-recalculate-scores-ajax.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\Admin|Ajax
4
+ */
5
+
6
+ /**
7
+ * Class WPSEO_Recalculate_Scores
8
+ *
9
+ * This class handles the SEO score recalculation for all posts with a filled focus keyword
10
+ */
11
+ class WPSEO_Recalculate_Scores_Ajax {
12
+
13
+ /**
14
+ * Initialize the AJAX hooks
15
+ */
16
+ public function __construct() {
17
+ add_action( 'wp_ajax_wpseo_recalculate_scores', array( $this, 'recalculate_scores' ) );
18
+ add_action( 'wp_ajax_wpseo_update_score', array( $this, 'save_score' ) );
19
+ add_action( 'wp_ajax_wpseo_recalculate_total', array( $this, 'get_total' ) );
20
+ }
21
+
22
+ /**
23
+ * Get the totals for the posts and the terms.
24
+ */
25
+ public function get_total() {
26
+ check_ajax_referer( 'wpseo_recalculate', 'nonce' );
27
+
28
+ wp_die(
29
+ wp_json_encode(
30
+ array(
31
+ 'posts' => $this->calculate_posts(),
32
+ 'terms' => $this->calculate_terms(),
33
+ )
34
+ )
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Start recalculation
40
+ */
41
+ public function recalculate_scores() {
42
+ check_ajax_referer( 'wpseo_recalculate', 'nonce' );
43
+
44
+ $fetch_object = $this->get_fetch_object();
45
+ if ( ! empty( $fetch_object ) ) {
46
+ $paged = filter_input( INPUT_POST, 'paged', FILTER_VALIDATE_INT );
47
+ $response = $fetch_object->get_items_to_recalculate( $paged );
48
+
49
+ if ( ! empty( $response ) ) {
50
+ wp_die( wp_json_encode( $response ) );
51
+ }
52
+ }
53
+
54
+ wp_die( '' );
55
+ }
56
+
57
+ /**
58
+ * Saves the new linkdex score for given post
59
+ */
60
+ public function save_score() {
61
+ check_ajax_referer( 'wpseo_recalculate', 'nonce' );
62
+
63
+ $fetch_object = $this->get_fetch_object();
64
+ if ( ! empty( $fetch_object ) ) {
65
+ $scores = filter_input( INPUT_POST, 'scores', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
66
+ $fetch_object->save_scores( $scores );
67
+ }
68
+
69
+ wp_die();
70
+ }
71
+
72
+ /**
73
+ * Returns the needed object for recalculating scores.
74
+ *
75
+ * @return WPSEO_Recalculate_Posts|WPSEO_Recalculate_Terms
76
+ */
77
+ private function get_fetch_object() {
78
+ switch ( filter_input( INPUT_POST, 'type' ) ) {
79
+ case 'post':
80
+ return new WPSEO_Recalculate_Posts();
81
+ case 'term':
82
+ return new WPSEO_Recalculate_Terms();
83
+ }
84
+
85
+ return null;
86
+ }
87
+
88
+ /**
89
+ * Gets the total number of posts
90
+ *
91
+ * @return int
92
+ */
93
+ private function calculate_posts() {
94
+ $count_posts_query = new WP_Query(
95
+ array(
96
+ 'post_type' => 'any',
97
+ 'meta_key' => '_yoast_wpseo_focuskw',
98
+ 'posts_per_page' => 1,
99
+ 'fields' => 'ids',
100
+ )
101
+ );
102
+
103
+ return $count_posts_query->found_posts;
104
+ }
105
+
106
+ /**
107
+ * Get the total number of terms
108
+ *
109
+ * @return int
110
+ */
111
+ private function calculate_terms() {
112
+ $total = 0;
113
+ foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) {
114
+ $total += wp_count_terms( $taxonomy->name, array( 'hide_empty' => false ) );
115
+ }
116
+
117
+ return $total;
118
+ }
119
+ }
admin/ajax/class-shortcode-filter.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\Admin|Ajax
4
+ */
5
+
6
+ /**
7
+ * Class WPSEO_Shortcode_Filter
8
+ *
9
+ * Used for parsing WP shortcodes with AJAX
10
+ */
11
+ class WPSEO_Shortcode_Filter {
12
+
13
+ /**
14
+ * Initialize the AJAX hooks
15
+ */
16
+ public function __construct() {
17
+ add_action( 'wp_ajax_wpseo_filter_shortcodes', array( $this, 'do_filter' ) );
18
+ }
19
+
20
+ /**
21
+ * Parse the shortcodes
22
+ */
23
+ public function do_filter() {
24
+ check_ajax_referer( 'wpseo-filter-shortcodes', 'nonce' );
25
+
26
+ $shortcodes = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
27
+
28
+ $parsed_shortcodes = array();
29
+
30
+ foreach ( $shortcodes as $shortcode ) {
31
+ $parsed_shortcodes[] = array(
32
+ 'shortcode' => $shortcode,
33
+ 'output' => do_shortcode( $shortcode ),
34
+ );
35
+ }
36
+
37
+ wp_die( wp_json_encode( $parsed_shortcodes ) );
38
+ }
39
+ }
admin/ajax/class-yoast-dismissable-notice.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\admin|ajax
4
+ */
5
+
6
+ /**
7
+ * This class will catch the request to dismiss the target notice (set by notice_name) and will store the dismiss status as an user meta
8
+ * in the database
9
+ */
10
+ class Yoast_Dismissable_Notice_Ajax {
11
+
12
+ /**
13
+ * @var string Notice type toggle value for user notices.
14
+ */
15
+ const FOR_USER = 'user_meta';
16
+
17
+ /**
18
+ * @var string Notice type toggle value for network notices.
19
+ */
20
+ const FOR_NETWORK = 'site_option';
21
+
22
+ /**
23
+ * @var string Notice type toggle value for site notices.
24
+ */
25
+ const FOR_SITE = 'option';
26
+
27
+
28
+ /**
29
+ * @var string Name of the notice that will be dismissed.
30
+ */
31
+ private $notice_name;
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ private $notice_type;
37
+
38
+ /**
39
+ * Initialize the hooks for the AJAX request
40
+ *
41
+ * @param string $notice_name The name for the hook to catch the notice.
42
+ * @param string $notice_type The notice type.
43
+ */
44
+ public function __construct( $notice_name, $notice_type = self::FOR_USER ) {
45
+ $this->notice_name = $notice_name;
46
+ $this->notice_type = $notice_type;
47
+
48
+ add_action( 'wp_ajax_wpseo_dismiss_' . $notice_name, array( $this, 'dismiss_notice' ) );
49
+ }
50
+
51
+ /**
52
+ * Handles the dismiss notice request
53
+ */
54
+ public function dismiss_notice() {
55
+ check_ajax_referer( 'wpseo-dismiss-' . $this->notice_name );
56
+
57
+ $this->save_dismissed();
58
+
59
+ wp_die( 'true' );
60
+ }
61
+
62
+ /**
63
+ * Storing the dismissed value in the database. The target location is based on the set notification type.
64
+ */
65
+ private function save_dismissed() {
66
+ if ( $this->notice_type === self::FOR_SITE ) {
67
+ update_option( 'wpseo_dismiss_' . $this->notice_name, 1 );
68
+
69
+ return;
70
+ }
71
+
72
+ if ( $this->notice_type === self::FOR_NETWORK ) {
73
+ update_site_option( 'wpseo_dismiss_' . $this->notice_name, 1 );
74
+
75
+ return;
76
+ }
77
+
78
+ update_user_meta( get_current_user_id(), 'wpseo_dismiss_' . $this->notice_name, 1 );
79
+ }
80
+ }
admin/ajax/class-yoast-onpage-ajax.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\admin|ajax
4
+ */
5
+
6
+ /**
7
+ * Class Yoast_OnPage_Ajax
8
+ *
9
+ * This class will catch the request to dismiss the Ryte notice and will store
10
+ * the dismiss status as an user meta in the database.
11
+ */
12
+ class Yoast_OnPage_Ajax {
13
+
14
+ /**
15
+ * Initialize the hooks for the AJAX request
16
+ */
17
+ public function __construct() {
18
+ add_action( 'wp_ajax_wpseo_dismiss_onpageorg', array( $this, 'dismiss_notice' ) );
19
+ }
20
+
21
+ /**
22
+ * Handles the dismiss notice request
23
+ */
24
+ public function dismiss_notice() {
25
+ check_ajax_referer( 'wpseo-dismiss-onpageorg' );
26
+
27
+ $this->save_dismissed();
28
+
29
+ wp_die( 'true' );
30
+ }
31
+
32
+ /**
33
+ * Storing the dismissed value as an user option in the database
34
+ */
35
+ private function save_dismissed() {
36
+ update_user_meta( get_current_user_id(), WPSEO_OnPage::USER_META_KEY, 1 );
37
+ }
38
+ }
admin/ajax/class-yoast-plugin-conflict-ajax.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\admin|ajax
4
+ */
5
+
6
+ /**
7
+ * Class Yoast_Plugin_Conflict_Ajax
8
+ */
9
+ class Yoast_Plugin_Conflict_Ajax {
10
+
11
+ /**
12
+ * @var string
13
+ */
14
+ private $option_name = 'wpseo_dismissed_conflicts';
15
+
16
+ /**
17
+ * @var array
18
+ */
19
+ private $dismissed_conflicts = array();
20
+
21
+ /**
22
+ * Initialize the hooks for the AJAX request
23
+ */
24
+ public function __construct() {
25
+ add_action( 'wp_ajax_wpseo_dismiss_plugin_conflict', array( $this, 'dismiss_notice' ) );
26
+ }
27
+
28
+ /**
29
+ * Handles the dismiss notice request
30
+ */
31
+ public function dismiss_notice() {
32
+ check_ajax_referer( 'dismiss-plugin-conflict' );
33
+
34
+ $conflict_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
35
+
36
+ $this->dismissed_conflicts = $this->get_dismissed_conflicts( $conflict_data['section'] );
37
+
38
+ $this->compare_plugins( $conflict_data['plugins'] );
39
+
40
+ $this->save_dismissed_conflicts( $conflict_data['section'] );
41
+
42
+ wp_die( 'true' );
43
+ }
44
+
45
+ /**
46
+ * Getting the user option from the database
47
+ *
48
+ * @return bool|array
49
+ */
50
+ private function get_dismissed_option() {
51
+ return get_user_meta( get_current_user_id(), $this->option_name, true );
52
+ }
53
+
54
+ /**
55
+ * Getting the dismissed conflicts from the database
56
+ *
57
+ * @param string $plugin_section Type of conflict group (such as Open Graph or sitemap).
58
+ *
59
+ * @return array
60
+ */
61
+ private function get_dismissed_conflicts( $plugin_section ) {
62
+ $dismissed_conflicts = $this->get_dismissed_option();
63
+
64
+ if ( is_array( $dismissed_conflicts ) && array_key_exists( $plugin_section, $dismissed_conflicts ) ) {
65
+ return $dismissed_conflicts[ $plugin_section ];
66
+ }
67
+
68
+ return array();
69
+ }
70
+
71
+ /**
72
+ * Storing the conflicting plugins as an user option in the database
73
+ *
74
+ * @param string $plugin_section Plugin conflict type (such as Open Graph or sitemap).
75
+ */
76
+ private function save_dismissed_conflicts( $plugin_section ) {
77
+ $dismissed_conflicts = $this->get_dismissed_option();
78
+
79
+ $dismissed_conflicts[ $plugin_section ] = $this->dismissed_conflicts;
80
+
81
+ update_user_meta( get_current_user_id(), $this->option_name, $dismissed_conflicts );
82
+ }
83
+
84
+ /**
85
+ * Loop through the plugins to compare them with the already stored dismissed plugin conflicts
86
+ *
87
+ * @param array $posted_plugins Plugin set to check.
88
+ */
89
+ public function compare_plugins( array $posted_plugins ) {
90
+ foreach ( $posted_plugins as $posted_plugin ) {
91
+ $this->compare_plugin( $posted_plugin );
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Check if plugin is already dismissed, if not store it in the array that will be saved later
97
+ *
98
+ * @param string $posted_plugin Plugin to check against dismissed conflicts.
99
+ */
100
+ private function compare_plugin( $posted_plugin ) {
101
+ if ( ! in_array( $posted_plugin, $this->dismissed_conflicts, true ) ) {
102
+ $this->dismissed_conflicts[] = $posted_plugin;
103
+ }
104
+ }
105
+ }
admin/banner/class-admin-banner-renderer.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\Admin\Banner
4
+ */
5
+
6
+ /**
7
+ * Represents the render object for generating the html for the given banner.
8
+ */
9
+ class WPSEO_Admin_Banner_Renderer {
10
+
11
+ /** @var string */
12
+ protected $base_path = '';
13
+
14
+ /**
15
+ * Renders the admin banner.
16
+ *
17
+ * @param WPSEO_Admin_Banner $banner The banner to render.
18
+ *
19
+ * @return string
20
+ */
21
+ public function render( WPSEO_Admin_Banner $banner ) {
22
+ $output = '<a class="wpseo-banner__link" target="_blank" href="' . esc_url( $banner->get_url() ) . '">';
23
+ $output .= '<img class="wpseo-banner__image" width="' . esc_attr( $banner->get_width() ) . '" height="' . esc_attr( $banner->get_height() ) . '" src="' . esc_attr( $this->get_image_path( $banner->get_image() ) ) . '" alt="' . esc_attr( $banner->get_alt() ) . '"/>';
24
+ $output .= '</a>';
25
+
26
+ return $output;
27
+ }
28
+
29
+ /**
30
+ * Sets the base path, where the images are located.
31
+ *
32
+ * @param string $base_path The image location.
33
+ */
34
+ public function set_base_path( $base_path ) {
35
+ $this->base_path = $base_path;
36
+ }
37
+
38
+ /**
39
+ * Returns the full path for the image.
40
+ *
41
+ * @param string $image The image path.
42
+ *
43
+ * @return string
44
+ */
45
+ protected function get_image_path( $image ) {
46
+ return rtrim( $this->base_path, '/' ) . '/' . ltrim( $image, '/' );
47
+ }
48
+ }
admin/banner/class-admin-banner-sidebar-renderer.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\Admin\Banner
4
+ */
5
+
6
+ /**
7
+ * Represents the render object for generating the html for the banner sidebar
8
+ */
9
+ class WPSEO_Admin_Banner_Sidebar_Renderer {
10
+
11
+ /** @var WPSEO_Admin_Banner_Spot_Renderer */
12
+ protected $spot_renderer;
13
+
14
+ /**
15
+ * Sets the spot renderer.
16
+ *
17
+ * @param WPSEO_Admin_Banner_Spot_Renderer $spot_renderer The spot renderer that has to be used.
18
+ */
19
+ public function __construct( WPSEO_Admin_Banner_Spot_Renderer $spot_renderer ) {
20
+ $this->spot_renderer = $spot_renderer;
21
+ }
22
+
23
+ /**
24
+ * Renders the admin banner sidebar.
25
+ *
26
+ * @param WPSEO_Admin_Banner_Sidebar $banner_sidebar The sidebar to render.
27
+ *
28
+ * @return string
29
+ */
30
+ public function render( WPSEO_Admin_Banner_Sidebar $banner_sidebar ) {
31
+ return sprintf( '
32
+ <div class="wpseo_content_cell" id="sidebar-container">
33
+ <div id="sidebar">
34
+ <div class="wpseo_content_cell_title yoast-sidebar__title ">
35
+ %1$s
36
+ </div>
37
+ %2$s
38
+ </div>
39
+ </div>',
40
+ $banner_sidebar->get_title(),
41
+ $this->render_banner_spots( $banner_sidebar->get_banner_spots() )
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Renders the admin banner spots.
47
+ *
48
+ * @param WPSEO_Admin_Banner_Spot[] $banner_spots The banner spots to render.
49
+ *
50
+ * @return string
51
+ */
52
+ protected function render_banner_spots( array $banner_spots ) {
53
+ $return = '';
54
+ foreach ( $banner_spots as $banner_spot ) {
55
+ $return .= $this->spot_renderer->render( $banner_spot );
56
+ }
57
+
58
+ return $return;
59
+ }
60
+ }
admin/banner/class-admin-banner-sidebar.php ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WPSEO\Admin\Banner
4
+ */
5
+
6
+ /**
7
+ * Represents the render object for generating the html for the given banner.
8
+ */
9
+ class WPSEO_Admin_Banner_Sidebar {
10
+
11
+ /** @var string */
12
+ protected $title = '';
13
+
14
+ /** @var WPSEO_Admin_Banner_Spot[] */
15
+ protected $banner_spots = array();
16
+
17
+ /** @var WPSEO_Admin_Banner_Renderer */
18
+ protected $banner_renderer;
19
+
20
+ /**
21
+ * WPSEO_Admin_Banner_Sidebar constructor.
22
+ *
23
+ * @param string $title The title for the sidebar.
24
+ * @param WPSEO_Admin_Banner_Renderer $banner_renderer The render class for banners.
25
+ */
26
+ public function __construct( $title, WPSEO_Admin_Banner_Renderer $banner_renderer ) {
27
+ $this->title = $title;
28
+ $this->banner_renderer = $banner_renderer;
29
+ }
30
+
31
+ /**
32
+ * Returns the set title.
33
+ *
34
+ * @return string
35
+ */
36
+ public function get_title() {
37
+ return $this->title;
38
+ }
39
+
40
+ /**
41
+ * Initializes the banner sidebar by setting its banner spots.
42
+ *
43
+ * @param WPSEO_Features $features Class regarding WPSEO Features.
44
+ */
45
+ public function initialize( WPSEO_Features $features ) {
46
+ if ( $features->is_free() ) {
47
+ $this->add_banner_spot( $this->get_premium_spot() );
48
+ }
49
+
50
+ $this->add_banner_spot( $this->get_services_spot() );
51
+
52
+ $extensions_spot = $this->get_extensions_spot( $this->get_active_extensions() );
53
+ if ( $extensions_spot->has_banners() ) {
54
+ $this->add_banner_spot( $extensions_spot );
55
+ }
56
+
57
+ $this->add_banner_spot( $this->get_courses_spot() );
58
+ $this->add_banner_spot( $this->get_remove_banner_spot() );
59
+ }
60
+
61
+ /**
62
+ * Returns array with bannerspots.
63
+ *
64
+ * @return WPSEO_Admin_Banner_Spot[]
65
+ */
66
+ public function get_banner_spots() {
67
+ return $this->banner_spots;
68
+ }
69
+
70
+ /**
71
+ * Adds a banner spot.
72
+ *
73
+ * @param WPSEO_Admin_Banner_Spot $spot The spot to add.
74
+ */
75
+ protected function add_banner_spot( WPSEO_Admin_Banner_Spot $spot ) {
76
+ $this->banner_spots[] = $spot;
77
+ }
78
+
79
+ /**
80
+ * Returns the premium banner spot.
81
+ *
82
+ * @return WPSEO_Admin_Banner_Spot
83
+ */