PluginProbe
Polylang / 3.8.10
Polylang v3.8.10
3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 All 234 releases
← All changes | src/modules/sitemaps/multilingual-sitemaps-provider.php +48 -27 3.8.4 → 3.8.10 View file →
@@ -9,8 +9,19 @@
9 9 * @since 2.8
10 10 */
11 11 class PLL_Multilingual_Sitemaps_Provider extends WP_Sitemaps_Provider {
12 12 /**
13 + * Separator between name and language slug.
14 + */
15 + public const SEPARATOR = '---pll-sep---';
16 +
17 + /**
18 + * Pattern to match a name with language.
19 + * `.*` in `(?<SUBTYPE>.*)` because users don't have sub-types. See `get_sitemap_data()`.
20 + */
21 + private const PATTERN = '#^(?<SUBTYPE>.*)' . self::SEPARATOR . '(?<LANG>.+)$#';
22 +
23 + /**
13 24 * The decorated sitemaps provider.
14 25 *
15 26 * @since 2.8
16 27 *
@@ -35,9 +46,8 @@
35 46 * @var PLL_Model
36 47 */
37 48 protected $model;
38 49
39 -
40 50 /**
41 51 * Language used to filter queries for the sitemap index.
42 52 *
43 53 * @since 2.8
@@ -54,14 +64,14 @@
54 64 * @param WP_Sitemaps_Provider $provider An instance of a WP_Sitemaps_Provider child class.
55 65 * @param PLL_Links_Model $links_model The PLL_Links_Model instance.
56 66 */
57 67 public function __construct( $provider, &$links_model ) {
58 - $this->name = $provider->name;
68 + $this->name = $provider->name;
59 69 $this->object_type = $provider->object_type;
60 70
61 - $this->provider = $provider;
71 + $this->provider = $provider;
62 72 $this->links_model = &$links_model;
63 - $this->model = &$links_model->model;
73 + $this->model = &$links_model->model;
64 74 }
65 75
66 76 /**
67 77 * Gets a URL list for a sitemap.
@@ -103,25 +113,32 @@
103 113 return $args;
104 114 }
105 115
106 116 /**
107 - * Gets data for a given sitemap type.
117 + * Returns data for a given sitemap sub-type.
118 + * Suffixes the given sub-type with a language slug, so `get_sitemap_url()` can receive it.
108 119 *
109 120 * @since 2.8
110 121 *
111 - * @param string $object_subtype_name Object subtype name if any.
112 - * @param string $lang Optional language name.
122 + * @param string $object_subtype_name Object sub-type name if any.
123 + * @param string $lang Optional language slug.
113 124 * @return array
114 125 */
115 126 protected function get_sitemap_data( $object_subtype_name, $lang = '' ) {
116 127 $object_subtype_name = (string) $object_subtype_name;
117 128
118 - if ( ! empty( $lang ) ) {
119 - self::$filter_lang = $lang;
129 + if ( empty( $lang ) ) {
130 + return array(
131 + 'name' => $object_subtype_name,
132 + 'pages' => $this->get_max_num_pages( $object_subtype_name ),
133 + );
120 134 }
121 135
136 + // Allow `page---pll-sep---fr` (page is a "posts sub-type") and `---pll-sep---fr` (the "users" type doesn't have sub-types).
137 + self::$filter_lang = $lang;
138 +
122 139 $return = array(
123 - 'name' => implode( '-', array_filter( array( $object_subtype_name, $lang ) ) ),
140 + 'name' => sprintf( "{$object_subtype_name}%s{$lang}", self::SEPARATOR ),
124 141 'pages' => $this->get_max_num_pages( $object_subtype_name ),
125 142 );
126 143
127 144 self::$filter_lang = '';
@@ -128,9 +145,9 @@
128 145 return $return;
129 146 }
130 147
131 148 /**
132 - * Gets data about each sitemap type.
149 + * Returns data about each sitemap type.
133 150 *
134 151 * @since 2.8
135 152 *
136 153 * @return array[] Array of sitemap types including object subtype name and number of pages.
@@ -141,12 +158,14 @@
141 158 add_filter( 'wp_sitemaps_posts_query_args', array( self::class, 'query_args' ) );
142 159 add_filter( 'wp_sitemaps_taxonomies_query_args', array( self::class, 'query_args' ) );
143 160
144 161 $object_subtypes = $this->get_object_subtypes();
162 + $language_slugs = $this->model->languages->get_list( array( 'fields' => 'slug' ) );
145 163
146 164 if ( empty( $object_subtypes ) ) {
147 - foreach ( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) as $language ) {
148 - $sitemap_data[] = $this->get_sitemap_data( '', $language );
165 + // No sub-types. Ex: users.
166 + foreach ( $language_slugs as $language_slug ) {
167 + $sitemap_data[] = $this->get_sitemap_data( '', $language_slug );
149 168 }
150 169 }
151 170
152 171 switch ( $this->provider->name ) {
@@ -160,15 +179,17 @@
160 179 return $sitemap_data;
161 180 }
162 181
163 182 foreach ( array_keys( $object_subtypes ) as $object_subtype_name ) {
164 - if ( call_user_func( $func, $object_subtype_name ) ) {
165 - foreach ( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) as $language ) {
166 - $sitemap_data[] = $this->get_sitemap_data( $object_subtype_name, $language );
167 - }
168 - } else {
183 + if ( ! call_user_func( $func, $object_subtype_name ) ) {
184 + // Not a translated sub-type.
169 185 $sitemap_data[] = $this->get_sitemap_data( $object_subtype_name );
186 + continue;
170 187 }
188 +
189 + foreach ( $language_slugs as $language_slug ) {
190 + $sitemap_data[] = $this->get_sitemap_data( $object_subtype_name, $language_slug );
191 + }
171 192 }
172 193
173 194 return $sitemap_data;
174 195 }
@@ -173,9 +194,9 @@
173 194 return $sitemap_data;
174 195 }
175 196
176 197 /**
177 - * Gets the URL of a sitemap entry.
198 + * Returns the URL of a sitemap entry.
178 199 *
179 200 * @since 2.8
180 201 *
181 202 * @param string $name The name of the sitemap.
@@ -182,24 +203,24 @@
182 203 * @param int $page The page of the sitemap.
183 204 * @return string The composed URL for a sitemap entry.
184 205 */
185 206 public function get_sitemap_url( $name, $page ) {
186 - // Check if a language was added in $name.
187 - $pattern = '#(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')$#';
188 - if ( preg_match( $pattern, $name, $matches ) ) {
189 - $lang = $this->model->get_language( $matches[1] );
207 + // Check if a language was added in `$name`.
208 + if ( preg_match( self::PATTERN, $name, $matches ) ) {
209 + $lang = $this->model->get_language( $matches['LANG'] );
190 210
191 211 if ( ! empty( $lang ) ) {
192 - $name = preg_replace( '#(-?' . $lang->slug . ')$#', '', $name );
193 - $url = $this->provider->get_sitemap_url( $name, $page );
212 + $url = $this->provider->get_sitemap_url( $matches['SUBTYPE'], $page );
194 213 return $this->links_model->add_language_to_link( $url, $lang );
195 214 }
215 + // Should not happen but we don't want our separator to stay in the final URL.
216 + $name = $matches['SUBTYPE'];
196 217 }
197 218
198 - // If no language is present in $name, we may attempt to get the current sitemap url (e.g. in redirect_canonical() ).
219 + // If no language is present in `$name`, we may attempt to get the current sitemap URL (e.g. in `redirect_canonical()` ).
199 220 if ( get_query_var( 'lang' ) ) {
200 221 $lang = $this->model->get_language( get_query_var( 'lang' ) );
201 - $url = $this->provider->get_sitemap_url( $name, $page );
222 + $url = $this->provider->get_sitemap_url( $name, $page );
202 223 return $this->links_model->add_language_to_link( $url, $lang );
203 224 }
204 225
205 226 return $this->provider->get_sitemap_url( $name, $page );