first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
<?php
class WPML_Sticky_Posts_Lang_Filter {
/** @var SitePress */
private $sitepress;
/** @var WPML_Post_Translation */
private $post_translation;
/** @var array */
private $post_valid_in_all_langs_cache = array();
/**
* @param SitePress $sitepress
* @param WPML_Post_Translation $post_translation
*/
public function __construct( SitePress $sitepress, WPML_Post_Translation $post_translation ) {
$this->sitepress = $sitepress;
$this->post_translation = $post_translation;
}
/**
* @param array $posts
* @param string $lang
*
* @return array
*/
public function filter_by_language( array $posts, $lang ) {
if ( ! $posts ) {
return $posts;
}
$result = array();
foreach ( $posts as $post_id ) {
if (
$this->post_translation->get_element_lang_code( $post_id ) === $lang ||
$this->is_post_type_valid_in_any_language( $this->post_translation->get_type( $post_id ) )
) {
$result[] = $post_id;
}
}
return $result;
}
/**
* @param string $post_type
*
* @return bool
*/
private function is_post_type_valid_in_any_language( $post_type ) {
if ( ! array_key_exists( $post_type, $this->post_valid_in_all_langs_cache ) ) {
$this->post_valid_in_all_langs_cache[ $post_type ] = ! $this->sitepress->is_translated_post_type( $post_type )
|| $this->sitepress->is_display_as_translated_post_type( $post_type );
}
return $this->post_valid_in_all_langs_cache[ $post_type ];
}
}

View File

@@ -0,0 +1,37 @@
<?php
class WPML_Sticky_Posts_Loader {
/** @var SitePress */
private $sitepress;
/**
* @param SitePress $sitepress
*/
public function __construct( SitePress $sitepress ) {
$this->sitepress = $sitepress;
}
public function add_hooks() {
if ( $this->sitepress->get_setting( 'sync_sticky_flag' ) ) {
$sticky_post_sync = wpml_sticky_post_sync( $this->sitepress );
add_filter(
'pre_option_sticky_posts',
array( $sticky_post_sync, 'pre_option_sticky_posts_filter' ),
10,
0
);
add_action( 'post_stuck', array( $sticky_post_sync, 'on_post_stuck' ) );
add_action( 'post_unstuck', array( $sticky_post_sync, 'on_post_unstuck' ) );
add_filter(
'pre_update_option_sticky_posts',
array( $sticky_post_sync, 'pre_update_option_sticky_posts' ),
10,
1
);
}
}
}

View File

@@ -0,0 +1,189 @@
<?php
class WPML_Sticky_Posts_Sync {
/** @var SitePress */
private $sitepress;
/** @var WPML_Post_Translation $post_translation */
private $post_translation;
/** @var WPML_Sticky_Posts_Lang_Filter */
private $populate_lang_option;
/**
* @param SitePress $sitepress
* @param WPML_Post_Translation $post_translation
* @param WPML_Sticky_Posts_Lang_Filter $populate_lang_option
*/
public function __construct(
SitePress $sitepress,
WPML_Post_Translation $post_translation,
WPML_Sticky_Posts_Lang_Filter $populate_lang_option
) {
$this->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() );
}
}