PluginProbe
Polylang / trunk
Polylang vtrunk
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.3 → trunk 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 );