PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.8
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.8
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / admin / formatter / class-metabox-formatter.php

class-metabox-formatter.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.8, at admin/formatter/class-metabox-formatter.php

316 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WPSEO plugin file.
4 *
5 * @package WPSEO\Admin\Formatter
6 */
7
8 use Yoast\WP\SEO\Config\Schema_Types;
9 use Yoast\WP\SEO\Config\SEMrush_Client;
10 use Yoast\WP\SEO\Exceptions\OAuth\Authentication_Failed_Exception;
11 use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Property_Exception;
12 use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Token_Exception;
13
14 /**
15 * This class forces needed methods for the metabox localization.
16 */
17 class WPSEO_Metabox_Formatter {
18
19 /**
20 * Object that provides formatted values.
21 *
22 * @var WPSEO_Metabox_Formatter_Interface
23 */
24 private $formatter;
25
26 /**
27 * Setting the formatter property.
28 *
29 * @param WPSEO_Metabox_Formatter_Interface $formatter Object that provides the formatted values.
30 */
31 public function __construct( WPSEO_Metabox_Formatter_Interface $formatter ) {
32 $this->formatter = $formatter;
33 }
34
35 /**
36 * Returns the values.
37 *
38 * @return array
39 */
40 public function get_values() {
41 $defaults = $this->get_defaults();
42 $values = $this->formatter->get_values();
43
44 return ( $values + $defaults );
45 }
46
47 /**
48 * Returns array with all the values always needed by a scraper object.
49 *
50 * @return array Default settings for the metabox.
51 */
52 private function get_defaults() {
53 $analysis_seo = new WPSEO_Metabox_Analysis_SEO();
54 $analysis_readability = new WPSEO_Metabox_Analysis_Readability();
55 $schema_types = new Schema_Types();
56 $is_wincher_active = YoastSEO()->helpers->wincher->is_active();
57
58 return [
59 'author_name' => get_the_author_meta( 'display_name' ),
60 'site_name' => get_bloginfo( 'name' ),
61 'sitewide_social_image' => WPSEO_Options::get( 'og_default_image' ),
62 'search_url' => '',
63 'post_edit_url' => '',
64 'base_url' => '',
65 'contentTab' => __( 'Readability', 'wordpress-seo' ),
66 'keywordTab' => __( 'Keyphrase:', 'wordpress-seo' ),
67 'removeKeyword' => __( 'Remove keyphrase', 'wordpress-seo' ),
68 'contentLocale' => get_locale(),
69 'userLocale' => \get_user_locale(),
70 'translations' => $this->get_translations(),
71 'keyword_usage' => [],
72 'title_template' => '',
73 'metadesc_template' => '',
74 'contentAnalysisActive' => $analysis_readability->is_enabled() ? 1 : 0,
75 'keywordAnalysisActive' => $analysis_seo->is_enabled() ? 1 : 0,
76 'cornerstoneActive' => WPSEO_Options::get( 'enable_cornerstone_content', false ) ? 1 : 0,
77 'semrushIntegrationActive' => WPSEO_Options::get( 'semrush_integration_active', true ) ? 1 : 0,
78 'intl' => $this->get_content_analysis_component_translations(),
79 'isRtl' => is_rtl(),
80 'isPremium' => YoastSEO()->helpers->product->is_premium(),
81 'wordFormRecognitionActive' => YoastSEO()->helpers->language->is_word_form_recognition_active( WPSEO_Language_Utils::get_language( get_locale() ) ),
82 'siteIconUrl' => get_site_icon_url(),
83 'countryCode' => WPSEO_Options::get( 'semrush_country_code', false ),
84 'SEMrushLoginStatus' => WPSEO_Options::get( 'semrush_integration_active', true ) ? $this->get_semrush_login_status() : false,
85 'showSocial' => [
86 'facebook' => WPSEO_Options::get( 'opengraph', false ),
87 'twitter' => WPSEO_Options::get( 'twitter', false ),
88 ],
89 'schema' => [
90 'displayFooter' => WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ),
91 'pageTypeOptions' => $schema_types->get_page_type_options(),
92 'articleTypeOptions' => $schema_types->get_article_type_options(),
93 ],
94 'twitterCardType' => YoastSEO()->helpers->options->get( 'twitter_card_type' ),
95
96 /**
97 * Filter to determine if the markers should be enabled or not.
98 *
99 * @param bool $showMarkers Should the markers being enabled. Default = true.
100 */
101 'show_markers' => apply_filters( 'wpseo_enable_assessment_markers', true ),
102 'publish_box' => [
103 'labels' => [
104 'content' => [
105 'na' => sprintf(
106 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the readability score. */
107 __( '%1$sReadability%2$s: %3$s', 'wordpress-seo' ),
108 '<a href="#yoast-readability-analysis-collapsible-metabox">',
109 '</a>',
110 '<strong>' . __( 'Not available', 'wordpress-seo' ) . '</strong>'
111 ),
112 'bad' => sprintf(
113 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the readability score. */
114 __( '%1$sReadability%2$s: %3$s', 'wordpress-seo' ),
115 '<a href="#yoast-readability-analysis-collapsible-metabox">',
116 '</a>',
117 '<strong>' . __( 'Needs improvement', 'wordpress-seo' ) . '</strong>'
118 ),
119 'ok' => sprintf(
120 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the readability score. */
121 __( '%1$sReadability%2$s: %3$s', 'wordpress-seo' ),
122 '<a href="#yoast-readability-analysis-collapsible-metabox">',
123 '</a>',
124 '<strong>' . __( 'OK', 'wordpress-seo' ) . '</strong>'
125 ),
126 'good' => sprintf(
127 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the readability score. */
128 __( '%1$sReadability%2$s: %3$s', 'wordpress-seo' ),
129 '<a href="#yoast-readability-analysis-collapsible-metabox">',
130 '</a>',
131 '<strong>' . __( 'Good', 'wordpress-seo' ) . '</strong>'
132 ),
133 ],
134 'keyword' => [
135 'na' => sprintf(
136 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the SEO score. */
137 __( '%1$sSEO%2$s: %3$s', 'wordpress-seo' ),
138 '<a href="#yoast-seo-analysis-collapsible-metabox">',
139 '</a>',
140 '<strong>' . __( 'Not available', 'wordpress-seo' ) . '</strong>'
141 ),
142 'bad' => sprintf(
143 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the SEO score. */
144 __( '%1$sSEO%2$s: %3$s', 'wordpress-seo' ),
145 '<a href="#yoast-seo-analysis-collapsible-metabox">',
146 '</a>',
147 '<strong>' . __( 'Needs improvement', 'wordpress-seo' ) . '</strong>'
148 ),
149 'ok' => sprintf(
150 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the SEO score. */
151 __( '%1$sSEO%2$s: %3$s', 'wordpress-seo' ),
152 '<a href="#yoast-seo-analysis-collapsible-metabox">',
153 '</a>',
154 '<strong>' . __( 'OK', 'wordpress-seo' ) . '</strong>'
155 ),
156 'good' => sprintf(
157 /* translators: %1$s expands to the opening anchor tag, %2$s to the closing anchor tag, %3$s to the SEO score. */
158 __( '%1$sSEO%2$s: %3$s', 'wordpress-seo' ),
159 '<a href="#yoast-seo-analysis-collapsible-metabox">',
160 '</a>',
161 '<strong>' . __( 'Good', 'wordpress-seo' ) . '</strong>'
162 ),
163 ],
164 ],
165 ],
166 'markdownEnabled' => $this->is_markdown_enabled(),
167 'analysisHeadingTitle' => __( 'Analysis', 'wordpress-seo' ),
168 'zapierIntegrationActive' => WPSEO_Options::get( 'zapier_integration_active', false ) ? 1 : 0,
169 'zapierConnectedStatus' => ! empty( WPSEO_Options::get( 'zapier_subscription', [] ) ) ? 1 : 0,
170 'wincherIntegrationActive' => ( $is_wincher_active ) ? 1 : 0,
171 'wincherLoginStatus' => ( $is_wincher_active ) ? YoastSEO()->helpers->wincher->login_status() : false,
172 'wincherWebsiteId' => WPSEO_Options::get( 'wincher_website_id', '' ),
173 'wincherAutoAddKeyphrases' => WPSEO_Options::get( 'wincher_automatically_add_keyphrases', false ),
174
175 /**
176 * Filter to determine whether the PreviouslyUsedKeyword assessment should run.
177 *
178 * @param bool $previouslyUsedKeywordActive Whether the PreviouslyUsedKeyword assessment should run.
179 */
180 'previouslyUsedKeywordActive' => apply_filters( 'wpseo_previously_used_keyword_active', true ),
181 ];
182 }
183
184 /**
185 * Returns required yoast-component translations.
186 *
187 * @return array
188 */
189 private function get_content_analysis_component_translations() {
190 // Esc_html is not needed because React already handles HTML in the (translations of) these strings.
191 return [
192 'locale' => \get_user_locale(),
193 'content-analysis.errors' => __( 'Errors', 'wordpress-seo' ),
194 'content-analysis.problems' => __( 'Problems', 'wordpress-seo' ),
195 'content-analysis.improvements' => __( 'Improvements', 'wordpress-seo' ),
196 'content-analysis.considerations' => __( 'Considerations', 'wordpress-seo' ),
197 'content-analysis.good' => __( 'Good results', 'wordpress-seo' ),
198 'content-analysis.highlight' => __( 'Highlight this result in the text', 'wordpress-seo' ),
199 'content-analysis.nohighlight' => __( 'Remove highlight from the text', 'wordpress-seo' ),
200 'content-analysis.disabledButton' => __( 'Marks are disabled in current view', 'wordpress-seo' ),
201 'a11yNotice.opensInNewTab' => __( '(Opens in a new browser tab)', 'wordpress-seo' ),
202 ];
203 }
204
205 /**
206 * Returns Jed compatible YoastSEO.js translations.
207 *
208 * @return array
209 */
210 private function get_translations() {
211 $locale = \get_user_locale();
212
213 $file = WPSEO_PATH . 'languages/wordpress-seo-' . $locale . '.json';
214 if ( file_exists( $file ) ) {
215 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Retrieving a local file.
216 $file = file_get_contents( $file );
217 if ( is_string( $file ) && $file !== '' ) {
218 return json_decode( $file, true );
219 }
220 }
221
222 return [];
223 }
224
225 /**
226 * Checks if Jetpack's markdown module is enabled.
227 * Can be extended to work with other plugins that parse markdown in the content.
228 *
229 * @return bool
230 */
231 private function is_markdown_enabled() {
232 $is_markdown = false;
233
234 if ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'get_active_modules' ) ) {
235 $active_modules = Jetpack::get_active_modules();
236
237 // First at all, check if Jetpack's markdown module is active.
238 $is_markdown = in_array( 'markdown', $active_modules, true );
239 }
240
241 /**
242 * Filters whether markdown support is active in the readability- and seo-analysis.
243 *
244 * @since 11.3
245 *
246 * @param array $is_markdown Is markdown support for Yoast SEO active.
247 */
248 return apply_filters( 'wpseo_is_markdown_enabled', $is_markdown );
249 }
250
251 /**
252 * Checks if the user is logged in to SEMrush.
253 *
254 * @return bool The SEMrush login status.
255 */
256 private function get_semrush_login_status() {
257 try {
258 $semrush_client = YoastSEO()->classes->get( SEMrush_Client::class );
259 } catch ( Empty_Property_Exception $e ) {
260 // Return false if token is malformed (empty property).
261 return false;
262 }
263
264 // Get token (and refresh it if it's expired).
265 try {
266 $semrush_client->get_tokens();
267 } catch ( Authentication_Failed_Exception $e ) {
268 return false;
269 } catch ( Empty_Token_Exception $e ) {
270 return false;
271 }
272
273 return $semrush_client->has_valid_tokens();
274 }
275
276 /* ********************* DEPRECATED METHODS ********************* */
277
278 /**
279 * Returns the translations for the Add Keyword modal.
280 *
281 * These strings are not escaped because they're meant to be used with React
282 * which already takes care of that. If used in PHP, they should be escaped.
283 *
284 * @deprecated 15.5
285 * @codeCoverageIgnore
286 *
287 * @return array Translated text strings for the Add Keyword modal.
288 */
289 public function get_add_keyword_upsell_translations() {
290 _deprecated_function( __METHOD__, 'WPSEO 15.5' );
291
292 return [
293 'title' => __( 'Would you like to add more than one keyphrase?', 'wordpress-seo' ),
294 'intro' => sprintf(
295 /* translators: %s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
296 __( 'Great news: you can, with %s!', 'wordpress-seo' ),
297 '{{link}}Yoast SEO Premium{{/link}}'
298 ),
299 'link' => WPSEO_Shortlinker::get( 'https://yoa.st/pe-premium-page' ),
300 'other' => sprintf(
301 /* translators: %s expands to 'Yoast SEO Premium'. */
302 __( 'Other benefits of %s for you:', 'wordpress-seo' ),
303 'Yoast SEO Premium'
304 ),
305 'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
306 'buy' => sprintf(
307 /* translators: %s expands to 'Yoast SEO Premium'. */
308 __( 'Get %s', 'wordpress-seo' ),
309 'Yoast SEO Premium'
310 ),
311 'small' => __( '1 year free support and updates included!', 'wordpress-seo' ),
312 'a11yNotice.opensInNewTab' => __( '(Opens in a new browser tab)', 'wordpress-seo' ),
313 ];
314 }
315 }
316