← 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 ); |