PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.6
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.6
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 / inc / sitemaps / class-author-sitemap-provider.php

class-author-sitemap-provider.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.6, at inc/sitemaps/class-author-sitemap-provider.php

267 lines 6.3 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\XML_Sitemaps
6 */
7
8 use Yoast\WP\SEO\Helpers\Author_Archive_Helper;
9 use Yoast\WP\SEO\Helpers\Wordpress_Helper;
10
11 /**
12 * Sitemap provider for author archives.
13 */
14 class WPSEO_Author_Sitemap_Provider implements WPSEO_Sitemap_Provider {
15
16 /**
17 * Check if provider supports given item type.
18 *
19 * @param string $type Type string to check for.
20 *
21 * @return bool
22 */
23 public function handles_type( $type ) {
24 // If the author archives have been disabled, we don't do anything.
25 if ( WPSEO_Options::get( 'disable-author', false ) || WPSEO_Options::get( 'noindex-author-wpseo', false ) ) {
26 return false;
27 }
28
29 return $type === 'author';
30 }
31
32 /**
33 * Get the links for the sitemap index.
34 *
35 * @param int $max_entries Entries per sitemap.
36 *
37 * @return array
38 */
39 public function get_index_links( $max_entries ) {
40
41 if ( ! $this->handles_type( 'author' ) ) {
42 return [];
43 }
44
45 // @todo Consider doing this less often / when necessary. R.
46 $this->update_user_meta();
47
48 $has_exclude_filter = has_filter( 'wpseo_sitemap_exclude_author' );
49
50 $query_arguments = [];
51
52 if ( ! $has_exclude_filter ) { // We only need full users if legacy filter(s) hooked to exclusion logic. R.
53 $query_arguments['fields'] = 'ID';
54 }
55
56 $users = $this->get_users( $query_arguments );
57
58 if ( $has_exclude_filter ) {
59 $users = $this->exclude_users( $users );
60 $users = wp_list_pluck( $users, 'ID' );
61 }
62
63 if ( empty( $users ) ) {
64 return [];
65 }
66
67 $index = [];
68 $user_pages = array_chunk( $users, $max_entries );
69
70 foreach ( $user_pages as $page_counter => $users_page ) {
71
72 $current_page = ( $page_counter === 0 ) ? '' : ( $page_counter + 1 );
73
74 $user_id = array_shift( $users_page ); // Time descending, first user on page is most recently updated.
75 $user = get_user_by( 'id', $user_id );
76 $index[] = [
77 'loc' => WPSEO_Sitemaps_Router::get_base_url( 'author-sitemap' . $current_page . '.xml' ),
78 'lastmod' => ( $user->_yoast_wpseo_profile_updated ) ? YoastSEO()->helpers->date->format_timestamp( $user->_yoast_wpseo_profile_updated ) : null,
79 ];
80 }
81
82 return $index;
83 }
84
85 /**
86 * Retrieve users, taking account of all necessary exclusions.
87 *
88 * @param array $arguments Arguments to add.
89 *
90 * @return array
91 */
92 protected function get_users( $arguments = [] ) {
93
94 global $wpdb;
95
96 $defaults = [
97 'capability' => [ 'edit_posts' ],
98 'meta_key' => '_yoast_wpseo_profile_updated',
99 'orderby' => 'meta_value_num',
100 'order' => 'DESC',
101 'meta_query' => [
102 'relation' => 'AND',
103 [
104 'key' => $wpdb->get_blog_prefix() . 'user_level',
105 'value' => '0',
106 'compare' => '!=',
107 ],
108 [
109 'relation' => 'OR',
110 [
111 'key' => 'wpseo_noindex_author',
112 'value' => 'on',
113 'compare' => '!=',
114 ],
115 [
116 'key' => 'wpseo_noindex_author',
117 'compare' => 'NOT EXISTS',
118 ],
119 ],
120 ],
121 ];
122
123 $wordpress_helper = new Wordpress_Helper();
124 $wordpress_version = $wordpress_helper->get_wordpress_version();
125
126 // Capability queries were only introduced in WP 5.9.
127 if ( version_compare( $wordpress_version, '5.8.99', '<' ) ) {
128 $defaults['who'] = 'authors';
129 unset( $defaults['capability'] );
130 }
131
132 if ( WPSEO_Options::get( 'noindex-author-noposts-wpseo', true ) ) {
133 unset( $defaults['who'], $defaults['capability'] ); // Otherwise it cancels out next argument.
134 $author_archive = new Author_Archive_Helper();
135 $defaults['has_published_posts'] = $author_archive->get_author_archive_post_types();
136 }
137
138 return get_users( array_merge( $defaults, $arguments ) );
139 }
140
141 /**
142 * Get set of sitemap link data.
143 *
144 * @param string $type Sitemap type.
145 * @param int $max_entries Entries per sitemap.
146 * @param int $current_page Current page of the sitemap.
147 *
148 * @return array
149 *
150 * @throws OutOfBoundsException When an invalid page is requested.
151 */
152 public function get_sitemap_links( $type, $max_entries, $current_page ) {
153
154 $links = [];
155
156 if ( ! $this->handles_type( 'author' ) ) {
157 return $links;
158 }
159
160 $user_criteria = [
161 'offset' => ( ( $current_page - 1 ) * $max_entries ),
162 'number' => $max_entries,
163 ];
164
165 $users = $this->get_users( $user_criteria );
166
167 // Throw an exception when there are no users in the sitemap.
168 if ( count( $users ) === 0 ) {
169 throw new OutOfBoundsException( 'Invalid sitemap page requested' );
170 }
171
172 $users = $this->exclude_users( $users );
173 if ( empty( $users ) ) {
174 $users = [];
175 }
176
177 $time = time();
178
179 foreach ( $users as $user ) {
180
181 $author_link = get_author_posts_url( $user->ID );
182
183 if ( empty( $author_link ) ) {
184 continue;
185 }
186
187 $mod = $time;
188
189 if ( isset( $user->_yoast_wpseo_profile_updated ) ) {
190 $mod = $user->_yoast_wpseo_profile_updated;
191 }
192
193 $url = [
194 'loc' => $author_link,
195 'mod' => date( DATE_W3C, $mod ),
196
197 // Deprecated, kept for backwards data compat. R.
198 'chf' => 'daily',
199 'pri' => 1,
200 ];
201
202 /** This filter is documented at inc/sitemaps/class-post-type-sitemap-provider.php */
203 $url = apply_filters( 'wpseo_sitemap_entry', $url, 'user', $user );
204
205 if ( ! empty( $url ) ) {
206 $links[] = $url;
207 }
208 }
209
210 return $links;
211 }
212
213 /**
214 * Update any users that don't have last profile update timestamp.
215 *
216 * @return int Count of users updated.
217 */
218 protected function update_user_meta() {
219
220 $user_criteria = [
221 'capability' => [ 'edit_posts' ],
222 'meta_query' => [
223 [
224 'key' => '_yoast_wpseo_profile_updated',
225 'compare' => 'NOT EXISTS',
226 ],
227 ],
228 ];
229
230 $wordpress_helper = new Wordpress_Helper();
231 $wordpress_version = $wordpress_helper->get_wordpress_version();
232
233 // Capability queries were only introduced in WP 5.9.
234 if ( version_compare( $wordpress_version, '5.8.99', '<' ) ) {
235 $user_criteria['who'] = 'authors';
236 unset( $user_criteria['capability'] );
237 }
238
239 $users = get_users( $user_criteria );
240
241 $time = time();
242
243 foreach ( $users as $user ) {
244 update_user_meta( $user->ID, '_yoast_wpseo_profile_updated', $time );
245 }
246
247 return count( $users );
248 }
249
250 /**
251 * Wrap legacy filter to deduplicate calls.
252 *
253 * @param array $users Array of user objects to filter.
254 *
255 * @return array
256 */
257 protected function exclude_users( $users ) {
258
259 /**
260 * Filter the authors, included in XML sitemap.
261 *
262 * @param array $users Array of user objects to filter.
263 */
264 return apply_filters( 'wpseo_sitemap_exclude_author', $users );
265 }
266 }
267