1000 lines
30 KiB
PHP
1000 lines
30 KiB
PHP
<?php
|
|
namespace ConnectPolylangElementor;
|
|
|
|
use Elementor\Core\Settings\Manager as SettingsManager;
|
|
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
|
|
class ConnectPlugins {
|
|
|
|
use \ConnectPolylangElementor\Util\Singleton;
|
|
|
|
/**
|
|
* Current template ID.
|
|
*
|
|
* @var int|null
|
|
*/
|
|
private $template_id = null;
|
|
|
|
/**
|
|
* __construct
|
|
*
|
|
* @return void
|
|
*/
|
|
private function __construct() {
|
|
|
|
// Auto add post types for translation.
|
|
add_filter( 'pll_get_post_types', array( $this, 'add_polylang_post_types' ), 10, 2 );
|
|
|
|
// Front template loading.
|
|
add_filter( 'elementor/theme/get_location_templates/template_id', array( $this, 'template_id_translation' ) );
|
|
add_filter( 'elementor/theme/get_location_templates/condition_sub_id', array( $this, 'condition_sub_id_translation' ), 10, 2 );
|
|
|
|
// Shortcode [elementor-template] translate 'template_id'.
|
|
add_filter( 'pre_do_shortcode_tag', array( $this, 'shortcode_template_translate' ), 10, 3 );
|
|
// Widget Template translate 'template_id'.
|
|
add_action( 'elementor/frontend/widget/before_render', array( $this, 'widget_template_translate' ) );
|
|
// WordPress Widget "Elementor Library" translate 'template_id'.
|
|
add_filter( 'widget_display_callback', array( $this, 'wp_widget_template_translate' ), 10, 2 );
|
|
|
|
// Elementor Kit template loading.
|
|
add_filter( 'option_elementor_active_kit', array( $this, 'elementor_kit_translation' ) );
|
|
|
|
// Fix home_url() for site-url Dynamic Tag and Search Form widget.
|
|
add_filter( 'pll_home_url_white_list', array( $this, 'elementor_home_url_white_list' ) );
|
|
add_filter( 'home_url', array( $this, 'home_url_language_dir_slash' ), 11, 2 );
|
|
|
|
// Translate Elementor order resume page (thankyou page).
|
|
add_filter( 'option_elementor_woocommerce_purchase_summary_page_id', 'pll_get_post' );
|
|
|
|
// Fix search url for Search Form widget.
|
|
add_action( 'elementor/frontend/widget/before_render', array( $this, 'add_search_form_home_url_filter' ) );
|
|
add_action( 'elementor/frontend/widget/after_render', array( $this, 'remove_search_form_home_url_filter' ) );
|
|
|
|
if ( is_admin() ) {
|
|
|
|
// All langs for template conditions & global widgets.
|
|
add_action( 'parse_query', array( $this, 'query_all_languages' ), 1 );
|
|
|
|
// Empty template conditions on translations.
|
|
add_filter( 'get_post_metadata', array( $this, 'elementor_conditions_empty_on_translations' ), 10, 3 );
|
|
add_filter( 'pre_update_option_elementor_pro_theme_builder_conditions', array( $this, 'theme_builder_conditions_remove_empty' ) );
|
|
|
|
// Global widgets hide language column.
|
|
add_action( 'manage_elementor_library_posts_custom_column', array( $this, 'hide_language_column_pre' ), 9, 2 );
|
|
add_action( 'manage_elementor_library_posts_custom_column', array( $this, 'hide_language_column_pos' ), 11, 2 );
|
|
|
|
if ( cpel_is_elementor_pro_active() ) {
|
|
// Update template conditions on language terms change.
|
|
add_action( 'set_object_terms', array( $this, 'update_conditions_on_term_change' ), 10, 4 );
|
|
|
|
// Translations conditions column.
|
|
add_action( 'manage_elementor_library_posts_custom_column', array( $this, 'instances_column_pre' ), 9, 2 );
|
|
add_action( 'manage_elementor_library_posts_custom_column', array( $this, 'instances_column_pos' ), 11, 2 );
|
|
}
|
|
|
|
// Don't add "_elementor_css" meta.
|
|
add_filter( 'update_post_metadata', array( $this, 'prevent_elementor_css_meta' ), 10, 3 );
|
|
add_action( 'pll_post_synchronized', array( $this, 'bulk_delete_elementor_css_meta' ), 10, 3 );
|
|
|
|
// Edit links for each language domain.
|
|
if ( cpel_is_polylang_multidomain() ) {
|
|
|
|
add_filter( 'post_row_actions', array( $this, 'fix_edit_link' ), 12, 2 );
|
|
add_filter( 'page_row_actions', array( $this, 'fix_edit_link' ), 12, 2 );
|
|
|
|
add_filter( 'elementor/document/urls/edit', array( $this, 'fix_elementor_edit_link' ), 10, 2 );
|
|
}
|
|
}
|
|
|
|
// Check if Elementor is installed and its version is greater than 3.25.0.
|
|
if ( cpel_elementor_min_version( '3.25.0' ) ) {
|
|
// Elementor 3.25.0 introduced a new way to handle language switcher controls.
|
|
add_action( 'elementor/documents/register_controls', array( $this, 'register_language_switcher_controls' ) );
|
|
} else {
|
|
// Deprecated way to handle language switcher controls.
|
|
// Elementor editor menu links to translations.
|
|
add_action( 'elementor/editor/after_enqueue_scripts', array( $this, 'elementor_editor_script' ) );
|
|
}
|
|
add_action( 'elementor/editor/after_enqueue_styles', array( $this, 'elementor_editor_style' ) );
|
|
|
|
// Elementor Site Editor template tweaks.
|
|
add_filter( 'elementor-pro/site-editor/data/template', array( $this, 'elementor_site_editor_template' ) );
|
|
|
|
}
|
|
|
|
/**
|
|
* Enable Elementor-specific post types automatically for Polylang translation
|
|
*
|
|
* @link https://polylang.pro/doc/filter-reference/
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $types The list of post type names for which Polylang manages language and translations.
|
|
* @param bool $is_settings True when displaying the list in Polylang settings.
|
|
* @return array The list of post type names for which Polylang manages language and translations
|
|
*/
|
|
public function add_polylang_post_types( $types, $is_settings ) {
|
|
|
|
$relevant_types = apply_filters(
|
|
'cpel/filter/polylang/post_types',
|
|
array(
|
|
'elementor_library', // Elementor.
|
|
'e-landing-page', // Elementor Landing pages.
|
|
'oceanwp_library', // OceanWP Library.
|
|
'astra-advanced-hook', // Astra Custom Layouts (Astra Pro).
|
|
'gp_elements', // GeneratePress Elements (GP Premium).
|
|
'jet-theme-core', // JetThemeCore (Kava Pro/ CrocoBlock).
|
|
'jet-engine', // JetEngine Listing Item (CrocoBlock).
|
|
'customify_hook', // Customify (Customify Pro).
|
|
'wpbf_hooks', // Page Builder Framework Sections (WPBF Premium).
|
|
'ae_global_templates', // AnyWhere Elementor plugin.
|
|
)
|
|
);
|
|
|
|
return array_merge( $types, array_combine( $relevant_types, $relevant_types ) );
|
|
|
|
}
|
|
|
|
/**
|
|
* Query all languages if conditions meets
|
|
*
|
|
* Note: Needs to be priority 1, since Polylang uses the action parse_query
|
|
* which is fired before 'pre_get_posts'.
|
|
*
|
|
* @link https://github.com/polylang/polylang/issues/152#issuecomment-320602328
|
|
* @link https://github.com/pojome/elementor/issues/4839
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param WP_Query $query current query.
|
|
* @return void
|
|
*/
|
|
public function query_all_languages( $query ) {
|
|
|
|
$global_widget_meta_query = array(
|
|
'key' => '_elementor_template_type',
|
|
'value' => 'widget',
|
|
);
|
|
|
|
$is_elementor_conditions = isset( $query->query_vars['meta_key'] )
|
|
&& '_elementor_conditions' === $query->query_vars['meta_key'];
|
|
|
|
$is_global_widget = isset( $query->query_vars['post_type'], $query->query_vars['meta_query'] )
|
|
&& 'elementor_library' === $query->query_vars['post_type']
|
|
&& is_array( $query->query_vars['meta_query'] )
|
|
&& in_array( $global_widget_meta_query, $query->query_vars['meta_query'], true );
|
|
|
|
if ( $is_elementor_conditions || $is_global_widget ) {
|
|
$query->set( 'lang', '' );
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Return empty conditions on secondary translations
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param mixed $null null for bypass.
|
|
* @param int $post_id current post ID.
|
|
* @param string $meta_key name of meta key.
|
|
* @return mixed null or empty array
|
|
*/
|
|
public function elementor_conditions_empty_on_translations( $null, $post_id, $meta_key ) {
|
|
|
|
return '_elementor_conditions' === $meta_key && cpel_is_translation( $post_id ) ? array( array() ) : $null;
|
|
|
|
}
|
|
|
|
/**
|
|
* Clear empty conditions before save 'elementor_pro_theme_builder_conditions' option
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $value array of theme builder conditions.
|
|
* @return array filtered array
|
|
*/
|
|
public function theme_builder_conditions_remove_empty( $value ) {
|
|
|
|
foreach ( $value as $location => $items ) {
|
|
$value[ $location ] = array_filter( $items );
|
|
}
|
|
|
|
return array_filter( $value );
|
|
|
|
}
|
|
|
|
/**
|
|
* Bypass Elementor template shortcode with their translation for the current language (if exists).
|
|
*
|
|
* @since 2.2.0
|
|
*
|
|
* @uses pll_get_post()
|
|
*
|
|
* @param mixed $false false or string with bypass output.
|
|
* @param string $tag shortcode tag.
|
|
* @param array $attr shortcode attributes.
|
|
* @return false|string false or string with bypass output
|
|
*/
|
|
public function shortcode_template_translate( $false, $tag, $attr ) {
|
|
|
|
if ( 'elementor-template' !== $tag ) {
|
|
return $false;
|
|
}
|
|
|
|
if ( isset( $attr['skip'] ) ) {
|
|
return $false;
|
|
}
|
|
|
|
// Translate post_id safely.
|
|
if ( isset( $attr['id'] ) && '' !== $attr['id'] ) {
|
|
$id = absint( $attr['id'] );
|
|
if ( $id ) {
|
|
$attr['id'] = pll_get_post( $id ) ?: $id; //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
}
|
|
}
|
|
// Skip next call.
|
|
$attr['skip'] = 1;
|
|
|
|
$output = '';
|
|
foreach ( $attr as $key => $val ) {
|
|
$output .= ' ' . esc_attr( sanitize_key( $key ) ) . '="' . esc_attr( $val ) . '"';
|
|
}
|
|
|
|
return do_shortcode( '[elementor-template' . $output . ']' );
|
|
|
|
}
|
|
|
|
/**
|
|
* Widget Template translate template_id
|
|
*
|
|
* @since 2.3.5
|
|
*
|
|
* @uses pll_get_post()
|
|
*
|
|
* @param \Elementor\Element_Base $element
|
|
* @return void
|
|
*/
|
|
public function widget_template_translate( $element ) {
|
|
|
|
if ( 'template' !== $element->get_name() ) {
|
|
return;
|
|
}
|
|
|
|
$template_id = pll_get_post( $element->get_settings( 'template_id' ) ) ?: $element->get_settings( 'template_id' ); //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
|
|
$element->set_settings( 'template_id', $template_id );
|
|
|
|
}
|
|
|
|
/**
|
|
* WordPress Widget "Elementor Library" translate 'template_id'
|
|
*
|
|
* @since 2.4.4
|
|
*
|
|
* @param array $instance
|
|
* @param WP_Widget $widget
|
|
* @return array
|
|
*/
|
|
public function wp_widget_template_translate( $instance, $widget ) {
|
|
|
|
if ( is_a( $widget, 'ElementorPro\Modules\Library\WP_Widgets\Elementor_Library' ) ) {
|
|
$instance['template_id'] = pll_get_post( absint( $instance['template_id'] ) ) ?: $instance['template_id']; //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
}
|
|
|
|
return $instance;
|
|
|
|
}
|
|
|
|
/**
|
|
* Change Elementor Kit template with their translation for the current language (if exists).
|
|
*
|
|
* @since 2.3.0
|
|
*
|
|
* @uses pll_get_post()
|
|
* @uses pll_get_post_language()
|
|
*
|
|
* @param mixed $value Value of 'elementor_active_kit' option, the ID of current Elementor Kit.
|
|
* @return int The translation ID, or the original Elementor Kit ID
|
|
*/
|
|
public function elementor_kit_translation( $value ) {
|
|
|
|
$translation = null;
|
|
// Is API REST '/wp-json/elementor/v1/globals'.
|
|
if ( defined( 'REST_REQUEST' ) && REST_REQUEST && isset( $_SERVER['HTTP_REFERER'] ) ) {
|
|
// Referrer is Elementor Editor?
|
|
$referer = esc_url_raw( $_SERVER['HTTP_REFERER'] );
|
|
wp_parse_str( wp_parse_url( $referer, PHP_URL_QUERY ), $query );
|
|
|
|
if ( isset( $query['action'], $query['post'] ) && 'elementor' === $query['action'] ) {
|
|
$translation = pll_get_post( $value, pll_get_post_language( absint( $query['post'] ) ) );
|
|
}
|
|
} elseif ( cpel_is_elementor_editor() ) {
|
|
$post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0;
|
|
$translation = $post_id ? pll_get_post( $value, pll_get_post_language( $post_id ) ) : null;
|
|
|
|
} elseif ( ! is_admin() ) {
|
|
|
|
$translation = pll_get_post( $value );
|
|
|
|
}
|
|
|
|
return $translation ? $translation : $value;
|
|
|
|
}
|
|
|
|
/**
|
|
* Change Elementor template with their translation for the current language (if exists).
|
|
*
|
|
* @link https://github.com/pojome/elementor/issues/4839
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @uses pll_get_post()
|
|
*
|
|
* @param int $post_id ID of the current post.
|
|
* @return string Based translation, the translation ID, or the original Post ID
|
|
*/
|
|
public function template_id_translation( $post_id ) {
|
|
|
|
$post_id = pll_get_post( $post_id ) ?: $post_id; //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
$this->template_id = $post_id; // Save for check sub_id.
|
|
|
|
return $post_id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Filter Elementor sub_conditions system
|
|
*
|
|
* If is translated template that is based on term or post
|
|
* return the translation ID of term or post.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @uses pll_get_post()
|
|
* @uses pll_get_term()
|
|
*
|
|
* @param int $sub_id ID of the object in subcondition.
|
|
* @param array $parsed_condition condition parts.
|
|
* @return int original sub ID or translated ID
|
|
*/
|
|
public function condition_sub_id_translation( $sub_id, $parsed_condition ) {
|
|
|
|
if ( $sub_id && cpel_is_translation( $this->template_id ) ) {
|
|
|
|
if ( in_array( $parsed_condition['sub_name'], get_post_types(), true ) ) {
|
|
|
|
$sub_id = pll_get_post( $sub_id ) ?: $sub_id; //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
|
|
} else {
|
|
|
|
$sub_id = pll_get_term( $sub_id ) ?: $sub_id; //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
|
|
}
|
|
}
|
|
|
|
return $sub_id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Update Elementor conditions
|
|
*
|
|
* On change post_translations terms on Elementor Library trigger conditions regenerate.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param mixed $post_id
|
|
* @param mixed $terms
|
|
* @param mixed $tt_ids
|
|
* @param mixed $taxonomy
|
|
* @return void
|
|
*/
|
|
public function update_conditions_on_term_change( $post_id, $terms, $tt_ids, $taxonomy ) {
|
|
|
|
if ( 'post_translations' === $taxonomy && 'elementor_library' === get_post_type( $post_id ) ) {
|
|
|
|
$theme_builder = \ElementorPro\Plugin::instance()->modules_manager->get_modules( 'theme-builder' );
|
|
$theme_builder->get_conditions_manager()->get_cache()->regenerate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Hide language column info pre
|
|
*
|
|
* Wrap language info for Global Widgets with a hidden div (open)
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $column
|
|
* @param int $post_id
|
|
* @return void
|
|
*/
|
|
public function hide_language_column_pre( $column, $post_id ) {
|
|
|
|
if ( false !== strpos( $column, 'language_' ) && 'widget' === get_post_meta( $post_id, '_elementor_template_type', true ) ) {
|
|
echo '<span aria-hidden="true">—</span><div class="hidden" aria-hidden="true">';
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Hide language column info pos
|
|
*
|
|
* Wrap language info for Global Widgets with a hidden div (close)
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $column
|
|
* @param int $post_id
|
|
* @return void
|
|
*/
|
|
public function hide_language_column_pos( $column, $post_id ) {
|
|
|
|
if ( false !== strpos( $column, 'language_' ) && 'widget' === get_post_meta( $post_id, '_elementor_template_type', true ) ) {
|
|
echo '</div>';
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Show default language instances in translations
|
|
*
|
|
* (Also wrap "None" with a hidden div)
|
|
*
|
|
* @since 2.0.4
|
|
*
|
|
* @param string $column
|
|
* @param int $post_id
|
|
* @return void
|
|
*/
|
|
public function instances_column_pre( $column, $post_id ) {
|
|
|
|
if ( 'instances' === $column && 'widget' !== get_post_meta( $post_id, '_elementor_template_type', true ) && cpel_is_translation( $post_id ) ) {
|
|
|
|
$default_post = pll_get_post( $post_id, pll_default_language() );
|
|
$theme_builder = \ElementorPro\Plugin::instance()->modules_manager->get_modules( 'theme-builder' );
|
|
$instances = $theme_builder->get_conditions_manager()->get_document_instances( $default_post );
|
|
|
|
if ( empty( $instances ) ) {
|
|
$instances = array( 'none' => esc_html__( 'None', 'elementor-pro' ) ); // phpcs:ignore WordPress.WP.I18n
|
|
}
|
|
|
|
echo '<span style="opacity:.4">' . esc_html( implode( ', ', $instances ) ) . '</span><div class="hidden" aria-hidden="true">';
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Show default language instances in translations (close)
|
|
*
|
|
* @since 2.0.4
|
|
*
|
|
* @param string $column
|
|
* @param int $post_id
|
|
* @return void
|
|
*/
|
|
public function instances_column_pos( $column, $post_id ) {
|
|
|
|
if ( 'instances' === $column && 'widget' !== get_post_meta( $post_id, '_elementor_template_type', true ) && cpel_is_translation( $post_id ) ) {
|
|
echo '</div>';
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Don't copy '_elementor_css' meta on Polylang add new translation
|
|
*
|
|
* Without this meta Elementor generates the css for the new post.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param mixed $null
|
|
* @param int $post_id
|
|
* @param string $meta_key
|
|
* @return mixed null or false
|
|
*/
|
|
public function prevent_elementor_css_meta( $null, $post_id, $meta_key ) {
|
|
|
|
global $pagenow;
|
|
|
|
return '_elementor_css' === $meta_key && 'post-new.php' === $pagenow
|
|
&& isset( $_GET['from_post'], $_GET['new_lang'] )
|
|
&& ! empty( absint( wp_unslash( $_GET['from_post'] ) ) )
|
|
&& ! empty( sanitize_key( wp_unslash( $_GET['new_lang'] ) ) ) ? false : $null;
|
|
|
|
}
|
|
|
|
/**
|
|
* Delete '_elementor_css' meta on Polylang bulk translation
|
|
*
|
|
* Without this meta Elementor generates the css for the new post.
|
|
*
|
|
* @since 2.4.3
|
|
*
|
|
* @param int $post_id
|
|
* @param int $tr_id
|
|
* @param string $lang
|
|
* @return void
|
|
*/
|
|
public function bulk_delete_elementor_css_meta( $post_id, $tr_id, $lang ) {
|
|
|
|
delete_post_meta( $tr_id, '_elementor_css' );
|
|
|
|
}
|
|
|
|
/**
|
|
* Whitelist Elementor Pro home_url()
|
|
*
|
|
* Polylang add home_url() to whitelist for Elementor Pro
|
|
* "Search Form" widget and "Site Url" dynamic tag.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $white_list
|
|
* @return array
|
|
*/
|
|
public function elementor_home_url_white_list( $white_list ) {
|
|
|
|
$white_list[] = array( 'file' => 'site-url.php' );
|
|
|
|
return $white_list;
|
|
|
|
}
|
|
|
|
/**
|
|
* Language subdir add trailing slash
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $url
|
|
* @param string $path
|
|
* @return string
|
|
*/
|
|
public function home_url_language_dir_slash( $url, $path ) {
|
|
|
|
return empty( $path ) && ! is_admin() && get_option( 'home' ) !== $url
|
|
&& function_exists( 'PLL' ) && 1 === PLL()->options['force_lang'] ? trailingslashit( $url ) : $url;
|
|
|
|
}
|
|
|
|
/**
|
|
* Replace home_url with correct language search url
|
|
*
|
|
* Only for Elementor Search Form that uses home_url() in form action.
|
|
*
|
|
* @since 2.0.6
|
|
*
|
|
* @param string $url
|
|
* @param string $path
|
|
* @return string
|
|
*/
|
|
public function search_form_home_url_filter( $url, $path ) {
|
|
|
|
if ( ! function_exists( 'PLL' ) || ! is_a( PLL()->curlang, 'PLL_Language', true ) ) {
|
|
return $url;
|
|
}
|
|
|
|
return method_exists( PLL()->curlang, 'get_search_url' ) ?
|
|
PLL()->curlang->get_search_url() :
|
|
PLL()->curlang->search_url;
|
|
|
|
}
|
|
|
|
/**
|
|
* Add home_url() filter before render Search Form
|
|
*
|
|
* @since 2.0.6
|
|
*
|
|
* @param Element_Base $element
|
|
* @return void
|
|
*/
|
|
public function add_search_form_home_url_filter( $element ) {
|
|
|
|
if ( 'search' === $element->get_name() || 'search-form' === $element->get_name() ) {
|
|
add_filter( 'home_url', array( $this, 'search_form_home_url_filter' ), 10, 2 );
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Remove home_url() filter after render Search Form
|
|
*
|
|
* @since 2.0.6
|
|
*
|
|
* @param Element_Base $element
|
|
* @return void
|
|
*/
|
|
public function remove_search_form_home_url_filter( $element ) {
|
|
|
|
if ( 'search' === $element->get_name() || 'search-form' === $element->get_name() ) {
|
|
remove_filter( 'home_url', array( $this, 'search_form_home_url_filter' ) );
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Elementor editor script
|
|
*
|
|
* Add script with links to translations on Elementor editor panel.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @return void
|
|
*/
|
|
public function elementor_editor_script() {
|
|
|
|
global $typenow, $post;
|
|
|
|
// If is post type translatable.
|
|
if ( pll_is_translated_post_type( $typenow ) ) {
|
|
|
|
$languages = pll_languages_list( array( 'fields' => '' ) );
|
|
$translations = pll_get_post_translations( $post->ID );
|
|
$current = pll_get_post_language( $post->ID, 'name' );
|
|
$use_emojis = apply_filters( 'cpel/filter/use_emojis', true );
|
|
|
|
$items = array();
|
|
foreach ( $languages as $language ) {
|
|
if ( $language->name === $current ) {
|
|
$translation_id = $translations[ $language->slug ];
|
|
|
|
$items[] = array(
|
|
'name' => 'cpel-current',
|
|
'icon' => 'eicon-document-file',
|
|
'title' => sprintf(
|
|
'%s — %s',
|
|
get_the_title( $translation_id ),
|
|
$use_emojis ? cpel_flag_emoji( $language->flag_code ) : $language->name
|
|
),
|
|
'callback' => 'function(){}',
|
|
);
|
|
|
|
} elseif ( isset( $translations[ $language->slug ] ) ) {
|
|
|
|
$translation_id = $translations[ $language->slug ];
|
|
$link = $this->fix_url_domain( get_edit_post_link( $translation_id, 'edit' ), $translation_id );
|
|
|
|
if ( get_post_meta( $translation_id, '_elementor_edit_mode', true ) ) {
|
|
$link = add_query_arg( 'action', 'elementor', $link );
|
|
}
|
|
|
|
$items[] = array(
|
|
'name' => "cpel-{$language->slug}",
|
|
'icon' => 'eicon-document-file',
|
|
'title' => sprintf(
|
|
'%s — %s',
|
|
get_the_title( $translation_id ),
|
|
$use_emojis ? cpel_flag_emoji( $language->flag_code ) : $language->name
|
|
),
|
|
'type' => 'link',
|
|
'link' => $link,
|
|
);
|
|
} else {
|
|
|
|
$args = array(
|
|
'post_type' => $typenow,
|
|
'from_post' => $post->ID,
|
|
'new_lang' => $language->slug,
|
|
'_wpnonce' => wp_create_nonce( 'new-post-translation' ),
|
|
);
|
|
|
|
$link = add_query_arg( $args, admin_url( 'post-new.php' ) );
|
|
|
|
$items[] = array(
|
|
'name' => "cpel-{$language->slug}",
|
|
'icon' => 'eicon-plus',
|
|
'title' => $use_emojis
|
|
? sprintf( __( 'Add a translation — %s', 'connect-polylang-elementor' ), cpel_flag_emoji( $language->flag_code ) ) // phpcs:ignore WordPress.WP.I18n
|
|
: sprintf( __( 'Add a translation in %s', 'polylang' ), $language->name ), // phpcs:ignore WordPress.WP.I18n
|
|
'type' => 'link',
|
|
'link' => $link,
|
|
);
|
|
}
|
|
}
|
|
|
|
$group = array(
|
|
'name' => 'cpel',
|
|
'title' => __( 'Languages', 'polylang' ), // phpcs:ignore WordPress.WP.I18n
|
|
'items' => $items,
|
|
);
|
|
|
|
$script = 'jQuery(window).on("elementor:init", () => {
|
|
window.elementor.on("panel:init", () => {
|
|
setTimeout(() => { window.elementor.modules.layouts.panel.pages.menu.Menu.groups.add(' . wp_json_encode( $group ) . '); });
|
|
});
|
|
});';
|
|
|
|
// Add after Elementor editor script.
|
|
wp_add_inline_script( 'elementor-editor', $script );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Elementor editor script
|
|
*
|
|
* Add script with links to translations on Elementor editor panel.
|
|
*
|
|
* @since 2.3.5
|
|
*
|
|
* @return void
|
|
*/
|
|
public function elementor_editor_style() {
|
|
|
|
global $typenow;
|
|
|
|
// If is post type translatable.
|
|
if ( ! pll_is_translated_post_type( $typenow ) ) {
|
|
return;
|
|
}
|
|
|
|
// New language switcher styles for Elementor 3.25.0+.
|
|
if ( cpel_elementor_min_version( '3.25.0' ) ) {
|
|
|
|
$style = '
|
|
.elementor-control-cpel-languages a {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
padding: 8px 5px;
|
|
border: none;
|
|
color: inherit;
|
|
line-height: 1.25em;
|
|
font-weight: 400;
|
|
text-decoration: none;
|
|
transition: none;
|
|
}
|
|
|
|
.elementor-control-cpel-languages a.current, .elementor-control-cpel-languages a:hover {
|
|
background-color: var(--e-a-bg-hover);
|
|
color: inherit;
|
|
}
|
|
|
|
.elementor-control-cpel-languages i {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.elementor-control-cpel-languages .flag {
|
|
margin-left: auto;
|
|
font-size: 16px;
|
|
}';
|
|
|
|
wp_add_inline_style( 'elementor-editor', $style );
|
|
|
|
return;
|
|
}
|
|
|
|
// Old language switcher styles for Elementor < 3.25.0
|
|
$style = '' .
|
|
".elementor-panel .elementor-panel-menu-item.elementor-panel-menu-item-cpel-current {\n" .
|
|
" background: #eceeef;\n" .
|
|
" cursor: default;\n" .
|
|
'}';
|
|
|
|
wp_add_inline_style( 'elementor-editor', $style );
|
|
|
|
$ui_theme = SettingsManager::get_settings_managers( 'editorPreferences' )->get_model()->get_settings( 'ui_theme' );
|
|
|
|
if ( 'light' !== $ui_theme ) {
|
|
$ui_theme_media_queries = 'auto' === $ui_theme ? '(prefers-color-scheme: dark)' : 'all';
|
|
|
|
$dark = '' .
|
|
"@media $ui_theme_media_queries {\n" .
|
|
" .elementor-panel .elementor-panel-menu-item.elementor-panel-menu-item-cpel-current {\n" .
|
|
" background: #7d7e82;\n" .
|
|
" }\n" .
|
|
'}';
|
|
|
|
wp_add_inline_style( 'elementor-editor-dark-mode', $dark );
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Elementor Site Editor template changes
|
|
*
|
|
* At 2.0.0 named "elementor_theme_editor_title"
|
|
*
|
|
* @since 2.0.4
|
|
*
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function elementor_site_editor_template( $data ) {
|
|
|
|
$post_id = $data['id'];
|
|
|
|
// Add lang info to title.
|
|
if ( apply_filters( 'cpel/filter/use_emojis', true ) ) {
|
|
$data['title'] = sprintf( '%s — %s', $data['title'], cpel_flag_emoji( pll_get_post_language( $post_id, 'flag_code' ) ) );
|
|
} else {
|
|
$data['title'] = sprintf( '%s — %s', $data['title'], pll_get_post_language( $post_id, 'name' ) );
|
|
}
|
|
|
|
// Show default language instances in translations (and recalc isActive).
|
|
if ( cpel_is_translation( $post_id ) ) {
|
|
|
|
$language = pll_default_language();
|
|
|
|
$default_post = pll_get_post( $post_id, $language );
|
|
$theme_builder = \ElementorPro\Plugin::instance()->modules_manager->get_modules( 'theme-builder' );
|
|
$instances = $theme_builder->get_conditions_manager()->get_document_instances( $default_post );
|
|
|
|
if ( empty( $instances ) ) {
|
|
$instances = array( 'no_instances' => esc_html__( 'No instances', 'elementor-pro' ) ); // phpcs:ignore WordPress.WP.I18n
|
|
$is_active = false;
|
|
} else {
|
|
$is_active = 'publish' === $data['status'];
|
|
}
|
|
|
|
$data['instances'] = array( 'cpel' => sprintf( esc_html__( '(from %s)', 'connect-polylang-elementor' ), strtoupper( $language ) ) ) + $instances; // phpcs:ignore WordPress.WP.I18n
|
|
$data['isActive'] = $is_active;
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
/**
|
|
* Fix url domain
|
|
*
|
|
* @param mixed $url current url.
|
|
* @param mixed $post_id current post ID.
|
|
* @return string fixed domain url
|
|
*/
|
|
private function fix_url_domain( $url, $post_id ) {
|
|
|
|
$current_host = wp_parse_url( pll_current_language( 'home_url' ) ?: trailingslashit( '//' . sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) ), PHP_URL_HOST ); //phpcs:ignore WordPress.PHP.DisallowShortTernary
|
|
$post_host = wp_parse_url( pll_get_post_language( $post_id, 'home_url' ), PHP_URL_HOST );
|
|
|
|
if ( $current_host !== $post_host ) {
|
|
$url = str_replace( $current_host, $post_host, $url );
|
|
}
|
|
|
|
return $url;
|
|
|
|
}
|
|
|
|
/**
|
|
* Fix domain for Elementor edit links in posts table
|
|
*
|
|
* @param array $actions
|
|
* @param WP_Post $post
|
|
* @return array
|
|
*/
|
|
public function fix_edit_link( $actions, $post ) {
|
|
|
|
if ( ! empty( $actions['edit_with_elementor'] ) ) {
|
|
// $actions['edit'] = $this->fix_url_domain( $actions['edit'], $post->ID );
|
|
$actions['edit_with_elementor'] = $this->fix_url_domain( $actions['edit_with_elementor'], $post->ID );
|
|
}
|
|
|
|
return $actions;
|
|
|
|
}
|
|
|
|
/**
|
|
* Fix domain for Elementor edit links in Theme Builder
|
|
*
|
|
* @param string $url
|
|
* @param Elementor\Core\Base\Document $document
|
|
* @return string
|
|
*/
|
|
public function fix_elementor_edit_link( $url, $document ) {
|
|
|
|
return $this->fix_url_domain( $url, $document->get_main_id() );
|
|
|
|
}
|
|
|
|
/**
|
|
* Register language switcher controls in Elementor's document settings panel.
|
|
* This function adds a "Languages" section where users can manage translations for the current post.
|
|
*
|
|
* @param \Elementor\Base\Document $document The Elementor document object.
|
|
* @since 2.5.0
|
|
*/
|
|
public function register_language_switcher_controls( $document ) {
|
|
|
|
global $typenow, $post;
|
|
|
|
// Exit if is not translatable.
|
|
if ( ! pll_is_translated_post_type( $typenow ) ) {
|
|
return;
|
|
}
|
|
|
|
// Get the current post ID being edited in Elementor.
|
|
$post_id = $post->ID;
|
|
|
|
// Retrieve available languages from Polylang.
|
|
$languages = pll_languages_list( array( 'fields' => '' ) );
|
|
$translations = pll_get_post_translations( $post_id );
|
|
$raw_html = '';
|
|
|
|
// Start adding a new section in Elementor settings panel.
|
|
$document->start_controls_section(
|
|
'cpel_language_section',
|
|
array(
|
|
'label' => esc_html__( 'Languages', 'polylang' ), // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
|
|
'tab' => \Elementor\Controls_Manager::TAB_SETTINGS,
|
|
)
|
|
);
|
|
|
|
// Loop through each available language.
|
|
foreach ( $languages as $language ) {
|
|
$lang_parts = array(
|
|
'class' => 'cpel-language',
|
|
'href' => '',
|
|
'icon' => '',
|
|
'text' => '',
|
|
'flag' => str_replace( '<img ', '<img class="flag" ', $language->flag ),
|
|
);
|
|
|
|
// Check if a translation exists for the current language.
|
|
if ( isset( $translations[ $language->slug ] ) ) {
|
|
// Get the post ID of the translated post.
|
|
$translation_id = $translations[ $language->slug ];
|
|
|
|
$lang_parts['icon'] = '<i class="eicon-document-file"></i>';
|
|
$lang_parts['text'] = '<span class="text">' . esc_html( get_the_title( $translation_id ) ) . '</span>';
|
|
|
|
if ( $translation_id === $post_id ) {
|
|
$lang_parts['class'] .= ' current';
|
|
} else {
|
|
// Get edit link for the translated post.
|
|
$edit_link = get_edit_post_link( $translation_id, 'edit' );
|
|
|
|
// Modify edit link if it's built with Elementor.
|
|
if ( get_post_meta( $translation_id, '_elementor_edit_mode', true ) ) {
|
|
$edit_link = add_query_arg( 'action', 'elementor', $edit_link );
|
|
}
|
|
|
|
$lang_parts['href'] = $edit_link;
|
|
}
|
|
} else {
|
|
// Generate the create translation link.
|
|
$args = array(
|
|
'post_type' => get_post_type( $post_id ),
|
|
'from_post' => $post_id,
|
|
'new_lang' => $language->slug,
|
|
'_wpnonce' => wp_create_nonce( 'new-post-translation' ),
|
|
);
|
|
$create_link = add_query_arg( $args, admin_url( 'post-new.php' ) );
|
|
|
|
$lang_parts['class'] .= ' add-new';
|
|
$lang_parts['icon'] = '<i class="eicon-plus"></i>';
|
|
$lang_parts['href'] = $create_link;
|
|
$lang_parts['text'] = '<span class="text">' . sprintf( esc_html__( 'Add a translation in %s', 'polylang' ), strtolower( esc_html( $language->name ) ) ) . '</span>'; // phpcs:ignore WordPress.WP.I18n
|
|
}
|
|
|
|
$raw_html .= sprintf(
|
|
'<li><a class="%s" %s>%s %s %s</a></li>',
|
|
$lang_parts['class'],
|
|
$lang_parts['href'] ? sprintf( 'href="%s" target="_blank"', esc_url( $lang_parts['href'] ) ) : '',
|
|
$lang_parts['icon'],
|
|
$lang_parts['text'],
|
|
$lang_parts['flag']
|
|
);
|
|
}
|
|
|
|
$document->add_control(
|
|
'cpel_languages',
|
|
array(
|
|
'type' => \Elementor\Controls_Manager::RAW_HTML,
|
|
'raw' => '<ul>' . $raw_html . '</ul>',
|
|
'content_classes' => 'elementor-control-cpel-languages',
|
|
)
|
|
);
|
|
|
|
// End the controls section.
|
|
$document->end_controls_section();
|
|
}
|
|
}
|