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,25 @@
<?php
namespace WPML\Compatibility\GoogleSiteKit;
use function WPML\Container\make;
class Hooks implements \IWPML_Backend_Action {
public function add_hooks() {
add_filter( 'googlesitekit_canonical_home_url', [ $this, 'getCanonicalHomeUrl' ] );
}
/**
* @return string
*/
public function getCanonicalHomeUrl() {
$wpml_url_filters = make( \WPML_URL_Filters::class );
$wpml_url_filters->remove_global_hooks();
$unfilteredHomeUrl = home_url();
$wpml_url_filters->add_global_hooks();
return $unfilteredHomeUrl;
}
}

View File

@@ -0,0 +1,13 @@
<?php
class WPML_Compatibility_Disqus_Factory implements IWPML_Frontend_Action_Loader {
/**
* @return WPML_Compatibility_Disqus
*/
public function create() {
global $sitepress;
return new WPML_Compatibility_Disqus( $sitepress );
}
}

View File

@@ -0,0 +1,84 @@
<?php
class WPML_Compatibility_Disqus implements IWPML_Action {
const LANGUAGE_NOT_SUPPORTED = '';
/** @var SitePress */
private $sitepress;
/**
* @param SitePress $sitepress
*/
public function __construct( SitePress $sitepress ) {
$this->sitepress = $sitepress;
}
public function add_hooks() {
add_action( 'wp_footer', array( $this, 'set_language' ) );
}
public function set_language() {
if ( is_singular() ) {
$current_language = $this->get_current_lang();
if ( $current_language !== self::LANGUAGE_NOT_SUPPORTED ) {
echo '
<script type="text/javascript">
/**
* We define our custom disqus configs here. This function is invoked from:
* /disqus-comment-system/public/js/comment_embed.js by variable `disqus_config_custom`
*/
var disqus_config = function () {
this.language = "' . $current_language . '";
};
</script>';
}
};
}
/**
* @return string
*/
private function get_current_lang() {
$current_language = $this->sitepress->get_current_language();
$map = $this->get_lang_map();
return isset( $map[ $current_language ] ) ? $map[ $current_language ] : $current_language;
}
/**
* @return array
*/
private function get_lang_map() {
$map = array(
'bs' => self::LANGUAGE_NOT_SUPPORTED,
'de' => 'de_formal',
'es' => 'es_ES',
'ga' => self::LANGUAGE_NOT_SUPPORTED,
'hi' => self::LANGUAGE_NOT_SUPPORTED,
'is' => 'id',
'ku' => self::LANGUAGE_NOT_SUPPORTED,
'mn' => self::LANGUAGE_NOT_SUPPORTED,
'mo' => self::LANGUAGE_NOT_SUPPORTED,
'mt' => self::LANGUAGE_NOT_SUPPORTED,
'ne' => self::LANGUAGE_NOT_SUPPORTED,
'pa' => self::LANGUAGE_NOT_SUPPORTED,
'pt-br' => 'pt_BR',
'pt-pt' => 'PT_EU',
'qu' => self::LANGUAGE_NOT_SUPPORTED,
'so' => self::LANGUAGE_NOT_SUPPORTED,
'sr' => 'sr_CYRL',
'sv' => 'sv_SE',
'ta' => self::LANGUAGE_NOT_SUPPORTED,
'uz' => self::LANGUAGE_NOT_SUPPORTED,
'yi' => self::LANGUAGE_NOT_SUPPORTED,
'zh-hans' => 'zh',
'zh-hant' => 'zh_AHNT',
'zu' => 'af',
);
return apply_filters( 'wpml_disqus_language_map', $map );
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* Class WPML_Google_Sitemap_Generator
*
* # Compatibility class for Google XML Sitemaps (https://wordpress.org/plugins/google-sitemap-generator/)
*
* ## Why is this needed?
*
* Google XML Sitemaps displays all the translations together. When we use a different domain per language we want to have separate sitemaps for each domain.
*
* ## How does this work?
*
* WPML fetches a list of post ids in other languages to pass them to the database query via 'sm_b_exclude' option.
*
* This class is loaded and instantiated by `plugins-integration.php` only if the `GoogleSitemapGeneratorLoader` class exists.
*/
class WPML_Google_Sitemap_Generator {
private $wpdb;
private $sitepress;
/**
* @param wpdb $wpdb
*/
public function __construct( wpdb $wpdb, SitePress $sitepress ) {
$this->wpdb = $wpdb;
$this->sitepress = $sitepress;
}
public function init_hooks() {
if ( ! is_admin() && $this->is_per_domain() ) {
add_filter( 'option_sm_options', [ $this, 'exclude_other_languages' ] );
}
add_action( 'sm_build_content', [ $this, 'init_permalink_hooks' ], 1 );
}
/**
* Add hooks for the different types of permalinks.
*/
public function init_permalink_hooks() {
add_filter( 'page_link', [ $this, 'permalink_filter' ], 10, 2 );
add_filter( 'post_link', [ $this, 'permalink_filter' ], 10, 2 );
add_filter( 'post_type_link', [ $this, 'permalink_filter' ], 10, 2 );
}
/**
* Filter sitemap urls to apply the correct URL format.
*
* @param string $permalink The URL to filter.
* @param WP_Post|int $post The post id it belongs to.
*
* @return string
*/
public function permalink_filter( $permalink, $post ) {
$post_id = $post instanceof WP_Post ? $post->ID : $post;
$language_code = $this->sitepress->get_language_for_element( $post_id, 'post_' . get_post_type( $post_id ) );
return $this->sitepress->convert_url( $permalink, $language_code );
}
/**
* @return bool
*/
private function is_per_domain() {
return WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->sitepress->get_setting( 'language_negotiation_type', false );
}
/**
* @param array $value
*
* @return array
*/
public function exclude_other_languages( $value ) {
$current_language = apply_filters( 'wpml_current_language', false );
$ids_query = "SELECT element_id FROM {$this->wpdb->prefix}icl_translations WHERE element_type LIKE 'post_%%' AND language_code <> %s";
$ids_prepared = $this->wpdb->prepare( $ids_query, $current_language );
$ids = $this->wpdb->get_col( $ids_prepared );
$ids = array_map( 'intval', $ids );
if ( ! is_array( $value ) ) {
$value = [];
}
if ( ! array_key_exists( 'sm_b_exclude', $value ) || ! is_array( $value['sm_b_exclude'] ) ) {
$value['sm_b_exclude'] = [];
}
$value['sm_b_exclude'] = array_merge( $value['sm_b_exclude'], $ids );
return $value;
}
}

View File

@@ -0,0 +1,43 @@
<?php
class WPML_Compatibility_Gutenberg implements IWPML_Action {
/**
* We need to load the filter after `wpml_before_init` where ST loads the blocking filter
* and before `plugins_loaded` (priority 10) where Gutenberg loads the text domain.
*/
const PRIORITY_ON_PLUGINS_LOADED = 5;
/** @var WPML_PHP_Functions $php_functions */
private $php_functions;
public function __construct( WPML_PHP_Functions $php_functions = null ) {
$this->php_functions = $php_functions;
}
public function add_hooks() {
add_action( 'plugins_loaded', array( $this, 'load_textdomain_filter' ), self::PRIORITY_ON_PLUGINS_LOADED );
}
public function load_textdomain_filter() {
if ( $this->php_functions->defined( 'WPML_ST_VERSION' )
&& $this->php_functions->function_exists( 'gutenberg_load_plugin_textdomain' )
) {
add_filter( 'override_load_textdomain', array( $this, 'unblock_gutenberg_domain' ), PHP_INT_MAX, 2 );
}
}
/**
* @param bool $override
* @param string $domain
*
* @return bool
*/
public function unblock_gutenberg_domain( $override, $domain ) {
if ( 'gutenberg' === $domain ) {
return false;
}
return $override;
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* Class WPML_Compatibility_Jetpack
*/
class WPML_Compatibility_Jetpack implements IWPML_Action {
/**
* Add hooks.
*/
public function add_hooks() {
add_filter(
'publicize_should_publicize_published_post',
array( $this, 'publicize_should_publicize_published_post_filter' ),
10,
2
);
}
/**
* Filter to prevent duplicate post from being publicized.
*
* @param bool $should_publicize Should publicize post.
* @param WP_Post $post Post.
*
* @return bool
*/
public function publicize_should_publicize_published_post_filter( $should_publicize, $post ) {
return ! $this->is_post_duplicated( $post );
}
/**
* Check if post is a duplicate being created at the moment.
* We cannot use standard method to determine duplicate as post meta '_icl_lang_duplicate_of' is not set yet.
*
* @param \WP_Post $post
*
* @return bool
*/
private function is_post_duplicated( $post ) {
if (
apply_filters( 'wpml_is_translated_post_type', false, $post->post_type ) &&
did_action( 'wpml_before_make_duplicate' )
) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,15 @@
<?php
class WPML_Compatibility_Tiny_Compress_Images_Factory implements IWPML_Backend_Action_Loader {
/**
* @return \WPML_Compatibility_Tiny_Compress_Images
*/
public function create() {
global $sitepress;
return new WPML_Compatibility_Tiny_Compress_Images(
new WPML_Translation_Element_Factory( $sitepress )
);
}
}

View File

@@ -0,0 +1,48 @@
<?php
class WPML_Compatibility_Tiny_Compress_Images {
/** @var \WPML_Translation_Element_Factory */
private $element_factory;
/**
* WPML_Compatibility_Tiny_Compress_Images constructor.
*
* @param \WPML_Translation_Element_Factory $element_factory
*/
function __construct( WPML_Translation_Element_Factory $element_factory ) {
$this->element_factory = $element_factory;
}
public function add_hooks() {
add_action( 'updated_tiny_postmeta', array( $this, 'updated_tiny_postmeta_action' ), 10, 3 );
}
/**
* @param int $post_id
* @param string $meta_key
* @param mixed $meta_value
*/
public function updated_tiny_postmeta_action( $post_id, $meta_key, $meta_value ) {
$attachment = $this->element_factory->create_post( $post_id );
$translations = $attachment->get_translations();
if ( ! $translations ) {
return;
}
$attached_file = get_attached_file( $post_id );
/** @var WPML_Translation_Element $translation */
foreach ( $translations as $translation ) {
$translation_id = $translation->get_id();
if ( $translation_id !== (int) $post_id && $this->source_and_translation_matches( $attached_file, $translation_id ) ) {
update_post_meta( $translation_id, $meta_key, $meta_value );
}
}
}
private function source_and_translation_matches( $source_attachment_file, $translated_attachment_id ) {
return get_attached_file( $translated_attachment_id ) === $source_attachment_file;
}
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* Class WPML_Compatibility_2017
*
* # Compatbility class for 2017 theme
*
* ## Why is this needed?
*
* When configuring 2017 to use a static page, you can define sections in these pages.
* Each section is another page and the value is stored with the ID of that page.
* In order to display the sections in the current language, WPML needs to know the IDs of the translated pages.
*
* ## How this works?
*
* WPML tries to retrieve the number of Frontpage panels and, for each of them, will add a filter to translate the ID with the one in the current language, if any.
*
* This class is loaded and instantiated by `plugins-integration.php` only if the `twentyseventeen_panel_count` function exists and the `twentyseventeen_translate_panel_id` does not.
*/
class WPML_Compatibility_2017 {
function init_hooks() {
/**
* @phpstan-ignore-next-line
*/
$num_sections = twentyseventeen_panel_count();
for ( $i = 1; $i <= $num_sections; $i ++ ) {
/**
* @see `get_theme_mod` documentation
* @link https://codex.wordpress.org/Function_Reference/get_theme_mod
* @link https://codex.wordpress.org/Plugin_API/Filter_Reference/theme_mod_$name
*/
add_filter( 'theme_mod_panel_' . $i, array( $this, 'get_translated_panel_id' ) );
}
}
function get_translated_panel_id( $id ) {
/**
* Get the translated ID of the given page using the `wpml_object_id` filter and returns the original if the translation is missing
*
* @see https://wpml.org/wpml-hook/wpml_object_id/
*/
return apply_filters( 'wpml_object_id', $id, 'page', true );
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* Class WPML_Compatibility_Factory
*/
class WPML_Compatibility_Factory implements IWPML_Frontend_Action_Loader, IWPML_Backend_Action_Loader {
/**
* Create array of compatibility objects.
*
* @return array
*/
public function create() {
$hooks = array();
$hooks['gutenberg'] = new WPML_Compatibility_Gutenberg( new WPML_WP_API() );
$hooks['jetpack'] = new WPML_Compatibility_Jetpack();
return $hooks;
}
}