PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | modules/seo-tools/class-jetpack-seo.php +300 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,300 @@
1 +<?php
2 +/**
3 + * Main class file for the SEO Tools module.
4 + *
5 + * @package automattic/jetpack
6 + */
7 +
8 +/**
9 + * An SEO expert walks into a bar, bars, pub, public house, Irish pub, drinks, beer, wine, liquor, Grey Goose, Cristal...
10 + *
11 + * @phan-constructor-used-for-side-effects
12 + */
13 +class Jetpack_SEO {
14 + /**
15 + * Constructor.
16 + */
17 + public function __construct() {
18 + add_action( 'init', array( $this, 'init' ) );
19 + }
20 +
21 + /**
22 + * Initialization method for Jetpack_SEO.
23 + */
24 + public function init() {
25 + /**
26 + * Can be used to prevent SEO tools from inserting custom meta tags.
27 + *
28 + * @module seo-tools
29 + *
30 + * @since 4.4.0
31 + *
32 + * @param bool true Should Jetpack's SEO Meta Tags be enabled. Defaults to true.
33 + */
34 + if ( apply_filters( 'jetpack_seo_meta_tags_enabled', true ) ) {
35 + add_action( 'wp_head', array( $this, 'meta_tags' ) );
36 +
37 + // Add support for editing page excerpts in pages, regardless of theme support.
38 + add_post_type_support( 'page', 'excerpt' );
39 + }
40 +
41 + /**
42 + * Can be used to prevent SEO tools from modifying site titles.
43 + *
44 + * @module seo-tools
45 + *
46 + * @since 4.4.0
47 + *
48 + * @param bool true Should Jetpack SEO modify site titles. Defaults to true.
49 + */
50 + if ( apply_filters( 'jetpack_seo_custom_titles', true ) ) {
51 + // Overwrite page title with custom SEO meta title for themes that support title-tag.
52 + add_filter( 'pre_get_document_title', array( 'Jetpack_SEO_Titles', 'get_custom_title' ) );
53 +
54 + // Add overwrite support for themes that don't support title-tag.
55 + add_filter( 'wp_title', array( 'Jetpack_SEO_Titles', 'get_custom_title' ) );
56 + }
57 +
58 + add_filter( 'jetpack_open_graph_tags', array( $this, 'set_custom_og_tags' ) );
59 + Jetpack_SEO_Posts::register_post_meta();
60 + // Exclude posts with 'jetpack_seo_noindex' set true from the Jetpack sitemap.
61 + add_filter( 'jetpack_sitemap_skip_post', array( 'Jetpack_SEO_Posts', 'exclude_noindex_posts_from_jetpack_sitemap' ), 10, 2 );
62 + add_action( 'rest_api_init', array( $this, 'add_custom_field_post_type_meta' ) );
63 + }
64 +
65 + /**
66 + * Add custom field meta to all public post types that don't already have it.
67 + */
68 + public function add_custom_field_post_type_meta() {
69 + /**
70 + * Filter the list of post types for which custom fields support is added.
71 + *
72 + * This filter allows modification of the post types that will be processed
73 + * to add support for custom fields if they do not already support it.
74 + *
75 + * @since 14.2
76 + *
77 + * @param array $post_types An array of post type names.
78 + */
79 + $post_types = apply_filters(
80 + 'jetpack_seo_custom_field_post_types',
81 + get_post_types(
82 + array(
83 + 'public' => true,
84 + 'show_ui' => true,
85 + '_builtin' => false,
86 + )
87 + )
88 + );
89 +
90 + foreach ( $post_types as $post_type ) {
91 + if ( ! post_type_supports( $post_type, 'custom-fields' ) ) {
92 + add_post_type_support( $post_type, 'custom-fields' );
93 + }
94 + }
95 + }
96 +
97 + /**
98 + * Helper method to fetch authors.
99 + */
100 + private function get_authors() {
101 + global $wp_query;
102 +
103 + $authors = array();
104 +
105 + foreach ( $wp_query->posts as $post ) {
106 + if ( ! $post instanceof WP_Post ) {
107 + continue;
108 + }
109 + $authors[] = get_the_author_meta( 'display_name', (int) $post->post_author );
110 + }
111 +
112 + $authors = array_unique( $authors );
113 +
114 + return $authors;
115 + }
116 +
117 + /**
118 + * Constructs open graph tag data.
119 + *
120 + * @param array $tags Array of tag data.
121 + * @return array of tag data.
122 + */
123 + public function set_custom_og_tags( $tags ) {
124 + $custom_title = Jetpack_SEO_Titles::get_custom_title();
125 +
126 + if ( ! empty( $custom_title ) ) {
127 + $tags['og:title'] = $custom_title;
128 + }
129 +
130 + // On archives and a latest-posts homepage, get_post() returns the first post in
131 + // the loop, whose description does not represent the page being viewed. Only use
132 + // the per-post custom description when we are actually on that singular post/page.
133 + $post_custom_description = is_singular()
134 + ? Jetpack_SEO_Posts::get_post_custom_description( get_post() )
135 + : '';
136 + $front_page_meta = Jetpack_SEO_Utils::get_front_page_meta_description();
137 +
138 + if ( class_exists( 'woocommerce' ) && is_shop() ) {
139 + $shop_page_id = get_option( 'woocommerce_shop_page_id' );
140 + if ( $shop_page_id ) {
141 + $post_custom_description = Jetpack_SEO_Posts::get_post_custom_description( get_post( $shop_page_id ) );
142 + }
143 + }
144 +
145 + if ( is_front_page() && ! empty( $front_page_meta ) ) {
146 + $tags['og:description'] = $front_page_meta;
147 + } elseif ( ! empty( $post_custom_description ) ) {
148 + $tags['og:description'] = $post_custom_description;
149 + }
150 +
151 + return $tags;
152 + }
153 +
154 + /**
155 + * Outputs Jetpack's SEO <meta> tags.
156 + */
157 + public function meta_tags() {
158 + global $wp_query;
159 +
160 + $post_count = is_countable( $wp_query->posts ) ? count( $wp_query->posts ) : 0;
161 + $period = '';
162 + $template = '';
163 + $meta = array();
164 +
165 + /**
166 + * Can be used to specify a list of themes that set their own meta tags.
167 + *
168 + * If current site is using one of the themes listed as conflicting, inserting Jetpack SEO
169 + * meta tags will be prevented.
170 + *
171 + * @module seo-tools
172 + *
173 + * @since 4.4.0
174 + *
175 + * @param array List of conflicted theme names. Defaults to empty array.
176 + */
177 + $conflicted_themes = apply_filters( 'jetpack_seo_meta_tags_conflicted_themes', array() );
178 +
179 + if ( isset( $conflicted_themes[ get_option( 'template' ) ] ) ) {
180 + return;
181 + }
182 +
183 + $front_page_meta = Jetpack_SEO_Utils::get_front_page_meta_description();
184 + $description = $front_page_meta ? $front_page_meta : get_bloginfo( 'description' );
185 + $meta['description'] = trim( $description );
186 +
187 + // Try to target things if we're on a "specific" page of any kind.
188 + if ( is_singular() ) {
189 + if ( ! ( is_front_page() && Jetpack_SEO_Utils::get_front_page_meta_description() ) ) {
190 + $description = Jetpack_SEO_Posts::get_post_description( get_post() );
191 +
192 + if ( $description ) {
193 + $description = wp_trim_words(
194 + strip_shortcodes(
195 + wp_strip_all_tags( $description, true )
196 + )
197 + );
198 + $meta['description'] = $description;
199 + }
200 + }
201 + } elseif ( is_author() ) {
202 + $obj = get_queried_object();
203 +
204 + $meta['description'] = sprintf(
205 + /* translators: first property is an user's display name, the second is the site's title. */
206 + _x( 'Read all of the posts by %1$s on %2$s', 'Read all of the posts by Author Name on Blog Title', 'jetpack' ),
207 + $obj->display_name ?? __( 'the author', 'jetpack' ),
208 + get_bloginfo( 'title' )
209 + );
210 + } elseif ( is_tag() || is_category() || is_tax() ) {
211 + $obj = get_queried_object();
212 + $description = '';
213 +
214 + if ( isset( $obj->term_id ) && isset( $obj->taxonomy ) ) {
215 + $description = get_term_field( 'description', $obj->term_id, $obj->taxonomy, 'raw' );
216 + }
217 +
218 + if ( ! is_wp_error( $description ) && $description ) {
219 + $meta['description'] = wp_trim_words( $description );
220 + } else {
221 + $authors = $this->get_authors();
222 +
223 + $meta['description'] = wp_sprintf(
224 + /* translators: %1$s: A post category. %2$l: Post authors. */
225 + _x( 'Posts about %1$s written by %2$l', 'Posts about Category written by John and Bob', 'jetpack' ),
226 + single_term_title( '', false ),
227 + $authors
228 + );
229 + }
230 + } elseif ( is_date() ) {
231 + if ( is_year() ) {
232 + $period = get_query_var( 'year' );
233 +
234 + /* translators: %1$s: Number of posts published. %2$l: Post author. %3$s: A year date. */
235 + $template = _nx(
236 + '%1$s post published by %2$l in the year %3$s', // Singular.
237 + '%1$s posts published by %2$l in the year %3$s', // Plural.
238 + $post_count, // Number.
239 + '10 posts published by John in the year 2012', // Context.
240 + 'jetpack'
241 + );
242 + } elseif ( is_month() ) {
243 + $period = gmdate( 'F Y', mktime( 0, 0, 0, get_query_var( 'monthnum' ), 1, get_query_var( 'year' ) ) );
244 +
245 + /* translators: %1$s: Number of posts published. %2$l: Post author. %3$s: A month/year date. */
246 + $template = _nx(
247 + '%1$s post published by %2$l during %3$s', // Singular.
248 + '%1$s posts published by %2$l during %3$s', // Plural.
249 + $post_count, // Number.
250 + '10 posts publishes by John during May 2012', // Context.
251 + 'jetpack'
252 + );
253 + } elseif ( is_day() ) {
254 + $period = gmdate(
255 + 'F j, Y',
256 + mktime( 0, 0, 0, get_query_var( 'monthnum' ), get_query_var( 'day' ), get_query_var( 'year' ) )
257 + );
258 +
259 + /* translators: %1$s: Number of posts published. %2$l: Post author. %3$s: A month/day/year date. */
260 + $template = _nx(
261 + '%1$s post published by %2$l on %3$s', // Singular.
262 + '%1$s posts published by %2$l on %3$s', // Plural.
263 + $post_count, // Number.
264 + '10 posts published by John on May 30, 2012', // Context.
265 + 'jetpack'
266 + );
267 + }
268 +
269 + $authors = $this->get_authors();
270 + $meta['description'] = wp_sprintf( $template, $post_count, $authors, $period );
271 + }
272 +
273 + $mark_as_noindex = Jetpack_SEO_Posts::get_post_noindex_setting( get_post() );
274 + if ( $mark_as_noindex ) {
275 + $meta['robots'] = 'noindex';
276 + }
277 +
278 + /**
279 + * Can be used to edit the default SEO tools meta tags.
280 + *
281 + * @module seo-tools
282 + *
283 + * @since 4.4.0
284 + *
285 + * @param array Array that consists of meta name and meta content pairs.
286 + */
287 + $meta = apply_filters( 'jetpack_seo_meta_tags', $meta );
288 +
289 + if ( ! is_array( $meta ) ) {
290 + return;
291 + }
292 +
293 + // Output them.
294 + foreach ( $meta as $name => $content ) {
295 + if ( ! empty( $content ) ) {
296 + echo '<meta name="' . esc_attr( $name ) . '" content="' . esc_attr( $content ) . '" />' . "\n";
297 + }
298 + }
299 + }
300 +}