sitepress = $sitepress; $this->post_translation = $post_translation; $this->populate_lang_option = $populate_lang_option; } /** * It returns only those sticky posts which belong to a current language * * @return array|false */ public function pre_option_sticky_posts_filter() { $current_language = $this->sitepress->get_current_language(); if ( 'all' === $current_language ) { return false; } $option = 'sticky_posts_' . $current_language; $posts = get_option( $option ); if ( false === $posts ) { $posts = $this->get_unfiltered_sticky_posts_option(); if ( $posts ) { $posts = $this->populate_lang_option->filter_by_language( $this->get_unfiltered_sticky_posts_option(), $current_language ); update_option( $option, $posts, true ); } } return $posts; } /** * Ensure that the original main `sticky_posts` option contains sticky posts from ALL languages * * @param array $posts * * @return array */ public function pre_update_option_sticky_posts( $posts ) { $langs = array_keys( $this->sitepress->get_active_languages() ); $langs = array_diff( $langs, array( $this->sitepress->get_current_language() ) ); $lang_parts = array_map( array( $this, 'get_option_by_lang' ), $langs ); $lang_parts[] = array_map( 'intval', $posts ); return array_unique( call_user_func_array( 'array_merge', $lang_parts ) ); } /** * It marks as `sticky` all posts which are translation of the post or have the same original post. * Basically, it means that they have the same trid in icl_translations table. * * @param int $post_id */ public function on_post_stuck( $post_id ) { $translations = $this->get_post_translations( $post_id ); if ( $translations ) { foreach ( $translations as $lang => $translated_post_id ) { $this->add_post_id( 'sticky_posts_' . $lang, (int) $translated_post_id ); $this->add_post_id_to_original_option( (int) $translated_post_id ); } } else { $this->add_post_id( 'sticky_posts_' . $this->sitepress->get_current_language(), (int) $post_id ); } } /** * It un-marks as `sticky` all posts which are translation of the post or have the same original post. * * @param int $post_id */ public function on_post_unstuck( $post_id ) { foreach ( $this->get_post_translations( $post_id ) as $lang => $translated_post_id ) { $this->remove_post_id( 'sticky_posts_' . $lang, (int) $translated_post_id ); $this->remove_post_id_from_original_option( (int) $translated_post_id ); } } /** * It returns an original, unfiltered `sticky_posts` option which contains sticky posts from ALL languages * * @return array|false */ public function get_unfiltered_sticky_posts_option() { remove_filter( 'pre_option_sticky_posts', array( $this, 'pre_option_sticky_posts_filter' ) ); $posts = get_option( 'sticky_posts' ); add_filter( 'pre_option_sticky_posts', array( $this, 'pre_option_sticky_posts_filter' ), 10, 0 ); return $posts; } /** * @param int $post_id * * @return array */ private function get_post_translations( $post_id ) { $this->post_translation->reload(); $trid = $this->post_translation->get_element_trid( $post_id ); return $this->post_translation->get_element_translations( false, $trid, false ); } /** * @param int $post_id */ private function add_post_id_to_original_option( $post_id ) { $this->update_original_option( $post_id, array( $this, 'add_post_id' ) ); } /** * @param string $option * @param int $post_id */ private function add_post_id( $option, $post_id ) { $sticky_posts = get_option( $option, array() ); if ( ! in_array( $post_id, $sticky_posts, true ) ) { $sticky_posts[] = $post_id; update_option( $option, $sticky_posts, true ); } } /** * @param int $post_id */ private function remove_post_id_from_original_option( $post_id ) { $this->update_original_option( $post_id, array( $this, 'remove_post_id' ) ); } /** * @param int $post_id * @param callable $callback */ private function update_original_option( $post_id, $callback ) { remove_filter( 'pre_option_sticky_posts', array( $this, 'pre_option_sticky_posts_filter' ) ); remove_filter( 'pre_update_option_sticky_posts', array( $this, 'pre_update_option_sticky_posts' ) ); call_user_func( $callback, 'sticky_posts', $post_id ); add_filter( 'pre_update_option_sticky_posts', array( $this, 'pre_update_option_sticky_posts' ), 10, 1 ); add_filter( 'pre_option_sticky_posts', array( $this, 'pre_option_sticky_posts_filter' ), 10, 0 ); } /** * @param string $option * @param int $post_id */ private function remove_post_id( $option, $post_id ) { $sticky_posts = get_option( $option, array() ); if ( ( $key = array_search( $post_id, $sticky_posts ) ) !== false ) { unset( $sticky_posts[ $key ] ); update_option( $option, array_values( $sticky_posts ), true ); } } /** * @param string $lang * * @return array */ private function get_option_by_lang( $lang ) { return get_option( 'sticky_posts_' . $lang, array() ); } }