Merge lp:~jlosito/wordpress/wp-plugin-yoast into lp:~canonical-sysadmins/wordpress/wp-plugin-yoast

Proposed by John Losito on 2019-11-08
Status: Merged
Merged at revision: 2
Proposed branch: lp:~jlosito/wordpress/wp-plugin-yoast
Merge into: lp:~canonical-sysadmins/wordpress/wp-plugin-yoast
Diff against target: 91954 lines (+57701/-13249)
1027 files modified
admin/admin-settings-changed-listener.php (+85/-0)
admin/ajax.php (+61/-44)
admin/ajax/class-recalculate-scores-ajax.php (+11/-9)
admin/ajax/class-shortcode-filter.php (+6/-5)
admin/ajax/class-yoast-dismissable-notice.php (+18/-9)
admin/ajax/class-yoast-onpage-ajax.php (+4/-4)
admin/ajax/class-yoast-plugin-conflict-ajax.php (+11/-7)
admin/banner/class-admin-banner-renderer.php (+0/-50)
admin/banner/class-admin-banner-sidebar-renderer.php (+0/-62)
admin/banner/class-admin-banner-sidebar.php (+0/-358)
admin/banner/class-admin-banner-spot-renderer.php (+0/-39)
admin/banner/class-admin-banner-spot.php (+0/-120)
admin/banner/class-admin-banner.php (+0/-89)
admin/capabilities/class-abstract-capability-manager.php (+7/-2)
admin/capabilities/class-capability-manager-factory.php (+1/-0)
admin/capabilities/class-capability-manager-integration.php (+18/-14)
admin/capabilities/class-capability-manager-vip.php (+1/-0)
admin/capabilities/class-capability-manager-wp.php (+1/-0)
admin/capabilities/class-capability-manager.php (+1/-0)
admin/capabilities/class-capability-utils.php (+1/-0)
admin/capabilities/class-register-capabilities.php (+1/-0)
admin/class-add-keyword-modal.php (+12/-8)
admin/class-admin-asset-analysis-worker-location.php (+75/-0)
admin/class-admin-asset-dev-server-location.php (+11/-19)
admin/class-admin-asset-manager.php (+324/-89)
admin/class-admin-asset-seo-location.php (+2/-0)
admin/class-admin-asset-yoast-components-l10n.php (+9/-5)
admin/class-admin-banner.php (+67/-0)
admin/class-admin-editor-specific-replace-vars.php (+227/-0)
admin/class-admin-gutenberg-compatibility-notification.php (+93/-0)
admin/class-admin-help-panel.php (+8/-0)
admin/class-admin-init.php (+184/-158)
admin/class-admin-media-purge-notification.php (+4/-3)
admin/class-admin-recommended-replace-vars.php (+14/-12)
admin/class-admin-user-profile.php (+3/-2)
admin/class-admin-utils.php (+21/-9)
admin/class-admin.php (+74/-186)
admin/class-asset.php (+108/-10)
admin/class-bulk-description-editor-list-table.php (+6/-3)
admin/class-bulk-editor-list-table.php (+88/-99)
admin/class-bulk-title-editor-list-table.php (+8/-6)
admin/class-collector.php (+6/-2)
admin/class-config.php (+53/-47)
admin/class-cornerstone-field.php (+0/-57)
admin/class-cornerstone.php (+0/-94)
admin/class-customizer.php (+117/-143)
admin/class-database-proxy.php (+28/-8)
admin/class-export.php (+69/-181)
admin/class-expose-shortlinks.php (+101/-0)
admin/class-extension-manager.php (+16/-4)
admin/class-extension.php (+14/-2)
admin/class-extensions.php (+27/-23)
admin/class-gutenberg-compatibility.php (+107/-0)
admin/class-help-center-item.php (+21/-5)
admin/class-help-center.php (+22/-63)
admin/class-keyword-synonyms-modal.php (+68/-0)
admin/class-license-page-manager.php (+7/-3)
admin/class-meta-columns.php (+19/-11)
admin/class-meta-storage.php (+20/-4)
admin/class-meta-table-accessible.php (+12/-13)
admin/class-multiple-keywords-modal.php (+68/-0)
admin/class-my-yoast-proxy.php (+247/-0)
admin/class-my-yoast-route.php (+317/-0)
admin/class-option-tab.php (+16/-4)
admin/class-option-tabs-formatter.php (+8/-3)
admin/class-option-tabs.php (+25/-11)
admin/class-paper-presenter.php (+141/-0)
admin/class-plugin-availability.php (+11/-26)
admin/class-plugin-compatibility.php (+41/-2)
admin/class-plugin-conflict.php (+11/-5)
admin/class-premium-benefits-list.php (+0/-53)
admin/class-premium-popup.php (+12/-7)
admin/class-premium-upsell-admin-block.php (+36/-10)
admin/class-primary-term-admin.php (+96/-25)
admin/class-product-upsell-notice.php (+22/-19)
admin/class-recalculate-scores.php (+3/-3)
admin/class-remote-request.php (+33/-7)
admin/class-schema-person-upgrade-notification.php (+76/-0)
admin/class-social-admin.php (+94/-71)
admin/class-suggested-plugins.php (+10/-6)
admin/class-unsupported-php-message.php (+0/-70)
admin/class-yoast-alerts.php (+71/-24)
admin/class-yoast-columns.php (+1/-1)
admin/class-yoast-dashboard-widget.php (+26/-19)
admin/class-yoast-form.php (+290/-133)
admin/class-yoast-input-validation.php (+323/-0)
admin/class-yoast-modal.php (+0/-97)
admin/class-yoast-network-admin.php (+321/-0)
admin/class-yoast-network-settings-api.php (+164/-0)
admin/class-yoast-notification-center.php (+139/-49)
admin/class-yoast-notification.php (+46/-30)
admin/class-yoast-plugin-conflict.php (+18/-23)
admin/config-ui/class-configuration-components.php (+12/-5)
admin/config-ui/class-configuration-endpoint.php (+46/-24)
admin/config-ui/class-configuration-options-adapter.php (+55/-30)
admin/config-ui/class-configuration-page.php (+17/-29)
admin/config-ui/class-configuration-service.php (+42/-20)
admin/config-ui/class-configuration-storage.php (+22/-16)
admin/config-ui/class-configuration-structure.php (+67/-39)
admin/config-ui/class-configuration-translations.php (+12/-4)
admin/config-ui/components/class-component-configuration-choices.php (+0/-102)
admin/config-ui/components/class-component-connect-google-search-console.php (+22/-8)
admin/config-ui/components/class-component-mailchimp-signup.php (+7/-2)
admin/config-ui/components/class-component-suggestions.php (+39/-28)
admin/config-ui/components/interface-component.php (+9/-2)
admin/config-ui/factories/class-factory-post-type.php (+9/-3)
admin/config-ui/fields/class-field-choice-post-type.php (+10/-4)
admin/config-ui/fields/class-field-choice.php (+8/-8)
admin/config-ui/fields/class-field-company-info-missing.php (+28/-0)
admin/config-ui/fields/class-field-company-logo.php (+4/-2)
admin/config-ui/fields/class-field-company-name.php (+5/-2)
admin/config-ui/fields/class-field-company-or-person.php (+8/-7)
admin/config-ui/fields/class-field-configuration-choices.php (+0/-43)
admin/config-ui/fields/class-field-connect-google-search-console.php (+3/-2)
admin/config-ui/fields/class-field-environment.php (+4/-5)
admin/config-ui/fields/class-field-google-search-console-intro.php (+10/-16)
admin/config-ui/fields/class-field-mailchimp-signup.php (+3/-4)
admin/config-ui/fields/class-field-multiple-authors.php (+7/-6)
admin/config-ui/fields/class-field-person-name.php (+0/-30)
admin/config-ui/fields/class-field-person.php (+32/-0)
admin/config-ui/fields/class-field-post-type-visibility.php (+2/-4)
admin/config-ui/fields/class-field-profile-url-facebook.php (+4/-2)
admin/config-ui/fields/class-field-profile-url-googleplus.php (+0/-31)
admin/config-ui/fields/class-field-profile-url-instagram.php (+4/-2)
admin/config-ui/fields/class-field-profile-url-linkedin.php (+4/-2)
admin/config-ui/fields/class-field-profile-url-myspace.php (+4/-2)
admin/config-ui/fields/class-field-profile-url-pinterest.php (+4/-2)
admin/config-ui/fields/class-field-profile-url-twitter.php (+4/-2)
admin/config-ui/fields/class-field-profile-url-wikipedia.php (+35/-0)
admin/config-ui/fields/class-field-profile-url-youtube.php (+4/-2)
admin/config-ui/fields/class-field-separator.php (+16/-18)
admin/config-ui/fields/class-field-site-name.php (+3/-3)
admin/config-ui/fields/class-field-site-type.php (+2/-2)
admin/config-ui/fields/class-field-social-profiles-intro.php (+0/-33)
admin/config-ui/fields/class-field-success-message.php (+11/-10)
admin/config-ui/fields/class-field-suggestions.php (+7/-8)
admin/config-ui/fields/class-field-title-intro.php (+2/-6)
admin/config-ui/fields/class-field-upsell-configuration-service.php (+14/-8)
admin/config-ui/fields/class-field-upsell-site-review.php (+14/-9)
admin/config-ui/fields/class-field.php (+34/-13)
admin/endpoints/class-endpoint-file-size.php (+85/-0)
admin/endpoints/class-endpoint-indexable.php (+49/-15)
admin/endpoints/class-endpoint-ryte.php (+26/-11)
admin/endpoints/class-endpoint-statistics.php (+26/-11)
admin/exceptions/class-file-size-exception.php (+46/-0)
admin/filters/class-abstract-post-filter.php (+15/-8)
admin/filters/class-cornerstone-filter.php (+50/-5)
admin/formatter/class-metabox-formatter.php (+131/-74)
admin/formatter/class-post-metabox-formatter.php (+32/-10)
admin/formatter/class-term-metabox-formatter.php (+31/-15)
admin/formatter/interface-metabox-formatter.php (+1/-2)
admin/google_search_console/class-gsc-ajax.php (+6/-6)
admin/google_search_console/class-gsc-bulk-action.php (+7/-7)
admin/google_search_console/class-gsc-category-filters.php (+88/-26)
admin/google_search_console/class-gsc-config.php (+3/-1)
admin/google_search_console/class-gsc-count.php (+16/-10)
admin/google_search_console/class-gsc-issue.php (+12/-4)
admin/google_search_console/class-gsc-issues.php (+11/-8)
admin/google_search_console/class-gsc-mapper.php (+5/-5)
admin/google_search_console/class-gsc-marker.php (+19/-9)
admin/google_search_console/class-gsc-modal.php (+15/-3)
admin/google_search_console/class-gsc-platform-tabs.php (+8/-6)
admin/google_search_console/class-gsc-service.php (+14/-10)
admin/google_search_console/class-gsc-settings.php (+9/-9)
admin/google_search_console/class-gsc-table.php (+95/-54)
admin/google_search_console/class-gsc.php (+109/-56)
admin/google_search_console/views/gsc-display.php (+64/-10)
admin/google_search_console/views/gsc-redirect-nopremium.php (+2/-0)
admin/import/class-import-detector.php (+2/-1)
admin/import/class-import-plugin.php (+6/-1)
admin/import/class-import-settings.php (+65/-154)
admin/import/class-import-status.php (+2/-1)
admin/import/plugins/class-abstract-plugin-importer.php (+6/-2)
admin/import/plugins/class-import-aioseo.php (+1/-0)
admin/import/plugins/class-import-greg-high-performance-seo.php (+1/-0)
admin/import/plugins/class-import-headspace.php (+2/-1)
admin/import/plugins/class-import-jetpack.php (+2/-1)
admin/import/plugins/class-import-platinum-seo-pack.php (+1/-1)
admin/import/plugins/class-import-premium-seo-pack.php (+1/-1)
admin/import/plugins/class-import-rankmath.php (+174/-0)
admin/import/plugins/class-import-seo-framework.php (+1/-0)
admin/import/plugins/class-import-seopressor.php (+3/-2)
admin/import/plugins/class-import-smartcrawl.php (+1/-0)
admin/import/plugins/class-import-squirrly.php (+1/-0)
admin/import/plugins/class-import-ultimate-seo.php (+1/-0)
admin/import/plugins/class-import-woothemes-seo.php (+1/-1)
admin/import/plugins/class-import-wp-meta-seo.php (+1/-0)
admin/import/plugins/class-import-wpseo.php (+4/-3)
admin/import/plugins/class-importers.php (+5/-1)
admin/interface-collection.php (+0/-1)
admin/links/class-link-column-count.php (+8/-3)
admin/links/class-link-columns.php (+28/-9)
admin/links/class-link-compatibility-notifier.php (+20/-8)
admin/links/class-link-content-processor.php (+10/-2)
admin/links/class-link-extractor.php (+5/-1)
admin/links/class-link-factory.php (+19/-8)
admin/links/class-link-filter.php (+7/-3)
admin/links/class-link-installer.php (+5/-1)
admin/links/class-link-notifier.php (+13/-15)
admin/links/class-link-reindex-dashboard.php (+24/-41)
admin/links/class-link-reindex-post-endpoint.php (+27/-12)
admin/links/class-link-reindex-post-service.php (+1/-1)
admin/links/class-link-storage.php (+19/-3)
admin/links/class-link-table-accessible-notifier.php (+18/-6)
admin/links/class-link-table-accessible.php (+12/-13)
admin/links/class-link-type-classifier.php (+13/-5)
admin/links/class-link-utils.php (+0/-11)
admin/links/class-link-watcher.php (+19/-1)
admin/links/class-link.php (+26/-3)
admin/menu/class-admin-menu.php (+20/-157)
admin/menu/class-base-menu.php (+262/-0)
admin/menu/class-menu.php (+17/-4)
admin/menu/class-network-admin-menu.php (+47/-34)
admin/menu/class-replacevar-editor.php (+85/-40)
admin/menu/class-replacevar-field.php (+42/-21)
admin/metabox/class-abstract-sectioned-metabox-tab.php (+95/-0)
admin/metabox/class-metabox-add-keyword-tab.php (+0/-69)
admin/metabox/class-metabox-addon-section.php (+0/-39)
admin/metabox/class-metabox-analysis-readability.php (+1/-1)
admin/metabox/class-metabox-analysis-seo.php (+1/-1)
admin/metabox/class-metabox-collapsible.php (+84/-0)
admin/metabox/class-metabox-collapsibles-section.php (+63/-0)
admin/metabox/class-metabox-editor.php (+3/-2)
admin/metabox/class-metabox-form-tab.php (+16/-0)
admin/metabox/class-metabox-null-tab.php (+1/-0)
admin/metabox/class-metabox-section-additional.php (+99/-0)
admin/metabox/class-metabox-section-react.php (+118/-0)
admin/metabox/class-metabox-section-readability.php (+42/-0)
admin/metabox/class-metabox-tab-section.php (+0/-168)
admin/metabox/class-metabox.php (+386/-455)
admin/metabox/interface-metabox-analysis.php (+1/-1)
admin/notifiers/class-configuration-notifier.php (+25/-5)
admin/notifiers/class-post-type-archive-notification-handler.php (+190/-0)
admin/notifiers/dismissible-notification.php (+121/-0)
admin/notifiers/interface-notification-handler.php (+21/-0)
admin/onpage/class-onpage-option.php (+45/-12)
admin/onpage/class-onpage-request.php (+7/-4)
admin/onpage/class-onpage.php (+7/-3)
admin/onpage/class-ryte-service.php (+30/-20)
admin/pages/dashboard.php (+1/-1)
admin/pages/network.php (+9/-141)
admin/pages/social.php (+1/-1)
admin/pages/tools.php (+2/-2)
admin/recalculate/class-recalculate-posts.php (+4/-4)
admin/recalculate/class-recalculate-terms.php (+4/-4)
admin/recalculate/class-recalculate.php (+7/-6)
admin/roles/class-abstract-role-manager.php (+7/-2)
admin/roles/class-register-roles.php (+1/-0)
admin/roles/class-role-manager-factory.php (+1/-0)
admin/roles/class-role-manager-vip.php (+1/-0)
admin/roles/class-role-manager.php (+1/-0)
admin/services/class-file-size.php (+106/-0)
admin/services/class-indexable-post-provider.php (+184/-65)
admin/services/class-indexable-provider.php (+38/-0)
admin/services/class-indexable-term-provider.php (+129/-62)
admin/services/class-indexable.php (+57/-29)
admin/services/interface-indexable-provider.php (+13/-1)
admin/statistics/class-statistics-integration.php (+2/-1)
admin/statistics/class-statistics-service.php (+40/-15)
admin/taxonomy/class-taxonomy-columns.php (+10/-6)
admin/taxonomy/class-taxonomy-content-fields.php (+15/-28)
admin/taxonomy/class-taxonomy-fields-presenter.php (+33/-49)
admin/taxonomy/class-taxonomy-fields.php (+6/-6)
admin/taxonomy/class-taxonomy-metabox.php (+89/-221)
admin/taxonomy/class-taxonomy-settings-fields.php (+10/-5)
admin/taxonomy/class-taxonomy-social-fields.php (+36/-18)
admin/taxonomy/class-taxonomy.php (+61/-25)
admin/tracking/class-tracking-plugin-data.php (+7/-6)
admin/tracking/class-tracking-settings-data.php (+196/-0)
admin/tracking/class-tracking.php (+60/-20)
admin/views/class-view-utils.php (+22/-24)
admin/views/class-yoast-feature-toggle.php (+133/-0)
admin/views/class-yoast-feature-toggles.php (+192/-0)
admin/views/class-yoast-form-fieldset.php (+0/-170)
admin/views/class-yoast-input-select.php (+17/-7)
admin/views/form/fieldset.php (+8/-7)
admin/views/form/select.php (+7/-7)
admin/views/js-templates-primary-term.php (+18/-22)
admin/views/licenses.php (+205/-148)
admin/views/paper-collapsible.php (+80/-0)
admin/views/partial-alerts-errors.php (+15/-8)
admin/views/partial-alerts-template.php (+59/-16)
admin/views/partial-alerts-warnings.php (+14/-7)
admin/views/sidebar.php (+171/-0)
admin/views/tabs/dashboard/dashboard.php (+8/-2)
admin/views/tabs/dashboard/features.php (+11/-106)
admin/views/tabs/dashboard/site-analysis.php (+2/-4)
admin/views/tabs/dashboard/webmaster-tools.php (+4/-6)
admin/views/tabs/metas/archives.php (+42/-134)
admin/views/tabs/metas/archives/help.php (+32/-0)
admin/views/tabs/metas/breadcrumbs.php (+7/-104)
admin/views/tabs/metas/general.php (+10/-9)
admin/views/tabs/metas/general/force-rewrite-title.php (+0/-25)
admin/views/tabs/metas/general/homepage.php (+0/-49)
admin/views/tabs/metas/general/knowledge-graph.php (+0/-43)
admin/views/tabs/metas/general/title-separator.php (+0/-25)
admin/views/tabs/metas/media.php (+13/-32)
admin/views/tabs/metas/paper-content/author-archive-settings.php (+85/-0)
admin/views/tabs/metas/paper-content/breadcrumbs-content.php (+112/-0)
admin/views/tabs/metas/paper-content/date-archives-settings.php (+55/-0)
admin/views/tabs/metas/paper-content/general-content.php (+12/-0)
admin/views/tabs/metas/paper-content/general/force-rewrite-title.php (+25/-0)
admin/views/tabs/metas/paper-content/general/homepage.php (+58/-0)
admin/views/tabs/metas/paper-content/general/knowledge-graph.php (+74/-0)
admin/views/tabs/metas/paper-content/general/title-separator.php (+25/-0)
admin/views/tabs/metas/paper-content/media-content.php (+51/-0)
admin/views/tabs/metas/paper-content/post-type-content.php (+73/-0)
admin/views/tabs/metas/paper-content/post_type/post-type.php (+45/-0)
admin/views/tabs/metas/paper-content/post_type/woocommerce-shop-page.php (+24/-0)
admin/views/tabs/metas/paper-content/rss-content.php (+52/-0)
admin/views/tabs/metas/paper-content/special-pages.php (+27/-0)
admin/views/tabs/metas/paper-content/taxonomy-content.php (+63/-0)
admin/views/tabs/metas/post-types.php (+26/-98)
admin/views/tabs/metas/rss.php (+16/-58)
admin/views/tabs/metas/taxonomies.php (+34/-76)
admin/views/tabs/metas/taxonomies/category-url.php (+28/-0)
admin/views/tabs/network/features.php (+67/-0)
admin/views/tabs/network/general.php (+52/-0)
admin/views/tabs/network/restore-site.php (+32/-0)
admin/views/tabs/social/accounts.php (+78/-15)
admin/views/tabs/social/facebook.php (+3/-5)
admin/views/tabs/social/google.php (+0/-27)
admin/views/tabs/social/pinterest.php (+3/-5)
admin/views/tabs/social/twitterbox.php (+9/-5)
admin/views/tabs/tool/import-seo.php (+12/-7)
admin/views/tabs/tool/wpseo-export.php (+9/-6)
admin/views/tabs/tool/wpseo-import.php (+19/-15)
admin/views/tool-bulk-editor.php (+74/-17)
admin/views/tool-file-editor.php (+22/-13)
admin/views/tool-import-export.php (+12/-8)
admin/views/user-profile.php (+6/-2)
admin/watchers/class-slug-change-watcher.php (+73/-5)
config/composer/actions.php (+120/-0)
config/dependency-injection/container-compiler.php (+52/-0)
config/dependency-injection/custom-loader.php (+220/-0)
config/dependency-injection/loader-pass.php (+72/-0)
config/dependency-injection/services.php (+55/-0)
config/php-codeshift/remove-vendor-prefixing-array-key-visitor.php (+36/-0)
config/php-codeshift/remove-vendor-prefixing-codemod.php (+34/-0)
config/php-codeshift/remove-vendor-prefixing-comment-visitor.php (+35/-0)
config/php-codeshift/remove-vendor-prefixing-visitor.php (+35/-0)
config/php-scoper/dependency-injection.inc.php (+41/-0)
config/php-scoper/guzzlehttp.inc.php (+56/-0)
config/php-scoper/idiorm.inc.php (+37/-0)
config/php-scoper/oauth2-client.inc.php (+54/-0)
config/php-scoper/psr.inc.php (+32/-0)
config/php-scoper/ruckusing.inc.php (+145/-0)
css/dist/admin-global-1240-rtl.min.css (+1/-0)
css/dist/admin-global-1240.min.css (+1/-0)
css/dist/admin-global-773-rtl.min.css (+0/-1)
css/dist/admin-global-773.min.css (+0/-1)
css/dist/adminbar-1240-rtl.min.css (+1/-0)
css/dist/adminbar-1240.min.css (+1/-0)
css/dist/adminbar-773-rtl.min.css (+0/-1)
css/dist/adminbar-773.min.css (+0/-1)
css/dist/alerts-1240-rtl.min.css (+1/-0)
css/dist/alerts-1240.min.css (+1/-0)
css/dist/alerts-773-rtl.min.css (+0/-1)
css/dist/alerts-773.min.css (+0/-1)
css/dist/dashboard-1240-rtl.min.css (+1/-0)
css/dist/dashboard-1240.min.css (+1/-0)
css/dist/dashboard-773-rtl.min.css (+0/-1)
css/dist/dashboard-773.min.css (+0/-1)
css/dist/edit-page-1240-rtl.min.css (+1/-0)
css/dist/edit-page-1240.min.css (+1/-0)
css/dist/edit-page-773-rtl.min.css (+0/-1)
css/dist/edit-page-773.min.css (+0/-1)
css/dist/featured-image-1240-rtl.min.css (+1/-0)
css/dist/featured-image-1240.min.css (+1/-0)
css/dist/featured-image-773-rtl.min.css (+0/-1)
css/dist/featured-image-773.min.css (+0/-1)
css/dist/filter-explanation-1240-rtl.min.css (+1/-0)
css/dist/filter-explanation-1240.min.css (+1/-0)
css/dist/filter-explanation-773-rtl.min.css (+0/-1)
css/dist/filter-explanation-773.min.css (+0/-1)
css/dist/inside-editor-1240-rtl.min.css (+1/-0)
css/dist/inside-editor-1240.min.css (+1/-0)
css/dist/inside-editor-773-rtl.min.css (+0/-1)
css/dist/inside-editor-773.min.css (+0/-1)
css/dist/metabox-1240-rtl.min.css (+1/-0)
css/dist/metabox-1240.min.css (+5/-0)
css/dist/metabox-773-rtl.min.css (+0/-1)
css/dist/metabox-773.min.css (+0/-1)
css/dist/metabox-primary-category-1240-rtl.min.css (+1/-0)
css/dist/metabox-primary-category-1240.min.css (+1/-0)
css/dist/metabox-primary-category-773-rtl.min.css (+0/-1)
css/dist/metabox-primary-category-773.min.css (+0/-1)
css/dist/search-appearance-1240-rtl.min.css (+1/-0)
css/dist/search-appearance-1240.min.css (+1/-0)
css/dist/search-appearance-773-rtl.min.css (+0/-1)
css/dist/search-appearance-773.min.css (+0/-1)
css/dist/select2/select2-rtl.min.css (+1/-0)
css/dist/snippet-773-rtl.min.css (+0/-1)
css/dist/snippet-773.min.css (+0/-1)
css/dist/structured-data-blocks-1240-rtl.min.css (+1/-0)
css/dist/structured-data-blocks-1240.min.css (+1/-0)
css/dist/toggle-switch-1240-rtl.min.css (+1/-0)
css/dist/toggle-switch-1240.min.css (+1/-0)
css/dist/toggle-switch-773-rtl.min.css (+0/-1)
css/dist/toggle-switch-773.min.css (+0/-1)
css/dist/wpseo-dismissible-1240-rtl.min.css (+1/-0)
css/dist/wpseo-dismissible-1240.min.css (+1/-0)
css/dist/wpseo-dismissible-773-rtl.min.css (+0/-1)
css/dist/wpseo-dismissible-773.min.css (+0/-1)
css/dist/yoast-components-1240-rtl.min.css (+1/-0)
css/dist/yoast-components-1240.min.css (+1/-0)
css/dist/yoast-components-773-rtl.min.css (+0/-1)
css/dist/yoast-components-773.min.css (+0/-1)
css/dist/yoast-extensions-1240-rtl.min.css (+1/-0)
css/dist/yoast-extensions-1240.min.css (+1/-0)
css/dist/yoast-extensions-773-rtl.min.css (+0/-1)
css/dist/yoast-extensions-773.min.css (+0/-1)
css/dist/yst_plugin_tools-1240-rtl.min.css (+1/-0)
css/dist/yst_plugin_tools-1240.min.css (+1/-0)
css/dist/yst_plugin_tools-773-rtl.min.css (+0/-1)
css/dist/yst_plugin_tools-773.min.css (+0/-1)
css/dist/yst_seo_score-1240-rtl.min.css (+1/-0)
css/dist/yst_seo_score-1240.min.css (+1/-0)
css/dist/yst_seo_score-773-rtl.min.css (+0/-1)
css/dist/yst_seo_score-773.min.css (+0/-1)
deprecated/admin/class-metabox-tab-section.php (+170/-0)
deprecated/admin/config-ui/fields/class-field-profile-url-googleplus.php (+38/-0)
deprecated/class-cornerstone.php (+61/-0)
deprecated/class-metabox-addon-section.php (+69/-0)
deprecated/class-recalibration-beta-notification.php (+52/-0)
deprecated/class-recalibration-beta.php (+248/-0)
deprecated/class-wpseo-option-internallinks.php (+3/-1)
deprecated/class-wpseo-option-permalinks.php (+7/-5)
deprecated/class-yoast-form-fieldset.php (+235/-0)
deprecated/class-yoast-modal.php (+81/-0)
frontend/class-breadcrumbs.php (+195/-75)
frontend/class-frontend-page-type.php (+31/-4)
frontend/class-frontend.php (+220/-148)
frontend/class-handle-404.php (+92/-0)
frontend/class-json-ld.php (+0/-300)
frontend/class-opengraph-image.php (+169/-67)
frontend/class-opengraph-oembed.php (+72/-0)
frontend/class-opengraph.php (+56/-66)
frontend/class-remove-reply-to-com.php (+6/-3)
frontend/class-twitter.php (+112/-94)
frontend/class-woocommerce-shop-page.php (+43/-11)
frontend/schema/class-schema-article.php (+179/-0)
frontend/schema/class-schema-author.php (+145/-0)
frontend/schema/class-schema-breadcrumb.php (+153/-0)
frontend/schema/class-schema-context.php (+234/-0)
frontend/schema/class-schema-faq-question-list.php (+115/-0)
frontend/schema/class-schema-faq-questions.php (+91/-0)
frontend/schema/class-schema-faq.php (+111/-0)
frontend/schema/class-schema-howto.php (+243/-0)
frontend/schema/class-schema-ids.php (+68/-0)
frontend/schema/class-schema-image.php (+154/-0)
frontend/schema/class-schema-main-image.php (+146/-0)
frontend/schema/class-schema-organization.php (+114/-0)
frontend/schema/class-schema-person.php (+262/-0)
frontend/schema/class-schema-utils.php (+31/-0)
frontend/schema/class-schema-webpage.php (+164/-0)
frontend/schema/class-schema-website.php (+114/-0)
frontend/schema/class-schema.php (+195/-0)
frontend/schema/interface-wpseo-graph-piece.php (+30/-0)
images/Local_SEO_Icon.svg (+1/-0)
images/News_SEO_Icon.svg (+1/-0)
images/SEO_for_beginners.svg (+1/-0)
images/Video_SEO_Icon.svg (+1/-0)
images/Woo_SEO_Icon.svg (+1/-0)
images/Yoast_SEO_Icon.svg (+1/-1)
images/Yoast_SEO_negative_icon.svg (+1/-1)
images/Yoast_icon_kader.svg (+1/-0)
images/all-round-SEO.svg (+1/-0)
images/brushstroke_background.svg (+1/-0)
images/crosshair.svg (+1/-0)
images/error-icon.svg (+1/-0)
images/link-in-icon.svg (+1/-1)
images/link-out-icon.svg (+1/-1)
images/local_assistant.svg (+1/-0)
images/new-to-configuration-notice.svg (+1/-1)
images/readability-icon.svg (+1/-1)
images/support-team.svg (+1/-1)
images/yoast-configuration-icon.svg (+0/-1)
images/yoast_seo_for_wp_2.svg (+1/-1)
inc/class-addon-manager.php (+518/-0)
inc/class-my-yoast-api-request.php (+363/-0)
inc/class-post-type.php (+27/-1)
inc/class-rewrite.php (+94/-18)
inc/class-structured-data-blocks.php (+81/-0)
inc/class-upgrade-history.php (+133/-0)
inc/class-upgrade.php (+163/-24)
inc/class-wpseo-admin-bar-menu.php (+676/-0)
inc/class-wpseo-content-images.php (+39/-26)
inc/class-wpseo-custom-fields.php (+69/-0)
inc/class-wpseo-custom-taxonomies.php (+72/-0)
inc/class-wpseo-endpoint-factory.php (+187/-0)
inc/class-wpseo-image-utils.php (+113/-18)
inc/class-wpseo-meta.php (+232/-292)
inc/class-wpseo-primary-term.php (+8/-4)
inc/class-wpseo-rank.php (+94/-23)
inc/class-wpseo-replace-vars.php (+157/-82)
inc/class-wpseo-replacement-variable.php (+10/-5)
inc/class-wpseo-shortlinker.php (+69/-36)
inc/class-wpseo-statistics.php (+4/-4)
inc/class-wpseo-utils.php (+436/-112)
inc/class-wpseo-validator.php (+72/-0)
inc/endpoints/class-myyoast-connect.php (+140/-0)
inc/exceptions/class-invalid-argument-exception.php (+153/-0)
inc/exceptions/class-invalid-indexable-exception.php (+46/-0)
inc/exceptions/class-myyoast-authentication-exception.php (+13/-0)
inc/exceptions/class-myyoast-bad-request-exception.php (+13/-0)
inc/exceptions/class-myyoast-invalid-json-exception.php (+13/-0)
inc/exceptions/class-rest-request-exception.php (+31/-0)
inc/health-check.php (+195/-0)
inc/indexables/class-indexable.php (+130/-0)
inc/indexables/class-object-type.php (+113/-0)
inc/indexables/class-post-indexable.php (+103/-0)
inc/indexables/class-post-object-type.php (+31/-0)
inc/indexables/class-term-indexable.php (+126/-0)
inc/indexables/class-term-object-type.php (+31/-0)
inc/indexables/validators/class-endpoint-validator.php (+21/-0)
inc/indexables/validators/class-keyword-validator.php (+29/-0)
inc/indexables/validators/class-link-validator.php (+29/-0)
inc/indexables/validators/class-meta-values-validator.php (+51/-0)
inc/indexables/validators/class-object-type-validator.php (+66/-0)
inc/indexables/validators/class-opengraph-validator.php (+35/-0)
inc/indexables/validators/class-robots-validator.php (+46/-0)
inc/indexables/validators/class-twitter-validator.php (+35/-0)
inc/interface-wpseo-wordpress-ajax-integration.php (+19/-0)
inc/interface-wpseo-wordpress-integration.php (+4/-2)
inc/language-utils.php (+19/-2)
inc/options/class-wpseo-option-ms.php (+65/-49)
inc/options/class-wpseo-option-social.php (+76/-49)
inc/options/class-wpseo-option-titles.php (+238/-151)
inc/options/class-wpseo-option-wpseo.php (+187/-19)
inc/options/class-wpseo-option.php (+300/-117)
inc/options/class-wpseo-options-backfill.php (+6/-1)
inc/options/class-wpseo-options.php (+55/-50)
inc/options/class-wpseo-taxonomy-meta.php (+106/-68)
inc/sitemaps/class-author-sitemap-provider.php (+23/-8)
inc/sitemaps/class-post-type-sitemap-provider.php (+238/-172)
inc/sitemaps/class-sitemap-cache-data.php (+24/-13)
inc/sitemaps/class-sitemap-image-parser.php (+35/-13)
inc/sitemaps/class-sitemap-timezone.php (+12/-10)
inc/sitemaps/class-sitemaps-admin.php (+14/-13)
inc/sitemaps/class-sitemaps-cache-validator.php (+31/-18)
inc/sitemaps/class-sitemaps-cache.php (+38/-13)
inc/sitemaps/class-sitemaps-renderer.php (+70/-33)
inc/sitemaps/class-sitemaps-router.php (+46/-19)
inc/sitemaps/class-sitemaps.php (+146/-48)
inc/sitemaps/class-taxonomy-sitemap-provider.php (+95/-29)
inc/sitemaps/interface-sitemap-cache-data.php (+22/-8)
inc/sitemaps/interface-sitemap-provider.php (+1/-1)
inc/wpseo-functions-deprecated.php (+2/-24)
inc/wpseo-functions.php (+30/-20)
inc/wpseo-non-ajax-functions.php (+99/-309)
js/dist/analysis-1240.min.js (+21/-0)
js/dist/babel-polyfill-1240.min.js (+1/-0)
js/dist/commons-1240.min.js (+1/-0)
js/dist/commons-773.min.js (+0/-42)
js/dist/components-1240.min.js (+88/-0)
js/dist/configuration-wizard-1240.min.js (+5/-0)
js/dist/configuration-wizard-773.min.js (+0/-27)
js/dist/search-appearance-1240.min.js (+1/-0)
js/dist/search-appearance-773.min.js (+0/-27)
js/dist/styled-components-1240.min.js (+9/-0)
js/dist/wp-apiFetch-1240.min.js (+1/-0)
js/dist/wp-components-1240.min.js (+19/-0)
js/dist/wp-compose-1240.min.js (+1/-0)
js/dist/wp-data-1240.min.js (+1/-0)
js/dist/wp-element-1240.min.js (+1/-0)
js/dist/wp-i18n-1240.min.js (+1/-0)
js/dist/wp-richText-1240.min.js (+1/-0)
js/dist/wp-seo-admin-1240.min.js (+1/-0)
js/dist/wp-seo-admin-773.min.js (+0/-1)
js/dist/wp-seo-admin-global-1240.min.js (+1/-0)
js/dist/wp-seo-admin-global-773.min.js (+0/-1)
js/dist/wp-seo-admin-gsc-1240.min.js (+1/-0)
js/dist/wp-seo-admin-gsc-773.min.js (+0/-1)
js/dist/wp-seo-admin-media-1240.min.js (+1/-0)
js/dist/wp-seo-admin-media-773.min.js (+0/-1)
js/dist/wp-seo-analysis-worker-1240.min.js (+1/-0)
js/dist/wp-seo-api-1240.min.js (+1/-0)
js/dist/wp-seo-api-773.min.js (+0/-1)
js/dist/wp-seo-babel-polyfill-773.min.js (+0/-5)
js/dist/wp-seo-bulk-editor-1240.min.js (+1/-0)
js/dist/wp-seo-bulk-editor-773.min.js (+0/-1)
js/dist/wp-seo-dashboard-widget-1240.min.js (+1/-0)
js/dist/wp-seo-dashboard-widget-773.min.js (+0/-7)
js/dist/wp-seo-dismissible-773.min.js (+0/-1)
js/dist/wp-seo-edit-page-1240.min.js (+1/-0)
js/dist/wp-seo-edit-page-773.min.js (+0/-1)
js/dist/wp-seo-featured-image-1240.min.js (+1/-0)
js/dist/wp-seo-featured-image-773.min.js (+0/-1)
js/dist/wp-seo-filter-explanation-1240.min.js (+1/-0)
js/dist/wp-seo-filter-explanation-773.min.js (+0/-1)
js/dist/wp-seo-help-center-1240.min.js (+1/-0)
js/dist/wp-seo-help-center-773.min.js (+0/-19)
js/dist/wp-seo-metabox-1240.min.js (+1/-0)
js/dist/wp-seo-metabox-773.min.js (+0/-1)
js/dist/wp-seo-metabox-category-1240.min.js (+1/-0)
js/dist/wp-seo-metabox-category-773.min.js (+0/-1)
js/dist/wp-seo-modal-1240.min.js (+1/-0)
js/dist/wp-seo-modal-773.min.js (+0/-23)
js/dist/wp-seo-network-admin-1240.min.js (+1/-0)
js/dist/wp-seo-post-scraper-1240.min.js (+5/-0)
js/dist/wp-seo-post-scraper-773.min.js (+0/-33)
js/dist/wp-seo-quick-edit-handler-1240.min.js (+1/-0)
js/dist/wp-seo-quick-edit-handler-773.min.js (+0/-1)
js/dist/wp-seo-recalculate-1240.min.js (+5/-0)
js/dist/wp-seo-recalculate-773.min.js (+0/-43)
js/dist/wp-seo-reindex-links-1240.min.js (+1/-0)
js/dist/wp-seo-reindex-links-773.min.js (+0/-1)
js/dist/wp-seo-replacevar-plugin-1240.min.js (+1/-0)
js/dist/wp-seo-replacevar-plugin-773.min.js (+0/-1)
js/dist/wp-seo-shortcode-plugin-1240.min.js (+1/-0)
js/dist/wp-seo-shortcode-plugin-773.min.js (+0/-1)
js/dist/wp-seo-structured-data-blocks-1240.min.js (+1/-0)
js/dist/wp-seo-term-scraper-1240.min.js (+1/-0)
js/dist/wp-seo-term-scraper-773.min.js (+0/-33)
js/dist/wp-seo-used-keywords-assessment-1240.min.js (+1/-0)
js/dist/wp-seo-wp-globals-backport-773.min.js (+0/-1)
js/vendor/lodash-noconflict.js (+1/-0)
js/vendor/lodash.min.js (+137/-0)
js/vendor/react-dom.min.js (+220/-0)
js/vendor/react.min.js (+33/-0)
languages/index.php (+0/-4)
languages/wordpress-seo-bg_BG.json (+1/-1)
languages/wordpress-seo-bs_BA.json (+1/-0)
languages/wordpress-seo-ca.json (+1/-1)
languages/wordpress-seo-cs_CZ.json (+1/-1)
languages/wordpress-seo-da_DK.json (+1/-1)
languages/wordpress-seo-de_CH.json (+1/-1)
languages/wordpress-seo-de_DE.json (+1/-1)
languages/wordpress-seo-el.json (+1/-1)
languages/wordpress-seo-en_AU.json (+1/-1)
languages/wordpress-seo-en_CA.json (+1/-1)
languages/wordpress-seo-en_GB.json (+1/-1)
languages/wordpress-seo-en_NZ.json (+1/-1)
languages/wordpress-seo-en_ZA.json (+1/-0)
languages/wordpress-seo-es_AR.json (+1/-1)
languages/wordpress-seo-es_ES.json (+1/-1)
languages/wordpress-seo-es_MX.json (+1/-0)
languages/wordpress-seo-es_PE.json (+1/-0)
languages/wordpress-seo-es_VE.json (+1/-1)
languages/wordpress-seo-fa_IR.json (+1/-1)
languages/wordpress-seo-fi.json (+0/-1)
languages/wordpress-seo-fr_CA.json (+1/-1)
languages/wordpress-seo-fr_FR.json (+1/-1)
languages/wordpress-seo-gl_ES.json (+1/-1)
languages/wordpress-seo-he_IL.json (+1/-1)
languages/wordpress-seo-hr.json (+1/-1)
languages/wordpress-seo-hu_HU.json (+1/-1)
languages/wordpress-seo-it_IT.json (+1/-1)
languages/wordpress-seo-ja.json (+1/-1)
languages/wordpress-seo-nb_NO.json (+1/-1)
languages/wordpress-seo-nl_BE.json (+1/-1)
languages/wordpress-seo-nl_NL.json (+1/-1)
languages/wordpress-seo-pl_PL.json (+1/-1)
languages/wordpress-seo-pt_AO.json (+1/-0)
languages/wordpress-seo-pt_BR.json (+1/-1)
languages/wordpress-seo-pt_PT.json (+1/-1)
languages/wordpress-seo-ro_RO.json (+1/-1)
languages/wordpress-seo-ru_RU.json (+1/-1)
languages/wordpress-seo-sk_SK.json (+1/-1)
languages/wordpress-seo-sr_RS.json (+1/-1)
languages/wordpress-seo-sv_SE.json (+1/-1)
languages/wordpress-seo-tr_TR.json (+1/-1)
languages/wordpress-seo-uk.json (+1/-0)
languages/wordpress-seo-vi.json (+1/-1)
languages/wordpress-seo-zh_CN.json (+1/-1)
languages/wordpress-seo-zh_HK.json (+0/-1)
languages/wordpress-seo-zh_TW.json (+1/-1)
languages/wordpress-seojs-bg_BG.json (+1/-1)
languages/wordpress-seojs-bs_BA.json (+1/-0)
languages/wordpress-seojs-ca.json (+1/-1)
languages/wordpress-seojs-cs_CZ.json (+1/-1)
languages/wordpress-seojs-da_DK.json (+1/-1)
languages/wordpress-seojs-de_CH.json (+1/-1)
languages/wordpress-seojs-de_DE.json (+1/-1)
languages/wordpress-seojs-el.json (+1/-1)
languages/wordpress-seojs-en_AU.json (+1/-1)
languages/wordpress-seojs-en_CA.json (+1/-1)
languages/wordpress-seojs-en_GB.json (+1/-1)
languages/wordpress-seojs-en_NZ.json (+1/-1)
languages/wordpress-seojs-en_ZA.json (+1/-0)
languages/wordpress-seojs-es_AR.json (+1/-1)
languages/wordpress-seojs-es_ES.json (+1/-1)
languages/wordpress-seojs-es_MX.json (+1/-0)
languages/wordpress-seojs-es_PE.json (+1/-0)
languages/wordpress-seojs-es_VE.json (+1/-1)
languages/wordpress-seojs-fa_IR.json (+1/-1)
languages/wordpress-seojs-fi.json (+0/-1)
languages/wordpress-seojs-fr_CA.json (+1/-1)
languages/wordpress-seojs-fr_FR.json (+1/-1)
languages/wordpress-seojs-gl_ES.json (+1/-1)
languages/wordpress-seojs-he_IL.json (+1/-1)
languages/wordpress-seojs-hr.json (+1/-1)
languages/wordpress-seojs-hu_HU.json (+1/-1)
languages/wordpress-seojs-it_IT.json (+1/-1)
languages/wordpress-seojs-ja.json (+1/-1)
languages/wordpress-seojs-nb_NO.json (+1/-1)
languages/wordpress-seojs-nl_BE.json (+1/-1)
languages/wordpress-seojs-nl_NL.json (+1/-1)
languages/wordpress-seojs-pl_PL.json (+1/-1)
languages/wordpress-seojs-pt_AO.json (+1/-0)
languages/wordpress-seojs-pt_BR.json (+1/-1)
languages/wordpress-seojs-pt_PT.json (+1/-1)
languages/wordpress-seojs-ro_RO.json (+1/-1)
languages/wordpress-seojs-ru_RU.json (+1/-1)
languages/wordpress-seojs-sk_SK.json (+1/-1)
languages/wordpress-seojs-sr_RS.json (+1/-1)
languages/wordpress-seojs-sv_SE.json (+1/-1)
languages/wordpress-seojs-tr_TR.json (+1/-1)
languages/wordpress-seojs-uk.json (+1/-0)
languages/wordpress-seojs-vi.json (+1/-1)
languages/wordpress-seojs-zh_CN.json (+1/-1)
languages/wordpress-seojs-zh_HK.json (+0/-1)
languages/wordpress-seojs-zh_TW.json (+1/-1)
languages/wordpress-seojs.json (+1/-1)
languages/wordpress-seojs.php (+306/-8)
languages/yoast-components-bg_BG.json (+1/-1)
languages/yoast-components-bs_BA.json (+1/-0)
languages/yoast-components-ca.json (+1/-1)
languages/yoast-components-cs_CZ.json (+1/-1)
languages/yoast-components-da_DK.json (+1/-1)
languages/yoast-components-de_CH.json (+1/-1)
languages/yoast-components-de_DE.json (+1/-1)
languages/yoast-components-el.json (+1/-1)
languages/yoast-components-en_AU.json (+1/-1)
languages/yoast-components-en_CA.json (+1/-1)
languages/yoast-components-en_GB.json (+1/-1)
languages/yoast-components-en_NZ.json (+1/-1)
languages/yoast-components-en_ZA.json (+1/-0)
languages/yoast-components-es_AR.json (+1/-1)
languages/yoast-components-es_ES.json (+1/-1)
languages/yoast-components-es_MX.json (+1/-0)
languages/yoast-components-es_PE.json (+1/-0)
languages/yoast-components-es_VE.json (+1/-1)
languages/yoast-components-fa_IR.json (+1/-1)
languages/yoast-components-fi.json (+0/-1)
languages/yoast-components-fr_CA.json (+1/-1)
languages/yoast-components-fr_FR.json (+1/-1)
languages/yoast-components-gl_ES.json (+1/-1)
languages/yoast-components-he_IL.json (+1/-1)
languages/yoast-components-hr.json (+1/-1)
languages/yoast-components-hu_HU.json (+1/-1)
languages/yoast-components-it_IT.json (+1/-1)
languages/yoast-components-ja.json (+1/-1)
languages/yoast-components-nb_NO.json (+1/-1)
languages/yoast-components-nl_BE.json (+1/-1)
languages/yoast-components-nl_NL.json (+1/-1)
languages/yoast-components-pl_PL.json (+1/-1)
languages/yoast-components-pt_AO.json (+1/-0)
languages/yoast-components-pt_BR.json (+1/-1)
languages/yoast-components-pt_PT.json (+1/-1)
languages/yoast-components-ro_RO.json (+1/-1)
languages/yoast-components-ru_RU.json (+1/-1)
languages/yoast-components-sk_SK.json (+1/-1)
languages/yoast-components-sr_RS.json (+1/-1)
languages/yoast-components-sv_SE.json (+1/-1)
languages/yoast-components-tr_TR.json (+1/-1)
languages/yoast-components-uk.json (+1/-0)
languages/yoast-components-vi.json (+1/-1)
languages/yoast-components-zh_CN.json (+1/-1)
languages/yoast-components-zh_HK.json (+0/-1)
languages/yoast-components-zh_TW.json (+1/-1)
languages/yoast-components.php (+219/-142)
languages/yoast-seo-js.json (+1/-1)
languages/yoast-seo-js.php (+455/-325)
migrations/20171228151840_WpYoastIndexable.php (+155/-0)
migrations/20171228151841_WpYoastPrimaryTerm.php (+96/-0)
migrations/20190529075038_WpYoastDropIndexableMetaTableIfExists.php (+41/-0)
migrations/20190529075734_WpYoastExpandIndexable.php (+86/-0)
migrations/ruckusing/lib/Ruckusing/Adapter/why (+7/-0)
migrations/ruckusing/lib/Task/why (+7/-0)
readme.txt (+204/-156)
src/builders/indexable-author-builder.php (+77/-0)
src/builders/indexable-post-builder.php (+179/-0)
src/builders/indexable-term-builder.php (+129/-0)
src/conditionals/admin-conditional.php (+21/-0)
src/conditionals/conditional.php (+23/-0)
src/conditionals/feature-flag-conditional.php (+31/-0)
src/conditionals/indexables-feature-flag-conditional.php (+21/-0)
src/conditionals/no-conditionals.php (+23/-0)
src/config/dependency-management.php (+32/-0)
src/database/database-setup.php (+47/-0)
src/database/migration-runner.php (+187/-0)
src/database/ruckusing-framework.php (+139/-0)
src/exceptions/missing-method.php (+33/-0)
src/generated/container.php (+323/-0)
src/loader.php (+126/-0)
src/loaders/oauth.php (+34/-0)
src/loggers/logger.php (+53/-0)
src/loggers/migration-logger.php (+55/-0)
src/main.php (+38/-0)
src/models/indexable-extension.php (+34/-0)
src/models/indexable.php (+100/-0)
src/models/primary-term.php (+31/-0)
src/models/seo-links.php (+22/-0)
src/models/seo-meta.php (+27/-0)
src/oauth/client.php (+266/-0)
src/orm/yoast-model.php (+709/-0)
src/orm/yoast-orm-wrapper.php (+159/-0)
src/repositories/indexable-repository.php (+182/-0)
src/repositories/primary-term-repository.php (+52/-0)
src/repositories/seo-links-repository.php (+33/-0)
src/repositories/seo-meta-repository.php (+42/-0)
src/watchers/indexable-author-watcher.php (+88/-0)
src/watchers/indexable-post-watcher.php (+111/-0)
src/watchers/indexable-term-watcher.php (+92/-0)
src/watchers/primary-term-watcher.php (+201/-0)
src/wordpress/initializer.php (+21/-0)
src/wordpress/integration.php (+23/-0)
src/wordpress/loadable.php (+21/-0)
src/wordpress/wrapper.php (+37/-0)
vendor/autoload.php (+1/-1)
vendor/autoload_52.php (+1/-1)
vendor/composer/ClassLoader.php (+2/-2)
vendor/composer/autoload_classmap.php (+302/-49)
vendor/composer/autoload_files.php (+0/-10)
vendor/composer/autoload_real.php (+4/-22)
vendor/composer/autoload_real_52.php (+3/-5)
vendor/composer/autoload_static.php (+307/-58)
vendor/yoast/i18n-module/CHANGELOG.md (+10/-0)
vendor/yoast/i18n-module/src/i18n-module-wordpressorg.php (+0/-86)
vendor/yoast/i18n-module/src/i18n-module.php (+0/-388)
vendor/yoast/i18n-module/src/i18n-v3.php (+418/-0)
vendor/yoast/i18n-module/src/i18n-wordpressorg-v3.php (+93/-0)
vendor/yoast/whip/CHANGELOG.md (+0/-34)
vendor/yoast/whip/LICENSE (+0/-21)
vendor/yoast/whip/phpunit.xml (+0/-13)
vendor/yoast/whip/src/Whip_Configuration.php (+0/-54)
vendor/yoast/whip/src/Whip_Host.php (+0/-88)
vendor/yoast/whip/src/Whip_MessageDismisser.php (+0/-45)
vendor/yoast/whip/src/Whip_MessageFormatter.php (+0/-37)
vendor/yoast/whip/src/Whip_MessagesManager.php (+0/-83)
vendor/yoast/whip/src/Whip_RequirementsChecker.php (+0/-148)
vendor/yoast/whip/src/Whip_VersionRequirement.php (+0/-133)
vendor/yoast/whip/src/Whip_WPDismissOption.php (+0/-36)
vendor/yoast/whip/src/Whip_WPMessageDismissListener.php (+0/-51)
vendor/yoast/whip/src/configs/default.php (+0/-5)
vendor/yoast/whip/src/configs/version.php (+0/-3)
vendor/yoast/whip/src/exceptions/Whip_EmptyProperty.php (+0/-10)
vendor/yoast/whip/src/exceptions/Whip_InvalidOperatorType.php (+0/-22)
vendor/yoast/whip/src/exceptions/Whip_InvalidType.php (+0/-18)
vendor/yoast/whip/src/exceptions/Whip_InvalidVersionComparisonString.php (+0/-19)
vendor/yoast/whip/src/facades/wordpress.php (+0/-36)
vendor/yoast/whip/src/interfaces/Whip_DismissStorage.php (+0/-24)
vendor/yoast/whip/src/interfaces/Whip_Listener.php (+0/-15)
vendor/yoast/whip/src/interfaces/Whip_Message.php (+0/-8)
vendor/yoast/whip/src/interfaces/Whip_MessagePresenter.php (+0/-10)
vendor/yoast/whip/src/interfaces/Whip_Requirement.php (+0/-8)
vendor/yoast/whip/src/interfaces/Whip_VersionDetector.php (+0/-21)
vendor/yoast/whip/src/messages/Whip_BasicMessage.php (+0/-42)
vendor/yoast/whip/src/messages/Whip_HostMessage.php (+0/-56)
vendor/yoast/whip/src/messages/Whip_InvalidVersionRequirementMessage.php (+0/-37)
vendor/yoast/whip/src/messages/Whip_NullMessage.php (+0/-13)
vendor/yoast/whip/src/messages/Whip_UpgradePhpMessage.php (+0/-55)
vendor/yoast/whip/src/presenters/Whip_WPMessagePresenter.php (+0/-83)
vendor/yoast/whip/tests/ConfigurationTest.php (+0/-62)
vendor/yoast/whip/tests/MessageDismisserTest.php (+0/-86)
vendor/yoast/whip/tests/MessageTest.php (+0/-23)
vendor/yoast/whip/tests/MessagesManagerTest.php (+0/-14)
vendor/yoast/whip/tests/RequirementsCheckerTest.php (+0/-144)
vendor/yoast/whip/tests/VersionRequirementTest.php (+0/-99)
vendor/yoast/whip/tests/bootstrap.php (+0/-5)
vendor_prefixed/guzzlehttp/guzzle/src/Client.php (+347/-0)
vendor_prefixed/guzzlehttp/guzzle/src/ClientInterface.php (+79/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJar.php (+245/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php (+76/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php (+83/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php (+66/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Cookie/SetCookie.php (+343/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/BadResponseException.php (+19/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/ClientException.php (+10/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/ConnectException.php (+31/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/GuzzleException.php (+16/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/RequestException.php (+165/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/SeekException.php (+25/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/ServerException.php (+10/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php (+7/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Exception/TransferException.php (+7/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlFactory.php (+425/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php (+26/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlHandler.php (+39/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php (+160/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/EasyHandle.php (+67/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/MockHandler.php (+152/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/Proxy.php (+46/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Handler/StreamHandler.php (+376/-0)
vendor_prefixed/guzzlehttp/guzzle/src/HandlerStack.php (+239/-0)
vendor_prefixed/guzzlehttp/guzzle/src/MessageFormatter.php (+151/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Middleware.php (+222/-0)
vendor_prefixed/guzzlehttp/guzzle/src/Pool.php (+106/-0)
vendor_prefixed/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php (+86/-0)
vendor_prefixed/guzzlehttp/guzzle/src/RedirectMiddleware.php (+160/-0)
vendor_prefixed/guzzlehttp/guzzle/src/RequestOptions.php (+228/-0)
vendor_prefixed/guzzlehttp/guzzle/src/RetryMiddleware.php (+84/-0)
vendor_prefixed/guzzlehttp/guzzle/src/TransferStats.php (+110/-0)
vendor_prefixed/guzzlehttp/guzzle/src/UriTemplate.php (+191/-0)
vendor_prefixed/guzzlehttp/guzzle/src/functions.php (+294/-0)
vendor_prefixed/guzzlehttp/guzzle/src/functions_include.php (+8/-0)
vendor_prefixed/guzzlehttp/promises/src/AggregateException.php (+14/-0)
vendor_prefixed/guzzlehttp/promises/src/CancellationException.php (+10/-0)
vendor_prefixed/guzzlehttp/promises/src/Coroutine.php (+135/-0)
vendor_prefixed/guzzlehttp/promises/src/EachPromise.php (+190/-0)
vendor_prefixed/guzzlehttp/promises/src/FulfilledPromise.php (+69/-0)
vendor_prefixed/guzzlehttp/promises/src/Promise.php (+231/-0)
vendor_prefixed/guzzlehttp/promises/src/PromiseInterface.php (+84/-0)
vendor_prefixed/guzzlehttp/promises/src/PromisorInterface.php (+16/-0)
vendor_prefixed/guzzlehttp/promises/src/RejectedPromise.php (+74/-0)
vendor_prefixed/guzzlehttp/promises/src/RejectionException.php (+40/-0)
vendor_prefixed/guzzlehttp/promises/src/TaskQueue.php (+62/-0)
vendor_prefixed/guzzlehttp/promises/src/TaskQueueInterface.php (+24/-0)
vendor_prefixed/guzzlehttp/promises/src/functions.php (+387/-0)
vendor_prefixed/guzzlehttp/promises/src/functions_include.php (+8/-0)
vendor_prefixed/guzzlehttp/psr7/src/AppendStream.php (+202/-0)
vendor_prefixed/guzzlehttp/psr7/src/BufferStream.php (+115/-0)
vendor_prefixed/guzzlehttp/psr7/src/CachingStream.php (+115/-0)
vendor_prefixed/guzzlehttp/psr7/src/DroppingStream.php (+36/-0)
vendor_prefixed/guzzlehttp/psr7/src/FnStream.php (+132/-0)
vendor_prefixed/guzzlehttp/psr7/src/InflateStream.php (+48/-0)
vendor_prefixed/guzzlehttp/psr7/src/LazyOpenStream.php (+35/-0)
vendor_prefixed/guzzlehttp/psr7/src/LimitStream.php (+128/-0)
vendor_prefixed/guzzlehttp/psr7/src/MessageTrait.php (+150/-0)
vendor_prefixed/guzzlehttp/psr7/src/MultipartStream.php (+123/-0)
vendor_prefixed/guzzlehttp/psr7/src/NoSeekStream.php (+20/-0)
vendor_prefixed/guzzlehttp/psr7/src/PumpStream.php (+140/-0)
vendor_prefixed/guzzlehttp/psr7/src/Request.php (+112/-0)
vendor_prefixed/guzzlehttp/psr7/src/Response.php (+61/-0)
vendor_prefixed/guzzlehttp/psr7/src/Rfc7230.php (+18/-0)
vendor_prefixed/guzzlehttp/psr7/src/ServerRequest.php (+302/-0)
vendor_prefixed/guzzlehttp/psr7/src/Stream.php (+212/-0)
vendor_prefixed/guzzlehttp/psr7/src/StreamDecoratorTrait.php (+128/-0)
vendor_prefixed/guzzlehttp/psr7/src/StreamWrapper.php (+102/-0)
vendor_prefixed/guzzlehttp/psr7/src/UploadedFile.php (+244/-0)
vendor_prefixed/guzzlehttp/psr7/src/Uri.php (+584/-0)
vendor_prefixed/guzzlehttp/psr7/src/UriNormalizer.php (+179/-0)
vendor_prefixed/guzzlehttp/psr7/src/UriResolver.php (+190/-0)
vendor_prefixed/guzzlehttp/psr7/src/functions.php (+657/-0)
vendor_prefixed/guzzlehttp/psr7/src/functions_include.php (+8/-0)
vendor_prefixed/j4mie/idiorm/idiorm.php (+2415/-0)
vendor_prefixed/league/oauth2-client/src/Grant/AbstractGrant.php (+72/-0)
vendor_prefixed/league/oauth2-client/src/Grant/AuthorizationCode.php (+38/-0)
vendor_prefixed/league/oauth2-client/src/Grant/ClientCredentials.php (+38/-0)
vendor_prefixed/league/oauth2-client/src/Grant/Exception/InvalidGrantException.php (+25/-0)
vendor_prefixed/league/oauth2-client/src/Grant/GrantFactory.php (+91/-0)
vendor_prefixed/league/oauth2-client/src/Grant/Password.php (+38/-0)
vendor_prefixed/league/oauth2-client/src/Grant/RefreshToken.php (+38/-0)
vendor_prefixed/league/oauth2-client/src/OptionProvider/HttpBasicAuthOptionProvider.php (+38/-0)
vendor_prefixed/league/oauth2-client/src/OptionProvider/OptionProviderInterface.php (+30/-0)
vendor_prefixed/league/oauth2-client/src/OptionProvider/PostAuthOptionProvider.php (+46/-0)
vendor_prefixed/league/oauth2-client/src/Provider/AbstractProvider.php (+709/-0)
vendor_prefixed/league/oauth2-client/src/Provider/Exception/IdentityProviderException.php (+45/-0)
vendor_prefixed/league/oauth2-client/src/Provider/GenericProvider.php (+190/-0)
vendor_prefixed/league/oauth2-client/src/Provider/GenericResourceOwner.php (+57/-0)
vendor_prefixed/league/oauth2-client/src/Provider/ResourceOwnerInterface.php (+35/-0)
vendor_prefixed/league/oauth2-client/src/Token/AccessToken.php (+174/-0)
vendor_prefixed/league/oauth2-client/src/Token/AccessTokenInterface.php (+65/-0)
vendor_prefixed/league/oauth2-client/src/Token/ResourceOwnerAccessTokenInterface.php (+25/-0)
vendor_prefixed/league/oauth2-client/src/Tool/ArrayAccessorTrait.php (+47/-0)
vendor_prefixed/league/oauth2-client/src/Tool/BearerAuthorizationTrait.php (+35/-0)
vendor_prefixed/league/oauth2-client/src/Tool/GuardedPropertyTrait.php (+66/-0)
vendor_prefixed/league/oauth2-client/src/Tool/MacAuthorizationTrait.php (+76/-0)
vendor_prefixed/league/oauth2-client/src/Tool/ProviderRedirectTrait.php (+105/-0)
vendor_prefixed/league/oauth2-client/src/Tool/QueryBuilderTrait.php (+33/-0)
vendor_prefixed/league/oauth2-client/src/Tool/RequestFactory.php (+67/-0)
vendor_prefixed/league/oauth2-client/src/Tool/RequiredParameterTrait.php (+51/-0)
vendor_prefixed/psr/container/src/ContainerExceptionInterface.php (+13/-0)
vendor_prefixed/psr/container/src/ContainerInterface.php (+36/-0)
vendor_prefixed/psr/container/src/NotFoundExceptionInterface.php (+13/-0)
vendor_prefixed/psr/http-message/src/MessageInterface.php (+177/-0)
vendor_prefixed/psr/http-message/src/RequestInterface.php (+124/-0)
vendor_prefixed/psr/http-message/src/ResponseInterface.php (+66/-0)
vendor_prefixed/psr/http-message/src/ServerRequestInterface.php (+249/-0)
vendor_prefixed/psr/http-message/src/StreamInterface.php (+144/-0)
vendor_prefixed/psr/http-message/src/UploadedFileInterface.php (+118/-0)
vendor_prefixed/psr/http-message/src/UriInterface.php (+309/-0)
vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php (+121/-0)
vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php (+7/-0)
vendor_prefixed/psr/log/Psr/Log/LogLevel.php (+18/-0)
vendor_prefixed/psr/log/Psr/Log/LoggerAwareInterface.php (+18/-0)
vendor_prefixed/psr/log/Psr/Log/LoggerAwareTrait.php (+25/-0)
vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php (+115/-0)
vendor_prefixed/psr/log/Psr/Log/LoggerTrait.php (+132/-0)
vendor_prefixed/psr/log/Psr/Log/NullLogger.php (+28/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/Base.php (+150/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/ColumnDefinition.php (+108/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/Interface.php (+223/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/MySQL/Base.php (+1189/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/MySQL/TableDefinition.php (+268/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/PgSQL/Base.php (+1241/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/PgSQL/TableDefinition.php (+252/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/Sqlite3/Base.php (+791/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/Sqlite3/TableDefinition.php (+208/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Adapter/TableDefinition.php (+95/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Exception.php (+94/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/FrameworkRunner.php (+481/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Migration/Base.php (+304/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Task/Base.php (+109/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Task/Interface.php (+54/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Task/Manager.php (+186/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Util/Logger.php (+107/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Util/Migrator.php (+299/-0)
vendor_prefixed/ruckusing/lib/Ruckusing/Util/Naming.php (+163/-0)
vendor_prefixed/ruckusing/lib/Task/Db/Generate.php (+208/-0)
vendor_prefixed/ruckusing/lib/Task/Db/Migrate.php (+347/-0)
vendor_prefixed/ruckusing/lib/Task/Db/Schema.php (+113/-0)
vendor_prefixed/ruckusing/lib/Task/Db/Setup.php (+85/-0)
vendor_prefixed/ruckusing/lib/Task/Db/Status.php (+109/-0)
vendor_prefixed/ruckusing/lib/Task/Db/Version.php (+98/-0)
vendor_prefixed/ruckusing/lib/version.php (+5/-0)
vendor_prefixed/symfony/dependency-injection/Argument/RewindableGenerator.php (+41/-0)
vendor_prefixed/symfony/dependency-injection/Container.php (+467/-0)
vendor_prefixed/symfony/dependency-injection/ContainerInterface.php (+91/-0)
vendor_prefixed/symfony/dependency-injection/Exception/EnvNotFoundException.php (+24/-0)
vendor_prefixed/symfony/dependency-injection/Exception/ExceptionInterface.php (+22/-0)
vendor_prefixed/symfony/dependency-injection/Exception/InvalidArgumentException.php (+20/-0)
vendor_prefixed/symfony/dependency-injection/Exception/LogicException.php (+18/-0)
vendor_prefixed/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php (+30/-0)
vendor_prefixed/symfony/dependency-injection/Exception/RuntimeException.php (+20/-0)
vendor_prefixed/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php (+36/-0)
vendor_prefixed/symfony/dependency-injection/Exception/ServiceNotFoundException.php (+58/-0)
vendor_prefixed/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php (+108/-0)
vendor_prefixed/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php (+62/-0)
vendor_prefixed/symfony/dependency-injection/ParameterBag/ParameterBag.php (+263/-0)
vendor_prefixed/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php (+103/-0)
vendor_prefixed/symfony/dependency-injection/ResettableContainerInterface.php (+30/-0)
wp-seo-main.php (+158/-65)
wp-seo.php (+5/-2)
wpml-config.xml (+0/-1)
To merge this branch: bzr merge lp:~jlosito/wordpress/wp-plugin-yoast
Reviewer Review Type Date Requested Status
David Lawson 2019-11-08 Approve on 2019-11-08
Review via email: mp+375333@code.launchpad.net

Commit message

Upgraded to 12.4

closes #121349

To post a comment you must log in.
David Lawson (deej) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'admin/admin-settings-changed-listener.php'
2--- admin/admin-settings-changed-listener.php 1970-01-01 00:00:00 +0000
3+++ admin/admin-settings-changed-listener.php 2019-11-08 16:06:28 +0000
4@@ -0,0 +1,85 @@
5+<?php
6+/**
7+ * WPSEO plugin file.
8+ *
9+ * @package WPSEO\Admin
10+ */
11+
12+/**
13+ * A WordPress integration that listens for whether the SEO changes have been saved successfully.
14+ */
15+class WPSEO_Admin_Settings_Changed_Listener implements WPSEO_WordPress_Integration {
16+
17+ /**
18+ * Have the Yoast SEO settings been saved.
19+ *
20+ * @var bool
21+ */
22+ private static $settings_saved = false;
23+
24+ /**
25+ * Registers all hooks to WordPress.
26+ *
27+ * @return void
28+ */
29+ public function register_hooks() {
30+ add_action( 'admin_init', array( $this, 'intercept_save_update_notification' ) );
31+ }
32+
33+ /**
34+ * Checks and overwrites the wp_settings_errors global to determine whether the Yoast SEO settings have been saved.
35+ */
36+ public function intercept_save_update_notification() {
37+ global $pagenow;
38+
39+ if ( $pagenow !== 'admin.php' || ! WPSEO_Utils::is_yoast_seo_page() ) {
40+ return;
41+ }
42+
43+ // Variable name is the same as the global that is set by get_settings_errors.
44+ $wp_settings_errors = get_settings_errors();
45+
46+ foreach ( $wp_settings_errors as $key => $wp_settings_error ) {
47+ if ( ! $this->is_settings_updated_notification( $wp_settings_error ) ) {
48+ continue;
49+ }
50+
51+ self::$settings_saved = true;
52+ unset( $wp_settings_errors[ $key ] );
53+ // Overwrite the global with the list excluding the Changed saved message.
54+ $GLOBALS['wp_settings_errors'] = $wp_settings_errors;
55+ break;
56+ }
57+ }
58+
59+ /**
60+ * Checks whether the settings notification is a settings_updated notification.
61+ *
62+ * @param array $wp_settings_error The settings object.
63+ *
64+ * @return bool Whether this is a settings updated settings notification.
65+ */
66+ public function is_settings_updated_notification( $wp_settings_error ) {
67+ return ! empty( $wp_settings_error['code'] ) && $wp_settings_error['code'] === 'settings_updated';
68+ }
69+
70+ /**
71+ * Get whether the settings have successfully been saved
72+ *
73+ * @return bool Whether the settings have successfully been saved.
74+ */
75+ public function have_settings_been_saved() {
76+ return self::$settings_saved;
77+ }
78+
79+ /**
80+ * Renders a success message if the Yoast SEO settings have been saved.
81+ */
82+ public function show_success_message() {
83+ if ( $this->have_settings_been_saved() ) {
84+ echo '<p class="wpseo-message"><span class="dashicons dashicons-yes"></span>',
85+ esc_html__( 'Settings saved.', 'wordpress-seo' ),
86+ '</p>';
87+ }
88+ }
89+}
90
91=== modified file 'admin/ajax.php'
92--- admin/ajax.php 2018-07-04 09:50:13 +0000
93+++ admin/ajax.php 2019-11-08 16:06:28 +0000
94@@ -12,16 +12,13 @@
95 }
96
97 /**
98- * @todo this whole thing should probably be a proper class.
99- */
100-
101-/**
102- * Convenience function to JSON encode and echo results and then die
103+ * Convenience function to JSON encode and echo results and then die.
104 *
105 * @param array $results Results array for encoding.
106 */
107 function wpseo_ajax_json_echo_die( $results ) {
108- echo wp_json_encode( $results );
109+ // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
110+ echo WPSEO_Utils::format_json_encode( $results );
111 die();
112 }
113
114@@ -87,25 +84,6 @@
115 add_action( 'wp_ajax_wpseo_dismiss_tagline_notice', 'wpseo_dismiss_tagline_notice' );
116
117 /**
118- * Used in the editor to replace vars for the snippet preview
119- */
120-function wpseo_ajax_replace_vars() {
121- global $post;
122- check_ajax_referer( 'wpseo-replace-vars' );
123-
124- $post = get_post( intval( filter_input( INPUT_POST, 'post_id' ) ) );
125- global $wp_query;
126- $wp_query->queried_object = $post;
127- $wp_query->queried_object_id = $post->ID;
128-
129- $omit = array( 'excerpt', 'excerpt_only', 'title' );
130- echo wpseo_replace_vars( stripslashes( filter_input( INPUT_POST, 'string' ) ), $post, $omit );
131- die;
132-}
133-
134-add_action( 'wp_ajax_wpseo_replace_vars', 'wpseo_ajax_replace_vars' );
135-
136-/**
137 * Save an individual SEO title from the Bulk Editor.
138 */
139 function wpseo_save_title() {
140@@ -124,7 +102,7 @@
141 add_action( 'wp_ajax_wpseo_save_metadesc', 'wpseo_save_description' );
142
143 /**
144- * Save titles & descriptions
145+ * Save titles & descriptions.
146 *
147 * @param string $what Type of item to save (title, description).
148 */
149@@ -246,30 +224,31 @@
150 add_action( 'wp_ajax_wpseo_save_all_descriptions', 'wpseo_save_all_descriptions' );
151
152 /**
153- * Utility function to save values
154+ * Utility function to save values.
155 *
156 * @param string $what Type of item so save.
157 */
158 function wpseo_save_all( $what ) {
159 check_ajax_referer( 'wpseo-bulk-editor' );
160
161- // @todo the WPSEO Utils class can't filter arrays in POST yet.
162- $new_values = $_POST['items'];
163- $original_values = $_POST['existing_items'];
164-
165 $results = array();
166-
167- if ( is_array( $new_values ) && $new_values !== array() ) {
168- foreach ( $new_values as $post_id => $new_value ) {
169- $original_value = $original_values[ $post_id ];
170- $results[] = wpseo_upsert_new( $what, $post_id, $new_value, $original_value );
171- }
172- }
173+ if ( ! isset( $_POST['items'], $_POST['existingItems'] ) ) {
174+ wpseo_ajax_json_echo_die( $results );
175+ }
176+
177+ $new_values = array_map( array( 'WPSEO_Utils', 'sanitize_text_field' ), wp_unslash( (array) $_POST['items'] ) );
178+ $original_values = array_map( array( 'WPSEO_Utils', 'sanitize_text_field' ), wp_unslash( (array) $_POST['existingItems'] ) );
179+
180+ foreach ( $new_values as $post_id => $new_value ) {
181+ $original_value = $original_values[ $post_id ];
182+ $results[] = wpseo_upsert_new( $what, $post_id, $new_value, $original_value );
183+ }
184+
185 wpseo_ajax_json_echo_die( $results );
186 }
187
188 /**
189- * Insert a new value
190+ * Insert a new value.
191 *
192 * @param string $what Item type (such as title).
193 * @param int $post_id Post ID.
194@@ -296,7 +275,8 @@
195 }
196
197 wp_die(
198- wp_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) )
199+ // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
200+ WPSEO_Utils::format_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) )
201 );
202 }
203
204@@ -326,12 +306,28 @@
205 $usage = $usage[ $keyword ];
206
207 wp_die(
208- wp_json_encode( $usage )
209+ // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
210+ WPSEO_Utils::format_json_encode( $usage )
211 );
212 }
213
214 add_action( 'wp_ajax_get_term_keyword_usage', 'ajax_get_term_keyword_usage' );
215
216+/**
217+ * Registers hooks for all AJAX integrations.
218+ *
219+ * @return void
220+ */
221+function wpseo_register_ajax_integrations() {
222+ $integrations = array( new Yoast_Network_Admin() );
223+
224+ foreach ( $integrations as $integration ) {
225+ $integration->register_ajax_hooks();
226+ }
227+}
228+
229+wpseo_register_ajax_integrations();
230+
231 // Crawl Issue Manager AJAX hooks.
232 new WPSEO_GSC_Ajax();
233
234@@ -347,11 +343,10 @@
235 // Setting the notice for the recalculate the posts.
236 new Yoast_Dismissable_Notice_Ajax( 'recalculate', Yoast_Dismissable_Notice_Ajax::FOR_SITE );
237
238-/********************** DEPRECATED METHODS **********************/
239-
240+/* ********************* DEPRECATED FUNCTIONS ********************* */
241
242 /**
243- * Removes stopword from the sample permalink that is generated in an AJAX request
244+ * Removes stopword from the sample permalink that is generated in an AJAX request.
245 *
246 * @deprecated 6.3
247 * @codeCoverageIgnore
248@@ -387,3 +382,25 @@
249 _deprecated_function( __FUNCTION__, 'WPSEO 7.0', 'This method is deprecated.' );
250 wpseo_ajax_json_echo_die( '' );
251 }
252+
253+/**
254+ * Used in the editor to replace vars for the snippet preview.
255+ *
256+ * @deprecated 11.9
257+ * @codeCoverageIgnore
258+ */
259+function wpseo_ajax_replace_vars() {
260+ _deprecated_function( __METHOD__, 'WPSEO 11.9' );
261+
262+ global $post;
263+ check_ajax_referer( 'wpseo-replace-vars' );
264+
265+ $post = get_post( intval( filter_input( INPUT_POST, 'post_id' ) ) );
266+ global $wp_query;
267+ $wp_query->queried_object = $post;
268+ $wp_query->queried_object_id = $post->ID;
269+
270+ $omit = array( 'excerpt', 'excerpt_only', 'title' );
271+ echo wpseo_replace_vars( stripslashes( filter_input( INPUT_POST, 'string' ) ), $post, $omit );
272+ die;
273+}
274
275=== modified file 'admin/ajax/class-recalculate-scores-ajax.php'
276--- admin/ajax/class-recalculate-scores-ajax.php 2018-07-04 09:50:13 +0000
277+++ admin/ajax/class-recalculate-scores-ajax.php 2019-11-08 16:06:28 +0000
278@@ -6,14 +6,14 @@
279 */
280
281 /**
282- * Class WPSEO_Recalculate_Scores
283+ * Class WPSEO_Recalculate_Scores.
284 *
285- * This class handles the SEO score recalculation for all posts with a filled focus keyword
286+ * This class handles the SEO score recalculation for all posts with a filled focus keyword.
287 */
288 class WPSEO_Recalculate_Scores_Ajax {
289
290 /**
291- * Initialize the AJAX hooks
292+ * Initialize the AJAX hooks.
293 */
294 public function __construct() {
295 add_action( 'wp_ajax_wpseo_recalculate_scores', array( $this, 'recalculate_scores' ) );
296@@ -28,7 +28,8 @@
297 check_ajax_referer( 'wpseo_recalculate', 'nonce' );
298
299 wp_die(
300- wp_json_encode(
301+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: WPSEO_Utils::format_json_encode is considered safe.
302+ WPSEO_Utils::format_json_encode(
303 array(
304 'posts' => $this->calculate_posts(),
305 'terms' => $this->calculate_terms(),
306@@ -38,7 +39,7 @@
307 }
308
309 /**
310- * Start recalculation
311+ * Start recalculation.
312 */
313 public function recalculate_scores() {
314 check_ajax_referer( 'wpseo_recalculate', 'nonce' );
315@@ -49,7 +50,8 @@
316 $response = $fetch_object->get_items_to_recalculate( $paged );
317
318 if ( ! empty( $response ) ) {
319- wp_die( wp_json_encode( $response ) );
320+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: WPSEO_Utils::format_json_encode is considered safe.
321+ wp_die( WPSEO_Utils::format_json_encode( $response ) );
322 }
323 }
324
325@@ -57,7 +59,7 @@
326 }
327
328 /**
329- * Saves the new linkdex score for given post
330+ * Saves the new linkdex score for given post.
331 */
332 public function save_score() {
333 check_ajax_referer( 'wpseo_recalculate', 'nonce' );
334@@ -88,7 +90,7 @@
335 }
336
337 /**
338- * Gets the total number of posts
339+ * Gets the total number of posts.
340 *
341 * @return int
342 */
343@@ -106,7 +108,7 @@
344 }
345
346 /**
347- * Get the total number of terms
348+ * Get the total number of terms.
349 *
350 * @return int
351 */
352
353=== modified file 'admin/ajax/class-shortcode-filter.php'
354--- admin/ajax/class-shortcode-filter.php 2018-07-04 09:50:13 +0000
355+++ admin/ajax/class-shortcode-filter.php 2019-11-08 16:06:28 +0000
356@@ -6,21 +6,21 @@
357 */
358
359 /**
360- * Class WPSEO_Shortcode_Filter
361+ * Class WPSEO_Shortcode_Filter.
362 *
363- * Used for parsing WP shortcodes with AJAX
364+ * Used for parsing WP shortcodes with AJAX.
365 */
366 class WPSEO_Shortcode_Filter {
367
368 /**
369- * Initialize the AJAX hooks
370+ * Initialize the AJAX hooks.
371 */
372 public function __construct() {
373 add_action( 'wp_ajax_wpseo_filter_shortcodes', array( $this, 'do_filter' ) );
374 }
375
376 /**
377- * Parse the shortcodes
378+ * Parse the shortcodes.
379 */
380 public function do_filter() {
381 check_ajax_referer( 'wpseo-filter-shortcodes', 'nonce' );
382@@ -36,6 +36,7 @@
383 );
384 }
385
386- wp_die( wp_json_encode( $parsed_shortcodes ) );
387+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: WPSEO_Utils::format_json_encode is considered safe.
388+ wp_die( WPSEO_Utils::format_json_encode( $parsed_shortcodes ) );
389 }
390 }
391
392=== modified file 'admin/ajax/class-yoast-dismissable-notice.php'
393--- admin/ajax/class-yoast-dismissable-notice.php 2018-07-04 09:50:13 +0000
394+++ admin/ajax/class-yoast-dismissable-notice.php 2019-11-08 16:06:28 +0000
395@@ -6,39 +6,48 @@
396 */
397
398 /**
399- * 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
400- * in the database
401+ * This class will catch the request to dismiss the target notice (set by notice_name)
402+ * and will store the dismiss status as an user meta in the database.
403 */
404 class Yoast_Dismissable_Notice_Ajax {
405
406 /**
407- * @var string Notice type toggle value for user notices.
408+ * Notice type toggle value for user notices.
409+ *
410+ * @var string
411 */
412 const FOR_USER = 'user_meta';
413
414 /**
415- * @var string Notice type toggle value for network notices.
416+ * Notice type toggle value for network notices.
417+ *
418+ * @var string
419 */
420 const FOR_NETWORK = 'site_option';
421
422 /**
423- * @var string Notice type toggle value for site notices.
424+ * Notice type toggle value for site notices.
425+ *
426+ * @var string
427 */
428 const FOR_SITE = 'option';
429
430-
431 /**
432- * @var string Name of the notice that will be dismissed.
433+ * Name of the notice that will be dismissed.
434+ *
435+ * @var string
436 */
437 private $notice_name;
438
439 /**
440+ * The type of the current notice.
441+ *
442 * @var string
443 */
444 private $notice_type;
445
446 /**
447- * Initialize the hooks for the AJAX request
448+ * Initialize the hooks for the AJAX request.
449 *
450 * @param string $notice_name The name for the hook to catch the notice.
451 * @param string $notice_type The notice type.
452@@ -51,7 +60,7 @@
453 }
454
455 /**
456- * Handles the dismiss notice request
457+ * Handles the dismiss notice request.
458 */
459 public function dismiss_notice() {
460 check_ajax_referer( 'wpseo-dismiss-' . $this->notice_name );
461
462=== modified file 'admin/ajax/class-yoast-onpage-ajax.php'
463--- admin/ajax/class-yoast-onpage-ajax.php 2018-07-04 09:50:13 +0000
464+++ admin/ajax/class-yoast-onpage-ajax.php 2019-11-08 16:06:28 +0000
465@@ -6,7 +6,7 @@
466 */
467
468 /**
469- * Class Yoast_OnPage_Ajax
470+ * Class Yoast_OnPage_Ajax.
471 *
472 * This class will catch the request to dismiss the Ryte notice and will store
473 * the dismiss status as an user meta in the database.
474@@ -14,14 +14,14 @@
475 class Yoast_OnPage_Ajax {
476
477 /**
478- * Initialize the hooks for the AJAX request
479+ * Initialize the hooks for the AJAX request.
480 */
481 public function __construct() {
482 add_action( 'wp_ajax_wpseo_dismiss_onpageorg', array( $this, 'dismiss_notice' ) );
483 }
484
485 /**
486- * Handles the dismiss notice request
487+ * Handles the dismiss notice request.
488 */
489 public function dismiss_notice() {
490 check_ajax_referer( 'wpseo-dismiss-onpageorg' );
491@@ -32,7 +32,7 @@
492 }
493
494 /**
495- * Storing the dismissed value as an user option in the database
496+ * Storing the dismissed value as an user option in the database.
497 */
498 private function save_dismissed() {
499 update_user_meta( get_current_user_id(), WPSEO_OnPage::USER_META_KEY, 1 );
500
501=== modified file 'admin/ajax/class-yoast-plugin-conflict-ajax.php'
502--- admin/ajax/class-yoast-plugin-conflict-ajax.php 2018-07-04 09:50:13 +0000
503+++ admin/ajax/class-yoast-plugin-conflict-ajax.php 2019-11-08 16:06:28 +0000
504@@ -6,29 +6,33 @@
505 */
506
507 /**
508- * Class Yoast_Plugin_Conflict_Ajax
509+ * Class Yoast_Plugin_Conflict_Ajax.
510 */
511 class Yoast_Plugin_Conflict_Ajax {
512
513 /**
514+ * Option identifier where dismissed conflicts are stored.
515+ *
516 * @var string
517 */
518 private $option_name = 'wpseo_dismissed_conflicts';
519
520 /**
521+ * List of notification identifiers that have been dismissed.
522+ *
523 * @var array
524 */
525 private $dismissed_conflicts = array();
526
527 /**
528- * Initialize the hooks for the AJAX request
529+ * Initialize the hooks for the AJAX request.
530 */
531 public function __construct() {
532 add_action( 'wp_ajax_wpseo_dismiss_plugin_conflict', array( $this, 'dismiss_notice' ) );
533 }
534
535 /**
536- * Handles the dismiss notice request
537+ * Handles the dismiss notice request.
538 */
539 public function dismiss_notice() {
540 check_ajax_referer( 'dismiss-plugin-conflict' );
541@@ -45,7 +49,7 @@
542 }
543
544 /**
545- * Getting the user option from the database
546+ * Getting the user option from the database.
547 *
548 * @return bool|array
549 */
550@@ -71,7 +75,7 @@
551 }
552
553 /**
554- * Storing the conflicting plugins as an user option in the database
555+ * Storing the conflicting plugins as an user option in the database.
556 *
557 * @param string $plugin_section Plugin conflict type (such as Open Graph or sitemap).
558 */
559@@ -84,7 +88,7 @@
560 }
561
562 /**
563- * Loop through the plugins to compare them with the already stored dismissed plugin conflicts
564+ * Loop through the plugins to compare them with the already stored dismissed plugin conflicts.
565 *
566 * @param array $posted_plugins Plugin set to check.
567 */
568@@ -95,7 +99,7 @@
569 }
570
571 /**
572- * Check if plugin is already dismissed, if not store it in the array that will be saved later
573+ * Check if plugin is already dismissed, if not store it in the array that will be saved later.
574 *
575 * @param string $posted_plugin Plugin to check against dismissed conflicts.
576 */
577
578=== removed directory 'admin/banner'
579=== removed file 'admin/banner/class-admin-banner-renderer.php'
580--- admin/banner/class-admin-banner-renderer.php 2018-07-04 09:50:13 +0000
581+++ admin/banner/class-admin-banner-renderer.php 1970-01-01 00:00:00 +0000
582@@ -1,50 +0,0 @@
583-<?php
584-/**
585- * WPSEO plugin file.
586- *
587- * @package WPSEO\Admin\Banner
588- */
589-
590-/**
591- * Represents the render object for generating the html for the given banner.
592- */
593-class WPSEO_Admin_Banner_Renderer {
594-
595- /** @var string */
596- protected $base_path = '';
597-
598- /**
599- * Renders the admin banner.
600- *
601- * @param WPSEO_Admin_Banner $banner The banner to render.
602- *
603- * @return string
604- */
605- public function render( WPSEO_Admin_Banner $banner ) {
606- $output = '<a class="wpseo-banner__link" target="_blank" href="' . esc_url( $banner->get_url() ) . '">';
607- $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() ) . '"/>';
608- $output .= '</a>';
609-
610- return $output;
611- }
612-
613- /**
614- * Sets the base path, where the images are located.
615- *
616- * @param string $base_path The image location.
617- */
618- public function set_base_path( $base_path ) {
619- $this->base_path = $base_path;
620- }
621-
622- /**
623- * Returns the full path for the image.
624- *
625- * @param string $image The image path.
626- *
627- * @return string
628- */
629- protected function get_image_path( $image ) {
630- return rtrim( $this->base_path, '/' ) . '/' . ltrim( $image, '/' );
631- }
632-}
633
634=== removed file 'admin/banner/class-admin-banner-sidebar-renderer.php'
635--- admin/banner/class-admin-banner-sidebar-renderer.php 2018-07-04 09:50:13 +0000
636+++ admin/banner/class-admin-banner-sidebar-renderer.php 1970-01-01 00:00:00 +0000
637@@ -1,62 +0,0 @@
638-<?php
639-/**
640- * WPSEO plugin file.
641- *
642- * @package WPSEO\Admin\Banner
643- */
644-
645-/**
646- * Represents the render object for generating the html for the banner sidebar
647- */
648-class WPSEO_Admin_Banner_Sidebar_Renderer {
649-
650- /** @var WPSEO_Admin_Banner_Spot_Renderer */
651- protected $spot_renderer;
652-
653- /**
654- * Sets the spot renderer.
655- *
656- * @param WPSEO_Admin_Banner_Spot_Renderer $spot_renderer The spot renderer that has to be used.
657- */
658- public function __construct( WPSEO_Admin_Banner_Spot_Renderer $spot_renderer ) {
659- $this->spot_renderer = $spot_renderer;
660- }
661-
662- /**
663- * Renders the admin banner sidebar.
664- *
665- * @param WPSEO_Admin_Banner_Sidebar $banner_sidebar The sidebar to render.
666- *
667- * @return string
668- */
669- public function render( WPSEO_Admin_Banner_Sidebar $banner_sidebar ) {
670- return sprintf( '
671- <div class="wpseo_content_cell" id="sidebar-container">
672- <div id="sidebar">
673- <div class="wpseo_content_cell_title yoast-sidebar__title ">
674- %1$s
675- </div>
676- %2$s
677- </div>
678- </div>',
679- $banner_sidebar->get_title(),
680- $this->render_banner_spots( $banner_sidebar->get_banner_spots() )
681- );
682- }
683-
684- /**
685- * Renders the admin banner spots.
686- *
687- * @param WPSEO_Admin_Banner_Spot[] $banner_spots The banner spots to render.
688- *
689- * @return string
690- */
691- protected function render_banner_spots( array $banner_spots ) {
692- $return = '';
693- foreach ( $banner_spots as $banner_spot ) {
694- $return .= $this->spot_renderer->render( $banner_spot );
695- }
696-
697- return $return;
698- }
699-}
700
701=== removed file 'admin/banner/class-admin-banner-sidebar.php'
702--- admin/banner/class-admin-banner-sidebar.php 2018-07-04 09:50:13 +0000
703+++ admin/banner/class-admin-banner-sidebar.php 1970-01-01 00:00:00 +0000
704@@ -1,358 +0,0 @@
705-<?php
706-/**
707- * WPSEO plugin file.
708- *
709- * @package WPSEO\Admin\Banner
710- */
711-
712-/**
713- * Represents the render object for generating the html for the given banner.
714- */
715-class WPSEO_Admin_Banner_Sidebar {
716-
717- /** @var string */
718- protected $title = '';
719-
720- /** @var WPSEO_Admin_Banner_Spot[] */
721- protected $banner_spots = array();
722-
723- /** @var WPSEO_Admin_Banner_Renderer */
724- protected $banner_renderer;
725-
726- /**
727- * WPSEO_Admin_Banner_Sidebar constructor.
728- *
729- * @param string $title The title for the sidebar.
730- * @param WPSEO_Admin_Banner_Renderer $banner_renderer The render class for banners.
731- */
732- public function __construct( $title, WPSEO_Admin_Banner_Renderer $banner_renderer ) {
733- $this->title = $title;
734- $this->banner_renderer = $banner_renderer;
735- }
736-
737- /**
738- * Returns the set title.
739- *
740- * @return string
741- */
742- public function get_title() {
743- return $this->title;
744- }
745-
746- /**
747- * Initializes the banner sidebar by setting its banner spots.
748- *
749- * @param WPSEO_Features $features Class regarding WPSEO Features.
750- */
751- public function initialize( WPSEO_Features $features ) {
752- if ( $features->is_free() ) {
753- $this->add_banner_spot( $this->get_premium_spot() );
754- }
755-
756- $this->add_banner_spot( $this->get_services_spot() );
757-
758- $extensions_spot = $this->get_extensions_spot( $this->get_active_extensions() );
759- if ( $extensions_spot->has_banners() ) {
760- $this->add_banner_spot( $extensions_spot );
761- }
762-
763- $this->add_banner_spot( $this->get_courses_spot() );
764- $this->add_banner_spot( $this->get_remove_banner_spot() );
765- }
766-
767- /**
768- * Returns array with bannerspots.
769- *
770- * @return WPSEO_Admin_Banner_Spot[]
771- */
772- public function get_banner_spots() {
773- return $this->banner_spots;
774- }
775-
776- /**
777- * Adds a banner spot.
778- *
779- * @param WPSEO_Admin_Banner_Spot $spot The spot to add.
780- */
781- protected function add_banner_spot( WPSEO_Admin_Banner_Spot $spot ) {
782- $this->banner_spots[] = $spot;
783- }
784-
785- /**
786- * Returns the premium banner spot.
787- *
788- * @return WPSEO_Admin_Banner_Spot
789- */
790- protected function get_premium_spot() {
791- $premium_spot = new WPSEO_Admin_Banner_Spot( '', $this->banner_renderer );
792-
793- $premium_uri = WPSEO_Shortlinker::get( 'https://yoa.st/jj' );
794-
795- $premium_spot->set_extra(
796- /* translators: %1$s expands to the plugin name */
797- '<h2>' . sprintf( esc_html__( 'Upgrade to %1$s', 'wordpress-seo' ), 'Yoast SEO Premium' ) . '</h2>' .
798- '<ul>' .
799- '<li><strong>' . esc_html__( 'Rank for up to 5 focus keywords per page', 'wordpress-seo' ) . '</strong></li>' .
800- '<li><strong>' . esc_html__( 'Preview your page in Facebook and Twitter', 'wordpress-seo' ) . '</strong></li>' .
801- '<li><strong>' . esc_html__( 'Get real-time suggestions for internal links', 'wordpress-seo' ) . '</strong></li>' .
802- '<li><strong>' . esc_html__( 'No more dead links a.k.a. 404 pages', 'wordpress-seo' ) . '</strong></li>' .
803- '<li><strong>' . esc_html__( '24/7 email support', 'wordpress-seo' ) . '</strong></li>' .
804- '<li><strong>' . esc_html__( 'No ads', 'wordpress-seo' ) . '</strong></li>' .
805- '</ul>' .
806- /* translators: %s expands to Yoast SEO Premium */
807- '<a id="wpseo-premium-button" class="button button-primary" href="' . $premium_uri . '" target="_blank">' . sprintf( __( 'Get %s now', 'wordpress-seo' ), 'Yoast SEO Premium' ) . '</a><br/>'
808- );
809-
810- return $premium_spot;
811- }
812-
813- /**
814- * Returns the services banner spot.
815- *
816- * @return WPSEO_Admin_Banner_Spot
817- */
818- protected function get_services_spot() {
819- $service_spot = new WPSEO_Admin_Banner_Spot( __( 'Services', 'wordpress-seo' ), $this->banner_renderer );
820-
821- $service_spot->set_description(
822- sprintf(
823- /* translators: %1$s expands to a link start tag to the Yoast Services page, %2$s to Yoast, %3$s is the link closing tag. */
824- __( 'Do you want to know how to improve your rankings? %1$sLet team %2$s help you!%3$s', 'wordpress-seo' ),
825- '<a target="_blank" href="' . WPSEO_Shortlinker::get( 'https://yoa.st/jk' ) . '">',
826- 'Yoast',
827- '</a>'
828- )
829- );
830-
831- $service_spot->add_banner(
832- new WPSEO_Admin_Banner(
833- WPSEO_Shortlinker::get( 'https://yoa.st/jm' ),
834- 'configuration-service.png',
835- 261,
836- 152,
837- sprintf(
838- /* translators: %1$s expands to Yoast SEO Premium. */
839- __( 'Let our experts set up your %1$s plugin!', 'wordpress-seo' ),
840- 'Yoast SEO Premium'
841- )
842- )
843- );
844-
845- return $service_spot;
846- }
847-
848- /**
849- * Returns an array with the Yoast SEO extensions with the value true when they are active.
850- *
851- * @return array
852- */
853- protected function get_active_extensions() {
854- return array(
855- 'video' => class_exists( 'wpseo_Video_Sitemap' ),
856- 'woocommerce' => class_exists( 'Woocommerce' ) && class_exists( 'Yoast_WooCommerce_SEO' ),
857- 'news' => class_exists( 'WPSEO_News' ),
858- 'local' => defined( 'WPSEO_LOCAL_VERSION' ),
859- );
860- }
861-
862- /**
863- * Returns the extensions banner spot.
864- *
865- * @param array $active_extensions The active extensions.
866- *
867- * @return WPSEO_Admin_Banner_Spot
868- */
869- protected function get_extensions_spot( array $active_extensions ) {
870- $extension_spot = new WPSEO_Admin_Banner_Spot( __( 'Extensions', 'wordpress-seo' ), $this->banner_renderer );
871-
872- $extension_spot->set_description(
873- sprintf(
874- /* translators: %1$s expands to a link start tag to the Yoast plugin page, %2$s is the link closing tag. */
875- __( 'Take your SEO to the next level and outrank your competition with our %1$sSEO plugins%2$s.', 'wordpress-seo' ),
876- '<a target="_blank" href="' . WPSEO_Shortlinker::get( 'https://yoa.st/jn' ) . '">',
877- '</a>'
878- )
879- );
880-
881- if ( empty( $active_extensions['video'] ) ) {
882- $extension_spot->add_banner(
883- new WPSEO_Admin_Banner(
884- WPSEO_Shortlinker::get( 'https://yoa.st/jo' ),
885- 'video-seo.png',
886- 261,
887- 152,
888- sprintf(
889- /* translators: %1$s expands to Yoast Video SEO. */
890- __( 'Buy the %1$s plugin now and optimize your videos for video search results and social media!', 'wordpress-seo' ),
891- 'Yoast Video SEO'
892- )
893- )
894- );
895- }
896-
897- if ( empty( $active_extensions['woocommerce'] ) ) {
898- $extension_spot->add_banner(
899- new WPSEO_Admin_Banner(
900- WPSEO_Shortlinker::get( 'https://yoa.st/jp' ),
901- 'woocommerce-seo.png',
902- 261,
903- 152,
904- sprintf(
905- /* translators: %1$s expands to Yoast WooCommerce SEO. */
906- __( 'Buy the %1$s plugin now and optimize your shop today to improve your product promotion!', 'wordpress-seo' ),
907- 'Yoast WooCommerce SEO'
908- )
909- )
910- );
911- }
912-
913- if ( empty( $active_extensions['local'] ) ) {
914- $extension_spot->add_banner(
915- new WPSEO_Admin_Banner(
916- WPSEO_Shortlinker::get( 'https://yoa.st/jq' ),
917- 'local-seo.png', 261,
918- 152,
919- sprintf(
920- /* translators: %1$s expands to Yoast Local SEO. */
921- __( 'Buy the %1$s plugin now to improve your site&#8217;s Local SEO and ranking in Google Maps!', 'wordpress-seo' ),
922- 'Yoast Local SEO'
923- )
924- )
925- );
926- }
927-
928- if ( empty( $active_extensions['news'] ) ) {
929- $extension_spot->add_banner(
930- new WPSEO_Admin_Banner(
931- WPSEO_Shortlinker::get( 'https://yoa.st/jr' ),
932- 'news-seo.png',
933- 261,
934- 152,
935- sprintf(
936- /* translators: %1$s expands to Yoast News SEO. */
937- __( 'Buy the %1$s plugin now and start optimizing to get your site featured in Google News!', 'wordpress-seo' ),
938- 'Yoast News SEO'
939- )
940- )
941- );
942- }
943-
944- return $extension_spot;
945- }
946-
947- /**
948- * Returns the courses banner spot.
949- *
950- * @return WPSEO_Admin_Banner_Spot
951- */
952- protected function get_courses_spot() {
953- $courses_spot = new WPSEO_Admin_Banner_Spot( __( 'Improve your SEO skills', 'wordpress-seo' ), $this->banner_renderer );
954-
955- $courses_spot->set_description(
956- sprintf(
957- /* translators: %1$s expands to a link start tag to the Yoast Services page, %2$s is the link closing tag. */
958- __( 'We believe SEO should be for everyone. That’s why we develop courses on any topic related to SEO. %1$sDiscover our online SEO courses &raquo;%2$s', 'wordpress-seo' ),
959- '<a target="_blank" href="' . WPSEO_Shortlinker::get( 'https://yoa.st/jt' ) . '">',
960- '</a>'
961- )
962- );
963-
964- $courses_spot->add_banner(
965- new WPSEO_Admin_Banner(
966- WPSEO_Shortlinker::get( 'https://yoa.st/ju' ),
967- 'basic-seo-training.png',
968- 261,
969- 152,
970- __( 'Take the online Basic SEO Training course and learn the fundamentals of SEO!', 'wordpress-seo' )
971- )
972- );
973-
974- $courses_spot->add_banner(
975- new WPSEO_Admin_Banner(
976- WPSEO_Shortlinker::get( 'https://yoa.st/jv' ),
977- 'yoast-seo-for-wordpress-training-2018.png',
978- 261,
979- 152,
980- sprintf(
981- /* translators: %1$s expands to Yoast SEO for WordPress Training, %2$s to Yoast SEO for WordPress. */
982- __( 'Take the %1$s course and become a certified %2$s expert!', 'wordpress-seo' ),
983- 'Yoast SEO for WordPress Training',
984- 'Yoast SEO for WordPress'
985- )
986- )
987- );
988-
989- $courses_spot->add_banner(
990- new WPSEO_Admin_Banner(
991- WPSEO_Shortlinker::get( 'https://yoa.st/jw' ),
992- 'seo-copywriting-training.png',
993- 261,
994- 152,
995- __( 'Take the online SEO Copywriting Training course and learn how to write awesome copy that ranks!', 'wordpress-seo' )
996- )
997- );
998-
999- $courses_spot->add_banner(
1000- new WPSEO_Admin_Banner(
1001- WPSEO_Shortlinker::get( 'https://yoa.st/qy' ),
1002- 'site-structure-training.png',
1003- 261,
1004- 152,
1005- __( 'Take the online Site Structure Training course and learn how to structure your website!', 'wordpress-seo' )
1006- )
1007- );
1008-
1009- $courses_spot->add_banner(
1010- new WPSEO_Admin_Banner(
1011- WPSEO_Shortlinker::get( 'https://yoa.st/jaa' ),
1012- 'technical-seo-training.png',
1013- 261,
1014- 152,
1015- __( 'Take the online Technical SEO Training course and learn essential technical SEO-concepts!', 'wordpress-seo' )
1016- )
1017- );
1018-
1019- $courses_spot->add_banner(
1020- new WPSEO_Admin_Banner(
1021- WPSEO_Shortlinker::get( 'https://yoa.st/15h' ),
1022- 'structured-data-course.png',
1023- 261,
1024- 152,
1025- __( 'Take the online Structured Data Training course and learn how to create rich snippets!', 'wordpress-seo' )
1026- )
1027- );
1028-
1029- $courses_spot->add_banner(
1030- new WPSEO_Admin_Banner(
1031- WPSEO_Shortlinker::get( 'https://yoa.st/2oi' ),
1032- 'seo-for-beginners-training.png',
1033- 261,
1034- 152,
1035- __( 'Get the FREE SEO for beginners training course and learn the SEO basics to make your site rank higher.', 'wordpress-seo' )
1036- )
1037- );
1038-
1039- return $courses_spot;
1040- }
1041-
1042- /**
1043- * Returns the remove banner spot.
1044- *
1045- * @return WPSEO_Admin_Banner_Spot
1046- */
1047- protected function get_remove_banner_spot() {
1048-
1049- $remove_banner_spot = new WPSEO_Admin_Banner_Spot(
1050- __( 'Remove these ads?', 'wordpress-seo' )
1051- );
1052-
1053- $remove_banner_spot->set_description(
1054- '<a target="_blank" href="' . WPSEO_Shortlinker::get( 'https://yoa.st/jy' ) . '">' .
1055- /* translators: %1$s expands to Yoast SEO Premium */
1056- sprintf( __( 'Upgrade to %1$s &raquo;', 'wordpress-seo' ), 'Yoast SEO Premium' ) .
1057- '</a>'
1058- );
1059-
1060- return $remove_banner_spot;
1061- }
1062-}
1063
1064=== removed file 'admin/banner/class-admin-banner-spot-renderer.php'
1065--- admin/banner/class-admin-banner-spot-renderer.php 2018-07-04 09:50:13 +0000
1066+++ admin/banner/class-admin-banner-spot-renderer.php 1970-01-01 00:00:00 +0000
1067@@ -1,39 +0,0 @@
1068-<?php
1069-/**
1070- * WPSEO plugin file.
1071- *
1072- * @package WPSEO\Admin\Banner
1073- */
1074-
1075-/**
1076- * Represents the render object for generating the html for the given banner spot.
1077- */
1078-class WPSEO_Admin_Banner_Spot_Renderer {
1079-
1080- /**
1081- * Renders the admin banner spot.
1082- *
1083- * @param WPSEO_Admin_Banner_Spot $banner_spot The spot to render.
1084- *
1085- * @return string
1086- */
1087- public function render( WPSEO_Admin_Banner_Spot $banner_spot ) {
1088- $output = '<div class="yoast-sidebar__spot">';
1089- if ( $banner_spot->get_title() !== '' ) {
1090- $output .= '<strong>' . $banner_spot->get_title() . '</strong>';
1091- }
1092-
1093- if ( $banner_spot->get_extra() !== '' ) {
1094- $output .= $banner_spot->get_extra();
1095- }
1096-
1097- if ( $banner_spot->get_description() !== '' ) {
1098- $output .= '<p>' . $banner_spot->get_description() . '</p>';
1099- }
1100-
1101- $output .= $banner_spot->render_banner();
1102- $output .= '</div>';
1103-
1104- return $output;
1105- }
1106-}
1107
1108=== removed file 'admin/banner/class-admin-banner-spot.php'
1109--- admin/banner/class-admin-banner-spot.php 2018-07-04 09:50:13 +0000
1110+++ admin/banner/class-admin-banner-spot.php 1970-01-01 00:00:00 +0000
1111@@ -1,120 +0,0 @@
1112-<?php
1113-/**
1114- * WPSEO plugin file.
1115- *
1116- * @package WPSEO\Admin\Banner
1117- */
1118-
1119-/**
1120- * Represents the an admin banner spot.
1121- */
1122-class WPSEO_Admin_Banner_Spot {
1123-
1124- /** @var string */
1125- private $title;
1126-
1127- /** @var string */
1128- private $description = '';
1129-
1130- /** @var string */
1131- private $extra = '';
1132-
1133- /** @var WPSEO_Admin_Banner[] */
1134- private $banners = array();
1135-
1136- /**
1137- * WPSEO_Admin_Banner_Spot constructor.
1138- *
1139- * @param string $title The title for the spot.
1140- * @param WPSEO_Admin_Banner_Renderer $banner_renderer The renderer for the banner.
1141- */
1142- public function __construct( $title, WPSEO_Admin_Banner_Renderer $banner_renderer = null ) {
1143- $this->title = $title;
1144- $this->banner_renderer = ( is_null( $banner_renderer ) ? new WPSEO_Admin_Banner_Renderer() : $banner_renderer );
1145- }
1146-
1147- /**
1148- * Returns the title.
1149- *
1150- * @return string
1151- */
1152- public function get_title() {
1153- return $this->title;
1154- }
1155-
1156- /**
1157- * Returns the description.
1158- *
1159- * @return string
1160- */
1161- public function get_description() {
1162- return $this->description;
1163- }
1164-
1165- /**
1166- * Returns the extra content.
1167- *
1168- * @return string
1169- */
1170- public function get_extra() {
1171- return $this->extra;
1172- }
1173-
1174- /**
1175- * Sets the description
1176- *
1177- * @param string $description The description.
1178- */
1179- public function set_description( $description ) {
1180- $this->description = $description;
1181- }
1182-
1183- /**
1184- * Sets the "extra"
1185- *
1186- * @param string $extra The "extra".
1187- */
1188- public function set_extra( $extra ) {
1189- $this->extra = $extra;
1190- }
1191-
1192- /**
1193- * Adds an admin banner.
1194- *
1195- * @param WPSEO_Admin_Banner $banner The banner to add.
1196- */
1197- public function add_banner( WPSEO_Admin_Banner $banner ) {
1198- $this->banners[] = $banner;
1199- }
1200-
1201- /**
1202- * Renders the banner.
1203- *
1204- * @return string
1205- */
1206- public function render_banner() {
1207- if ( ! $this->has_banners() ) {
1208- return '';
1209- }
1210-
1211- return $this->banner_renderer->render( $this->get_random_banner() );
1212- }
1213-
1214- /**
1215- * Checks if there are any banners set.
1216- *
1217- * @return bool
1218- */
1219- public function has_banners() {
1220- return ! empty( $this->banners );
1221- }
1222-
1223- /**
1224- * Returns a random banner.
1225- *
1226- * @return null|WPSEO_Admin_Banner
1227- */
1228- protected function get_random_banner() {
1229- return $this->banners[ array_rand( $this->banners, 1 ) ];
1230- }
1231-}
1232
1233=== removed file 'admin/banner/class-admin-banner.php'
1234--- admin/banner/class-admin-banner.php 2018-07-04 09:50:13 +0000
1235+++ admin/banner/class-admin-banner.php 1970-01-01 00:00:00 +0000
1236@@ -1,89 +0,0 @@
1237-<?php
1238-/**
1239- * WPSEO plugin file.
1240- *
1241- * @package WPSEO\Admin\Banner
1242- */
1243-
1244-/**
1245- * Represents an admin banner.
1246- */
1247-class WPSEO_Admin_Banner {
1248-
1249- /** @var string */
1250- private $url;
1251-
1252- /** @var string */
1253- private $image;
1254-
1255- /** @var integer */
1256- private $width;
1257-
1258- /** @var integer */
1259- private $height;
1260-
1261- /** @var string */
1262- private $alt;
1263-
1264- /**
1265- * Sets the attributes for this object.
1266- *
1267- * @param string $url The URL where the banner links to.
1268- * @param string $image The image filename.
1269- * @param integer $width The width of the image.
1270- * @param integer $height The height of the image.
1271- * @param string $alt The alt text for the image.
1272- */
1273- public function __construct( $url, $image, $width, $height, $alt = '' ) {
1274- $this->url = $url;
1275- $this->image = $image;
1276- $this->alt = $alt;
1277- $this->width = $width;
1278- $this->height = $height;
1279- }
1280-
1281- /**
1282- * Returns the set url.
1283- *
1284- * @return string
1285- */
1286- public function get_url() {
1287- return $this->url;
1288- }
1289-
1290- /**
1291- * Returns the image.
1292- *
1293- * @return string
1294- */
1295- public function get_image() {
1296- return $this->image;
1297- }
1298-
1299- /**
1300- * Returns the alt-text.
1301- *
1302- * @return string
1303- */
1304- public function get_alt() {
1305- return $this->alt;
1306- }
1307-
1308- /**
1309- * Returns the width.
1310- *
1311- * @return string
1312- */
1313- public function get_width() {
1314- return $this->width;
1315- }
1316-
1317- /**
1318- * Returns the height.
1319- *
1320- * @return string
1321- */
1322- public function get_height() {
1323- return $this->height;
1324- }
1325-}
1326
1327=== modified file 'admin/capabilities/class-abstract-capability-manager.php'
1328--- admin/capabilities/class-abstract-capability-manager.php 2018-07-04 09:50:13 +0000
1329+++ admin/capabilities/class-abstract-capability-manager.php 2019-11-08 16:06:28 +0000
1330@@ -9,7 +9,12 @@
1331 * Abstract Capability Manager shared code.
1332 */
1333 abstract class WPSEO_Abstract_Capability_Manager implements WPSEO_Capability_Manager {
1334- /** @var array Registered capabilities */
1335+
1336+ /**
1337+ * Registered capabilities.
1338+ *
1339+ * @var array
1340+ */
1341 protected $capabilities = array();
1342
1343 /**
1344@@ -17,7 +22,7 @@
1345 *
1346 * @param string $capability Capability to register.
1347 * @param array $roles Roles to add the capability to.
1348- * @param bool $overwrite Optional. Use add or overwrite as registration method.
1349+ * @param bool $overwrite Optional. Use add or overwrite as registration method.
1350 */
1351 public function register( $capability, array $roles, $overwrite = false ) {
1352 if ( $overwrite || ! isset( $this->capabilities[ $capability ] ) ) {
1353
1354=== modified file 'admin/capabilities/class-capability-manager-factory.php'
1355--- admin/capabilities/class-capability-manager-factory.php 2018-07-04 09:50:13 +0000
1356+++ admin/capabilities/class-capability-manager-factory.php 2019-11-08 16:06:28 +0000
1357@@ -9,6 +9,7 @@
1358 * Capability Manager Factory.
1359 */
1360 class WPSEO_Capability_Manager_Factory {
1361+
1362 /**
1363 * Returns the Manager to use.
1364 *
1365
1366=== modified file 'admin/capabilities/class-capability-manager-integration.php'
1367--- admin/capabilities/class-capability-manager-integration.php 2018-07-04 09:50:13 +0000
1368+++ admin/capabilities/class-capability-manager-integration.php 2019-11-08 16:06:28 +0000
1369@@ -13,7 +13,11 @@
1370 */
1371 class WPSEO_Capability_Manager_Integration implements WPSEO_WordPress_Integration {
1372
1373- /** @var WPSEO_Capability_Manager Capability manager to use. */
1374+ /**
1375+ * Capability manager to use.
1376+ *
1377+ * @var WPSEO_Capability_Manager
1378+ */
1379 public $manager;
1380
1381 /**
1382@@ -56,29 +60,29 @@
1383 /**
1384 * Add capabilities to its own group in the Members plugin.
1385 *
1386- * @see members_register_cap_group()
1387+ * @see members_register_cap_group()
1388 */
1389 public function action_members_register_cap_group() {
1390 if ( ! function_exists( 'members_register_cap_group' ) ) {
1391 return;
1392 }
1393+
1394 // Register the yoast group.
1395- members_register_cap_group( 'wordpress-seo',
1396- array(
1397- 'label' => esc_html__( 'Yoast SEO', 'wordpress-seo' ),
1398- 'caps' => $this->get_capabilities(),
1399- 'icon' => 'dashicons-admin-plugins',
1400- 'diff_added' => true,
1401- )
1402+ $args = array(
1403+ 'label' => esc_html__( 'Yoast SEO', 'wordpress-seo' ),
1404+ 'caps' => $this->get_capabilities(),
1405+ 'icon' => 'dashicons-admin-plugins',
1406+ 'diff_added' => true,
1407 );
1408+ members_register_cap_group( 'wordpress-seo', $args );
1409 }
1410
1411 /**
1412 * Adds Yoast SEO capability group in the User Role Editor plugin.
1413 *
1414- * @see URE_Capabilities_Groups_Manager::get_groups_tree()
1415+ * @see URE_Capabilities_Groups_Manager::get_groups_tree()
1416 *
1417- * @param array $groups Current groups.
1418+ * @param array $groups Current groups.
1419 *
1420 * @return array Filtered list of capabilty groups.
1421 */
1422@@ -97,10 +101,10 @@
1423 /**
1424 * Adds capabilities to the Yoast SEO group in the User Role Editor plugin.
1425 *
1426- * @see URE_Capabilities_Groups_Manager::get_cap_groups()
1427+ * @see URE_Capabilities_Groups_Manager::get_cap_groups()
1428 *
1429- * @param array $groups Current capability groups.
1430- * @param string $cap_id Capability identifier.
1431+ * @param array $groups Current capability groups.
1432+ * @param string $cap_id Capability identifier.
1433 *
1434 * @return array List of filtered groups.
1435 */
1436
1437=== modified file 'admin/capabilities/class-capability-manager-vip.php'
1438--- admin/capabilities/class-capability-manager-vip.php 2018-07-04 09:50:13 +0000
1439+++ admin/capabilities/class-capability-manager-vip.php 2019-11-08 16:06:28 +0000
1440@@ -9,6 +9,7 @@
1441 * VIP implementation of the Capability Manager.
1442 */
1443 final class WPSEO_Capability_Manager_VIP extends WPSEO_Abstract_Capability_Manager {
1444+
1445 /**
1446 * Adds the registered capabilities to the system.
1447 *
1448
1449=== modified file 'admin/capabilities/class-capability-manager-wp.php'
1450--- admin/capabilities/class-capability-manager-wp.php 2018-07-04 09:50:13 +0000
1451+++ admin/capabilities/class-capability-manager-wp.php 2019-11-08 16:06:28 +0000
1452@@ -9,6 +9,7 @@
1453 * Default WordPress capability manager implementation.
1454 */
1455 final class WPSEO_Capability_Manager_WP extends WPSEO_Abstract_Capability_Manager {
1456+
1457 /**
1458 * Adds the capabilities to the roles.
1459 *
1460
1461=== modified file 'admin/capabilities/class-capability-manager.php'
1462--- admin/capabilities/class-capability-manager.php 2018-07-04 09:50:13 +0000
1463+++ admin/capabilities/class-capability-manager.php 2019-11-08 16:06:28 +0000
1464@@ -9,6 +9,7 @@
1465 * Capability Manager interface.
1466 */
1467 interface WPSEO_Capability_Manager {
1468+
1469 /**
1470 * Registers a capability.
1471 *
1472
1473=== modified file 'admin/capabilities/class-capability-utils.php'
1474--- admin/capabilities/class-capability-utils.php 2018-07-04 09:50:13 +0000
1475+++ admin/capabilities/class-capability-utils.php 2019-11-08 16:06:28 +0000
1476@@ -9,6 +9,7 @@
1477 * Capability Utils collection.
1478 */
1479 class WPSEO_Capability_Utils {
1480+
1481 /**
1482 * Checks if the user has the proper capabilities.
1483 *
1484
1485=== modified file 'admin/capabilities/class-register-capabilities.php'
1486--- admin/capabilities/class-register-capabilities.php 2018-07-04 09:50:13 +0000
1487+++ admin/capabilities/class-register-capabilities.php 2019-11-08 16:06:28 +0000
1488@@ -9,6 +9,7 @@
1489 * Capabilities registration class.
1490 */
1491 class WPSEO_Register_Capabilities implements WPSEO_WordPress_Integration {
1492+
1493 /**
1494 * Registers the hooks.
1495 *
1496
1497=== modified file 'admin/class-add-keyword-modal.php'
1498--- admin/class-add-keyword-modal.php 2018-07-04 09:50:13 +0000
1499+++ admin/class-add-keyword-modal.php 2019-11-08 16:06:28 +0000
1500@@ -1,5 +1,7 @@
1501 <?php
1502 /**
1503+ * WPSEO plugin file.
1504+ *
1505 * @package WPSEO\Admin
1506 */
1507
1508@@ -18,36 +20,38 @@
1509 */
1510 public function get_translations() {
1511 return array(
1512- 'title' => __( 'Want to add more than one keyword?', 'wordpress-seo' ),
1513+ 'title' => __( 'Would you like to add more than one keyphrase?', 'wordpress-seo' ),
1514 'intro' => sprintf(
1515- /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
1516- __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
1517+ /* translators: %s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
1518+ __( 'Great news: you can, with %s!', 'wordpress-seo' ),
1519 '{{link}}Yoast SEO Premium{{/link}}'
1520 ),
1521 'link' => WPSEO_Shortlinker::get( 'https://yoa.st/pe-premium-page' ),
1522 'other' => sprintf(
1523 /* translators: %s expands to 'Yoast SEO Premium'. */
1524- __( 'Other benefits of %s for you:', 'wordpress-seo' ), 'Yoast SEO Premium'
1525+ __( 'Other benefits of %s for you:', 'wordpress-seo' ),
1526+ 'Yoast SEO Premium'
1527 ),
1528 'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
1529 'buy' => sprintf(
1530 /* translators: %s expands to 'Yoast SEO Premium'. */
1531- __( 'Get %s now!', 'wordpress-seo' ), 'Yoast SEO Premium'
1532+ __( 'Get %s', 'wordpress-seo' ),
1533+ 'Yoast SEO Premium'
1534 ),
1535- 'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
1536+ 'small' => __( '1 year free support and updates included!', 'wordpress-seo' ),
1537 'a11yNotice.opensInNewTab' => __( '(Opens in a new browser tab)', 'wordpress-seo' ),
1538 );
1539 }
1540
1541 /**
1542- * Pass tanslations to JS for the Add Keyword modal component.
1543+ * Passes translations to JS for the Add Keyword modal component.
1544 *
1545 * @return array Translated text strings for the Add Keyword modal component.
1546 */
1547 public function get_translations_for_js() {
1548 $translations = $this->get_translations();
1549 return array(
1550- 'locale' => WPSEO_Utils::get_user_locale(),
1551+ 'locale' => WPSEO_Language_Utils::get_user_locale(),
1552 'intl' => $translations,
1553 );
1554 }
1555
1556=== added file 'admin/class-admin-asset-analysis-worker-location.php'
1557--- admin/class-admin-asset-analysis-worker-location.php 1970-01-01 00:00:00 +0000
1558+++ admin/class-admin-asset-analysis-worker-location.php 2019-11-08 16:06:28 +0000
1559@@ -0,0 +1,75 @@
1560+<?php
1561+/**
1562+ * WPSEO plugin file.
1563+ *
1564+ * @package WPSEO\Admin
1565+ */
1566+
1567+/**
1568+ * Represents a way to determine the analysis worker asset location.
1569+ */
1570+final class WPSEO_Admin_Asset_Analysis_Worker_Location implements WPSEO_Admin_Asset_Location {
1571+
1572+ /**
1573+ * Holds the asset's location.
1574+ *
1575+ * @var WPSEO_Admin_Asset_Location $asset_location.
1576+ */
1577+ private $asset_location;
1578+
1579+ /**
1580+ * Holds the asset itself.
1581+ *
1582+ * @var WPSEO_Admin_Asset $asset.
1583+ */
1584+ private $asset;
1585+
1586+ /**
1587+ * Constructs the location of the analysis worker asset.
1588+ *
1589+ * @param string $flat_version The flat version of the asset.
1590+ * @param string $name The name of the analysis worker asset.
1591+ */
1592+ public function __construct( $flat_version = '', $name = 'analysis-worker' ) {
1593+ if ( $flat_version === '' ) {
1594+ $asset_manager = new WPSEO_Admin_Asset_Manager();
1595+ $flat_version = $asset_manager->flatten_version( WPSEO_VERSION );
1596+ }
1597+
1598+ $analysis_worker = 'wp-seo-' . $name . '-' . $flat_version;
1599+
1600+ $this->asset_location = WPSEO_Admin_Asset_Manager::create_default_location();
1601+ $this->asset = new WPSEO_Admin_Asset(
1602+ array(
1603+ 'name' => $name,
1604+ 'src' => $analysis_worker,
1605+ )
1606+ );
1607+ }
1608+
1609+ /**
1610+ * Retrieves the analysis worker asset.
1611+ *
1612+ * @return WPSEO_Admin_Asset The analysis worker asset.
1613+ */
1614+ public function get_asset() {
1615+ return $this->asset;
1616+ }
1617+
1618+ /**
1619+ * Determines the URL of the asset on the dev server.
1620+ *
1621+ * @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
1622+ * @param string $type The type of asset. Usually JS or CSS.
1623+ *
1624+ * @return string The URL of the asset.
1625+ */
1626+ public function get_url( WPSEO_Admin_Asset $asset, $type ) {
1627+ $scheme = wp_parse_url( $asset->get_src(), PHP_URL_SCHEME );
1628+ if ( in_array( $scheme, array( 'http', 'https' ), true ) ) {
1629+ return $asset->get_src();
1630+ }
1631+
1632+ return $this->asset_location->get_url( $asset, $type );
1633+ }
1634+}
1635
1636=== modified file 'admin/class-admin-asset-dev-server-location.php'
1637--- admin/class-admin-asset-dev-server-location.php 2018-07-04 09:50:13 +0000
1638+++ admin/class-admin-asset-dev-server-location.php 2019-11-08 16:06:28 +0000
1639@@ -9,32 +9,24 @@
1640 * Changes the asset paths to dev server paths.
1641 */
1642 final class WPSEO_Admin_Asset_Dev_Server_Location implements WPSEO_Admin_Asset_Location {
1643+
1644+ /**
1645+ * Holds the dev server's default URL.
1646+ *
1647+ * @var string
1648+ */
1649 const DEFAULT_URL = 'http://localhost:8080';
1650
1651 /**
1652- * @var array
1653- */
1654- private static $dev_server_script = array(
1655- 'commons',
1656- 'configuration-wizard',
1657- 'search-appearance',
1658- 'wp-seo-dashboard-widget',
1659- 'wp-seo-help-center',
1660- 'wp-seo-metabox',
1661- 'wp-seo-modal',
1662- 'wp-seo-post-scraper',
1663- 'wp-seo-replacevar-plugin',
1664- 'wp-seo-term-scraper',
1665- 'wp-seo-modal',
1666- 'wp-seo-wp-globals-backport',
1667- );
1668-
1669- /**
1670+ * Holds the url where the server is located.
1671+ *
1672 * @var string
1673 */
1674 private $url;
1675
1676 /**
1677+ * Class constructor.
1678+ *
1679 * @param string $url Where the dev server is located.
1680 */
1681 public function __construct( $url = null ) {
1682@@ -62,7 +54,7 @@
1683 $flat_version = $asset_manager->flatten_version( WPSEO_VERSION );
1684 $version_less_source = str_replace( '-' . $flat_version, '', $asset->get_src() );
1685
1686- if ( ! in_array( $version_less_source, self::$dev_server_script, true ) ) {
1687+ if ( false !== strpos( $version_less_source, 'select2' ) ) {
1688 return $this->get_default_url( $asset, $type );
1689 }
1690
1691
1692=== modified file 'admin/class-admin-asset-manager.php'
1693--- admin/class-admin-asset-manager.php 2018-07-04 09:50:13 +0000
1694+++ admin/class-admin-asset-manager.php 2019-11-08 16:06:28 +0000
1695@@ -6,22 +6,31 @@
1696 */
1697
1698 /**
1699- * This class registers all the necessary styles and scripts. Also has methods for the enqueing of scripts and styles. It automatically adds a prefix to the handle.
1700+ * This class registers all the necessary styles and scripts.
1701+ *
1702+ * Also has methods for the enqueing of scripts and styles.
1703+ * It automatically adds a prefix to the handle.
1704 */
1705 class WPSEO_Admin_Asset_Manager {
1706
1707 /**
1708+ * Class that manages the assets' location.
1709+ *
1710 * @var WPSEO_Admin_Asset_Location
1711 */
1712 protected $asset_location;
1713
1714 /**
1715- * Prefix for naming the assets.
1716+ * Prefix for naming the assets.
1717+ *
1718+ * @var string
1719 */
1720 const PREFIX = 'yoast-seo-';
1721
1722 /**
1723- * @var string prefix for naming the assets.
1724+ * Prefix for naming the assets.
1725+ *
1726+ * @var string
1727 */
1728 private $prefix;
1729
1730@@ -66,7 +75,7 @@
1731 public function register_script( WPSEO_Admin_Asset $script ) {
1732 wp_register_script(
1733 $this->prefix . $script->get_name(),
1734- $this->asset_location->get_url( $script, WPSEO_Admin_Asset::TYPE_JS ),
1735+ $this->get_url( $script, WPSEO_Admin_Asset::TYPE_JS ),
1736 $script->get_deps(),
1737 $script->get_version(),
1738 $script->is_in_footer()
1739@@ -81,7 +90,7 @@
1740 public function register_style( WPSEO_Admin_Asset $style ) {
1741 wp_register_style(
1742 $this->prefix . $style->get_name(),
1743- $this->asset_location->get_url( $style, WPSEO_Admin_Asset::TYPE_CSS ),
1744+ $this->get_url( $style, WPSEO_Admin_Asset::TYPE_CSS ),
1745 $style->get_deps(),
1746 $style->get_version(),
1747 $style->get_media()
1748@@ -109,9 +118,9 @@
1749 }
1750
1751 /**
1752- * Registers all the styles it recieves.
1753+ * Registers all the styles it receives.
1754 *
1755- * @param array $styles Styles that need to be registerd.
1756+ * @param array $styles Styles that need to be registered.
1757 */
1758 public function register_styles( $styles ) {
1759 foreach ( $styles as $style ) {
1760@@ -127,17 +136,16 @@
1761 */
1762 public function special_styles() {
1763 $flat_version = $this->flatten_version( WPSEO_VERSION );
1764-
1765- return array(
1766- 'inside-editor' => new WPSEO_Admin_Asset( array(
1767- 'name' => 'inside-editor',
1768- 'src' => 'inside-editor-' . $flat_version,
1769- ) ),
1770+ $asset_args = array(
1771+ 'name' => 'inside-editor',
1772+ 'src' => 'inside-editor-' . $flat_version,
1773 );
1774+
1775+ return array( 'inside-editor' => new WPSEO_Admin_Asset( $asset_args ) );
1776 }
1777
1778 /**
1779- * Flattens a version number for use in a filename
1780+ * Flattens a version number for use in a filename.
1781 *
1782 * @param string $version The original version number.
1783 *
1784@@ -169,17 +177,147 @@
1785 }
1786
1787 /**
1788+ * Registers the WordPress dependencies that exist in 5.0 in case they are not present.
1789+ *
1790+ * This function can be removed when WordPress 5.1 has been released, because from 5.0 wp-elements will be
1791+ * registered earlier, which means we don't have to reregister things.
1792+ *
1793+ * @return void
1794+ */
1795+ public function register_wp_assets() {
1796+
1797+ global $wp_scripts;
1798+
1799+ $script = $wp_scripts->query( 'react' );
1800+
1801+ // IE11 needs wp-polyfill to be registered before react.
1802+ if ( $script && ! in_array( 'wp-polyfill', $script->deps, true ) ) {
1803+ $script->deps[] = 'wp-polyfill';
1804+ }
1805+
1806+ $flat_version = $this->flatten_version( WPSEO_VERSION );
1807+
1808+ wp_register_script(
1809+ 'react',
1810+ plugins_url( 'js/vendor/react.min.js', WPSEO_FILE ),
1811+ array(),
1812+ 'v16.6.1',
1813+ true
1814+ );
1815+
1816+ wp_register_script(
1817+ 'react-dom',
1818+ plugins_url( 'js/vendor/react-dom.min.js', WPSEO_FILE ),
1819+ array( 'react' ),
1820+ 'v16.6.1',
1821+ true
1822+ );
1823+
1824+ wp_register_script(
1825+ 'lodash-base',
1826+ plugins_url( 'js/vendor/lodash.min.js', WPSEO_FILE ),
1827+ array(),
1828+ '4.17.5',
1829+ true
1830+ );
1831+
1832+ wp_register_script(
1833+ 'lodash',
1834+ plugins_url( 'js/vendor/lodash-noconflict.js', WPSEO_FILE ),
1835+ array( 'lodash-base' ),
1836+ WPSEO_VERSION,
1837+ true
1838+ );
1839+
1840+ wp_register_script(
1841+ 'wp-polyfill',
1842+ plugins_url( 'js/dist/babel-polyfill-' . $flat_version . '.min.js', WPSEO_FILE ),
1843+ array(),
1844+ WPSEO_VERSION,
1845+ true
1846+ );
1847+
1848+ wp_register_script(
1849+ 'wp-element',
1850+ plugins_url( 'js/dist/wp-element-' . $flat_version . '.min.js', WPSEO_FILE ),
1851+ array( 'lodash', 'wp-polyfill', 'react', 'react-dom' ),
1852+ WPSEO_VERSION,
1853+ true
1854+ );
1855+
1856+ wp_register_script(
1857+ 'wp-api-fetch',
1858+ plugins_url( 'js/dist/wp-apiFetch-' . $flat_version . '.min.js', WPSEO_FILE ),
1859+ array( 'wp-i18n', 'wp-polyfill' ),
1860+ WPSEO_VERSION,
1861+ true
1862+ );
1863+
1864+ wp_register_script(
1865+ 'wp-components',
1866+ plugins_url( 'js/dist/wp-components-' . $flat_version . '.min.js', WPSEO_FILE ),
1867+ array( 'lodash', 'wp-api-fetch', 'wp-i18n', 'wp-polyfill', 'wp-compose' ),
1868+ WPSEO_VERSION,
1869+ true
1870+ );
1871+
1872+ wp_register_script(
1873+ 'wp-data',
1874+ plugins_url( 'js/dist/wp-data-' . $flat_version . '.min.js', WPSEO_FILE ),
1875+ array( 'lodash', 'wp-element', 'wp-polyfill', 'wp-compose' ),
1876+ WPSEO_VERSION,
1877+ true
1878+ );
1879+
1880+ wp_register_script(
1881+ 'wp-i18n',
1882+ plugins_url( 'js/dist/wp-i18n-' . $flat_version . '.min.js', WPSEO_FILE ),
1883+ array( 'wp-polyfill' ),
1884+ WPSEO_VERSION,
1885+ true
1886+ );
1887+
1888+ wp_register_script(
1889+ 'wp-rich-text',
1890+ plugins_url( 'js/dist/wp-rich-text-' . $flat_version . '.min.js', WPSEO_FILE ),
1891+ array( 'lodash', 'wp-polyfill', 'wp-data' ),
1892+ WPSEO_VERSION,
1893+ true
1894+ );
1895+
1896+ wp_register_script(
1897+ 'wp-compose',
1898+ plugins_url( 'js/dist/wp-compose-' . $flat_version . '.min.js', WPSEO_FILE ),
1899+ array( 'lodash', 'wp-polyfill' ),
1900+ WPSEO_VERSION,
1901+ true
1902+ );
1903+
1904+ /*
1905+ * wp-annotations only exists from Gutenberg 4.3 and onwards, so we register a no-op in earlier versions.
1906+ * The no-op achieves that our scripts that depend on this are actually loaded. Because WordPress doesn't
1907+ * load a script if any of the dependencies are missing.
1908+ *
1909+ * @phpcs:disable WordPress.WP.EnqueuedResourceParameters -- The no-op does not require these settings.
1910+ */
1911+ wp_register_script(
1912+ 'wp-annotations',
1913+ null
1914+ );
1915+ // phpcs:enable -- End of disable.
1916+ }
1917+
1918+ /**
1919 * Returns the scripts that need to be registered.
1920 *
1921 * @todo Data format is not self-documenting. Needs explanation inline. R.
1922 *
1923- * @return array scripts that need to be registered.
1924+ * @return array The scripts that need to be registered.
1925 */
1926 protected function scripts_to_be_registered() {
1927-
1928 $select2_language = 'en';
1929- $user_locale = WPSEO_Utils::get_user_locale();
1930- $language = WPSEO_Utils::get_language( $user_locale );
1931+ $user_locale = WPSEO_Language_Utils::get_user_locale();
1932+ $language = WPSEO_Language_Utils::get_language( $user_locale );
1933
1934 if ( file_exists( WPSEO_PATH . "js/dist/select2/i18n/{$user_locale}.js" ) ) {
1935 $select2_language = $user_locale; // Chinese and some others use full locale.
1936@@ -190,52 +328,33 @@
1937
1938 $flat_version = $this->flatten_version( WPSEO_VERSION );
1939
1940- $backport_wp_dependencies = array( self::PREFIX . 'react-dependencies' );
1941-
1942- // If Gutenberg is present we can borrow their globals for our own.
1943- if ( function_exists( 'gutenberg_register_scripts_and_styles' ) ) {
1944- $backport_wp_dependencies[] = 'wp-element';
1945- $backport_wp_dependencies[] = 'wp-data';
1946-
1947- /*
1948- * The version of TinyMCE that Gutenberg uses is incompatible with
1949- * the one core uses. So we need to make sure that the core version
1950- * is used in the classic editor.
1951- *
1952- * $_GET is used here because as far as I am aware you cannot use
1953- * filter_input to check for the existence of a query variable.
1954- */
1955- if ( wp_script_is( 'tinymce-latest', 'registered' ) && isset( $_GET['classic-editor'] ) ) {
1956- wp_deregister_script( 'tinymce-latest' );
1957- wp_register_script( 'tinymce-latest', includes_url( 'js/tinymce/' ) . 'wp-tinymce.php', array( 'jquery' ), false, true );
1958- }
1959- }
1960-
1961 return array(
1962 array(
1963- 'name' => 'react-dependencies',
1964+ 'name' => 'commons',
1965 // Load webpack-commons for bundle support.
1966 'src' => 'commons-' . $flat_version,
1967 'deps' => array(
1968- self::PREFIX . 'babel-polyfill',
1969+ 'wp-polyfill',
1970 ),
1971 ),
1972 array(
1973 'name' => 'search-appearance',
1974- 'src' => 'search-appearance-' . $flat_version,
1975- 'deps' => 'react-dependencies',
1976- ),
1977- array(
1978- 'name' => 'wp-globals-backport',
1979- 'src' => 'wp-seo-wp-globals-backport-' . $flat_version,
1980- 'deps' => $backport_wp_dependencies,
1981+ 'src' => 'search-appearance-' . $flat_version,
1982+ 'deps' => array(
1983+ 'wp-api',
1984+ self::PREFIX . 'components',
1985+ self::PREFIX . 'commons',
1986+ ),
1987 ),
1988 array(
1989 'name' => 'yoast-modal',
1990 'src' => 'wp-seo-modal-' . $flat_version,
1991 'deps' => array(
1992 'jquery',
1993- self::PREFIX . 'wp-globals-backport',
1994+ 'wp-element',
1995+ 'wp-i18n',
1996+ self::PREFIX . 'components',
1997+ self::PREFIX . 'commons',
1998 ),
1999 ),
2000 array(
2001@@ -243,19 +362,23 @@
2002 'src' => 'wp-seo-help-center-' . $flat_version,
2003 'deps' => array(
2004 'jquery',
2005- self::PREFIX . 'wp-globals-backport',
2006+ 'wp-element',
2007+ 'wp-i18n',
2008+ self::PREFIX . 'components',
2009+ self::PREFIX . 'commons',
2010 ),
2011 ),
2012 array(
2013 'name' => 'admin-script',
2014 'src' => 'wp-seo-admin-' . $flat_version,
2015 'deps' => array(
2016+ 'lodash',
2017 'jquery',
2018 'jquery-ui-core',
2019 'jquery-ui-progressbar',
2020 self::PREFIX . 'select2',
2021 self::PREFIX . 'select2-translations',
2022- self::PREFIX . 'babel-polyfill',
2023+ self::PREFIX . 'commons',
2024 ),
2025 ),
2026 array(
2027@@ -264,32 +387,45 @@
2028 'deps' => array(
2029 'jquery',
2030 'jquery-ui-core',
2031- self::PREFIX . 'babel-polyfill',
2032+ self::PREFIX . 'commons',
2033+ ),
2034+ ),
2035+ array(
2036+ 'name' => 'network-admin-script',
2037+ 'src' => 'wp-seo-network-admin-' . $flat_version,
2038+ 'deps' => array(
2039+ 'jquery',
2040+ self::PREFIX . 'commons',
2041 ),
2042 ),
2043 array(
2044 'name' => 'bulk-editor',
2045 'src' => 'wp-seo-bulk-editor-' . $flat_version,
2046- 'deps' => array( 'jquery', self::PREFIX . 'babel-polyfill' ),
2047- ),
2048- array(
2049- 'name' => 'dismissible',
2050- 'src' => 'wp-seo-dismissible-' . $flat_version,
2051- 'deps' => array( 'jquery', self::PREFIX . 'babel-polyfill' ),
2052+ 'deps' => array(
2053+ 'jquery',
2054+ self::PREFIX . 'commons',
2055+ ),
2056 ),
2057 array(
2058 'name' => 'admin-global-script',
2059 'src' => 'wp-seo-admin-global-' . $flat_version,
2060- 'deps' => array( 'jquery', self::PREFIX . 'babel-polyfill' ),
2061+ 'deps' => array(
2062+ 'jquery',
2063+ self::PREFIX . 'commons',
2064+ ),
2065 ),
2066 array(
2067 'name' => 'metabox',
2068 'src' => 'wp-seo-metabox-' . $flat_version,
2069 'deps' => array(
2070 'jquery',
2071+ 'wp-element',
2072+ 'wp-i18n',
2073+ 'wp-data',
2074+ 'wp-components',
2075 self::PREFIX . 'select2',
2076 self::PREFIX . 'select2-translations',
2077- self::PREFIX . 'wp-globals-backport',
2078+ self::PREFIX . 'commons',
2079 ),
2080 'in_footer' => false,
2081 ),
2082@@ -298,45 +434,72 @@
2083 'src' => 'wp-seo-featured-image-' . $flat_version,
2084 'deps' => array(
2085 'jquery',
2086- self::PREFIX . 'babel-polyfill',
2087+ self::PREFIX . 'commons',
2088 ),
2089 ),
2090 array(
2091 'name' => 'admin-gsc',
2092 'src' => 'wp-seo-admin-gsc-' . $flat_version,
2093- 'deps' => array( self::PREFIX . 'babel-polyfill' ),
2094+ 'deps' => array(
2095+ 'wp-element',
2096+ 'wp-i18n',
2097+ self::PREFIX . 'styled-components',
2098+ self::PREFIX . 'components',
2099+ self::PREFIX . 'commons',
2100+ ),
2101 'in_footer' => false,
2102 ),
2103 array(
2104 'name' => 'post-scraper',
2105 'src' => 'wp-seo-post-scraper-' . $flat_version,
2106 'deps' => array(
2107+ 'wp-util',
2108+ 'wp-api',
2109+ 'wp-sanitize',
2110+ 'wp-element',
2111+ 'wp-i18n',
2112+ 'wp-data',
2113+ 'wp-api-fetch',
2114+ 'wp-annotations',
2115+ 'wp-compose',
2116 self::PREFIX . 'replacevar-plugin',
2117 self::PREFIX . 'shortcode-plugin',
2118- 'wp-util',
2119- self::PREFIX . 'wp-globals-backport',
2120+ self::PREFIX . 'analysis',
2121+ self::PREFIX . 'components',
2122+ self::PREFIX . 'commons',
2123 ),
2124 ),
2125 array(
2126 'name' => 'term-scraper',
2127 'src' => 'wp-seo-term-scraper-' . $flat_version,
2128 'deps' => array(
2129+ 'wp-sanitize',
2130+ 'wp-element',
2131+ 'wp-i18n',
2132+ 'wp-data',
2133+ 'wp-api-fetch',
2134+ 'wp-compose',
2135 self::PREFIX . 'replacevar-plugin',
2136- self::PREFIX . 'wp-globals-backport',
2137+ self::PREFIX . 'analysis',
2138+ self::PREFIX . 'components',
2139+ self::PREFIX . 'commons',
2140 ),
2141 ),
2142 array(
2143 'name' => 'replacevar-plugin',
2144 'src' => 'wp-seo-replacevar-plugin-' . $flat_version,
2145 'deps' => array(
2146- self::PREFIX . 'babel-polyfill',
2147+ self::PREFIX . 'analysis',
2148+ self::PREFIX . 'components',
2149+ self::PREFIX . 'commons',
2150 ),
2151 ),
2152 array(
2153 'name' => 'shortcode-plugin',
2154 'src' => 'wp-seo-shortcode-plugin-' . $flat_version,
2155 'deps' => array(
2156- self::PREFIX . 'babel-polyfill',
2157+ self::PREFIX . 'analysis',
2158+ self::PREFIX . 'commons',
2159 ),
2160 ),
2161 array(
2162@@ -346,7 +509,8 @@
2163 'jquery',
2164 'jquery-ui-core',
2165 'jquery-ui-progressbar',
2166- self::PREFIX . 'babel-polyfill',
2167+ self::PREFIX . 'analysis',
2168+ self::PREFIX . 'commons',
2169 ),
2170 ),
2171 array(
2172@@ -355,7 +519,13 @@
2173 'deps' => array(
2174 'jquery',
2175 'wp-util',
2176- self::PREFIX . 'babel-polyfill',
2177+ 'wp-element',
2178+ 'wp-i18n',
2179+ 'wp-components',
2180+ 'wp-data',
2181+ self::PREFIX . 'analysis',
2182+ self::PREFIX . 'components',
2183+ self::PREFIX . 'commons',
2184 ),
2185 ),
2186 array(
2187@@ -382,18 +552,13 @@
2188 'src' => 'configuration-wizard-' . $flat_version,
2189 'deps' => array(
2190 'jquery',
2191- self::PREFIX . 'wp-globals-backport',
2192+ 'wp-element',
2193+ 'wp-i18n',
2194+ 'wp-api',
2195+ self::PREFIX . 'components',
2196+ self::PREFIX . 'commons',
2197 ),
2198 ),
2199- // Register for backwards-compatiblity.
2200- array(
2201- 'name' => 'polyfill',
2202- 'src' => 'wp-seo-babel-polyfill-' . $flat_version,
2203- ),
2204- array(
2205- 'name' => 'babel-polyfill',
2206- 'src' => 'wp-seo-babel-polyfill-' . $flat_version,
2207- ),
2208 array(
2209 'name' => 'reindex-links',
2210 'src' => 'wp-seo-reindex-links-' . $flat_version,
2211@@ -401,17 +566,24 @@
2212 'jquery',
2213 'jquery-ui-core',
2214 'jquery-ui-progressbar',
2215+ self::PREFIX . 'commons',
2216 ),
2217 ),
2218 array(
2219 'name' => 'edit-page-script',
2220 'src' => 'wp-seo-edit-page-' . $flat_version,
2221- 'deps' => array( 'jquery' ),
2222+ 'deps' => array(
2223+ 'jquery',
2224+ self::PREFIX . 'commons',
2225+ ),
2226 ),
2227 array(
2228 'name' => 'quick-edit-handler',
2229 'src' => 'wp-seo-quick-edit-handler-' . $flat_version,
2230- 'deps' => array( 'jquery' ),
2231+ 'deps' => array(
2232+ 'jquery',
2233+ self::PREFIX . 'commons',
2234+ ),
2235 'in_footer' => true,
2236 ),
2237 array(
2238@@ -420,6 +592,7 @@
2239 'deps' => array(
2240 'wp-api',
2241 'jquery',
2242+ self::PREFIX . 'commons',
2243 ),
2244 ),
2245 array(
2246@@ -428,13 +601,54 @@
2247 'deps' => array(
2248 self::PREFIX . 'api',
2249 'jquery',
2250- self::PREFIX . 'wp-globals-backport',
2251+ 'wp-element',
2252+ 'wp-i18n',
2253+ self::PREFIX . 'components',
2254+ self::PREFIX . 'commons',
2255 ),
2256 ),
2257 array(
2258 'name' => 'filter-explanation',
2259 'src' => 'wp-seo-filter-explanation-' . $flat_version,
2260- 'deps' => array( 'jquery' ),
2261+ 'deps' => array(
2262+ 'jquery',
2263+ self::PREFIX . 'commons',
2264+ ),
2265+ ),
2266+ array(
2267+ 'name' => 'analysis',
2268+ 'src' => 'analysis-' . $flat_version,
2269+ 'deps' => array(
2270+ 'lodash',
2271+ self::PREFIX . 'commons',
2272+ ),
2273+ ),
2274+ array(
2275+ 'name' => 'components',
2276+ 'src' => 'components-' . $flat_version,
2277+ 'deps' => array(
2278+ self::PREFIX . 'analysis',
2279+ self::PREFIX . 'styled-components',
2280+ self::PREFIX . 'commons',
2281+ ),
2282+ ),
2283+ array(
2284+ 'name' => 'structured-data-blocks',
2285+ 'src' => 'wp-seo-structured-data-blocks-' . $flat_version,
2286+ 'deps' => array(
2287+ 'wp-blocks',
2288+ 'wp-i18n',
2289+ 'wp-element',
2290+ self::PREFIX . 'styled-components',
2291+ self::PREFIX . 'commons',
2292+ ),
2293+ ),
2294+ array(
2295+ 'name' => 'styled-components',
2296+ 'src' => 'styled-components-' . $flat_version,
2297+ 'deps' => array(
2298+ 'wp-element',
2299+ ),
2300 ),
2301 );
2302 }
2303@@ -444,7 +658,7 @@
2304 *
2305 * @todo Data format is not self-documenting. Needs explanation inline. R.
2306 *
2307- * @return array styles that need to be registered.
2308+ * @return array Styles that need to be registered.
2309 */
2310 protected function styles_to_be_registered() {
2311 $flat_version = $this->flatten_version( WPSEO_VERSION );
2312@@ -491,12 +705,11 @@
2313 'src' => 'yst_seo_score-' . $flat_version,
2314 ),
2315 array(
2316- 'name' => 'snippet',
2317- 'src' => 'snippet-' . $flat_version,
2318- ),
2319- array(
2320 'name' => 'adminbar',
2321 'src' => 'adminbar-' . $flat_version,
2322+ 'deps' => array(
2323+ 'admin-bar',
2324+ ),
2325 ),
2326 array(
2327 'name' => 'primary-category',
2328@@ -527,8 +740,30 @@
2329 ),
2330 array(
2331 'name' => 'search-appearance',
2332- 'src' => 'search-appearance-' . $flat_version,
2333+ 'src' => 'search-appearance-' . $flat_version,
2334+ ),
2335+ array(
2336+ 'name' => 'structured-data-blocks',
2337+ 'src' => 'structured-data-blocks-' . $flat_version,
2338+ 'deps' => array( 'wp-edit-blocks' ),
2339 ),
2340 );
2341 }
2342+
2343+ /**
2344+ * Determines the URL of the asset.
2345+ *
2346+ * @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
2347+ * @param string $type The type of asset. Usually JS or CSS.
2348+ *
2349+ * @return string The URL of the asset.
2350+ */
2351+ protected function get_url( WPSEO_Admin_Asset $asset, $type ) {
2352+ $scheme = wp_parse_url( $asset->get_src(), PHP_URL_SCHEME );
2353+ if ( in_array( $scheme, array( 'http', 'https' ), true ) ) {
2354+ return $asset->get_src();
2355+ }
2356+
2357+ return $this->asset_location->get_url( $asset, $type );
2358+ }
2359 }
2360
2361=== modified file 'admin/class-admin-asset-seo-location.php'
2362--- admin/class-admin-asset-seo-location.php 2018-07-04 09:50:13 +0000
2363+++ admin/class-admin-asset-seo-location.php 2019-11-08 16:06:28 +0000
2364@@ -11,6 +11,8 @@
2365 final class WPSEO_Admin_Asset_SEO_Location implements WPSEO_Admin_Asset_Location {
2366
2367 /**
2368+ * Path to the plugin file.
2369+ *
2370 * @var string
2371 */
2372 protected $plugin_file;
2373
2374=== modified file 'admin/class-admin-asset-yoast-components-l10n.php'
2375--- admin/class-admin-asset-yoast-components-l10n.php 2018-07-04 09:50:13 +0000
2376+++ admin/class-admin-asset-yoast-components-l10n.php 2019-11-08 16:06:28 +0000
2377@@ -1,12 +1,15 @@
2378 <?php
2379 /**
2380+ * WPSEO plugin file.
2381+ *
2382 * @package WPSEO\Admin
2383 */
2384
2385 /**
2386 * Localizes JavaScript files.
2387 */
2388-final class WPSEO_Admin_Asset_Yoast_Components_l10n {
2389+final class WPSEO_Admin_Asset_Yoast_Components_L10n {
2390+
2391 /**
2392 * Localizes the given script with the JavaScript translations.
2393 *
2394@@ -15,10 +18,11 @@
2395 * @return void
2396 */
2397 public function localize_script( $script_handle ) {
2398- wp_localize_script( $script_handle, 'wpseoYoastJSL10n', array(
2399+ $translations = array(
2400 'yoast-components' => $this->get_translations( 'yoast-components' ),
2401- 'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
2402- ) );
2403+ 'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
2404+ );
2405+ wp_localize_script( $script_handle, 'wpseoYoastJSL10n', $translations );
2406 }
2407
2408 /**
2409@@ -28,7 +32,7 @@
2410 * @return object The translations in a Jed format for JS files.
2411 */
2412 protected function get_translations( $component ) {
2413- $locale = WPSEO_Utils::get_user_locale();
2414+ $locale = WPSEO_Language_Utils::get_user_locale();
2415
2416 $file = plugin_dir_path( WPSEO_FILE ) . 'languages/' . $component . '-' . $locale . '.json';
2417 if ( file_exists( $file ) ) {
2418
2419=== added file 'admin/class-admin-banner.php'
2420--- admin/class-admin-banner.php 1970-01-01 00:00:00 +0000
2421+++ admin/class-admin-banner.php 2019-11-08 16:06:28 +0000
2422@@ -0,0 +1,67 @@
2423+<?php
2424+/**
2425+ * WPSEO plugin file.
2426+ *
2427+ * @package WPSEO\Admin
2428+ */
2429+
2430+/**
2431+ * Class WPSEO_Admin_Banner.
2432+ */
2433+class WPSEO_Admin_Banner implements WPSEO_WordPress_Integration {
2434+ /**
2435+ * Registers all hooks to WordPress.
2436+ *
2437+ * @return void
2438+ */
2439+ public function register_hooks() {
2440+ add_action( 'admin_notices', array( $this, 'banner' ) );
2441+ }
2442+
2443+ /**
2444+ * Renders the admin banner.
2445+ */
2446+ public function banner() {
2447+ if ( isset( $_GET['yst_dismiss_bf'] ) ) {
2448+ WPSEO_Options::set( 'bf_banner_2019_dismissed', $_GET['yst_dismiss_bf'] === '1' );
2449+ }
2450+
2451+ if ( ! $this->should_run_banner() ) {
2452+ return;
2453+ }
2454+
2455+ $close_url = add_query_arg( array( 'yst_dismiss_bf' => 1 ) );
2456+
2457+ ?>
2458+ <div class="yoast_bf_sale">
2459+ <a class="close" href="<?php echo esc_url( $close_url ); ?>" aria-label="Dismiss the Yoast Black Friday Banner">X</a>
2460+ <a class="target" href="<?php echo esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/bf-sale-2019' ) ); ?>"></a>
2461+ </div>
2462+ <?php
2463+ }
2464+
2465+ /**
2466+ * Determines whether the banner should be shown or not.
2467+ *
2468+ * @return bool True if it should be shown, false if not.
2469+ */
2470+ private function should_run_banner() {
2471+ if ( WPSEO_Utils::is_yoast_seo_premium() ) {
2472+ return false;
2473+ }
2474+
2475+ if ( WPSEO_Options::get( 'bf_banner_2019_dismissed' ) ) {
2476+ return false;
2477+ }
2478+
2479+ $time = time();
2480+
2481+ // 1574938800 is November 28th 12:00 CET.
2482+ // 1575381600 is December 3rd 15:00 CET.
2483+ if ( $time >= 1574938800 && $time < 1575381600 ) {
2484+ return true;
2485+ }
2486+
2487+ return false;
2488+ }
2489+}
2490
2491=== added file 'admin/class-admin-editor-specific-replace-vars.php'
2492--- admin/class-admin-editor-specific-replace-vars.php 1970-01-01 00:00:00 +0000
2493+++ admin/class-admin-editor-specific-replace-vars.php 2019-11-08 16:06:28 +0000
2494@@ -0,0 +1,227 @@
2495+<?php
2496+/**
2497+ * WPSEO plugin file.
2498+ *
2499+ * @package WPSEO\Admin
2500+ */
2501+
2502+/**
2503+ * Determines the editor specific replacement variables.
2504+ */
2505+class WPSEO_Admin_Editor_Specific_Replace_Vars {
2506+
2507+ /**
2508+ * Holds the editor specific replacements variables.
2509+ *
2510+ * @var array The editor specific replacement variables.
2511+ */
2512+ protected $replacement_variables = array(
2513+ // Posts types.
2514+ 'page' => array( 'id', 'pt_single', 'pt_plural', 'parent_title' ),
2515+ 'post' => array( 'id', 'term404', 'pt_single', 'pt_plural' ),
2516+ // Custom post type.
2517+ 'custom_post_type' => array( 'id', 'term404', 'pt_single', 'pt_plural', 'parent_title' ),
2518+ // Settings - archive pages.
2519+ 'custom-post-type_archive' => array( 'pt_single', 'pt_plural' ),
2520+
2521+ // Taxonomies.
2522+ 'category' => array( 'term_title', 'term_description', 'category_description', 'parent_title' ),
2523+ 'post_tag' => array( 'term_title', 'term_description', 'tag_description' ),
2524+ 'post_format' => array(),
2525+ // Custom taxonomy.
2526+ 'term-in-custom-taxonomy' => array( 'term_title', 'term_description', 'category_description', 'parent_title' ),
2527+
2528+ // Settings - special pages.
2529+ 'search' => array( 'searchphrase' ),
2530+ );
2531+
2532+ /**
2533+ * WPSEO_Admin_Editor_Specific_Replace_Vars constructor.
2534+ */
2535+ public function __construct() {
2536+ $this->add_for_page_types(
2537+ array( 'page', 'post', 'custom_post_type' ),
2538+ WPSEO_Custom_Fields::get_custom_fields()
2539+ );
2540+
2541+ $this->add_for_page_types(
2542+ array( 'post', 'term-in-custom-taxonomies' ),
2543+ WPSEO_Custom_Taxonomies::get_custom_taxonomies()
2544+ );
2545+ }
2546+
2547+ /**
2548+ * Retrieves the editor specific replacement variables.
2549+ *
2550+ * @return array The editor specific replacement variables.
2551+ */
2552+ public function get() {
2553+ /**
2554+ * Filter: Adds the possibility to add extra editor specific replacement variables.
2555+ *
2556+ * @api array $replacement_variables Empty array to add the editor specific replace vars to.
2557+ */
2558+ $replacement_variables = apply_filters(
2559+ 'wpseo_editor_specific_replace_vars',
2560+ $this->replacement_variables
2561+ );
2562+
2563+ if ( ! is_array( $replacement_variables ) ) {
2564+ $replacement_variables = $this->replacement_variables;
2565+ }
2566+
2567+ return array_filter( $replacement_variables, 'is_array' );
2568+ }
2569+
2570+ /**
2571+ * Retrieves the generic replacement variable names.
2572+ *
2573+ * Which are the replacement variables without the editor specific ones.
2574+ *
2575+ * @param array $replacement_variables Possibly generic replacement variables.
2576+ *
2577+ * @return array The generic replacement variable names.
2578+ */
2579+ public function get_generic( $replacement_variables ) {
2580+ $shared_variables = array_diff(
2581+ $this->extract_names( $replacement_variables ),
2582+ $this->get_unique_replacement_variables()
2583+ );
2584+
2585+ return array_values( $shared_variables );
2586+ }
2587+
2588+ /**
2589+ * Determines the page type of the current term.
2590+ *
2591+ * @param string $taxonomy The taxonomy name.
2592+ *
2593+ * @return string The page type.
2594+ */
2595+ public function determine_for_term( $taxonomy ) {
2596+ $replacement_variables = $this->get();
2597+ if ( array_key_exists( $taxonomy, $replacement_variables ) ) {
2598+ return $taxonomy;
2599+ }
2600+
2601+ return 'term-in-custom-taxonomy';
2602+ }
2603+
2604+ /**
2605+ * Determines the page type of the current post.
2606+ *
2607+ * @param WP_Post $post A WordPress post instance.
2608+ *
2609+ * @return string The page type.
2610+ */
2611+ public function determine_for_post( $post ) {
2612+ if ( $post instanceof WP_Post === false ) {
2613+ return 'post';
2614+ }
2615+
2616+ $replacement_variables = $this->get();
2617+ if ( array_key_exists( $post->post_type, $replacement_variables ) ) {
2618+ return $post->post_type;
2619+ }
2620+
2621+ return 'custom_post_type';
2622+ }
2623+
2624+ /**
2625+ * Determines the page type for a post type.
2626+ *
2627+ * @param string $post_type The name of the post_type.
2628+ * @param string $fallback The page type to fall back to.
2629+ *
2630+ * @return string The page type.
2631+ */
2632+ public function determine_for_post_type( $post_type, $fallback = 'custom_post_type' ) {
2633+ if ( ! $this->has_for_page_type( $post_type ) ) {
2634+ return $fallback;
2635+ }
2636+
2637+ return $post_type;
2638+ }
2639+
2640+ /**
2641+ * Determines the page type for an archive page.
2642+ *
2643+ * @param string $name The name of the archive.
2644+ * @param string $fallback The page type to fall back to.
2645+ *
2646+ * @return string The page type.
2647+ */
2648+ public function determine_for_archive( $name, $fallback = 'custom-post-type_archive' ) {
2649+ $page_type = $name . '_archive';
2650+
2651+ if ( ! $this->has_for_page_type( $page_type ) ) {
2652+ return $fallback;
2653+ }
2654+
2655+ return $page_type;
2656+ }
2657+
2658+ /**
2659+ * Adds the replavement variables for the given page types.
2660+ *
2661+ * @param array $page_types Page types to add variables for.
2662+ * @param array $replacement_variables_to_add The variables to add.
2663+ *
2664+ * @return void
2665+ */
2666+ protected function add_for_page_types( array $page_types, array $replacement_variables_to_add ) {
2667+ if ( empty( $replacement_variables_to_add ) ) {
2668+ return;
2669+ }
2670+
2671+ $replacement_variables_to_add = array_fill_keys( $page_types, $replacement_variables_to_add );
2672+ $replacement_variables = $this->replacement_variables;
2673+
2674+ $this->replacement_variables = array_merge_recursive( $replacement_variables, $replacement_variables_to_add );
2675+ }
2676+
2677+ /**
2678+ * Extracts the names from the given replacements variables.
2679+ *
2680+ * @param array $replacement_variables Replacement variables to extract the name from.
2681+ *
2682+ * @return array Extracted names.
2683+ */
2684+ protected function extract_names( $replacement_variables ) {
2685+ $extracted_names = array();
2686+
2687+ foreach ( $replacement_variables as $replacement_variable ) {
2688+ if ( empty( $replacement_variable['name'] ) ) {
2689+ continue;
2690+ }
2691+
2692+ $extracted_names[] = $replacement_variable['name'];
2693+ }
2694+
2695+ return $extracted_names;
2696+ }
2697+
2698+ /**
2699+ * Returns whether the given page type has editor specific replace vars.
2700+ *
2701+ * @param string $page_type The page type to check.
2702+ *
2703+ * @return bool True if there are associated editor specific replace vars.
2704+ */
2705+ protected function has_for_page_type( $page_type ) {
2706+ $replacement_variables = $this->get();
2707+
2708+ return ( ! empty( $replacement_variables[ $page_type ] ) && is_array( $replacement_variables[ $page_type ] ) );
2709+ }
2710+
2711+ /**
2712+ * Merges all editor specific replacement variables into one array and removes duplicates.
2713+ *
2714+ * @return array The list of unique editor specific replacement variables.
2715+ */
2716+ protected function get_unique_replacement_variables() {
2717+ $merged_replacement_variables = call_user_func_array( 'array_merge', $this->get() );
2718+
2719+ return array_unique( $merged_replacement_variables );
2720+ }
2721+}
2722
2723=== added file 'admin/class-admin-gutenberg-compatibility-notification.php'
2724--- admin/class-admin-gutenberg-compatibility-notification.php 1970-01-01 00:00:00 +0000
2725+++ admin/class-admin-gutenberg-compatibility-notification.php 2019-11-08 16:06:28 +0000
2726@@ -0,0 +1,93 @@
2727+<?php
2728+/**
2729+ * WPSEO plugin file.
2730+ *
2731+ * @package WPSEO\Admin
2732+ */
2733+
2734+/**
2735+ * Handles the Gutenberg Compatibility notification showing and hiding.
2736+ */
2737+class WPSEO_Admin_Gutenberg_Compatibility_Notification implements WPSEO_WordPress_Integration {
2738+
2739+ /**
2740+ * Notification ID to use.
2741+ *
2742+ * @var string
2743+ */
2744+ private $notification_id = 'wpseo-outdated-gutenberg-plugin';
2745+
2746+ /**
2747+ * Instance of gutenberg compatibility checker.
2748+ *
2749+ * @var WPSEO_Gutenberg_Compatibility
2750+ */
2751+ private $compatibility_checker;
2752+
2753+ /**
2754+ * Instance of Yoast Notification Center.
2755+ *
2756+ * @var Yoast_Notification_Center
2757+ */
2758+ private $notification_center;
2759+
2760+ /**
2761+ * WPSEO_Admin_Gutenberg_Compatibility_Notification constructor.
2762+ */
2763+ public function __construct() {
2764+ $this->compatibility_checker = new WPSEO_Gutenberg_Compatibility();
2765+ $this->notification_center = Yoast_Notification_Center::get();
2766+ }
2767+
2768+ /**
2769+ * Registers all hooks to WordPress.
2770+ *
2771+ * @return void
2772+ */
2773+ public function register_hooks() {
2774+ add_action( 'admin_init', array( $this, 'manage_notification' ) );
2775+ }
2776+
2777+ /**
2778+ * Manages if the notification should be shown or removed.
2779+ *
2780+ * @return void
2781+ */
2782+ public function manage_notification() {
2783+ if ( ! $this->compatibility_checker->is_installed() || $this->compatibility_checker->is_fully_compatible() ) {
2784+ $this->notification_center->remove_notification_by_id( $this->notification_id );
2785+
2786+ return;
2787+ }
2788+
2789+ $this->add_notification();
2790+ }
2791+
2792+ /**
2793+ * Adds the notification to the notificaton center.
2794+ *
2795+ * @return void
2796+ */
2797+ private function add_notification() {
2798+ $level = $this->compatibility_checker->is_below_minimum() ? Yoast_Notification::ERROR : Yoast_Notification::WARNING;
2799+
2800+ $message = sprintf(
2801+ /* translators: %1$s expands to Yoast SEO, %2$s expands to the installed version, %3$s expands to Gutenberg */
2802+ __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ),
2803+ 'Yoast SEO',
2804+ $this->compatibility_checker->get_installed_version(),
2805+ 'Gutenberg'
2806+ );
2807+
2808+ $notification = new Yoast_Notification(
2809+ $message,
2810+ array(
2811+ 'id' => $this->notification_id,
2812+ 'type' => $level,
2813+ 'priority' => 1,
2814+ )
2815+ );
2816+
2817+ $this->notification_center->add_notification( $notification );
2818+ }
2819+}
2820
2821=== modified file 'admin/class-admin-help-panel.php'
2822--- admin/class-admin-help-panel.php 2018-07-04 09:50:13 +0000
2823+++ admin/class-admin-help-panel.php 2019-11-08 16:06:28 +0000
2824@@ -11,21 +11,29 @@
2825 class WPSEO_Admin_Help_Panel {
2826
2827 /**
2828+ * Unique identifier of the element the inline help refers to, used as an identifier in the html.
2829+ *
2830 * @var string
2831 */
2832 private $id;
2833
2834 /**
2835+ * The Help Button text. Needs a properly escaped string.
2836+ *
2837 * @var string
2838 */
2839 private $help_button_text;
2840
2841 /**
2842+ * The Help Panel content. Needs a properly escaped string (might contain HTML).
2843+ *
2844 * @var string
2845 */
2846 private $help_content;
2847
2848 /**
2849+ * Optional Whether to print out a container div element for the Help Panel, used for styling.
2850+ *
2851 * @var string
2852 */
2853 private $wrapper;
2854
2855=== modified file 'admin/class-admin-init.php'
2856--- admin/class-admin-init.php 2018-07-04 09:50:13 +0000
2857+++ admin/class-admin-init.php 2019-11-08 16:06:28 +0000
2858@@ -25,7 +25,7 @@
2859 private $asset_manager;
2860
2861 /**
2862- * Class constructor
2863+ * Class constructor.
2864 */
2865 public function __construct() {
2866 $GLOBALS['wpseo_admin'] = new WPSEO_Admin();
2867@@ -40,13 +40,28 @@
2868 add_action( 'admin_init', array( $this, 'permalink_notice' ), 15 );
2869 add_action( 'admin_init', array( $this, 'page_comments_notice' ), 15 );
2870 add_action( 'admin_init', array( $this, 'ga_compatibility_notice' ), 15 );
2871- add_action( 'admin_init', array( $this, 'yoast_plugin_compatibility_notification' ), 15 );
2872 add_action( 'admin_init', array( $this, 'yoast_plugin_suggestions_notification' ), 15 );
2873 add_action( 'admin_init', array( $this, 'recalculate_notice' ), 15 );
2874 add_action( 'admin_init', array( $this, 'unsupported_php_notice' ), 15 );
2875+ add_action( 'admin_init', array( $this, 'wordpress_upgrade_notice' ), 15 );
2876 add_action( 'admin_init', array( $this->asset_manager, 'register_assets' ) );
2877 add_action( 'admin_init', array( $this, 'show_hook_deprecation_warnings' ) );
2878 add_action( 'admin_init', array( 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ) );
2879+ add_action( 'admin_init', array( $this, 'handle_notifications' ), 15 );
2880+ add_action( 'admin_notices', array( $this, 'permalink_settings_notice' ) );
2881+ add_action( 'admin_enqueue_scripts', array( $this->asset_manager, 'register_wp_assets' ), PHP_INT_MAX );
2882+
2883+ $listeners = array();
2884+ $listeners[] = new WPSEO_Post_Type_Archive_Notification_Handler();
2885+
2886+ /**
2887+ * Listener interface classes.
2888+ *
2889+ * @var WPSEO_Listener $listener
2890+ */
2891+ foreach ( $listeners as $listener ) {
2892+ $listener->listen();
2893+ }
2894
2895 $this->load_meta_boxes();
2896 $this->load_taxonomy_class();
2897@@ -57,6 +72,26 @@
2898 }
2899
2900 /**
2901+ * Handles the notifiers for the dashboard page.
2902+ *
2903+ * @return void
2904+ */
2905+ public function handle_notifications() {
2906+ /**
2907+ * Notification handlers.
2908+ *
2909+ * @var WPSEO_Notification_Handler[] $handlers
2910+ */
2911+ $handlers = array();
2912+ $handlers[] = new WPSEO_Post_Type_Archive_Notification_Handler();
2913+
2914+ $notification_center = Yoast_Notification_Center::get();
2915+ foreach ( $handlers as $handler ) {
2916+ $handler->handle( $notification_center );
2917+ }
2918+ }
2919+
2920+ /**
2921 * Enqueue our styling for dismissible yoast notifications.
2922 */
2923 public function enqueue_dismissible() {
2924@@ -64,28 +99,13 @@
2925 }
2926
2927 /**
2928- * Helper to verify if the current user has already seen the about page for the current version
2929- *
2930- * @return bool
2931- */
2932- private function seen_about() {
2933- $seen_about_version = substr( get_user_meta( get_current_user_id(), 'wpseo_seen_about_version', true ), 0, 3 );
2934- $last_minor_version = substr( WPSEO_VERSION, 0, 3 );
2935-
2936- return version_compare( $seen_about_version, $last_minor_version, '>=' );
2937- }
2938-
2939- /**
2940- * Notify about the default tagline if the user hasn't changed it
2941+ * Notify about the default tagline if the user hasn't changed it.
2942 */
2943 public function tagline_notice() {
2944-
2945- $current_url = ( is_ssl() ? 'https://' : 'http://' );
2946- $current_url .= sanitize_text_field( $_SERVER['SERVER_NAME'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] );
2947- $customize_url = add_query_arg( array(
2948+ $query_args = array(
2949 'autofocus[control]' => 'blogdescription',
2950- 'url' => urlencode( $current_url ),
2951- ), wp_customize_url() );
2952+ );
2953+ $customize_url = add_query_arg( $query_args, wp_customize_url() );
2954
2955 $info_message = sprintf(
2956 /* translators: 1: link open tag; 2: link close tag. */
2957@@ -103,16 +123,11 @@
2958 $tagline_notification = new Yoast_Notification( $info_message, $notification_options );
2959
2960 $notification_center = Yoast_Notification_Center::get();
2961- if ( $this->has_default_tagline() ) {
2962- $notification_center->add_notification( $tagline_notification );
2963- }
2964- else {
2965- $notification_center->remove_notification( $tagline_notification );
2966- }
2967+ $notification_center->remove_notification( $tagline_notification );
2968 }
2969
2970 /**
2971- * Add an alert if the blog is not publicly visible
2972+ * Add an alert if the blog is not publicly visible.
2973 */
2974 public function blog_public_notice() {
2975
2976@@ -143,7 +158,7 @@
2977 }
2978
2979 /**
2980- * Display notice to disable comment pagination
2981+ * Display notice to disable comment pagination.
2982 */
2983 public function page_comments_notice() {
2984
2985@@ -175,7 +190,7 @@
2986 }
2987
2988 /**
2989- * Returns whether or not the site has the default tagline
2990+ * Returns whether or not the site has the default tagline.
2991 *
2992 * @return bool
2993 */
2994@@ -185,13 +200,13 @@
2995
2996 // We are checking against the WordPress internal translation.
2997 // @codingStandardsIgnoreLine
2998- $translated_blog_description = __( 'Just another WordPress site' );
2999+ $translated_blog_description = __( 'Just another WordPress site', 'default' );
3000
3001 return $translated_blog_description === $blog_description || $default_blog_description === $blog_description;
3002 }
3003
3004 /**
3005- * Show alert when the permalink doesn't contain %postname%
3006+ * Show alert when the permalink doesn't contain %postname%.
3007 */
3008 public function permalink_notice() {
3009
3010@@ -223,7 +238,7 @@
3011 }
3012
3013 /**
3014- * Are page comments enabled
3015+ * Are page comments enabled.
3016 *
3017 * @return bool
3018 */
3019@@ -249,7 +264,7 @@
3020 }
3021
3022 /**
3023- * Build compatibility problem notification
3024+ * Build compatibility problem notification.
3025 *
3026 * @return Yoast_Notification
3027 */
3028@@ -325,56 +340,6 @@
3029 }
3030
3031 /**
3032- * Add an alert if outdated versions of Yoast SEO plugins are running.
3033- */
3034- public function yoast_plugin_compatibility_notification() {
3035- $compatibility_checker = new WPSEO_Plugin_Compatibility( WPSEO_VERSION );
3036- $plugins = $compatibility_checker->get_installed_plugins_compatibility();
3037-
3038- $notification_center = Yoast_Notification_Center::get();
3039-
3040- foreach ( $plugins as $name => $plugin ) {
3041- $type = ( $plugin['active'] ) ? Yoast_Notification::ERROR : Yoast_Notification::WARNING;
3042- $notification = $this->get_yoast_seo_compatibility_notification( $name, $plugin, $type );
3043-
3044- if ( $plugin['compatible'] === false ) {
3045- $notification_center->add_notification( $notification );
3046-
3047- continue;
3048- }
3049-
3050- $notification_center->remove_notification( $notification );
3051- }
3052- }
3053-
3054- /**
3055- * Build Yoast SEO compatibility problem notification
3056- *
3057- * @param string $name The plugin name to use for the unique ID.
3058- * @param array $plugin The plugin to retrieve the data from.
3059- * @param string $level The severity level to use for the notification.
3060- *
3061- * @return Yoast_Notification
3062- */
3063- private function get_yoast_seo_compatibility_notification( $name, $plugin, $level = Yoast_Notification::WARNING ) {
3064- $info_message = sprintf(
3065- /* translators: %1$s expands to Yoast SEO, %2$s expands to the plugin version, %3$s expands to the plugin name */
3066- __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ),
3067- 'Yoast SEO',
3068- $plugin['version'],
3069- $plugin['title']
3070- );
3071-
3072- return new Yoast_Notification(
3073- $info_message,
3074- array(
3075- 'id' => 'wpseo-outdated-yoast-seo-plugin-' . $name,
3076- 'type' => $level,
3077- )
3078- );
3079- }
3080-
3081- /**
3082 * Shows the notice for recalculating the post. the Notice will only be shown if the user hasn't dismissed it before.
3083 */
3084 public function recalculate_notice() {
3085@@ -418,38 +383,108 @@
3086 * @return void
3087 */
3088 public function unsupported_php_notice() {
3089- $info_message = sprintf(
3090- /* translators: 1: The strong opening tag; 2: The strong closing tag; 3: the Yoast SEO version that is dropping support; 4: The release date of the version of Yoast SEO that is dropping support; 5: The PHP version no longer being supported; */
3091- __( '%1$sAction is needed%2$s: As of version %3$s, due to be released on %4$s, Yoast SEO will no longer work with PHP %5$s. Unfortunately, your site is running on PHP %5$s right now, so action is needed. Thankfully, you can update your PHP yourself.', 'wordpress-seo' ),
3092+ $notification_center = Yoast_Notification_Center::get();
3093+ $notification_center->remove_notification_by_id( 'wpseo-dismiss-unsupported-php' );
3094+ }
3095+
3096+ /**
3097+ * Gets the latest released major WordPress version from the WordPress stable-check api.
3098+ *
3099+ * @return float The latest released major WordPress version. 0 The stable-check api doesn't respond.
3100+ */
3101+ private function get_latest_major_wordpress_version() {
3102+ $core_updates = get_core_updates( array( 'dismissed' => true ) );
3103+
3104+ if ( $core_updates === false ) {
3105+ return 0;
3106+ }
3107+
3108+ $wp_version_latest = get_bloginfo( 'version' );
3109+ foreach ( $core_updates as $update ) {
3110+ if ( $update->response === 'upgrade' && version_compare( $update->version, $wp_version_latest, '>' ) ) {
3111+ $wp_version_latest = $update->version;
3112+ }
3113+ }
3114+
3115+ // Strip the patch version and convert to a float.
3116+ return (float) $wp_version_latest;
3117+ }
3118+
3119+ /**
3120+ * Creates a WordPress upgrade notification in the notification center.
3121+ *
3122+ * @return void
3123+ */
3124+ public function wordpress_upgrade_notice() {
3125+ global $wp_version;
3126+
3127+ $latest_major_wp_version = number_format( $this->get_latest_major_wordpress_version(), 1 );
3128+ $next_major_wp_version = number_format( ( $latest_major_wp_version + 0.1 ), 1 );
3129+
3130+ $wp_less_than_50 = version_compare( $wp_version, '5.0', '<' );
3131+ $wp_less_than_latest_version = version_compare( $wp_version, $latest_major_wp_version, '<' );
3132+
3133+ $notification_center = Yoast_Notification_Center::get();
3134+
3135+ $message = sprintf(
3136+ /* translators: %1$s expands to an opening strong tag, %2$s expands to a closing strong tag, %3$s expands to a html break, %4$s expands to Yoast, %5$s expands to Yoast SEO, %6$s expands to the latest major released WP version, %7$s expands to the next major WP release version */
3137+ __(
3138+ '%1$sUpgrade WordPress to the most recent version%2$s%3$sWe’ve noticed that you’re not on the latest WordPress version, which might cause an issue soon. %4$s (for reasons of security and stability) only supports the current and previous version of WordPress. When the next version of WordPress comes out, that means that we will support WordPress %6$s and %7$s. This means you will not get any updates to %5$s until you update your WordPress, so please make sure to upgrade to the latest WordPress version soon!%3$s%3$s',
3139+ 'wordpress-seo'
3140+ ),
3141 '<strong>',
3142 '</strong>',
3143- '7.7',
3144- date_i18n( get_option( 'date_format' ), strtotime( '11-06-2018' ) ),
3145- '5.2'
3146+ '<br/>',
3147+ 'Yoast',
3148+ 'Yoast SEO',
3149+ $latest_major_wp_version,
3150+ $next_major_wp_version
3151+ );
3152+ if ( $wp_less_than_50 ) {
3153+ $message .= sprintf(
3154+ /* translators: %1$s expands to Yoast SEO, %2$s expands to 5.0 */
3155+ __(
3156+ 'If you’ve held off on updating to %2$s and higher because of the new Gutenberg editor, please install the Classic Editor plugin. It will give you the same editing experience you have now, but also the security of newer versions of WordPress and %1$s.',
3157+ 'wordpress-seo'
3158+ ),
3159+ 'Yoast SEO',
3160+ '5.0'
3161+ );
3162+ }
3163+ $message .= '<br/><br/>';
3164+ $message .= sprintf(
3165+ /* translators: %1$s expands to an opening anchor tag, %2$s expands to a closing anchor tag */
3166+ __(
3167+ 'Read %1$sthis post for more information about why we’re not supporting older versions.%2$s',
3168+ 'wordpress-seo'
3169+ ),
3170+ '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/old-wp-support' ) . '" target="_blank" rel="nofollow">',
3171+ WPSEO_Admin_Utils::get_new_tab_message() . '</a>'
3172 );
3173
3174- $unsupported_php_notification = new Yoast_Notification(
3175- $info_message,
3176+ $notification = new Yoast_Notification(
3177+ $message,
3178 array(
3179- 'type' => Yoast_Notification::ERROR,
3180- 'id' => 'wpseo-dismiss-unsupported-php',
3181- 'capabilities' => 'wpseo_manage_options',
3182+ 'type' => Yoast_Notification::ERROR,
3183+ 'id' => 'wpseo-dismiss-wordpress-upgrade',
3184 )
3185 );
3186
3187- $notification_center = Yoast_Notification_Center::get();
3188-
3189- if ( WPSEO_Admin_Utils::is_supported_php_version_installed() === false ) {
3190- $notification_center->add_notification( $unsupported_php_notification );
3191-
3192+ if ( $wp_less_than_latest_version ) {
3193+ // If the latest WordPress version is not known, do not initiate the WordPress upgrade notice.
3194+ if ( $this->get_latest_major_wordpress_version() === 0 ) {
3195+ $notification_center->remove_notification( $notification );
3196+ return;
3197+ }
3198+
3199+ $notification_center->add_notification( $notification );
3200 return;
3201 }
3202-
3203- $notification_center->remove_notification( $unsupported_php_notification );
3204+ $notification_center->remove_notification( $notification );
3205 }
3206
3207 /**
3208- * Check if the user has dismissed the given notice (by $notice_name)
3209+ * Check if the user has dismissed the given notice (by $notice_name).
3210 *
3211 * @param string $notice_name The name of the notice that might be dismissed.
3212 *
3213@@ -566,7 +601,8 @@
3214 'textdomain' => 'wordpress-seo',
3215 'plugin_name' => 'Yoast SEO',
3216 'hook' => 'wpseo_admin_promo_footer',
3217- ), false
3218+ ),
3219+ false
3220 );
3221
3222 $message = $i18n_module->get_promo_message();
3223@@ -595,7 +631,7 @@
3224 }
3225
3226 /**
3227- * See if we should start our XML Sitemaps Admin class
3228+ * See if we should start our XML Sitemaps Admin class.
3229 */
3230 private function load_xml_sitemaps_admin() {
3231 if ( WPSEO_Options::get( 'enable_xml_sitemap', false ) ) {
3232@@ -604,7 +640,7 @@
3233 }
3234
3235 /**
3236- * Check if the site is set to be publicly visible
3237+ * Check if the site is set to be publicly visible.
3238 *
3239 * @return bool
3240 */
3241@@ -618,50 +654,14 @@
3242 public function show_hook_deprecation_warnings() {
3243 global $wp_filter;
3244
3245- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
3246- return false;
3247+ if ( wp_doing_ajax() ) {
3248+ return;
3249 }
3250
3251 // WordPress hooks that have been deprecated since a Yoast SEO version.
3252 $deprecated_filters = array(
3253- 'wpseo_metadesc_length' => array(
3254- 'version' => '3.0',
3255- 'alternative' => 'javascript',
3256- ),
3257- 'wpseo_metadesc_length_reason' => array(
3258- 'version' => '3.0',
3259- 'alternative' => 'javascript',
3260- ),
3261- 'wpseo_body_length_score' => array(
3262- 'version' => '3.0',
3263- 'alternative' => 'javascript',
3264- ),
3265- 'wpseo_linkdex_results' => array(
3266- 'version' => '3.0',
3267- 'alternative' => 'javascript',
3268- ),
3269- 'wpseo_snippet' => array(
3270- 'version' => '3.0',
3271- 'alternative' => 'javascript',
3272- ),
3273- 'wp_seo_get_bc_title' => array(
3274- 'version' => '5.8',
3275- 'alternative' => 'wpseo_breadcrumb_single_link_info',
3276- ),
3277- 'wpseo_metakey' => array(
3278- 'version' => '6.3',
3279- 'alternative' => null,
3280- ),
3281- 'wpseo_metakeywords' => array(
3282- 'version' => '6.3',
3283- 'alternative' => null,
3284- ),
3285- 'wpseo_stopwords' => array(
3286- 'version' => '7.0',
3287- 'alternative' => null,
3288- ),
3289- 'wpseo_redirect_orphan_attachment' => array(
3290- 'version' => '7.0',
3291+ 'wpseo_genesis_force_adjacent_rel_home' => array(
3292+ 'version' => '9.4',
3293 'alternative' => null,
3294 ),
3295 );
3296@@ -675,31 +675,57 @@
3297 // Show notice for each deprecated filter or action that has been registered.
3298 foreach ( $deprecated_notices as $deprecated_filter ) {
3299 $deprecation_info = $deprecated_filters[ $deprecated_filter ];
3300+ // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- only uses the hardcoded values from above.
3301 _deprecated_hook(
3302 $deprecated_filter,
3303 'WPSEO ' . $deprecation_info['version'],
3304 $deprecation_info['alternative']
3305 );
3306+ // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped.
3307 }
3308 }
3309
3310 /**
3311- * Check if there is a dismiss notice action.
3312- *
3313- * @param string $notice_name The name of the notice to dismiss.
3314- *
3315- * @return bool
3316- */
3317- private function dismiss_notice( $notice_name ) {
3318- return filter_input( INPUT_GET, $notice_name ) === '1' && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), $notice_name );
3319- }
3320-
3321- /**
3322- * Check if the permalink uses %postname%
3323+ * Check if the permalink uses %postname%.
3324 *
3325 * @return bool
3326 */
3327 private function has_postname_in_permalink() {
3328 return ( false !== strpos( get_option( 'permalink_structure' ), '%postname%' ) );
3329 }
3330+
3331+ /**
3332+ * Shows a notice on the permalink settings page.
3333+ */
3334+ public function permalink_settings_notice() {
3335+ global $pagenow;
3336+
3337+ if ( $pagenow === 'options-permalink.php' ) {
3338+ printf(
3339+ '<div class="notice notice-warning"><p><strong>%1$s</strong><br>%2$s<br><a href="%3$s" target="_blank">%4$s</a></p></div>',
3340+ esc_html__( 'WARNING:', 'wordpress-seo' ),
3341+ sprintf(
3342+ /* translators: %1$s and %2$s expand to <em> items to emphasize the word in the middle. */
3343+ esc_html__( 'Changing your permalinks settings can seriously impact your search engine visibility. It should almost %1$s never %2$s be done on a live website.', 'wordpress-seo' ),
3344+ '<em>',
3345+ '</em>'
3346+ ),
3347+ esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/why-permalinks/' ) ),
3348+ // The link's content.
3349+ esc_html__( 'Learn about why permalinks are important for SEO.', 'wordpress-seo' )
3350+ );
3351+ }
3352+ }
3353+
3354+ /* ********************* DEPRECATED METHODS ********************* */
3355+
3356+ /**
3357+ * Add an alert if outdated versions of Yoast SEO plugins are running.
3358+ *
3359+ * @deprecated 12.3
3360+ * @codeCoverageIgnore
3361+ */
3362+ public function yoast_plugin_compatibility_notification() {
3363+ _deprecated_function( __METHOD__, 'WPSEO 12.3' );
3364+ }
3365 }
3366
3367=== modified file 'admin/class-admin-media-purge-notification.php'
3368--- admin/class-admin-media-purge-notification.php 2018-07-04 09:50:13 +0000
3369+++ admin/class-admin-media-purge-notification.php 2019-11-08 16:06:28 +0000
3370@@ -65,16 +65,17 @@
3371 */
3372 private function get_notification() {
3373 $content = sprintf(
3374- /* translators: %1$s expands to the link to the article, %2$s closes the link tag. */
3375+ /* translators: %1$s expands to the link to the article, %2$s closes the link tag. */
3376 __( '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' ),
3377- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/2r8' ) ) . '" rel="nofollow noreferer" target="_blank">',
3378+ '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/2r8' ) ) . '" rel="noopener noreferrer" target="_blank">',
3379 '</a>'
3380 );
3381
3382 $content .= '<br><br>';
3383 $content .= sprintf(
3384+ /* translators: %1$s dismiss link open tag, %2$s closes the link tag. */
3385 __( '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' ),
3386- '<a href="' . admin_url( 'admin.php?page=wpseo_dashboard&dismiss=' . $this->notification_id ) . '">',
3387+ '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_dashboard&dismiss=' . $this->notification_id ) ) . '">',
3388 '</a>'
3389 );
3390
3391
3392=== modified file 'admin/class-admin-recommended-replace-vars.php'
3393--- admin/class-admin-recommended-replace-vars.php 2018-07-04 09:50:13 +0000
3394+++ admin/class-admin-recommended-replace-vars.php 2019-11-08 16:06:28 +0000
3395@@ -11,24 +11,26 @@
3396 class WPSEO_Admin_Recommended_Replace_Vars {
3397
3398 /**
3399- * @var array The recommended replacement variables.
3400+ * The recommended replacement variables.
3401+ *
3402+ * @var array
3403 */
3404 protected $recommended_replace_vars = array(
3405 // Posts types.
3406- 'page' => array( 'sitename', 'title', 'sep', 'primary_category' ),
3407- 'post' => array( 'sitename', 'title', 'sep', 'primary_category' ),
3408+ 'page' => array( 'sitename', 'title', 'sep', 'primary_category' ),
3409+ 'post' => array( 'sitename', 'title', 'sep', 'primary_category' ),
3410 // Homepage.
3411- 'homepage' => array( 'sitename', 'sitedesc', 'sep' ),
3412+ 'homepage' => array( 'sitename', 'sitedesc', 'sep' ),
3413 // Custom post type.
3414- 'custom_post_type' => array( 'sitename', 'title', 'sep' ),
3415+ 'custom_post_type' => array( 'sitename', 'title', 'sep' ),
3416
3417 // Taxonomies.
3418- 'category' => array( 'sitename', 'term_title', 'sep' ),
3419- 'post_tag' => array( 'sitename', 'term_title', 'sep' ),
3420- 'post_format' => array( 'sitename', 'term_title', 'sep', 'page' ),
3421+ 'category' => array( 'sitename', 'term_title', 'sep' ),
3422+ 'post_tag' => array( 'sitename', 'term_title', 'sep' ),
3423+ 'post_format' => array( 'sitename', 'term_title', 'sep', 'page' ),
3424
3425 // Custom taxonomy.
3426- 'term-in-custom-taxomomy' => array( 'sitename', 'term_title', 'sep' ),
3427+ 'term-in-custom-taxomomy' => array( 'sitename', 'term_title', 'sep' ),
3428
3429 // Settings - archive pages.
3430 'author_archive' => array( 'sitename', 'title', 'sep', 'page' ),
3431@@ -36,8 +38,8 @@
3432 'custom-post-type_archive' => array( 'sitename', 'title', 'sep', 'page' ),
3433
3434 // Settings - special pages.
3435- 'search' => array( 'sitename', 'searchphrase', 'sep', 'page' ),
3436- '404' => array( 'sitename', 'sep' ),
3437+ 'search' => array( 'sitename', 'searchphrase', 'sep', 'page' ),
3438+ '404' => array( 'sitename', 'sep' ),
3439 );
3440
3441 /**
3442@@ -59,7 +61,7 @@
3443 /**
3444 * Determines the page type of the current post.
3445 *
3446- * @param WP_Post $post The WordPress global post object.
3447+ * @param WP_Post $post A WordPress post instance.
3448 *
3449 * @return string The page type.
3450 */
3451
3452=== modified file 'admin/class-admin-user-profile.php'
3453--- admin/class-admin-user-profile.php 2018-07-04 09:50:13 +0000
3454+++ admin/class-admin-user-profile.php 2019-11-08 16:06:28 +0000
3455@@ -10,6 +10,7 @@
3456 * Customizes user profile.
3457 */
3458 class WPSEO_Admin_User_Profile {
3459+
3460 /**
3461 * Class constructor.
3462 */
3463@@ -27,9 +28,9 @@
3464 *
3465 * @since 3.1
3466 *
3467- * @param int $meta_id The ID of the meta option changed.
3468+ * @param int $meta_id The ID of the meta option changed.
3469 * @param int $object_id The ID of the user.
3470- * @param string $meta_key The key of the meta field changed.
3471+ * @param string $meta_key The key of the meta field changed.
3472 */
3473 public function clear_author_sitemap_cache( $meta_id, $object_id, $meta_key ) {
3474 if ( '_yoast_wpseo_profile_updated' === $meta_key ) {
3475
3476=== modified file 'admin/class-admin-utils.php'
3477--- admin/class-admin-utils.php 2018-07-04 09:50:13 +0000
3478+++ admin/class-admin-utils.php 2019-11-08 16:06:28 +0000
3479@@ -54,7 +54,7 @@
3480 * @return string The link to the plugin install. Returns the title if the plugin is deemed a Premium product.
3481 */
3482 public static function get_install_link( $plugin ) {
3483- $install_url = WPSEO_Admin_Utils::get_install_url( $plugin['slug'] );
3484+ $install_url = self::get_install_url( $plugin['slug'] );
3485
3486 if ( $install_url === '' || ( isset( $plugin['premium'] ) && $plugin['premium'] === true ) ) {
3487 return $plugin['title'];
3488@@ -65,20 +65,32 @@
3489 $install_url,
3490 $plugin['title']
3491 );
3492-
3493- }
3494+ }
3495+
3496+ /**
3497+ * Gets a visually hidden accessible message for links that open in a new browser tab.
3498+ *
3499+ * @return string The visually hidden accessible message.
3500+ */
3501+ public static function get_new_tab_message() {
3502+ return sprintf(
3503+ '<span class="screen-reader-text">%s</span>',
3504+ esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' )
3505+ );
3506+ }
3507+
3508+ /* ********************* DEPRECATED METHODS ********************* */
3509
3510 /**
3511 * Determines whether or not the user has an invalid version of PHP installed.
3512 *
3513+ * @deprecated 8.1
3514+ * @codeCoverageIgnore
3515+ *
3516 * @return bool Whether or not PHP 5.2 or lower is installed.
3517 */
3518 public static function is_supported_php_version_installed() {
3519- $checker = new Whip_RequirementsChecker( array( 'php' => PHP_VERSION ) );
3520-
3521- $checker->addRequirement( Whip_VersionRequirement::fromCompareString( 'php', '>=5.3' ) );
3522- $checker->check();
3523-
3524- return $checker->hasMessages() === false;
3525+ // Intentionally left blank.
3526+ return true;
3527 }
3528 }
3529
3530=== modified file 'admin/class-admin.php'
3531--- admin/class-admin.php 2018-07-04 09:50:13 +0000
3532+++ admin/class-admin.php 2019-11-08 16:06:28 +0000
3533@@ -10,7 +10,13 @@
3534 */
3535 class WPSEO_Admin {
3536
3537- /** The page identifier used in WordPress to register the admin page !DO NOT CHANGE THIS! */
3538+ /**
3539+ * The page identifier used in WordPress to register the admin page.
3540+ *
3541+ * !DO NOT CHANGE THIS!
3542+ *
3543+ * @var string
3544+ */
3545 const PAGE_IDENTIFIER = 'wpseo_dashboard';
3546
3547 /**
3548@@ -41,14 +47,8 @@
3549 add_action( 'delete_category', array( $this, 'schedule_rewrite_flush' ) );
3550 }
3551
3552- $this->admin_features = array(
3553- // Google Search Console.
3554- 'google_search_console' => new WPSEO_GSC(),
3555- 'dashboard_widget' => new Yoast_Dashboard_Widget(),
3556- );
3557-
3558- if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) {
3559- $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin();
3560+ if ( WPSEO_Options::get( 'disable-attachment' ) === true ) {
3561+ add_filter( 'wpseo_accessible_post_types', array( 'WPSEO_Post_Type', 'filter_attachment_post_type' ) );
3562 }
3563
3564 if ( filter_input( INPUT_GET, 'page' ) === 'wpseo_tools' && filter_input( INPUT_GET, 'tool' ) === null ) {
3565@@ -71,8 +71,6 @@
3566
3567 add_action( 'admin_init', array( $this, 'map_manage_options_cap' ) );
3568
3569- add_action( 'admin_init', array( $this, 'check_php_version' ) );
3570-
3571 WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' );
3572 WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'home' );
3573
3574@@ -90,21 +88,43 @@
3575
3576 $this->initialize_cornerstone_content();
3577
3578- new Yoast_Modal();
3579+ if ( WPSEO_Utils::is_plugin_network_active() ) {
3580+ $integrations[] = new Yoast_Network_Admin();
3581+ }
3582+
3583+ $this->admin_features = array(
3584+ 'google_search_console' => new WPSEO_GSC(),
3585+ 'dashboard_widget' => new Yoast_Dashboard_Widget(),
3586+ );
3587+
3588+ if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) {
3589+ $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin();
3590+ }
3591
3592 $integrations[] = new WPSEO_Yoast_Columns();
3593 $integrations[] = new WPSEO_License_Page_Manager();
3594 $integrations[] = new WPSEO_Statistic_Integration();
3595- $integrations[] = new WPSEO_Slug_Change_Watcher();
3596 $integrations[] = new WPSEO_Capability_Manager_Integration( WPSEO_Capability_Manager_Factory::get() );
3597 $integrations[] = new WPSEO_Admin_Media_Purge_Notification();
3598- $integrations = array_merge( $integrations, $this->initialize_seo_links() );
3599-
3600- /** @var WPSEO_WordPress_Integration $integration */
3601+ $integrations[] = new WPSEO_Admin_Gutenberg_Compatibility_Notification();
3602+ $integrations[] = new WPSEO_Expose_Shortlinks();
3603+ $integrations[] = new WPSEO_MyYoast_Proxy();
3604+ $integrations[] = new WPSEO_MyYoast_Route();
3605+ $integrations[] = new WPSEO_Schema_Person_Upgrade_Notification();
3606+ $integrations[] = new WPSEO_Tracking( 'https://tracking.yoast.com/stats', ( WEEK_IN_SECONDS * 2 ) );
3607+ $integrations[] = new WPSEO_Admin_Settings_Changed_Listener();
3608+ $integrations[] = new WPSEO_Admin_Banner();
3609+
3610+ $integrations = array_merge(
3611+ $integrations,
3612+ $this->get_admin_features(),
3613+ $this->initialize_seo_links(),
3614+ $this->initialize_cornerstone_content()
3615+ );
3616+
3617 foreach ( $integrations as $integration ) {
3618 $integration->register_hooks();
3619 }
3620-
3621 }
3622
3623 /**
3624@@ -205,21 +225,17 @@
3625 array_unshift( $links, $settings_link );
3626 }
3627
3628- if ( class_exists( 'WPSEO_Product_Premium' ) ) {
3629- $product_premium = new WPSEO_Product_Premium();
3630- $extension_manager = new WPSEO_Extension_Manager();
3631-
3632- if ( $extension_manager->is_activated( $product_premium->get_slug() ) ) {
3633- return $links;
3634- }
3635+ $addon_manager = new WPSEO_Addon_Manager();
3636+ if ( WPSEO_Utils::is_yoast_seo_premium() && $addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) {
3637+ return $links;
3638 }
3639
3640 // Add link to premium support landing page.
3641- $premium_link = '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yb' ) ) . '">' . __( 'Premium Support', 'wordpress-seo' ) . '</a>';
3642+ $premium_link = '<a style="font-weight: bold;" href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yb' ) ) . '" target="_blank">' . __( 'Premium Support', 'wordpress-seo' ) . '</a>';
3643 array_unshift( $links, $premium_link );
3644
3645 // Add link to docs.
3646- $faq_link = '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yc' ) ) . '">' . __( 'FAQ', 'wordpress-seo' ) . '</a>';
3647+ $faq_link = '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yc' ) ) . '" target="_blank">' . __( 'FAQ', 'wordpress-seo' ) . '</a>';
3648 array_unshift( $links, $faq_link );
3649
3650 return $links;
3651@@ -244,21 +260,27 @@
3652 }
3653
3654 /**
3655- * Filter the $contactmethods array and add Facebook, Google+ and Twitter.
3656+ * Filter the $contactmethods array and add a set of social profiles.
3657 *
3658 * These are used with the Facebook author, rel="author" and Twitter cards implementation.
3659 *
3660+ * @link https://developers.google.com/search/docs/data-types/social-profile
3661+ *
3662 * @param array $contactmethods Currently set contactmethods.
3663 *
3664 * @return array $contactmethods with added contactmethods.
3665 */
3666 public function update_contactmethods( $contactmethods ) {
3667- // Add Google+.
3668- $contactmethods['googleplus'] = __( 'Google+', 'wordpress-seo' );
3669- // Add Twitter.
3670- $contactmethods['twitter'] = __( 'Twitter username (without @)', 'wordpress-seo' );
3671- // Add Facebook.
3672- $contactmethods['facebook'] = __( 'Facebook profile URL', 'wordpress-seo' );
3673+ $contactmethods['facebook'] = __( 'Facebook profile URL', 'wordpress-seo' );
3674+ $contactmethods['instagram'] = __( 'Instagram profile URL', 'wordpress-seo' );
3675+ $contactmethods['linkedin'] = __( 'LinkedIn profile URL', 'wordpress-seo' );
3676+ $contactmethods['myspace'] = __( 'MySpace profile URL', 'wordpress-seo' );
3677+ $contactmethods['pinterest'] = __( 'Pinterest profile URL', 'wordpress-seo' );
3678+ $contactmethods['soundcloud'] = __( 'SoundCloud profile URL', 'wordpress-seo' );
3679+ $contactmethods['tumblr'] = __( 'Tumblr profile URL', 'wordpress-seo' );
3680+ $contactmethods['twitter'] = __( 'Twitter username (without @)', 'wordpress-seo' );
3681+ $contactmethods['youtube'] = __( 'YouTube profile URL', 'wordpress-seo' );
3682+ $contactmethods['wikipedia'] = __( 'Wikipedia page about you', 'wordpress-seo' ) . '<br/><small>' . __( '(if one exists)', 'wordpress-seo' ) . '</small>';
3683
3684 return $contactmethods;
3685 }
3686@@ -286,7 +308,8 @@
3687 'variable_warning' => sprintf( __( 'Warning: the variable %s cannot be used in this template. See the help center for more info.', 'wordpress-seo' ), '<code>%s</code>' ),
3688 'dismiss_about_url' => $this->get_dismiss_url( 'wpseo-dismiss-about' ),
3689 'dismiss_tagline_url' => $this->get_dismiss_url( 'wpseo-dismiss-tagline-notice' ),
3690- 'help_video_iframe_title' => __( 'Yoast SEO video tutorial', 'wordpress-seo' ),
3691+ /* translators: %s: expends to Yoast SEO */
3692+ 'help_video_iframe_title' => sprintf( __( '%s video tutorial', 'wordpress-seo' ), 'Yoast SEO' ),
3693 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ),
3694 );
3695 }
3696@@ -317,59 +340,6 @@
3697 }
3698
3699 /**
3700- * Initializes Whip to show a notice for outdated PHP versions.
3701- *
3702- * @todo Deprecate this method when WordPress 5.1 is our currently minimal supported version.
3703- *
3704- * @return void
3705- */
3706- public function check_php_version() {
3707- // If the user isn't an admin, don't display anything.
3708- if ( ! current_user_can( 'manage_options' ) ) {
3709- return;
3710- }
3711-
3712- // Check if the user is running PHP 5.2.
3713- if ( WPSEO_Admin_Utils::is_supported_php_version_installed() === false ) {
3714- $this->show_unsupported_php_message();
3715-
3716- return;
3717- }
3718-
3719- /*
3720- * The Whip message shouldn't be shown from WordPress 5.0.0 and higher because
3721- * that version introduces Serve Happy which is almost similar to Whip.
3722- */
3723- $minimal_wp_version = '5.0.0';
3724- if ( version_compare( $GLOBALS['wp_version'], $minimal_wp_version, '>=' ) ) {
3725- return;
3726- }
3727-
3728- if ( ! $this->on_dashboard_page() ) {
3729- return;
3730- }
3731-
3732- whip_wp_check_versions( array(
3733- 'php' => '>=5.4',
3734- ) );
3735- }
3736-
3737- /**
3738- * Creates a new message to display regarding the usage of PHP 5.2 (or lower).
3739- *
3740- * @return void
3741- */
3742- protected function show_unsupported_php_message() {
3743- $presenter = new Whip_WPMessagePresenter(
3744- new WPSEO_Unsupported_PHP_Message(),
3745- new Whip_MessageDismisser( time(), ( WEEK_IN_SECONDS * 4 ), new Whip_WPDismissOption() ),
3746- __( 'Remind me again in 4 weeks.', 'wordpress-seo' )
3747- );
3748-
3749- $presenter->register_hooks();
3750- }
3751-
3752- /**
3753 * Whether we are on the admin dashboard page.
3754 *
3755 * @returns bool
3756@@ -380,17 +350,17 @@
3757
3758 /**
3759 * Loads the cornerstone filter.
3760+ *
3761+ * @return WPSEO_WordPress_Integration[] The integrations to initialize.
3762 */
3763 protected function initialize_cornerstone_content() {
3764 if ( ! WPSEO_Options::get( 'enable_cornerstone_content' ) ) {
3765- return;
3766+ return array();
3767 }
3768
3769- $cornerstone = new WPSEO_Cornerstone();
3770- $cornerstone->register_hooks();
3771-
3772- $cornerstone_filter = new WPSEO_Cornerstone_Filter();
3773- $cornerstone_filter->register_hooks();
3774+ return array(
3775+ 'cornerstone_filter' => new WPSEO_Cornerstone_Filter(),
3776+ );
3777 }
3778
3779 /**
3780@@ -448,59 +418,13 @@
3781 return $integrations;
3782 }
3783
3784- /********************** DEPRECATED METHODS **********************/
3785-
3786- // @codeCoverageIgnoreStart
3787- /**
3788- * Register the menu item and its sub menu's.
3789- *
3790- * @deprecated 5.5
3791- */
3792- public function register_settings_page() {
3793- _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
3794- }
3795-
3796- /**
3797- * Register the settings page for the Network settings.
3798- *
3799- * @deprecated 5.5
3800- */
3801- public function register_network_settings_page() {
3802- _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
3803- }
3804-
3805- /**
3806- * Load the form for a WPSEO admin page.
3807- *
3808- * @deprecated 5.5
3809- */
3810- public function load_page() {
3811- _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
3812- }
3813-
3814- /**
3815- * Loads the form for the network configuration page.
3816- *
3817- * @deprecated 5.5
3818- */
3819- public function network_config_page() {
3820- _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
3821- }
3822-
3823- /**
3824- * Filters all advanced settings pages from the given pages.
3825- *
3826- * @deprecated 5.5
3827- * @param array $pages The pages to filter.
3828- */
3829- public function filter_settings_pages( array $pages ) {
3830- _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
3831- }
3832+ /* ********************* DEPRECATED METHODS ********************* */
3833
3834 /**
3835 * Cleans stopwords out of the slug, if the slug hasn't been set yet.
3836 *
3837 * @deprecated 7.0
3838+ * @codeCoverageIgnore
3839 *
3840 * @return void
3841 */
3842@@ -512,6 +436,7 @@
3843 * Filter the stopwords from the slug.
3844 *
3845 * @deprecated 7.0
3846+ * @codeCoverageIgnore
3847 *
3848 * @return void
3849 */
3850@@ -520,51 +445,14 @@
3851 }
3852
3853 /**
3854- * Adds contextual help to the titles & metas page.
3855- *
3856- * @deprecated 5.6.0
3857+ * Initializes WHIP to show a notice for outdated PHP versions.
3858+ *
3859+ * @deprecated 8.1
3860+ * @codeCoverageIgnore
3861+ *
3862+ * @return void
3863 */
3864- public function title_metas_help_tab() {
3865- _deprecated_function( __METHOD__, '5.6.0' );
3866-
3867- $screen = get_current_screen();
3868-
3869- $screen->set_help_sidebar( '
3870- <p><strong>' . __( 'For more information:', 'wordpress-seo' ) . '</strong></p>
3871- <p><a target="_blank" href="https://yoast.com/wordpress-seo/#titles">' . __( 'Title optimization', 'wordpress-seo' ) . '</a></p>
3872- <p><a target="_blank" href="https://yoast.com/google-page-title/">' . __( 'Why Google won\'t display the right page title', 'wordpress-seo' ) . '</a></p>'
3873- );
3874-
3875- $screen->add_help_tab(
3876- array(
3877- 'id' => 'basic-help',
3878- 'title' => __( 'Template explanation', 'wordpress-seo' ),
3879- 'content' => "\n\t\t<h2>" . __( 'Template explanation', 'wordpress-seo' ) . "</h2>\n\t\t" . '<p>' .
3880- sprintf(
3881- /* translators: %1$s expands to Yoast SEO. */
3882- __( 'The title &amp; metas settings for %1$s are made up of variables that are replaced by specific values from the page when the page is displayed. The tabs on the left explain the available variables.', 'wordpress-seo' ),
3883- 'Yoast SEO'
3884- ) .
3885- '</p><p>' . __( 'Note that not all variables can be used in every template.', 'wordpress-seo' ) . '</p>',
3886- )
3887- );
3888-
3889- $screen->add_help_tab(
3890- array(
3891- 'id' => 'title-vars',
3892- 'title' => __( 'Basic Variables', 'wordpress-seo' ),
3893- 'content' => "\n\t\t<h2>" . __( 'Basic Variables', 'wordpress-seo' ) . "</h2>\n\t\t" . WPSEO_Replace_Vars::get_basic_help_texts(),
3894- )
3895- );
3896-
3897- $screen->add_help_tab(
3898- array(
3899- 'id' => 'title-vars-advanced',
3900- 'title' => __( 'Advanced Variables', 'wordpress-seo' ),
3901- 'content' => "\n\t\t<h2>" . __( 'Advanced Variables', 'wordpress-seo' ) . "</h2>\n\t\t" . WPSEO_Replace_Vars::get_advanced_help_texts(),
3902- )
3903- );
3904+ public function check_php_version() {
3905+ // Intentionally left empty.
3906 }
3907-
3908- // @codeCoverageIgnoreEnd
3909 }
3910
3911=== modified file 'admin/class-asset.php'
3912--- admin/class-asset.php 2018-07-04 09:50:13 +0000
3913+++ admin/class-asset.php 2019-11-08 16:06:28 +0000
3914@@ -10,62 +10,148 @@
3915 */
3916 class WPSEO_Admin_Asset {
3917
3918+ /**
3919+ * Constant used to identify file type as a JS file.
3920+ *
3921+ * @var string
3922+ */
3923 const TYPE_JS = 'js';
3924+
3925+ /**
3926+ * Constant used to identify file type as a CSS file.
3927+ *
3928+ * @var string
3929+ */
3930 const TYPE_CSS = 'css';
3931
3932+ /**
3933+ * The name option identifier.
3934+ *
3935+ * @var string
3936+ */
3937 const NAME = 'name';
3938+
3939+ /**
3940+ * The source option identifier.
3941+ *
3942+ * @var string
3943+ */
3944 const SRC = 'src';
3945+
3946+ /**
3947+ * The dependencies option identifier.
3948+ *
3949+ * @var string
3950+ */
3951 const DEPS = 'deps';
3952+
3953+ /**
3954+ * The version option identifier.
3955+ *
3956+ * @var string
3957+ */
3958 const VERSION = 'version';
3959
3960- // Style specific.
3961+ /* Style specific. */
3962+
3963+ /**
3964+ * The media option identifier.
3965+ *
3966+ * @var string
3967+ */
3968 const MEDIA = 'media';
3969+
3970+ /**
3971+ * The rtl option identifier.
3972+ *
3973+ * @var string
3974+ */
3975 const RTL = 'rtl';
3976
3977- // Script specific.
3978+ /* Script specific. */
3979+
3980+ /**
3981+ * The "in footer" option identifier.
3982+ *
3983+ * @var string
3984+ */
3985 const IN_FOOTER = 'in_footer';
3986
3987 /**
3988+ * Asset identifier.
3989+ *
3990 * @var string
3991 */
3992 protected $name;
3993
3994 /**
3995+ * Path to the asset.
3996+ *
3997 * @var string
3998 */
3999 protected $src;
4000
4001 /**
4002+ * Asset dependencies.
4003+ *
4004 * @var string|array
4005 */
4006 protected $deps;
4007
4008 /**
4009+ * Asset version.
4010+ *
4011 * @var string
4012 */
4013 protected $version;
4014
4015 /**
4016+ * For CSS Assets. The type of media for which this stylesheet has been defined.
4017+ *
4018+ * See https://www.w3.org/TR/CSS2/media.html#media-types.
4019+ *
4020 * @var string
4021 */
4022 protected $media;
4023
4024 /**
4025+ * For JS Assets. Whether or not the script should be loaded in the footer.
4026+ *
4027 * @var boolean
4028 */
4029 protected $in_footer;
4030
4031 /**
4032+ * For CSS Assets. Whether this stylesheet is a right-to-left stylesheet.
4033+ *
4034 * @var boolean
4035 */
4036 protected $rtl;
4037
4038 /**
4039+ * File suffix.
4040+ *
4041 * @var string
4042 */
4043 protected $suffix;
4044
4045 /**
4046+ * Default asset arguments.
4047+ *
4048+ * @var array
4049+ */
4050+ private $defaults = array(
4051+ 'deps' => array(),
4052+ 'version' => WPSEO_VERSION,
4053+ 'in_footer' => true,
4054+ 'rtl' => true,
4055+ 'media' => 'all',
4056+ 'suffix' => WPSEO_CSSJS_SUFFIX,
4057+ );
4058+
4059+ /**
4060+ * Constructs an instance of the WPSEO_Admin_Asset class.
4061+ *
4062 * @param array $args The arguments for this asset.
4063 *
4064 * @throws InvalidArgumentException Throws when no name or src has been provided.
4065@@ -79,14 +165,7 @@
4066 throw new InvalidArgumentException( 'src is a required argument' );
4067 }
4068
4069- $args = array_merge( array(
4070- 'deps' => array(),
4071- 'version' => WPSEO_VERSION,
4072- 'in_footer' => true,
4073- 'rtl' => true,
4074- 'media' => 'all',
4075- 'suffix' => WPSEO_CSSJS_SUFFIX,
4076- ), $args );
4077+ $args = array_merge( $this->defaults, $args );
4078
4079 $this->name = $args['name'];
4080 $this->src = $args['src'];
4081@@ -99,6 +178,8 @@
4082 }
4083
4084 /**
4085+ * Returns the asset identifier.
4086+ *
4087 * @return string
4088 */
4089 public function get_name() {
4090@@ -106,6 +187,8 @@
4091 }
4092
4093 /**
4094+ * Returns the path to the asset.
4095+ *
4096 * @return string
4097 */
4098 public function get_src() {
4099@@ -113,6 +196,8 @@
4100 }
4101
4102 /**
4103+ * Returns the asset dependencies.
4104+ *
4105 * @return array|string
4106 */
4107 public function get_deps() {
4108@@ -120,6 +205,8 @@
4109 }
4110
4111 /**
4112+ * Returns the asset version.
4113+ *
4114 * @return string
4115 */
4116 public function get_version() {
4117@@ -127,6 +214,8 @@
4118 }
4119
4120 /**
4121+ * Returns the media type for CSS assets.
4122+ *
4123 * @return string
4124 */
4125 public function get_media() {
4126@@ -134,6 +223,8 @@
4127 }
4128
4129 /**
4130+ * Returns whether a script asset should be loaded in the footer of the page.
4131+ *
4132 * @return boolean
4133 */
4134 public function is_in_footer() {
4135@@ -141,6 +232,8 @@
4136 }
4137
4138 /**
4139+ * Returns whether this CSS has a RTL counterpart.
4140+ *
4141 * @return boolean
4142 */
4143 public function has_rtl() {
4144@@ -148,6 +241,8 @@
4145 }
4146
4147 /**
4148+ * Returns the file suffix.
4149+ *
4150 * @return string
4151 */
4152 public function get_suffix() {
4153@@ -157,6 +252,9 @@
4154 /**
4155 * Returns the full URL for this asset based on the path to the plugin file.
4156 *
4157+ * @deprecated 6.2
4158+ * @codeCoverageIgnore
4159+ *
4160 * @param string $type Type of asset.
4161 * @param string $plugin_file Absolute path to the plugin file.
4162 *
4163
4164=== modified file 'admin/class-bulk-description-editor-list-table.php'
4165--- admin/class-bulk-description-editor-list-table.php 2018-07-04 09:50:13 +0000
4166+++ admin/class-bulk-description-editor-list-table.php 2019-11-08 16:06:28 +0000
4167@@ -19,7 +19,7 @@
4168 protected $page_type = 'description';
4169
4170 /**
4171- * Settings with are used in __construct
4172+ * Settings with are used in __construct.
4173 *
4174 * @var array
4175 */
4176@@ -37,7 +37,7 @@
4177 protected $target_db_field = 'metadesc';
4178
4179 /**
4180- * The columns shown on the table
4181+ * The columns shown on the table.
4182 *
4183 * @return array
4184 */
4185@@ -51,7 +51,7 @@
4186 }
4187
4188 /**
4189- * Parse the metadescription
4190+ * Parse the metadescription.
4191 *
4192 * @param string $column_name Column name.
4193 * @param object $record Data object.
4194@@ -70,6 +70,9 @@
4195
4196 case 'col_existing_yoast_seo_metadesc':
4197 // @todo Inconsistent return/echo behavior R.
4198+ // I traced the escaping of the attributes to WPSEO_Bulk_List_Table::column_attributes. Alexander.
4199+ // The output of WPSEO_Bulk_List_Table::parse_meta_data_field is properly escaped.
4200+ // phpcs:ignore WordPress.Security.EscapeOutput
4201 echo $this->parse_meta_data_field( $record->ID, $attributes );
4202 break;
4203 }
4204
4205=== modified file 'admin/class-bulk-editor-list-table.php'
4206--- admin/class-bulk-editor-list-table.php 2018-07-04 09:50:13 +0000
4207+++ admin/class-bulk-editor-list-table.php 2019-11-08 16:06:28 +0000
4208@@ -12,7 +12,7 @@
4209 class WPSEO_Bulk_List_Table extends WP_List_Table {
4210
4211 /**
4212- * The nonce that was passed with the request
4213+ * The nonce that was passed with the request.
4214 *
4215 * @var string
4216 */
4217@@ -40,35 +40,35 @@
4218 protected $meta_data = array();
4219
4220 /**
4221- * The current requested page_url
4222+ * The current requested page_url.
4223 *
4224 * @var string
4225 */
4226- private $request_url;
4227+ private $request_url = '';
4228
4229 /**
4230- * The current page (depending on $_GET['paged']) if current tab is for current page_type, else it will be 1
4231+ * The current page (depending on $_GET['paged']) if current tab is for current page_type, else it will be 1.
4232 *
4233 * @var integer
4234 */
4235 private $current_page;
4236
4237 /**
4238- * The current post filter, if is used (depending on $_GET['post_type_filter'])
4239+ * The current post filter, if is used (depending on $_GET['post_type_filter']).
4240 *
4241 * @var string
4242 */
4243 private $current_filter;
4244
4245 /**
4246- * The current post status, if is used (depending on $_GET['post_status'])
4247+ * The current post status, if is used (depending on $_GET['post_status']).
4248 *
4249 * @var string
4250 */
4251 private $current_status;
4252
4253 /**
4254- * The current sorting, if used (depending on $_GET['order'] and $_GET['orderby'])
4255+ * The current sorting, if used (depending on $_GET['order'] and $_GET['orderby']).
4256 *
4257 * @var string
4258 */
4259@@ -83,7 +83,7 @@
4260
4261 /**
4262 * Based on the page_type ($this->page_type) there will be constructed an url part, for subpages and
4263- * navigation
4264+ * navigation.
4265 *
4266 * @var string
4267 */
4268@@ -97,72 +97,52 @@
4269 protected $settings;
4270
4271 /**
4272+ * Holds the pagination config.
4273+ *
4274 * @var array
4275 */
4276 protected $pagination = array();
4277
4278 /**
4279- * Class constructor
4280- */
4281- public function __construct() {
4282+ * Holds the sanitized data from the user input.
4283+ *
4284+ * @var array
4285+ */
4286+ protected $input_fields = array();
4287+
4288+ /**
4289+ * Class constructor.
4290+ *
4291+ * @param array $args The arguments.
4292+ */
4293+ public function __construct( $args = array() ) {
4294 parent::__construct( $this->settings );
4295
4296- $this->request_url = $_SERVER['REQUEST_URI'];
4297- $this->current_page = ( ! empty( $_GET['paged'] ) ) ? $_GET['paged'] : 1;
4298- $this->current_filter = ( ! empty( $_GET['post_type_filter'] ) ) ? $_GET['post_type_filter'] : 1;
4299- $this->current_status = ( ! empty( $_GET['post_status'] ) ) ? $_GET['post_status'] : 1;
4300+ $args = wp_parse_args(
4301+ $args,
4302+ array(
4303+ 'nonce' => '',
4304+ 'input_fields' => array(),
4305+ )
4306+ );
4307+
4308+ $this->input_fields = $args['input_fields'];
4309+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
4310+ $this->request_url = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
4311+ }
4312+
4313+ $this->current_page = ( ! empty( $this->input_fields['paged'] ) ) ? $this->input_fields['paged'] : 1;
4314+ $this->current_filter = ( ! empty( $this->input_fields['post_type_filter'] ) ) ? $this->input_fields['post_type_filter'] : 1;
4315+ $this->current_status = ( ! empty( $this->input_fields['post_status'] ) ) ? $this->input_fields['post_status'] : 1;
4316 $this->current_order = array(
4317- 'order' => ( ! empty( $_GET['order'] ) ) ? $_GET['order'] : 'asc',
4318- 'orderby' => ( ! empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : 'post_title',
4319+ 'order' => ( ! empty( $this->input_fields['order'] ) ) ? $this->input_fields['order'] : 'asc',
4320+ 'orderby' => ( ! empty( $this->input_fields['orderby'] ) ) ? $this->input_fields['orderby'] : 'post_title',
4321 );
4322
4323- $this->verify_nonce();
4324-
4325- $this->nonce = wp_create_nonce( 'bulk-editor-table' );
4326+ $this->nonce = $args['nonce'];
4327 $this->page_url = "&nonce={$this->nonce}&type={$this->page_type}#top#{$this->page_type}";
4328
4329 $this->populate_editable_post_types();
4330-
4331- }
4332-
4333- /**
4334- * Verifies nonce if additional parameters have been sent.
4335- *
4336- * Shows an error notification if the nonce check fails.
4337- */
4338- private function verify_nonce() {
4339- if ( $this->should_verify_nonce() && ! wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'bulk-editor-table' ) ) {
4340- Yoast_Notification_Center::get()->add_notification(
4341- new Yoast_Notification(
4342- __( 'You are not allowed to access this page.', 'wordpress-seo' ),
4343- array( 'type' => Yoast_Notification::ERROR )
4344- )
4345- );
4346- Yoast_Notification_Center::get()->display_notifications();
4347- die;
4348- }
4349- }
4350-
4351- /**
4352- * Checks if additional parameters have been sent to determine if nonce should be checked or not.
4353- *
4354- * @return bool
4355- */
4356- private function should_verify_nonce() {
4357- $possible_params = array(
4358- 'type',
4359- 'paged',
4360- 'post_type_filter',
4361- 'post_status',
4362- 'order',
4363- 'orderby',
4364- );
4365-
4366- foreach ( $possible_params as $param_name ) {
4367- if ( filter_input( INPUT_GET, $param_name ) ) {
4368- return true;
4369- }
4370- }
4371 }
4372
4373 /**
4374@@ -207,9 +187,8 @@
4375 }
4376 }
4377
4378-
4379 /**
4380- * Will shown the navigation for the table like pagenavigation and pagefilter;
4381+ * Will show the navigation for the table like pagenavigation and pagefilter.
4382 *
4383 * @param string $which Table nav location (such as top).
4384 */
4385@@ -255,7 +234,8 @@
4386 * This function takes into account the post types in which the current user can
4387 * edit all posts, and the ones the current user can only edit his/her own.
4388 *
4389- * @return string $subquery The subquery, which should always be used in $wpdb->prepare(), passing the current user_id in as the first parameter.
4390+ * @return string The subquery, which should always be used in $wpdb->prepare(),
4391+ * passing the current user_id in as the first parameter.
4392 */
4393 public function get_base_subquery() {
4394 global $wpdb;
4395@@ -278,9 +258,10 @@
4396 return $subquery;
4397 }
4398
4399-
4400 /**
4401- * @return array
4402+ * Gets the views.
4403+ *
4404+ * @return array The views.
4405 */
4406 public function get_views() {
4407 global $wpdb;
4408@@ -301,15 +282,15 @@
4409 );
4410
4411
4412- $post_status = filter_input( INPUT_GET, 'post_status' );
4413- $class = empty( $post_status ) ? ' class="current"' : '';
4414- $localized_text = sprintf(
4415+ $post_status = filter_input( INPUT_GET, 'post_status' );
4416+ $current_link_attributes = empty( $post_status ) ? ' class="current" aria-current="page"' : '';
4417+ $localized_text = sprintf(
4418 /* translators: %s expands to the number of posts in localized format. */
4419 _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_posts, 'posts', 'wordpress-seo' ),
4420 number_format_i18n( $total_posts )
4421 );
4422
4423- $status_links['all'] = '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=bulk-editor' . $this->page_url ) ) . '"' . $class . '>' . $localized_text . '</a>';
4424+ $status_links['all'] = '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=bulk-editor' . $this->page_url ) ) . '"' . $current_link_attributes . '>' . $localized_text . '</a>';
4425
4426 $post_stati = get_post_stati( array( 'show_in_admin_all_list' => true ), 'objects' );
4427 if ( is_array( $post_stati ) && $post_stati !== array() ) {
4428@@ -331,15 +312,15 @@
4429 continue;
4430 }
4431
4432- $class = '';
4433+ $current_link_attributes = '';
4434 if ( $status_name === $post_status ) {
4435- $class = ' class="current"';
4436+ $current_link_attributes = ' class="current" aria-current="page"';
4437 }
4438
4439- $status_links[ $status_name ] = '<a href="' . esc_url( add_query_arg( array( 'post_status' => $status_name ), admin_url( 'admin.php?page=wpseo_tools&tool=bulk-editor' . $this->page_url ) ) ) . '"' . $class . '>' . sprintf( translate_nooped_plural( $status->label_count, $total ), number_format_i18n( $total ) ) . '</a>';
4440+ $status_links[ $status_name ] = '<a href="' . esc_url( add_query_arg( array( 'post_status' => $status_name ), admin_url( 'admin.php?page=wpseo_tools&tool=bulk-editor' . $this->page_url ) ) ) . '"' . $current_link_attributes . '>' . sprintf( translate_nooped_plural( $status->label_count, $total ), number_format_i18n( $total ) ) . '</a>';
4441 }
4442 }
4443- unset( $post_stati, $status, $status_name, $total, $class );
4444+ unset( $post_stati, $status, $status_name, $total, $current_link_attributes );
4445
4446 $trashed_posts = $wpdb->get_var(
4447 "
4448@@ -348,9 +329,9 @@
4449 "
4450 );
4451
4452- $class = '';
4453+ $current_link_attributes = '';
4454 if ( 'trash' === $post_status ) {
4455- $class = 'class="current"';
4456+ $current_link_attributes = 'class="current" aria-current="page"';
4457 }
4458
4459 $localized_text = sprintf(
4460@@ -359,13 +340,14 @@
4461 number_format_i18n( $trashed_posts )
4462 );
4463
4464- $status_links['trash'] = '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=bulk-editor&post_status=trash' . $this->page_url ) ) . '"' . $class . '>' . $localized_text . '</a>';
4465+ $status_links['trash'] = '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=bulk-editor&post_status=trash' . $this->page_url ) ) . '"' . $current_link_attributes . '>' . $localized_text . '</a>';
4466
4467 return $status_links;
4468 }
4469
4470-
4471 /**
4472+ * Outputs extra table navigation.
4473+ *
4474 * @param string $which Table nav location (such as top).
4475 */
4476 public function extra_tablenav( $which ) {
4477@@ -427,17 +409,21 @@
4478 );
4479 printf(
4480 '<select name="post_type_filter" id="%2$s">%1$s</select>',
4481+ // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $options is properly escaped above.
4482 $options,
4483 esc_attr( 'post-type-filter-' . $instance_type )
4484 );
4485
4486- submit_button( __( 'Filter', 'wordpress-seo' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
4487+ submit_button( esc_html__( 'Filter', 'wordpress-seo' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
4488 echo '</div>';
4489 }
4490 }
4491 }
4492
4493 /**
4494+ * Gets a list of sortable columns.
4495+ *
4496+ * The format is: 'internal-name' => array( 'orderby', bool ).
4497 *
4498 * @return array
4499 */
4500@@ -450,7 +436,7 @@
4501 }
4502
4503 /**
4504- * Sets the correct pagenumber and pageurl for the navigation
4505+ * Sets the correct pagenumber and pageurl for the navigation.
4506 */
4507 public function prepare_page_navigation() {
4508
4509@@ -461,8 +447,11 @@
4510 $current_status = $this->current_status;
4511 $current_order = $this->current_order;
4512
4513- // If current type doesn't compare with objects page_type, than we have to unset some vars in the requested url (which will be use for internal table urls).
4514- if ( $_GET['type'] !== $this->page_type ) {
4515+ /*
4516+ * If current type doesn't compare with objects page_type, then we have to unset
4517+ * some vars in the requested url (which will be used for internal table urls).
4518+ */
4519+ if ( isset( $this->input_fields['type'] ) && $this->input_fields['type'] !== $this->page_type ) {
4520 $request_url = remove_query_arg( 'paged', $request_url ); // Page will be set with value 1 below.
4521 $request_url = remove_query_arg( 'post_type_filter', $request_url );
4522 $request_url = remove_query_arg( 'post_status', $request_url );
4523@@ -488,11 +477,10 @@
4524 $_GET['post_status'] = $current_status;
4525 $_GET['orderby'] = $current_order['orderby'];
4526 $_GET['order'] = $current_order['order'];
4527-
4528 }
4529
4530 /**
4531- * Preparing the requested pagerows and setting the needed variables
4532+ * Preparing the requested pagerows and setting the needed variables.
4533 */
4534 public function prepare_items() {
4535
4536@@ -513,11 +501,10 @@
4537
4538 // Get the metadata for the current items ($this->items).
4539 $this->get_meta_data();
4540-
4541 }
4542
4543 /**
4544- * Getting the columns for first row
4545+ * Getting the columns for first row.
4546 *
4547 * @return array
4548 */
4549@@ -526,7 +513,7 @@
4550 }
4551
4552 /**
4553- * Setting the column headers
4554+ * Setting the column headers.
4555 */
4556 protected function set_column_headers() {
4557 $columns = $this->get_columns();
4558@@ -536,7 +523,7 @@
4559 }
4560
4561 /**
4562- * Counting total items
4563+ * Counting total items.
4564 *
4565 * @param string $subquery SQL FROM part.
4566 * @param string $all_states SQL IN part.
4567@@ -558,7 +545,7 @@
4568 }
4569
4570 /**
4571- * Getting the post_type_clause filter
4572+ * Getting the post_type_clause filter.
4573 *
4574 * @return string
4575 */
4576@@ -605,7 +592,6 @@
4577 'per_page' => $per_page,
4578 'offset' => ( $paged - 1 ) * $per_page,
4579 );
4580-
4581 }
4582
4583 /**
4584@@ -645,7 +631,8 @@
4585 }
4586
4587 /**
4588- * Heavily restricts the possible columns by which a user can order the table in the bulk editor, thereby preventing a possible CSRF vulnerability.
4589+ * Heavily restricts the possible columns by which a user can order the table
4590+ * in the bulk editor, thereby preventing a possible CSRF vulnerability.
4591 *
4592 * @param string $orderby The column by which we want to order.
4593 *
4594@@ -666,7 +653,8 @@
4595 }
4596
4597 /**
4598- * Makes sure the order clause is always ASC or DESC for the bulk editor table, thereby preventing a possible CSRF vulnerability.
4599+ * Makes sure the order clause is always ASC or DESC for the bulk editor table,
4600+ * thereby preventing a possible CSRF vulnerability.
4601 *
4602 * @param string $order Whether we want to sort ascending or descending.
4603 *
4604@@ -706,8 +694,8 @@
4605 $states = get_post_stati( array( 'show_in_admin_all_list' => true ) );
4606 $states['trash'] = 'trash';
4607
4608- if ( ! empty( $_GET['post_status'] ) ) {
4609- $requested_state = sanitize_text_field( $_GET['post_status'] );
4610+ if ( ! empty( $this->input_fields['post_status'] ) ) {
4611+ $requested_state = $this->input_fields['post_status'];
4612 if ( in_array( $requested_state, $states, true ) ) {
4613 $states = array( $requested_state );
4614 }
4615@@ -783,7 +771,7 @@
4616 }
4617
4618 if ( ! empty( $class ) ) {
4619- $attributes = 'class="' . implode( ' ', $class ) . '"';
4620+ $attributes = 'class="' . esc_attr( implode( ' ', $class ) ) . '"';
4621 }
4622
4623 $attributes .= ' data-colname="' . esc_attr( $column_display_name ) . '"';
4624@@ -845,7 +833,6 @@
4625 $return .= $this->row_actions( $actions );
4626
4627 return $return;
4628-
4629 }
4630
4631 /**
4632@@ -924,7 +911,11 @@
4633 $meta_value = $values[ $meta_value ];
4634 }
4635
4636- return sprintf( '<td %2$s id="wpseo-existing-%4$s-%3$s">%1$s</td>', $meta_value, $attributes, $record_id, $this->target_db_field );
4637+ $id = "wpseo-existing-$record_id-$this->target_db_field";
4638+
4639+ // $attributes correctly escaped, verified by Alexander. See WPSEO_Bulk_Description_List_Table::parse_page_specific_column.
4640+ // phpcs:ignore WordPress.Security.EscapeOutput
4641+ return sprintf( '<td %2$s id="%3$s">%1$s</td>', esc_html( $meta_value ), $attributes, esc_attr( $id ) );
4642 }
4643
4644 /**
4645@@ -942,7 +933,6 @@
4646
4647 // Little housekeeping.
4648 unset( $post_ids, $meta_data );
4649-
4650 }
4651
4652 /**
4653@@ -992,7 +982,6 @@
4654 foreach ( $meta_data as $row ) {
4655 $this->meta_data[ $row->post_id ][ $row->meta_key ] = $row->meta_value;
4656 }
4657-
4658 }
4659
4660 /**
4661
4662=== modified file 'admin/class-bulk-title-editor-list-table.php'
4663--- admin/class-bulk-title-editor-list-table.php 2018-07-04 09:50:13 +0000
4664+++ admin/class-bulk-title-editor-list-table.php 2019-11-08 16:06:28 +0000
4665@@ -12,15 +12,14 @@
4666 class WPSEO_Bulk_Title_Editor_List_Table extends WPSEO_Bulk_List_Table {
4667
4668 /**
4669- * Current type for this class will be title
4670+ * Current type for this class will be title.
4671 *
4672 * @var string
4673 */
4674 protected $page_type = 'title';
4675
4676-
4677 /**
4678- * Settings with are used in __construct
4679+ * Settings with are used in __construct.
4680 *
4681 * @var array
4682 */
4683@@ -38,7 +37,7 @@
4684 protected $target_db_field = 'title';
4685
4686 /**
4687- * The columns shown on the table
4688+ * The columns shown on the table.
4689 *
4690 * @return array
4691 */
4692@@ -55,7 +54,7 @@
4693 }
4694
4695 /**
4696- * Parse the title columns
4697+ * Parse the title columns.
4698 *
4699 * @param string $column_name Column name.
4700 * @param object $record Data object.
4701@@ -70,7 +69,10 @@
4702
4703 switch ( $column_name ) {
4704 case 'col_existing_yoast_seo_title':
4705- // @todo Inconsistent echo/return behavior R.
4706+ // @todo Inconsistent return/echo behavior R.
4707+ // I traced the escaping of the attributes to WPSEO_Bulk_List_Table::column_attributes.
4708+ // The output of WPSEO_Bulk_List_Table::parse_meta_data_field is properly escaped.
4709+ // phpcs:ignore WordPress.Security.EscapeOutput
4710 echo $this->parse_meta_data_field( $record->ID, $attributes );
4711 break;
4712
4713
4714=== modified file 'admin/class-collector.php'
4715--- admin/class-collector.php 2018-07-04 09:50:13 +0000
4716+++ admin/class-collector.php 2019-11-08 16:06:28 +0000
4717@@ -10,7 +10,11 @@
4718 */
4719 class WPSEO_Collector {
4720
4721- /** @var WPSEO_Collection[] */
4722+ /**
4723+ * Holds the collections.
4724+ *
4725+ * @var WPSEO_Collection[]
4726+ */
4727 protected $collections = array();
4728
4729 /**
4730@@ -43,6 +47,6 @@
4731 * @return false|string The encode string.
4732 */
4733 public function get_as_json() {
4734- return wp_json_encode( $this->collect() );
4735+ return WPSEO_Utils::format_json_encode( $this->collect() );
4736 }
4737 }
4738
4739=== modified file 'admin/class-config.php'
4740--- admin/class-config.php 2018-07-04 09:50:13 +0000
4741+++ admin/class-config.php 2019-11-08 16:06:28 +0000
4742@@ -6,14 +6,16 @@
4743 */
4744
4745 /**
4746- * Class WPSEO_Admin_Pages
4747+ * Class WPSEO_Admin_Pages.
4748 *
4749 * Class with functionality for the Yoast SEO admin pages.
4750 */
4751 class WPSEO_Admin_Pages {
4752
4753 /**
4754- * @var string $currentoption The option in use for the current admin page.
4755+ * The option in use for the current admin page.
4756+ *
4757+ * @var string
4758 */
4759 public $currentoption = 'wpseo';
4760
4761@@ -25,7 +27,7 @@
4762 private $asset_manager;
4763
4764 /**
4765- * Class constructor, which basically only hooks the init function on the init hook
4766+ * Class constructor, which basically only hooks the init function on the init hook.
4767 */
4768 public function __construct() {
4769 add_action( 'init', array( $this, 'init' ), 20 );
4770@@ -33,7 +35,7 @@
4771 }
4772
4773 /**
4774- * Make sure the needed scripts are loaded for admin pages
4775+ * Make sure the needed scripts are loaded for admin pages.
4776 */
4777 public function init() {
4778 if ( filter_input( INPUT_GET, 'wpseo_reset_defaults' ) && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'wpseo_reset_defaults' ) && current_user_can( 'manage_options' ) ) {
4779@@ -41,26 +43,11 @@
4780 wp_redirect( admin_url( 'admin.php?page=' . WPSEO_Configuration_Page::PAGE_IDENTIFIER ) );
4781 }
4782
4783- add_action( 'admin_init', array( $this, 'admin_init' ) );
4784 add_action( 'admin_enqueue_scripts', array( $this, 'config_page_scripts' ) );
4785 add_action( 'admin_enqueue_scripts', array( $this, 'config_page_styles' ) );
4786 }
4787
4788 /**
4789- * Run admin-specific actions.
4790- */
4791- public function admin_init() {
4792-
4793- $page = filter_input( INPUT_GET, 'page' );
4794- $tool = filter_input( INPUT_GET, 'tool' );
4795- $export_nonce = filter_input( INPUT_POST, WPSEO_Export::NONCE_NAME );
4796-
4797- if ( 'wpseo_tools' === $page && 'import-export' === $tool && $export_nonce !== null ) {
4798- $this->do_yoast_export();
4799- }
4800- }
4801-
4802- /**
4803 * Loads the required styles for the config page.
4804 */
4805 public function config_page_styles() {
4806@@ -84,7 +71,7 @@
4807
4808 if ( $page === 'wpseo_titles' ) {
4809 wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'search-appearance', 'wpseoReplaceVarsL10n', $this->localize_replace_vars_script() );
4810- wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'search-appearance', 'wpseoSearchAppearance', array( 'isRtl' => is_rtl() ) );
4811+ wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'search-appearance', 'wpseoSearchAppearance', $this->localize_search_appearance_script() );
4812 $this->asset_manager->enqueue_script( 'search-appearance' );
4813 $this->asset_manager->enqueue_style( 'search-appearance' );
4814 /**
4815@@ -93,14 +80,14 @@
4816 */
4817 remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
4818
4819- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_l10n();
4820+ $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
4821 $yoast_components_l10n->localize_script( 'search-appearance' );
4822 }
4823
4824 wp_enqueue_script( 'dashboard' );
4825 wp_enqueue_script( 'thickbox' );
4826
4827- wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-script', 'wpseoSelect2Locale', WPSEO_Utils::get_language( WPSEO_Utils::get_user_locale() ) );
4828+ wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-script', 'wpseoSelect2Locale', WPSEO_Language_Utils::get_language( WPSEO_Language_Utils::get_user_locale() ) );
4829
4830 if ( in_array( $page, array( 'wpseo_social', WPSEO_Admin::PAGE_IDENTIFIER, 'wpseo_titles' ), true ) ) {
4831 wp_enqueue_media();
4832@@ -131,13 +118,52 @@
4833 * @return array The replacement and recommended replacement variables.
4834 */
4835 public function localize_replace_vars_script() {
4836- $replace_vars = new WPSEO_Replace_Vars();
4837- $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
4838+ $replace_vars = new WPSEO_Replace_Vars();
4839+ $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
4840+ $editor_specific_replace_vars = new WPSEO_Admin_Editor_Specific_Replace_Vars();
4841+ $replace_vars_list = $replace_vars->get_replacement_variables_list();
4842
4843 return array(
4844- 'replace_vars' => $replace_vars->get_replacement_variables_list(),
4845- 'recommended_replace_vars' => $recommended_replace_vars->get_recommended_replacevars(),
4846- );
4847+ 'replace_vars' => $replace_vars_list,
4848+ 'recommended_replace_vars' => $recommended_replace_vars->get_recommended_replacevars(),
4849+ 'editor_specific_replace_vars' => $editor_specific_replace_vars->get(),
4850+ 'shared_replace_vars' => $editor_specific_replace_vars->get_generic( $replace_vars_list ),
4851+ );
4852+ }
4853+
4854+ /**
4855+ * Retrieves some variables that are needed for the search appearance in JS.
4856+ *
4857+ * @return array The search appearance variables.
4858+ */
4859+ public function localize_search_appearance_script() {
4860+ $search_appearance_l10n = array(
4861+ 'isRtl' => is_rtl(),
4862+ 'userEditUrl' => add_query_arg( 'user_id', '{user_id}', admin_url( 'user-edit.php' ) ),
4863+ 'brushstrokeBackgroundURL' => plugins_url( 'images/brushstroke_background.svg', WPSEO_FILE ),
4864+ 'showLocalSEOUpsell' => $this->should_show_local_seo_upsell(),
4865+ 'localSEOUpsellURL' => WPSEO_Shortlinker::get( 'https://yoa.st/3mp' ),
4866+ );
4867+
4868+ $search_appearance_l10n['knowledgeGraphCompanyInfoMissing'] = WPSEO_Language_Utils::get_knowledge_graph_company_info_missing_l10n();
4869+
4870+ return $search_appearance_l10n;
4871+ }
4872+
4873+ /**
4874+ * Determines whether the Local SEO upsell should be shown.
4875+ *
4876+ * The Local SEO upsell should:
4877+ * - Only be shown in Free, not when Premium is active.
4878+ * - Not be shown when Local SEO is active.
4879+ *
4880+ * @return bool Whether the Local SEO upsell should be shown.
4881+ */
4882+ private function should_show_local_seo_upsell() {
4883+ $addon_manager = new WPSEO_Addon_Manager();
4884+
4885+ return ! WPSEO_Utils::is_yoast_seo_premium()
4886+ && ! ( defined( 'WPSEO_LOCAL_FILE' ) );
4887 }
4888
4889 /**
4890@@ -154,24 +180,4 @@
4891 $this->asset_manager->enqueue_script( 'bulk-editor' );
4892 }
4893 }
4894-
4895- /**
4896- * Runs the yoast exporter class to possibly init the file download.
4897- */
4898- private function do_yoast_export() {
4899- check_admin_referer( WPSEO_Export::NONCE_ACTION, WPSEO_Export::NONCE_NAME );
4900-
4901- if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) {
4902- return;
4903- }
4904-
4905- $wpseo_post = filter_input( INPUT_POST, 'wpseo' );
4906- $include_taxonomy = ! empty( $wpseo_post['include_taxonomy'] );
4907- $export = new WPSEO_Export( $include_taxonomy );
4908-
4909- if ( $export->has_error() ) {
4910- add_action( 'admin_notices', array( $export, 'set_error_hook' ) );
4911-
4912- }
4913- }
4914 } /* End of class */
4915
4916=== removed file 'admin/class-cornerstone-field.php'
4917--- admin/class-cornerstone-field.php 2018-07-04 09:50:13 +0000
4918+++ admin/class-cornerstone-field.php 1970-01-01 00:00:00 +0000
4919@@ -1,57 +0,0 @@
4920-<?php
4921-/**
4922- * WPSEO plugin file.
4923- *
4924- * @package WPSEO\Admin
4925- */
4926-
4927-/**
4928- * Adds a checkbox to the focus keyword section.
4929- */
4930-class WPSEO_Cornerstone_Field {
4931-
4932- /**
4933- * Returns a label with a checkbox in it. Make it possible to mark the page as cornerstone content.
4934- *
4935- * @param WP_POST $post The post object.
4936- *
4937- * @return string The HTML to show.
4938- */
4939- public function get_html( $post ) {
4940-
4941- $post_types = apply_filters( 'wpseo_cornerstone_post_types', WPSEO_Post_Type::get_accessible_post_types() );
4942- if ( ! is_array( $post_types ) || ! isset( $post_types[ get_post_type( $post ) ] ) ) {
4943- return '';
4944- }
4945-
4946- $return = '';
4947- $return .= sprintf(
4948- '<input id="%1$s" class="wpseo-cornerstone-checkbox" type="checkbox" value="1" name="%1$s" %2$s/>',
4949- WPSEO_Cornerstone::FIELD_NAME,
4950- checked( $this->get_meta_value( $post->ID ), '1', false )
4951- );
4952-
4953- $return .= sprintf( '<label for="%1$s">', WPSEO_Cornerstone::FIELD_NAME );
4954-
4955- $return .= sprintf(
4956- /* translators: 1: link open tag; 2: link close tag. */
4957- __( 'This article is %1$scornerstone content%2$s', 'wordpress-seo' ),
4958- '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/metabox-help-cornerstone' ) . '" target="_blank">',
4959- '</a>'
4960- );
4961- $return .= '</label>';
4962-
4963- return $return;
4964- }
4965-
4966- /**
4967- * Gets the meta value from the database.
4968- *
4969- * @param int $post_id The post id to get the meta value for.
4970- *
4971- * @return null|string The meta value from the database.
4972- */
4973- protected function get_meta_value( $post_id ) {
4974- return WPSEO_Meta::get_value( WPSEO_Cornerstone::META_NAME, $post_id );
4975- }
4976-}
4977
4978=== removed file 'admin/class-cornerstone.php'
4979--- admin/class-cornerstone.php 2018-07-04 09:50:13 +0000
4980+++ admin/class-cornerstone.php 1970-01-01 00:00:00 +0000
4981@@ -1,94 +0,0 @@
4982-<?php
4983-/**
4984- * WPSEO plugin file.
4985- *
4986- * @package WPSEO\Admin
4987- */
4988-
4989-/**
4990- * Represents the yoast cornerstone content.
4991- */
4992-class WPSEO_Cornerstone {
4993-
4994- const META_NAME = 'is_cornerstone';
4995-
4996- const FIELD_NAME = 'yoast_wpseo_is_cornerstone';
4997-
4998- /**
4999- * Registers the hooks.
5000- *
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches