| @@ -1,123 +1,230 @@ | ||
| 1 | 1 | <?php |
| 2 | +/** | |
| 3 | + * @package Polylang | |
| 4 | + */ | |
| 2 | 5 | |
| 3 | 6 | /** |
| 4 | - * Base class to manage the static front page and the page for posts | |
| 7 | + * Base class to manage the static front page and the page for posts. | |
| 5 | 8 | * |
| 6 | 9 | * @since 1.8 |
| 7 | 10 | */ |
| 8 | 11 | class PLL_Static_Pages { |
| 9 | - public $model, $options; | |
| 10 | - public $page_on_front, $page_for_posts; | |
| 12 | + /** | |
| 13 | + * Id of the page on front. | |
| 14 | + * | |
| 15 | + * @var int | |
| 16 | + */ | |
| 17 | + public $page_on_front = 0; | |
| 11 | 18 | |
| 12 | 19 | /** |
| 13 | - * Constructor: setups filters and actions | |
| 20 | + * Id of the page for posts. | |
| 14 | 21 | * |
| 22 | + * @var int | |
| 23 | + */ | |
| 24 | + public $page_for_posts = 0; | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * @var PLL_Model | |
| 28 | + */ | |
| 29 | + protected $model; | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * Current language. | |
| 33 | + * | |
| 34 | + * @var PLL_Language|null | |
| 35 | + */ | |
| 36 | + protected $curlang; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructor: setups filters and actions. | |
| 40 | + * | |
| 15 | 41 | * @since 1.8 |
| 16 | 42 | * |
| 17 | - * @param object $polylang | |
| 43 | + * @param object $polylang The Polylang object. | |
| 18 | 44 | */ |
| 19 | 45 | public function __construct( &$polylang ) { |
| 20 | 46 | $this->model = &$polylang->model; |
| 21 | - $this->options = &$polylang->options; | |
| 22 | 47 | $this->curlang = &$polylang->curlang; |
| 23 | 48 | |
| 24 | 49 | $this->init(); |
| 25 | 50 | |
| 26 | - // Modifies the page link in case the front page is not in the default language | |
| 27 | - add_filter( 'page_link', array( $this, 'page_link' ), 20, 2 ); | |
| 51 | + add_filter( 'pll_additional_language_data', array( $this, 'set_static_pages' ), 5, 2 ); // Before PLL_Links_Model. | |
| 28 | 52 | |
| 29 | - // Clean the languages cache when editing page of front, page for posts | |
| 30 | - add_action( 'update_option_show_on_front', array( $this->model, 'clean_languages_cache' ) ); | |
| 31 | - add_action( 'update_option_page_on_front', array( $this->model, 'clean_languages_cache' ) ); | |
| 32 | - add_action( 'update_option_page_for_posts', array( $this->model, 'clean_languages_cache' ) ); | |
| 53 | + // Clean the languages cache when editing page of front, page for posts. | |
| 54 | + add_action( 'update_option_show_on_front', array( $this, 'clean_cache' ) ); | |
| 55 | + add_action( 'update_option_page_on_front', array( $this, 'clean_cache' ) ); | |
| 56 | + add_action( 'update_option_page_for_posts', array( $this, 'clean_cache' ) ); | |
| 33 | 57 | |
| 34 | - // Refresh rewrite rules when the page on front is modified | |
| 58 | + // Refresh rewrite rules when the page on front is modified. | |
| 35 | 59 | add_action( 'update_option_page_on_front', 'flush_rewrite_rules' ); |
| 36 | 60 | |
| 37 | - // OEmbed | |
| 61 | + // Add option filters when the current language is defined | |
| 62 | + add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ) ); | |
| 63 | + | |
| 64 | + // Modifies the page link in case the front page is not in the default language. | |
| 65 | + add_filter( 'page_link', array( $this, 'page_link' ), 20, 2 ); | |
| 66 | + | |
| 67 | + // OEmbed. | |
| 38 | 68 | add_filter( 'oembed_request_post_id', array( $this, 'oembed_request_post_id' ), 10, 2 ); |
| 39 | 69 | } |
| 40 | 70 | |
| 41 | 71 | /** |
| 42 | - * Stores the page on front and page for posts ids | |
| 72 | + * Stores the page on front and page for posts ids. | |
| 43 | 73 | * |
| 44 | 74 | * @since 1.8 |
| 75 | + * | |
| 76 | + * @return void | |
| 45 | 77 | */ |
| 46 | 78 | public function init() { |
| 47 | - if ( 'page' == get_option( 'show_on_front' ) ) { | |
| 48 | - $this->page_on_front = get_option( 'page_on_front' ); | |
| 49 | - $this->page_for_posts = get_option( 'page_for_posts' ); | |
| 50 | - } else { | |
| 51 | - $this->page_on_front = 0; | |
| 52 | - $this->page_for_posts = 0; | |
| 79 | + $this->page_on_front = 0; | |
| 80 | + $this->page_for_posts = 0; | |
| 81 | + | |
| 82 | + if ( 'page' !== get_option( 'show_on_front' ) ) { | |
| 83 | + return; | |
| 53 | 84 | } |
| 85 | + | |
| 86 | + $page_on_front = get_option( 'page_on_front' ); | |
| 87 | + if ( is_numeric( $page_on_front ) ) { | |
| 88 | + $this->page_on_front = (int) $page_on_front; | |
| 89 | + } | |
| 90 | + | |
| 91 | + $page_for_posts = get_option( 'page_for_posts' ); | |
| 92 | + if ( is_numeric( $page_for_posts ) ) { | |
| 93 | + $this->page_for_posts = (int) $page_for_posts; | |
| 94 | + } | |
| 54 | 95 | } |
| 55 | 96 | |
| 56 | 97 | /** |
| 57 | - * Modifies the page link in case the front page is not in the default language | |
| 98 | + * Returns the ID of the static page translation. | |
| 58 | 99 | * |
| 59 | - * @since 0.7.2 | |
| 100 | + * @since 3.4 | |
| 60 | 101 | * |
| 61 | - * @param string $link link to the page | |
| 62 | - * @param int $id post id of the page | |
| 63 | - * @return string modified link | |
| 102 | + * @param string $static_page Static page option name; `page_on_front` or `page_for_posts`. | |
| 103 | + * @param array $language Language data. | |
| 104 | + * @return int | |
| 64 | 105 | */ |
| 65 | - public function page_link( $link, $id ) { | |
| 66 | - $lang = $this->model->post->get_language( $id ); | |
| 106 | + protected function get_translation( $static_page, $language ) { | |
| 107 | + $translations = $this->model->post->get_raw_translations( $this->$static_page ); | |
| 67 | 108 | |
| 68 | - if ( $lang && $id == $lang->page_on_front ) { | |
| 69 | - return $lang->home_url; | |
| 109 | + // When the current static page doesn't have any translation, we must return itself for its language. | |
| 110 | + if ( empty( $translations ) ) { | |
| 111 | + $page_lang = $this->model->post->get_object_term( $this->$static_page, $this->model->post->get_tax_language() ); | |
| 112 | + | |
| 113 | + if ( ! empty( $page_lang ) && $page_lang->slug === $language['slug'] ) { | |
| 114 | + return $this->$static_page; | |
| 115 | + } | |
| 70 | 116 | } |
| 71 | - return $link; | |
| 117 | + | |
| 118 | + if ( ! isset( $translations[ $language['slug'] ] ) ) { | |
| 119 | + return 0; | |
| 120 | + } | |
| 121 | + | |
| 122 | + return $translations[ $language['slug'] ]; | |
| 72 | 123 | } |
| 73 | 124 | |
| 74 | 125 | /** |
| 75 | - * Adds page_on_front and page_for_posts properties to the language objects | |
| 126 | + * Adds `page_on_front` and `page_for_posts` properties to language data before the object is created. | |
| 76 | 127 | * |
| 77 | - * @since 1.8 | |
| 128 | + * @since 3.4 | |
| 78 | 129 | * |
| 79 | - * @param array $languages | |
| 80 | - * @param object $model | |
| 130 | + * @param array $additional_data Array of language additional data. | |
| 131 | + * @param array $language Language data. | |
| 132 | + * @return array Language data with additional `page_on_front` and `page_for_posts` options added. | |
| 81 | 133 | */ |
| 82 | - public static function pll_languages_list( $languages, $model ) { | |
| 83 | - if ( 'page' === get_option( 'show_on_front' ) ) { | |
| 84 | - foreach ( $languages as $k => $language ) { | |
| 85 | - $languages[ $k ]->page_on_front = $model->post->get( get_option( 'page_on_front' ), $language ); | |
| 86 | - $languages[ $k ]->page_for_posts = $model->post->get( get_option( 'page_for_posts' ), $language ); | |
| 87 | - } | |
| 134 | + public function set_static_pages( $additional_data, $language ) { | |
| 135 | + $additional_data['page_on_front'] = $this->get_translation( 'page_on_front', $language ); | |
| 136 | + $additional_data['page_for_posts'] = $this->get_translation( 'page_for_posts', $language ); | |
| 137 | + | |
| 138 | + return $additional_data; | |
| 139 | + } | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Cleans the language cache and resets the internal properties when options are updated. | |
| 143 | + * | |
| 144 | + * @since 3.4 | |
| 145 | + * | |
| 146 | + * @return void | |
| 147 | + */ | |
| 148 | + public function clean_cache() { | |
| 149 | + $this->model->clean_languages_cache(); | |
| 150 | + $this->init(); | |
| 151 | + } | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * Init the hooks that filter the "page on front" and "page for posts" options. | |
| 155 | + * | |
| 156 | + * @since 3.3 | |
| 157 | + * | |
| 158 | + * @return void | |
| 159 | + */ | |
| 160 | + public function pll_language_defined() { | |
| 161 | + // Translates page for posts and page on front. | |
| 162 | + add_filter( 'option_page_on_front', array( $this, 'translate_page_id' ), 10, 2 ); | |
| 163 | + add_filter( 'option_page_for_posts', array( $this, 'translate_page_id' ), 10, 2 ); | |
| 164 | + } | |
| 165 | + | |
| 166 | + /** | |
| 167 | + * Translates the page on front or page for posts option. | |
| 168 | + * | |
| 169 | + * @since 3.6 Replaces `translate_page_on_front()` and `translate_page_on_front()` methods. | |
| 170 | + * | |
| 171 | + * @param int $page_id ID of the page on front or page for posts. | |
| 172 | + * @param string $option Option name: `page_on_front` or `page_for_posts`. | |
| 173 | + * @return int | |
| 174 | + */ | |
| 175 | + public function translate_page_id( $page_id, $option ) { | |
| 176 | + | |
| 177 | + if ( empty( $this->curlang->{$option} ) ) { | |
| 178 | + return $page_id; | |
| 88 | 179 | } |
| 89 | 180 | |
| 90 | - return $languages; | |
| 181 | + if ( doing_action( "update_option_{$option}" ) || doing_action( 'switch_blog' ) || doing_action( 'before_delete_post' ) || doing_action( 'wp_trash_post' ) ) { | |
| 182 | + /* | |
| 183 | + * Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache. | |
| 184 | + * Don't translate while deleting a post or it will mess up `_reset_front_page_settings_for_post()`. | |
| 185 | + * Don't translate while updating the option itself. | |
| 186 | + */ | |
| 187 | + return $page_id; | |
| 188 | + } | |
| 189 | + | |
| 190 | + return $this->curlang->{$option}; | |
| 91 | 191 | } |
| 92 | 192 | |
| 93 | 193 | /** |
| 94 | - * Translates page for posts | |
| 194 | + * Modifies the page link in case the front page is not in the default language. | |
| 95 | 195 | * |
| 96 | - * @since 1.8 | |
| 196 | + * @since 0.7.2 | |
| 97 | 197 | * |
| 98 | - * @param int $v page for posts page id | |
| 99 | - * @return int | |
| 198 | + * @param string $link The link to the page. | |
| 199 | + * @param int $id The post ID of the page. | |
| 200 | + * @return string Modified link. | |
| 100 | 201 | */ |
| 101 | - public function translate_page_for_posts( $v ) { | |
| 102 | - // Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache | |
| 103 | - return isset( $this->curlang->page_for_posts ) && ! doing_action( 'switch_blog' ) ? $this->curlang->page_for_posts : $v; | |
| 202 | + public function page_link( $link, $id ) { | |
| 203 | + $lang = $this->model->post->get_language( $id ); | |
| 204 | + | |
| 205 | + if ( $lang && $id == $lang->page_on_front ) { | |
| 206 | + return $lang->get_home_url(); | |
| 207 | + } | |
| 208 | + return $link; | |
| 104 | 209 | } |
| 105 | 210 | |
| 106 | 211 | /** |
| 107 | 212 | * Fixes the oembed for the translated static front page |
| 108 | - * when the language page is redirected to the front page | |
| 213 | + * when the language page is redirected to the front page. | |
| 109 | 214 | * |
| 110 | 215 | * @since 2.6 |
| 111 | 216 | * |
| 112 | 217 | * @param int $post_id The post ID. |
| 113 | 218 | * @param string $url The requested URL. |
| 219 | + * @return int | |
| 114 | 220 | */ |
| 115 | 221 | public function oembed_request_post_id( $post_id, $url ) { |
| 116 | 222 | foreach ( $this->model->get_languages_list() as $lang ) { |
| 117 | - if ( trailingslashit( $url ) === trailingslashit( $lang->home_url ) ) { | |
| 118 | - $post_id = $lang->page_on_front; | |
| 223 | + if ( is_string( $lang->get_home_url() ) && trailingslashit( $url ) === trailingslashit( $lang->get_home_url() ) ) { | |
| 224 | + return (int) $lang->page_on_front; | |
| 119 | 225 | } |
| 120 | 226 | } |
| 227 | + | |
| 121 | 228 | return $post_id; |
| 122 | 229 | } |
| 123 | 230 | } |