first commit
This commit is contained in:
575
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-base.php
vendored
Normal file
575
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-base.php
vendored
Normal file
@@ -0,0 +1,575 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Setup features available on all admin pages.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
abstract class PLL_Admin_Base extends PLL_Base {
|
||||
/**
|
||||
* Current language (used to filter the content).
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Language selected in the admin language filter.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $filter_lang;
|
||||
|
||||
/**
|
||||
* Preferred language to assign to new contents.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $pref_lang;
|
||||
|
||||
/**
|
||||
* @var PLL_Filters_Links|null
|
||||
*/
|
||||
public $filters_links;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Notices|null
|
||||
*/
|
||||
public $notices;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Static_Pages|null
|
||||
*/
|
||||
public $static_pages;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Default_Term|null
|
||||
*/
|
||||
public $default_term;
|
||||
|
||||
/**
|
||||
* Setups actions needed on all admin pages.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param PLL_Links_Model $links_model Reference to the links model.
|
||||
*/
|
||||
public function __construct( &$links_model ) {
|
||||
parent::__construct( $links_model );
|
||||
|
||||
// Adds the link to the languages panel in the WordPress admin menu
|
||||
add_action( 'admin_menu', array( $this, 'add_menus' ) );
|
||||
|
||||
add_action( 'admin_menu', array( $this, 'remove_customize_submenu' ) );
|
||||
|
||||
// Setup js scripts and css styles
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
add_action( 'admin_print_footer_scripts', array( $this, 'admin_print_footer_scripts' ), 0 ); // High priority in case an ajax request is sent by an immediately invoked function
|
||||
|
||||
add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts' ) );
|
||||
|
||||
// Early instantiated to be able to correctly initialize language properties.
|
||||
$this->static_pages = new PLL_Admin_Static_Pages( $this );
|
||||
$this->model->set_languages_ready();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups filters and action needed on all admin pages and on plugins page
|
||||
* Loads the settings pages or the filters base on the request
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
$this->notices = new PLL_Admin_Notices( $this );
|
||||
|
||||
$this->default_term = new PLL_Admin_Default_Term( $this );
|
||||
$this->default_term->add_hooks();
|
||||
|
||||
if ( ! $this->model->has_languages() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
|
||||
$this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ?
|
||||
|
||||
// Filter admin language for users
|
||||
// We must not call user info before WordPress defines user roles in wp-settings.php
|
||||
add_action( 'setup_theme', array( $this, 'init_user' ) );
|
||||
add_filter( 'request', array( $this, 'request' ) );
|
||||
|
||||
// Adds the languages in admin bar
|
||||
add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 100 ); // 100 determines the position
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the link to the languages panel in the WordPress admin menu
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_menus() {
|
||||
global $admin_page_hooks;
|
||||
|
||||
// Prepare the list of tabs
|
||||
$tabs = array( 'lang' => __( 'Languages', 'polylang' ) );
|
||||
|
||||
// Only if at least one language has been created
|
||||
if ( $this->model->has_languages() ) {
|
||||
$tabs['strings'] = __( 'Translations', 'polylang' );
|
||||
}
|
||||
|
||||
$tabs['settings'] = __( 'Settings', 'polylang' );
|
||||
|
||||
/**
|
||||
* Filter the list of tabs in Polylang settings
|
||||
*
|
||||
* @since 1.5.1
|
||||
*
|
||||
* @param array $tabs list of tab names
|
||||
*/
|
||||
$tabs = apply_filters( 'pll_settings_tabs', $tabs );
|
||||
|
||||
$parent = '';
|
||||
|
||||
foreach ( $tabs as $tab => $title ) {
|
||||
$page = 'lang' === $tab ? 'mlang' : "mlang_$tab";
|
||||
if ( empty( $parent ) ) {
|
||||
$parent = $page;
|
||||
add_menu_page( $title, __( 'Languages', 'polylang' ), 'manage_options', $page, '__return_null', 'dashicons-translation' );
|
||||
$admin_page_hooks[ $page ] = 'languages'; // Hack to avoid the localization of the hook name. See: https://core.trac.wordpress.org/ticket/18857
|
||||
}
|
||||
|
||||
add_submenu_page( $parent, $title, $title, 'manage_options', $page, array( $this, 'languages_page' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup js scripts & css styles ( only on the relevant pages )
|
||||
*
|
||||
* @since 0.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_enqueue_scripts() {
|
||||
$screen = get_current_screen();
|
||||
if ( empty( $screen ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
/*
|
||||
* For each script:
|
||||
* 0 => the pages on which to load the script
|
||||
* 1 => the scripts it needs to work
|
||||
* 2 => true if loaded even if languages have not been defined yet, false otherwise
|
||||
* 3 => true if loaded in footer
|
||||
*/
|
||||
$scripts = array(
|
||||
'user' => array( array( 'profile', 'user-edit' ), array( 'jquery' ), false, false ),
|
||||
'widgets' => array( array( 'widgets' ), array( 'jquery' ), false, false ),
|
||||
);
|
||||
|
||||
$block_screens = array( 'widgets', 'site-editor' );
|
||||
|
||||
if ( ! empty( $screen->post_type ) && $this->model->is_translated_post_type( $screen->post_type ) ) {
|
||||
$scripts['post'] = array( array( 'edit', 'upload' ), array( 'jquery', 'wp-ajax-response' ), false, true );
|
||||
|
||||
// Classic editor.
|
||||
if ( ! method_exists( $screen, 'is_block_editor' ) || ! $screen->is_block_editor() ) {
|
||||
$scripts['classic-editor'] = array( array( 'post', 'media', 'async-upload' ), array( 'jquery', 'wp-ajax-response', 'post', 'jquery-ui-dialog', 'wp-i18n' ), false, true );
|
||||
}
|
||||
|
||||
// Block editor with legacy metabox in WP 5.0+.
|
||||
$block_screens[] = 'post';
|
||||
}
|
||||
|
||||
if ( $this->is_block_editor( $screen ) ) {
|
||||
$scripts['block-editor'] = array( $block_screens, array( 'jquery', 'wp-ajax-response', 'wp-api-fetch', 'jquery-ui-dialog', 'wp-i18n' ), false, true );
|
||||
}
|
||||
|
||||
if ( ! empty( $screen->taxonomy ) && $this->model->is_translated_taxonomy( $screen->taxonomy ) ) {
|
||||
$scripts['term'] = array( array( 'edit-tags', 'term' ), array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), false, true );
|
||||
}
|
||||
|
||||
foreach ( $scripts as $script => $v ) {
|
||||
if ( in_array( $screen->base, $v[0] ) && ( $v[2] || $this->model->has_languages() ) ) {
|
||||
wp_enqueue_script( 'pll_' . $script, plugins_url( '/js/build/' . $script . $suffix . '.js', POLYLANG_ROOT_FILE ), $v[1], POLYLANG_VERSION, $v[3] );
|
||||
if ( 'classic-editor' === $script || 'block-editor' === $script ) {
|
||||
wp_set_script_translations( 'pll_' . $script, 'polylang' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_register_style( 'polylang_admin', plugins_url( '/css/build/admin' . $suffix . '.css', POLYLANG_ROOT_FILE ), array( 'wp-jquery-ui-dialog' ), POLYLANG_VERSION );
|
||||
wp_enqueue_style( 'polylang_dialog', plugins_url( '/css/build/dialog' . $suffix . '.css', POLYLANG_ROOT_FILE ), array( 'polylang_admin' ), POLYLANG_VERSION );
|
||||
|
||||
$this->add_inline_scripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether or not the given screen is block editor kind.
|
||||
* e.g. widget, site or post editor.
|
||||
*
|
||||
* @since 3.3
|
||||
*
|
||||
* @param WP_Screen $screen Screen object.
|
||||
* @return bool True if the screen is a block editor, false otherwise.
|
||||
*/
|
||||
protected function is_block_editor( $screen ) {
|
||||
return method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() && ! pll_use_block_editor_plugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts to the WP Customizer.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function customize_controls_enqueue_scripts() {
|
||||
if ( $this->model->has_languages() ) {
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
wp_enqueue_script( 'pll_widgets', plugins_url( '/js/build/widgets' . $suffix . '.js', POLYLANG_ROOT_FILE ), array( 'jquery' ), POLYLANG_VERSION, true );
|
||||
$this->add_inline_scripts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds inline scripts to set the default language in JS
|
||||
* and localizes scripts.
|
||||
*
|
||||
* @since 3.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_inline_scripts() {
|
||||
if ( wp_script_is( 'pll_block-editor', 'enqueued' ) ) {
|
||||
$default_lang_script = 'const pllDefaultLanguage = "' . $this->options['default_lang'] . '";';
|
||||
wp_add_inline_script(
|
||||
'pll_block-editor',
|
||||
$default_lang_script,
|
||||
'before'
|
||||
);
|
||||
}
|
||||
if ( wp_script_is( 'pll_widgets', 'enqueued' ) ) {
|
||||
wp_localize_script(
|
||||
'pll_widgets',
|
||||
'pll_widgets',
|
||||
array(
|
||||
'flags' => wp_list_pluck( $this->model->get_languages_list(), 'flag', 'slug' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pll_ajax_backend on all backend ajax request
|
||||
* The final goal is to detect if an ajax request is made on admin or frontend
|
||||
*
|
||||
* Takes care to various situations:
|
||||
* when the ajax request has no options.data thanks to ScreenfeedFr
|
||||
* see: https://wordpress.org/support/topic/ajaxprefilter-may-not-work-as-expected
|
||||
* when options.data is a json string
|
||||
* see: https://wordpress.org/support/topic/polylang-breaking-third-party-ajax-requests-on-admin-panels
|
||||
* when options.data is an empty string (GET request with the method 'load')
|
||||
* see: https://wordpress.org/support/topic/invalid-url-during-wordpress-new-dashboard-widget-operation
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_print_footer_scripts() {
|
||||
global $post_ID, $tag_ID;
|
||||
|
||||
$params = array( 'pll_ajax_backend' => 1 );
|
||||
if ( ! empty( $post_ID ) ) {
|
||||
$params = array_merge( $params, array( 'pll_post_id' => (int) $post_ID ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $tag_ID ) ) {
|
||||
$params = array_merge( $params, array( 'pll_term_id' => (int) $tag_ID ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of parameters to add to the admin ajax request.
|
||||
*
|
||||
* @since 3.4.5
|
||||
*
|
||||
* @param array $params List of parameters to add to the admin ajax request.
|
||||
*/
|
||||
$params = apply_filters( 'pll_admin_ajax_params', $params );
|
||||
|
||||
$str = http_build_query( $params );
|
||||
$arr = wp_json_encode( $params );
|
||||
?>
|
||||
<script>
|
||||
if (typeof jQuery != 'undefined') {
|
||||
jQuery(
|
||||
function( $ ){
|
||||
$.ajaxPrefilter( function ( options, originalOptions, jqXHR ) {
|
||||
if ( -1 != options.url.indexOf( ajaxurl ) || -1 != ajaxurl.indexOf( options.url ) ) {
|
||||
|
||||
function addPolylangParametersAsString() {
|
||||
if ( 'undefined' === typeof options.data || '' === options.data.trim() ) {
|
||||
// Only Polylang data need to be send. So it could be as a simple query string.
|
||||
options.data = '<?php echo $str; // phpcs:ignore WordPress.Security.EscapeOutput ?>';
|
||||
} else {
|
||||
/*
|
||||
* In some cases data could be a JSON string like in third party plugins.
|
||||
* So we need not to break their process by adding polylang parameters as valid JSON data.
|
||||
*/
|
||||
try {
|
||||
options.data = JSON.stringify( Object.assign( JSON.parse( options.data ), <?php echo $arr; // phpcs:ignore WordPress.Security.EscapeOutput ?> ) );
|
||||
} catch( exception ) {
|
||||
// Add Polylang data to the existing query string.
|
||||
options.data = options.data + '&<?php echo $str; // phpcs:ignore WordPress.Security.EscapeOutput ?>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* options.processData set to true is the default jQuery process where the data is converted in a query string by using jQuery.param().
|
||||
* This step is done before applying filters. Thus here the options.data is already a string in this case.
|
||||
* @See https://github.com/jquery/jquery/blob/3.5.1/src/ajax.js#L563-L569 jQuery ajax function.
|
||||
* It is the most case WordPress send ajax request this way however third party plugins or themes could be send JSON string.
|
||||
* Use JSON format is recommended in jQuery.param() documentation to be able to send complex data structures.
|
||||
* @See https://api.jquery.com/jquery.param/ jQuery param function.
|
||||
*/
|
||||
if ( options.processData ) {
|
||||
addPolylangParametersAsString();
|
||||
} else {
|
||||
/*
|
||||
* If options.processData is set to false data could be undefined or pass as a string.
|
||||
* So data as to be processed as if options.processData is set to true.
|
||||
*/
|
||||
if ( 'undefined' === typeof options.data || 'string' === typeof options.data ) {
|
||||
addPolylangParametersAsString();
|
||||
} else {
|
||||
// Otherwise options.data is probably an object.
|
||||
options.data = Object.assign( options.data || {} , <?php echo $arr; // phpcs:ignore WordPress.Security.EscapeOutput ?> );
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the admin current language, used to filter the content
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_current_language() {
|
||||
$this->curlang = $this->filter_lang;
|
||||
|
||||
// Edit Post
|
||||
if ( isset( $_REQUEST['pll_post_id'] ) && $lang = $this->model->post->get_language( (int) $_REQUEST['pll_post_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = $lang;
|
||||
} elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_GET['post'] ) && $this->model->is_translated_post_type( get_post_type( (int) $_GET['post'] ) ) && $lang = $this->model->post->get_language( (int) $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = $lang;
|
||||
} elseif ( 'post-new.php' === $GLOBALS['pagenow'] && ( empty( $_GET['post_type'] ) || $this->model->is_translated_post_type( sanitize_key( $_GET['post_type'] ) ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = empty( $_GET['new_lang'] ) ? $this->pref_lang : $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
// Edit Term
|
||||
elseif ( isset( $_REQUEST['pll_term_id'] ) && $lang = $this->model->term->get_language( (int) $_REQUEST['pll_term_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = $lang;
|
||||
} elseif ( in_array( $GLOBALS['pagenow'], array( 'edit-tags.php', 'term.php' ) ) && isset( $_GET['taxonomy'] ) && $this->model->is_translated_taxonomy( sanitize_key( $_GET['taxonomy'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
if ( isset( $_GET['tag_ID'] ) && $lang = $this->model->term->get_language( (int) $_GET['tag_ID'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = $lang;
|
||||
} elseif ( ! empty( $_GET['new_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
} elseif ( empty( $this->curlang ) ) {
|
||||
$this->curlang = $this->pref_lang;
|
||||
}
|
||||
}
|
||||
|
||||
// Ajax
|
||||
if ( wp_doing_ajax() && ! empty( $_REQUEST['lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->curlang = $this->model->get_language( sanitize_key( $_REQUEST['lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the current language used by Polylang in the admin context.
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @param PLL_Language|false|null $curlang Instance of the current language.
|
||||
* @param PLL_Admin_Base $polylang Instance of the main Polylang's object.
|
||||
*/
|
||||
$this->curlang = apply_filters( 'pll_admin_current_language', $this->curlang, $this );
|
||||
|
||||
// Inform that the admin language has been set.
|
||||
if ( $this->curlang instanceof PLL_Language ) {
|
||||
/** This action is documented in frontend/choose-lang.php */
|
||||
do_action( 'pll_language_defined', $this->curlang->slug, $this->curlang );
|
||||
} else {
|
||||
/** This action is documented in include/class-polylang.php */
|
||||
do_action( 'pll_no_language_defined' ); // To load overridden textdomains.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the backend language and the admin language filter based on user preferences
|
||||
*
|
||||
* @since 1.2.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_user() {
|
||||
// Language for admin language filter: may be empty
|
||||
// $_GET['lang'] is numeric when editing a language, not when selecting a new language in the filter
|
||||
// We intentionally don't use a nonce to update the language filter
|
||||
if ( ! wp_doing_ajax() && ! empty( $_GET['lang'] ) && ! is_numeric( sanitize_key( $_GET['lang'] ) ) && current_user_can( 'edit_user', $user_id = get_current_user_id() ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
update_user_meta( $user_id, 'pll_filter_content', ( $lang = $this->model->get_language( sanitize_key( $_GET['lang'] ) ) ) ? $lang->slug : '' ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
$this->filter_lang = $this->model->get_language( get_user_meta( get_current_user_id(), 'pll_filter_content', true ) );
|
||||
|
||||
// Set preferred language for use when saving posts and terms: must not be empty
|
||||
$this->pref_lang = empty( $this->filter_lang ) ? $this->model->get_default_language() : $this->filter_lang;
|
||||
|
||||
/**
|
||||
* Filters the preferred language on admin side.
|
||||
* The preferred language is used for example to determine the language of a new post.
|
||||
*
|
||||
* @since 1.2.3
|
||||
*
|
||||
* @param PLL_Language $pref_lang Preferred language.
|
||||
*/
|
||||
$this->pref_lang = apply_filters( 'pll_admin_preferred_language', $this->pref_lang );
|
||||
|
||||
$this->set_current_language();
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoids parsing a tax query when all languages are requested
|
||||
* Fixes https://wordpress.org/support/topic/notice-undefined-offset-0-in-wp-includesqueryphp-on-line-3877 introduced in WP 4.1
|
||||
*
|
||||
* @see https://core.trac.wordpress.org/ticket/31246 the suggestion of @boonebgorges.
|
||||
*
|
||||
* @since 1.6.5
|
||||
*
|
||||
* @param array $qvars The array of requested query variables.
|
||||
* @return array
|
||||
*/
|
||||
public function request( $qvars ) {
|
||||
if ( isset( $qvars['lang'] ) && 'all' === $qvars['lang'] ) {
|
||||
unset( $qvars['lang'] );
|
||||
}
|
||||
|
||||
return $qvars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the languages list in admin bar for the admin languages filter.
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar global object.
|
||||
* @return void
|
||||
*/
|
||||
public function admin_bar_menu( $wp_admin_bar ) {
|
||||
$all_item = (object) array(
|
||||
'slug' => 'all',
|
||||
'name' => __( 'Show all languages', 'polylang' ),
|
||||
'flag' => '<span class="ab-icon"></span>',
|
||||
);
|
||||
|
||||
$selected = empty( $this->filter_lang ) ? $all_item : $this->filter_lang;
|
||||
|
||||
$title = sprintf(
|
||||
'<span class="ab-label"%1$s><span class="screen-reader-text">%2$s</span>%3$s</span>',
|
||||
$selected instanceof PLL_Language ? sprintf( ' lang="%s"', esc_attr( $selected->get_locale( 'display' ) ) ) : '',
|
||||
__( 'Filters content by language', 'polylang' ),
|
||||
esc_html( $selected->name )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the admin languages filter submenu items
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $items The admin languages filter submenu items.
|
||||
*/
|
||||
$items = apply_filters( 'pll_admin_languages_filter', array_merge( array( $all_item ), $this->model->get_languages_list() ) );
|
||||
|
||||
$menu = array(
|
||||
'id' => 'languages',
|
||||
'title' => $selected->flag . $title,
|
||||
'href' => esc_url( add_query_arg( 'lang', $selected->slug, remove_query_arg( 'paged' ) ) ),
|
||||
'meta' => array(
|
||||
'title' => __( 'Filters content by language', 'polylang' ),
|
||||
),
|
||||
);
|
||||
|
||||
if ( 'all' !== $selected->slug ) {
|
||||
$menu['meta']['class'] = 'pll-filtered-languages';
|
||||
}
|
||||
|
||||
if ( ! empty( $items ) ) {
|
||||
$wp_admin_bar->add_menu( $menu );
|
||||
}
|
||||
|
||||
foreach ( $items as $lang ) {
|
||||
if ( $selected->slug === $lang->slug ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_menu(
|
||||
array(
|
||||
'parent' => 'languages',
|
||||
'id' => $lang->slug,
|
||||
'title' => $lang->flag . esc_html( $lang->name ),
|
||||
'href' => esc_url( add_query_arg( 'lang', $lang->slug, remove_query_arg( 'paged' ) ) ),
|
||||
'meta' => 'all' === $lang->slug ? array() : array( 'lang' => esc_attr( $lang->get_locale( 'display' ) ) ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the customize submenu when using a block theme.
|
||||
*
|
||||
* WordPress removes the Customizer menu if a block theme is activated and no other plugins interact with it.
|
||||
* As Polylang interacts with the Customizer, we have to delete this menu ourselves in the case of a block theme,
|
||||
* unless another plugin than Polylang interacts with the Customizer.
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove_customize_submenu() {
|
||||
if ( ! $this->should_customize_menu_be_removed() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $submenu;
|
||||
|
||||
if ( ! empty( $submenu['themes.php'] ) ) {
|
||||
foreach ( $submenu['themes.php'] as $submenu_item ) {
|
||||
if ( 'customize' === $submenu_item[1] ) {
|
||||
remove_submenu_page( 'themes.php', $submenu_item[2] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
92
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-block-editor.php
vendored
Normal file
92
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-block-editor.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to the block editor
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
class PLL_Admin_Block_Editor {
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* @var PLL_Filter_REST_Routes
|
||||
*/
|
||||
public $filter_rest_routes;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param PLL_Admin $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->model = &$polylang->model;
|
||||
$this->filter_rest_routes = new PLL_Filter_REST_Routes( $polylang->model );
|
||||
|
||||
add_filter( 'block_editor_rest_api_preload_paths', array( $this, 'filter_preload_paths' ), 50, 2 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'add_block_editor_inline_script' ), 15 ); // After `PLL_Admin_Base::admin_enqueue_scripts()` to ensure `pll_block-editor`script is enqueued.
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters preload paths based on the context (block editor for posts, site editor or widget editor for instance).
|
||||
*
|
||||
* @since 3.5
|
||||
*
|
||||
* @param array $preload_paths Preload paths.
|
||||
* @param WP_Block_Editor_Context $context Editor context.
|
||||
* @return array Filtered preload paths.
|
||||
*/
|
||||
public function filter_preload_paths( $preload_paths, $context ) {
|
||||
if ( ! $context instanceof WP_Block_Editor_Context ) {
|
||||
return $preload_paths;
|
||||
}
|
||||
|
||||
// Backward compatibility with WP < 6.0 where `WP_Block_Editor_Context::$name` doesn't exist yet.
|
||||
if (
|
||||
( property_exists( $context, 'name' ) && 'core/edit-post' !== $context->name )
|
||||
|| ! $context->post instanceof WP_Post
|
||||
) {
|
||||
// Do nothing if not post editor.
|
||||
return $preload_paths;
|
||||
}
|
||||
|
||||
if ( ! $this->model->is_translated_post_type( $context->post->post_type ) ) {
|
||||
return $preload_paths;
|
||||
}
|
||||
|
||||
$language = $this->model->post->get_language( $context->post->ID );
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
return $preload_paths;
|
||||
}
|
||||
|
||||
return $this->filter_rest_routes->add_query_parameters(
|
||||
$preload_paths,
|
||||
array(
|
||||
'lang' => $language->slug,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds inline block editor script for filterable REST routes.
|
||||
*
|
||||
* @since 3.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_block_editor_inline_script() {
|
||||
$handle = 'pll_block-editor';
|
||||
|
||||
if ( wp_script_is( $handle, 'enqueued' ) ) {
|
||||
$this->filter_rest_routes->add_inline_script( $handle );
|
||||
}
|
||||
}
|
||||
}
|
||||
371
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-classic-editor.php
vendored
Normal file
371
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-classic-editor.php
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to the classic editor
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
class PLL_Admin_Classic_Editor {
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* Current language (used to filter the content).
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Preferred language to assign to new contents.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $pref_lang;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->model = &$polylang->model;
|
||||
$this->links = &$polylang->links;
|
||||
$this->curlang = &$polylang->curlang;
|
||||
$this->pref_lang = &$polylang->pref_lang;
|
||||
|
||||
// Adds the Languages box in the 'Edit Post' and 'Edit Page' panels
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
|
||||
|
||||
// Ajax response for changing the language in the post metabox
|
||||
add_action( 'wp_ajax_post_lang_choice', array( $this, 'post_lang_choice' ) );
|
||||
add_action( 'wp_ajax_pll_posts_not_translated', array( $this, 'ajax_posts_not_translated' ) );
|
||||
|
||||
// Filters the pages by language in the parent dropdown list in the page attributes metabox
|
||||
add_filter( 'page_attributes_dropdown_pages_args', array( $this, 'page_attributes_dropdown_pages_args' ), 10, 2 );
|
||||
|
||||
// Notice
|
||||
add_action( 'edit_form_top', array( $this, 'edit_form_top' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Language box in the 'Edit Post' and 'Edit Page' panels ( as well as in custom post types panels )
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string $post_type Current post type
|
||||
* @return void
|
||||
*/
|
||||
public function add_meta_boxes( $post_type ) {
|
||||
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
||||
add_meta_box(
|
||||
'ml_box',
|
||||
__( 'Languages', 'polylang' ),
|
||||
array( $this, 'post_language' ),
|
||||
$post_type,
|
||||
'side',
|
||||
'high',
|
||||
array(
|
||||
'__back_compat_meta_box' => pll_use_block_editor_plugin(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the Languages metabox in the 'Edit Post' and 'Edit Page' panels
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function post_language() {
|
||||
global $post_ID;
|
||||
$post_type = get_post_type( $post_ID );
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
$from_post_id = isset( $_GET['from_post'] ) ? (int) $_GET['from_post'] : 0;
|
||||
|
||||
$lang = ( $lg = $this->model->post->get_language( $post_ID ) ) ? $lg :
|
||||
( isset( $_GET['new_lang'] ) ? $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->pref_lang );
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
|
||||
$id = ( 'attachment' === $post_type ) ? sprintf( 'attachments[%d][language]', (int) $post_ID ) : 'post_lang_choice';
|
||||
|
||||
$dropdown_html = $dropdown->walk(
|
||||
$this->model->get_languages_list(),
|
||||
-1,
|
||||
array(
|
||||
'name' => $id,
|
||||
'class' => 'post_lang_choice tags-input',
|
||||
'selected' => $lang ? $lang->slug : '',
|
||||
'flag' => true,
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'pll_language', '_pll_nonce' );
|
||||
|
||||
// NOTE: the class "tags-input" allows to include the field in the autosave $_POST ( see autosave.js )
|
||||
printf(
|
||||
'<p><strong>%1$s</strong></p>
|
||||
<label class="screen-reader-text" for="%2$s">%1$s</label>
|
||||
<div id="select-%3$s-language">%4$s</div>',
|
||||
esc_html__( 'Language', 'polylang' ),
|
||||
esc_attr( $id ),
|
||||
( 'attachment' === $post_type ? 'media' : 'post' ),
|
||||
$dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
);
|
||||
|
||||
/**
|
||||
* Fires before displaying the list of translations in the Languages metabox for posts
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
do_action( 'pll_before_post_translations', $post_type );
|
||||
|
||||
echo '<div id="post-translations" class="translations">';
|
||||
if ( $lang ) {
|
||||
if ( 'attachment' === $post_type ) {
|
||||
include __DIR__ . '/view-translations-media.php';
|
||||
} else {
|
||||
include __DIR__ . '/view-translations-post.php';
|
||||
}
|
||||
}
|
||||
echo '</div>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax response for changing the language in the post metabox
|
||||
*
|
||||
* @since 0.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function post_lang_choice() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
if ( ! isset( $_POST['post_id'], $_POST['lang'], $_POST['post_type'] ) ) {
|
||||
wp_die( 'The request is missing the parameter "post_type", "lang" and/or "post_id".' );
|
||||
}
|
||||
|
||||
global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
|
||||
$post_ID = (int) $_POST['post_id'];
|
||||
$lang_slug = sanitize_key( $_POST['lang'] );
|
||||
$lang = $this->model->get_language( $lang_slug );
|
||||
$post_type = sanitize_key( $_POST['post_type'] );
|
||||
|
||||
if ( empty( $lang ) ) {
|
||||
wp_die( esc_html( "{$lang_slug} is not a valid language code." ) );
|
||||
}
|
||||
|
||||
$post_type_object = get_post_type_object( $post_type );
|
||||
|
||||
if ( empty( $post_type_object ) ) {
|
||||
wp_die( esc_html( "{$post_type} is not a valid post type." ) );
|
||||
}
|
||||
|
||||
if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
|
||||
wp_die( 'You are not allowed to edit this post.' );
|
||||
}
|
||||
|
||||
$this->model->post->set_language( $post_ID, $lang );
|
||||
|
||||
ob_start();
|
||||
if ( 'attachment' === $post_type ) {
|
||||
include __DIR__ . '/view-translations-media.php';
|
||||
} else {
|
||||
include __DIR__ . '/view-translations-post.php';
|
||||
}
|
||||
$x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
|
||||
ob_end_clean();
|
||||
|
||||
// Categories
|
||||
if ( isset( $_POST['taxonomies'] ) ) { // Not set for pages
|
||||
$supplemental = array();
|
||||
|
||||
foreach ( array_map( 'sanitize_key', $_POST['taxonomies'] ) as $taxname ) {
|
||||
$taxonomy = get_taxonomy( $taxname );
|
||||
|
||||
if ( ! empty( $taxonomy ) ) {
|
||||
ob_start();
|
||||
$popular_ids = wp_popular_terms_checklist( $taxonomy->name );
|
||||
$supplemental['populars'] = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
ob_start();
|
||||
// Use $post_ID to remember checked terms in case we come back to the original language
|
||||
wp_terms_checklist( $post_ID, array( 'taxonomy' => $taxonomy->name, 'popular_cats' => $popular_ids ) );
|
||||
$supplemental['all'] = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$supplemental['dropdown'] = wp_dropdown_categories(
|
||||
array(
|
||||
'taxonomy' => $taxonomy->name,
|
||||
'hide_empty' => 0,
|
||||
'name' => 'new' . $taxonomy->name . '_parent',
|
||||
'orderby' => 'name',
|
||||
'hierarchical' => 1,
|
||||
'show_option_none' => '— ' . $taxonomy->labels->parent_item . ' —',
|
||||
'echo' => 0,
|
||||
)
|
||||
);
|
||||
|
||||
$x->Add( array( 'what' => 'taxonomy', 'data' => $taxonomy->name, 'supplemental' => $supplemental ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parent dropdown list ( only for hierarchical post types )
|
||||
if ( in_array( $post_type, get_post_types( array( 'hierarchical' => true ) ) ) ) {
|
||||
$post = get_post( $post_ID );
|
||||
|
||||
if ( ! empty( $post ) ) {
|
||||
// Args and filter from 'page_attributes_meta_box' in wp-admin/includes/meta-boxes.php of WP 4.2.1
|
||||
$dropdown_args = array(
|
||||
'post_type' => $post->post_type,
|
||||
'exclude_tree' => $post->ID,
|
||||
'selected' => $post->post_parent,
|
||||
'name' => 'parent_id',
|
||||
'show_option_none' => __( '(no parent)', 'polylang' ),
|
||||
'sort_column' => 'menu_order, post_title',
|
||||
'echo' => 0,
|
||||
);
|
||||
|
||||
/** This filter is documented in wp-admin/includes/meta-boxes.php */
|
||||
$dropdown_args = (array) apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post ); // Since WP 3.3.
|
||||
$dropdown_args['echo'] = 0; // Make sure to not print it.
|
||||
|
||||
/** @var string $data */
|
||||
$data = wp_dropdown_pages( $dropdown_args ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
|
||||
$x->Add( array( 'what' => 'pages', 'data' => $data ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Flag
|
||||
$x->Add( array( 'what' => 'flag', 'data' => empty( $lang->flag ) ? esc_html( $lang->slug ) : $lang->flag ) );
|
||||
|
||||
// Sample permalink
|
||||
$x->Add( array( 'what' => 'permalink', 'data' => get_sample_permalink_html( $post_ID ) ) );
|
||||
|
||||
$x->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax response for input in translation autocomplete input box
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_posts_not_translated() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
if ( ! isset( $_GET['post_type'], $_GET['post_language'], $_GET['translation_language'], $_GET['term'], $_GET['pll_post_id'] ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
$post_type = sanitize_key( $_GET['post_type'] );
|
||||
|
||||
if ( ! post_type_exists( $post_type ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
$term = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||
|
||||
$post_language = $this->model->get_language( sanitize_key( $_GET['post_language'] ) );
|
||||
$translation_language = $this->model->get_language( sanitize_key( $_GET['translation_language'] ) );
|
||||
|
||||
$return = array();
|
||||
|
||||
$untranslated_posts = $this->model->post->get_untranslated( $post_type, $post_language, $translation_language, $term );
|
||||
|
||||
// format output
|
||||
foreach ( $untranslated_posts as $post ) {
|
||||
$return[] = array(
|
||||
'id' => $post->ID,
|
||||
'value' => $post->post_title,
|
||||
'link' => $this->links->edit_post_translation_link( $post->ID ),
|
||||
);
|
||||
}
|
||||
|
||||
// Add current translation in list
|
||||
if ( $post_id = $this->model->post->get_translation( (int) $_GET['pll_post_id'], $translation_language ) ) {
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! empty( $post ) ) {
|
||||
array_unshift(
|
||||
$return,
|
||||
array(
|
||||
'id' => $post_id,
|
||||
'value' => $post->post_title,
|
||||
'link' => $this->links->edit_post_translation_link( $post_id ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
wp_die( wp_json_encode( $return ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the pages by language in the parent dropdown list in the page attributes metabox.
|
||||
*
|
||||
* @since 0.6
|
||||
*
|
||||
* @param array $dropdown_args Arguments passed to wp_dropdown_pages().
|
||||
* @param WP_Post $post The page being edited.
|
||||
* @return array Modified arguments.
|
||||
*/
|
||||
public function page_attributes_dropdown_pages_args( $dropdown_args, $post ) {
|
||||
$language = isset( $_POST['lang'] ) ? $this->model->get_language( sanitize_key( $_POST['lang'] ) ) : $this->model->post->get_language( $post->ID ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
$language = $this->pref_lang;
|
||||
}
|
||||
|
||||
if ( ! empty( $language ) ) {
|
||||
$dropdown_args['lang'] = $language->slug;
|
||||
}
|
||||
|
||||
return $dropdown_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a notice if the user has not sufficient rights to overwrite synchronized taxonomies and metas.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param WP_Post $post the post currently being edited.
|
||||
* @return void
|
||||
*/
|
||||
public function edit_form_top( $post ) {
|
||||
if ( ! $this->model->post->current_user_can_synchronize( $post->ID ) ) {
|
||||
?>
|
||||
<div class="pll-notice notice notice-warning">
|
||||
<p>
|
||||
<?php
|
||||
esc_html_e( 'Some taxonomies or metadata may be synchronized with existing translations that you are not allowed to modify.', 'polylang' );
|
||||
echo ' ';
|
||||
esc_html_e( 'If you attempt to modify them anyway, your changes will not be saved.', 'polylang' );
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
264
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-default-term.php
vendored
Normal file
264
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-default-term.php
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to default terms.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class PLL_Admin_Default_Term {
|
||||
|
||||
/**
|
||||
* A reference to the PLL_Model instance.
|
||||
*
|
||||
* @var PLL_Model
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* Preferred language to assign to new contents.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
protected $pref_lang;
|
||||
|
||||
/**
|
||||
* Array of registered taxonomy names for which Polylang manages languages and translations.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $taxonomies;
|
||||
|
||||
/**
|
||||
* Constructor: setups properties.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->model = &$polylang->model;
|
||||
$this->pref_lang = &$polylang->pref_lang;
|
||||
$this->taxonomies = $this->model->get_translated_taxonomies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups filters and actions needed.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_hooks() {
|
||||
foreach ( $this->taxonomies as $taxonomy ) {
|
||||
if ( 'category' === $taxonomy ) {
|
||||
// Allows to get the default terms in all languages
|
||||
add_filter( 'option_default_' . $taxonomy, array( $this, 'option_default_term' ) );
|
||||
add_action( 'update_option_default_' . $taxonomy, array( $this, 'update_option_default_term' ), 10, 2 );
|
||||
|
||||
// Adds the language column in the 'Terms' table.
|
||||
add_filter( 'manage_' . $taxonomy . '_custom_column', array( $this, 'term_column' ), 10, 3 );
|
||||
}
|
||||
}
|
||||
add_action( 'pll_add_language', array( $this, 'handle_default_term_on_create_language' ) );
|
||||
|
||||
// The default term should be in the default language
|
||||
add_action( 'pll_update_default_lang', array( $this, 'update_default_term_language' ) );
|
||||
|
||||
// Prevents deleting all the translations of the default term
|
||||
add_filter( 'map_meta_cap', array( $this, 'fix_delete_default_term' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the default term in note below the term list table and in settings->writing dropdown
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param int $taxonomy_term_id The taxonomy term id.
|
||||
* @return int A taxonomy term id.
|
||||
*/
|
||||
public function option_default_term( $taxonomy_term_id ) {
|
||||
if ( isset( $this->pref_lang ) && $tr = $this->model->term->get( $taxonomy_term_id, $this->pref_lang ) ) {
|
||||
$taxonomy_term_id = $tr;
|
||||
}
|
||||
return $taxonomy_term_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the new default term is translated in all languages
|
||||
* If not, create the translations
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param int $old_value The old option value.
|
||||
* @param int $value The new option value.
|
||||
* @return void
|
||||
*/
|
||||
public function update_option_default_term( $old_value, $value ) {
|
||||
$default_cat_lang = $this->model->term->get_language( $value );
|
||||
|
||||
// Assign a default language to default term
|
||||
if ( ! $default_cat_lang ) {
|
||||
$default_cat_lang = $this->model->get_default_language();
|
||||
$this->model->term->set_language( (int) $value, $default_cat_lang );
|
||||
}
|
||||
|
||||
if ( empty( $default_cat_lang ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$taxonomy = substr( current_filter(), 22 );
|
||||
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( $language->slug != $default_cat_lang->slug && ! $this->model->term->get_translation( $value, $language ) ) {
|
||||
$this->create_default_term( $language, $taxonomy );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default term for a language
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object|string|int $lang language
|
||||
* @param string $taxonomy The current taxonomy
|
||||
* @return void
|
||||
*/
|
||||
public function create_default_term( $lang, $taxonomy ) {
|
||||
$lang = $this->model->get_language( $lang );
|
||||
|
||||
// create a new term
|
||||
// FIXME this is translated in admin language when we would like it in $lang
|
||||
$cat_name = __( 'Uncategorized', 'polylang' );
|
||||
$cat_slug = sanitize_title( $cat_name . '-' . $lang->slug );
|
||||
$cat = wp_insert_term( $cat_name, $taxonomy, array( 'slug' => $cat_slug ) );
|
||||
|
||||
// check that the term was not previously created ( in case the language was deleted and recreated )
|
||||
$cat = isset( $cat->error_data['term_exists'] ) ? $cat->error_data['term_exists'] : $cat['term_id'];
|
||||
|
||||
// set language
|
||||
$this->model->term->set_language( (int) $cat, $lang );
|
||||
|
||||
// this is a translation of the default term
|
||||
$default = (int) get_option( 'default_' . $taxonomy );
|
||||
$translations = $this->model->term->get_translations( $default );
|
||||
|
||||
$this->model->term->save_translations( (int) $cat, $translations );
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the default term when new languages are created.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param array $args Argument used to create the language. @see PLL_Admin_Model::add_language().
|
||||
* @return void
|
||||
*/
|
||||
public function handle_default_term_on_create_language( $args ) {
|
||||
foreach ( $this->taxonomies as $taxonomy ) {
|
||||
if ( 'category' === $taxonomy ) {
|
||||
$default = (int) get_option( 'default_' . $taxonomy );
|
||||
|
||||
// Assign default language to default term
|
||||
if ( ! $this->model->term->get_language( $default ) ) {
|
||||
$this->model->term->set_language( $default, $args['slug'] );
|
||||
} elseif ( empty( $args['no_default_cat'] ) && ! $this->model->term->get( $default, $args['slug'] ) ) {
|
||||
$this->create_default_term( $args['slug'], $taxonomy );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify the default term in the terms list table to disable the language dropdown in js.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param string $out The output.
|
||||
* @param string $column The custom column's name.
|
||||
* @param int $term_id The term id.
|
||||
* @return string The HTML string.
|
||||
*/
|
||||
public function term_column( $out, $column, $term_id ) {
|
||||
if ( $column === $this->get_first_language_column() && $this->is_default_term( $term_id ) ) {
|
||||
$out .= sprintf( '<div class="hidden" id="default_cat_%1$d">%1$d</div>', intval( $term_id ) );
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first language column in the posts, pages and media library tables
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @return string first language column name
|
||||
*/
|
||||
protected function get_first_language_column() {
|
||||
$columns = array();
|
||||
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
$columns[] = 'language_' . $language->slug;
|
||||
}
|
||||
|
||||
return empty( $columns ) ? '' : reset( $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents deleting all the translations of the default term
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @param array $caps The user's actual capabilities.
|
||||
* @param string $cap Capability name.
|
||||
* @param int $user_id The user ID.
|
||||
* @param array $args Adds the context to the cap. The term id.
|
||||
* @return array
|
||||
*/
|
||||
public function fix_delete_default_term( $caps, $cap, $user_id, $args ) {
|
||||
if ( 'delete_term' === $cap && $this->is_default_term( reset( $args ) ) ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the term is the default term.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param int $term_id The term id.
|
||||
* @return bool True if the term is the default term, false otherwise.
|
||||
*/
|
||||
public function is_default_term( $term_id ) {
|
||||
$term = get_term( $term_id );
|
||||
if ( $term instanceof WP_Term ) {
|
||||
$default_term_id = get_option( 'default_' . $term->taxonomy );
|
||||
return $default_term_id && in_array( $default_term_id, $this->model->term->get_translations( $term_id ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the default term language.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param string $slug Language slug.
|
||||
* @return void
|
||||
*/
|
||||
public function update_default_term_language( $slug ) {
|
||||
foreach ( $this->taxonomies as $taxonomy ) {
|
||||
if ( 'category' === $taxonomy ) {
|
||||
$default_cats = $this->model->term->get_translations( get_option( 'default_' . $taxonomy ) );
|
||||
if ( isset( $default_cats[ $slug ] ) ) {
|
||||
update_option( 'default_' . $taxonomy, $default_cats[ $slug ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
451
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-columns.php
vendored
Normal file
451
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-columns.php
vendored
Normal file
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the language column in posts and terms list tables
|
||||
* Manages quick edit and bulk edit as well
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters_Columns {
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* Language selected in the admin language filter.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $filter_lang;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links = &$polylang->links;
|
||||
$this->model = &$polylang->model;
|
||||
$this->filter_lang = &$polylang->filter_lang;
|
||||
|
||||
// Hide the column of the filtered language.
|
||||
add_filter( 'hidden_columns', array( $this, 'hidden_columns' ) ); // Since WP 4.4.
|
||||
|
||||
// Add the language and translations columns in 'All Posts', 'All Pages' and 'Media library' panels.
|
||||
foreach ( $this->model->get_translated_post_types() as $type ) {
|
||||
// Use the latest filter late as some plugins purely overwrite what's done by others :(
|
||||
// Specific case for media.
|
||||
add_filter( 'manage_' . ( 'attachment' == $type ? 'upload' : 'edit-' . $type ) . '_columns', array( $this, 'add_post_column' ), 100 );
|
||||
add_action( 'manage_' . ( 'attachment' == $type ? 'media' : $type . '_posts' ) . '_custom_column', array( $this, 'post_column' ), 10, 2 );
|
||||
}
|
||||
|
||||
// Quick edit and bulk edit.
|
||||
add_filter( 'quick_edit_custom_box', array( $this, 'quick_edit_custom_box' ) );
|
||||
add_filter( 'bulk_edit_custom_box', array( $this, 'quick_edit_custom_box' ) );
|
||||
|
||||
// Adds the language column in the 'Categories' and 'Post Tags' tables.
|
||||
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
||||
add_filter( 'manage_edit-' . $tax . '_columns', array( $this, 'add_term_column' ) );
|
||||
add_filter( 'manage_' . $tax . '_custom_column', array( $this, 'term_column' ), 10, 3 );
|
||||
}
|
||||
|
||||
// Ajax responses to update list table rows.
|
||||
add_action( 'wp_ajax_pll_update_post_rows', array( $this, 'ajax_update_post_rows' ) );
|
||||
add_action( 'wp_ajax_pll_update_term_rows', array( $this, 'ajax_update_term_rows' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds languages and translations columns in posts, pages, media, categories and tags tables.
|
||||
*
|
||||
* @since 0.8.2
|
||||
*
|
||||
* @param string[] $columns List of table columns.
|
||||
* @param string $before The column before which we want to add our languages.
|
||||
* @return string[] Modified list of columns.
|
||||
*/
|
||||
protected function add_column( $columns, $before ) {
|
||||
if ( $n = array_search( $before, array_keys( $columns ) ) ) {
|
||||
$end = array_slice( $columns, $n );
|
||||
$columns = array_slice( $columns, 0, $n );
|
||||
}
|
||||
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
$columns[ 'language_' . $language->slug ] = $this->get_flag_html( $language ) . '<span class="screen-reader-text">' . esc_html( $language->name ) . '</span>';
|
||||
}
|
||||
|
||||
return isset( $end ) ? array_merge( $columns, $end ) : $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first language column in the posts, pages and media library tables
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @return string first language column name
|
||||
*/
|
||||
protected function get_first_language_column() {
|
||||
$columns = array();
|
||||
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
$columns[] = 'language_' . $language->slug;
|
||||
}
|
||||
|
||||
return empty( $columns ) ? '' : reset( $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the column for the filtered language.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param string[] $hidden Array of hidden columns.
|
||||
* @return string[]
|
||||
*/
|
||||
public function hidden_columns( $hidden ) {
|
||||
if ( ! empty( $this->filter_lang ) ) {
|
||||
$hidden[] = 'language_' . $this->filter_lang->slug;
|
||||
}
|
||||
return $hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language and translations columns ( before the comments column ) in the posts, pages and media library tables.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string[] $columns List of posts table columns.
|
||||
* @return string[] Modified list of columns.
|
||||
*/
|
||||
public function add_post_column( $columns ) {
|
||||
return $this->add_column( $columns, 'comments' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the language and translations columns in the posts, pages and media library tables
|
||||
* take care that when doing ajax inline edit, the post may not be updated in database yet
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string $column Column name.
|
||||
* @param int $post_id Post ID.
|
||||
* @return void
|
||||
*/
|
||||
public function post_column( $column, $post_id ) {
|
||||
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $inline ? $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) ) : $this->model->post->get_language( $post_id ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
if ( false === strpos( $column, 'language_' ) || ! $lang ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$language = $this->model->get_language( substr( $column, 9 ) );
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hidden field containing the post language for quick edit
|
||||
if ( $column == $this->get_first_language_column() ) {
|
||||
printf( '<div class="hidden" id="lang_%d">%s</div>', intval( $post_id ), esc_html( $lang->slug ) );
|
||||
}
|
||||
|
||||
// Link to edit post ( or a translation )
|
||||
if ( $id = $this->model->post->get( $post_id, $language ) ) {
|
||||
// get_edit_post_link returns nothing if the user cannot edit the post
|
||||
// Thanks to Solinx. See http://wordpress.org/support/topic/feature-request-incl-code-check-for-capabilities-in-admin-screens
|
||||
if ( $link = get_edit_post_link( $id ) ) {
|
||||
$flag = '';
|
||||
if ( $id === $post_id ) {
|
||||
$flag = $this->get_flag_html( $language );
|
||||
$class = 'pll_column_flag';
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
$s = sprintf( __( 'Edit this item in %s', 'polylang' ), $language->name );
|
||||
} else {
|
||||
$class = esc_attr( 'pll_icon_edit translation_' . $id );
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
$s = sprintf( __( 'Edit the translation in %s', 'polylang' ), $language->name );
|
||||
}
|
||||
|
||||
$post = get_post( $id );
|
||||
|
||||
if ( ! empty( $post ) ) {
|
||||
printf(
|
||||
'<a class="%1$s" title="%2$s" href="%3$s"><span class="screen-reader-text">%4$s</span>%5$s</a>',
|
||||
esc_attr( $class ),
|
||||
esc_attr( $post->post_title ),
|
||||
esc_url( $link ),
|
||||
esc_html( $s ),
|
||||
$flag // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
}
|
||||
} elseif ( $id === $post_id ) {
|
||||
printf(
|
||||
'<span class="pll_column_flag" style=""><span class="screen-reader-text">%1$s</span>%2$s</span>',
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'This item is in %s', 'polylang' ), $language->name ) ),
|
||||
$this->get_flag_html( $language ) // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
}
|
||||
}
|
||||
// Link to add a new translation
|
||||
else {
|
||||
echo $this->links->new_post_translation_link( $post_id, $language ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick edit & bulk edit
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param string $column column name
|
||||
* @return string unmodified $column
|
||||
*/
|
||||
public function quick_edit_custom_box( $column ) {
|
||||
if ( $column == $this->get_first_language_column() ) {
|
||||
|
||||
$elements = $this->model->get_languages_list();
|
||||
if ( current_filter() == 'bulk_edit_custom_box' ) {
|
||||
array_unshift( $elements, (object) array( 'slug' => -1, 'name' => __( '— No Change —', 'polylang' ) ) );
|
||||
}
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
// The hidden field 'old_lang' allows to pass the old language to ajax request
|
||||
printf(
|
||||
'<fieldset class="inline-edit-col-left">
|
||||
<div class="inline-edit-col">
|
||||
<label class="alignleft">
|
||||
<span class="title">%s</span>
|
||||
%s
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>',
|
||||
esc_html__( 'Language', 'polylang' ),
|
||||
$dropdown->walk( $elements, -1, array( 'name' => 'inline_lang_choice', 'id' => '' ) ) // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
);
|
||||
}
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language column ( before the posts column ) in the 'Categories' or 'Post Tags' table.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string[] $columns List of terms table columns.
|
||||
* @return string[] modified List of columns.
|
||||
*/
|
||||
public function add_term_column( $columns ) {
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Avoid displaying languages in screen options when editing a term.
|
||||
if ( $screen instanceof WP_Screen && 'term' === $screen->base ) {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
return $this->add_column( $columns, 'posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the language column in the taxonomy terms list table.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string $out Column output.
|
||||
* @param string $column Column name.
|
||||
* @param int $term_id Term ID.
|
||||
* @return string
|
||||
*/
|
||||
public function term_column( $out, $column, $term_id ) {
|
||||
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save-tax' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
if ( false === strpos( $column, 'language_' ) || ! ( $lang = $inline ? $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) ) : $this->model->term->get_language( $term_id ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
return $out;
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$post_type = sanitize_key( $_REQUEST['post_type'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $GLOBALS['post_type'] ) ) {
|
||||
$post_type = $GLOBALS['post_type'];
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['taxonomy'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$taxonomy = sanitize_key( $_REQUEST['taxonomy'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $GLOBALS['taxonomy'] ) ) {
|
||||
$taxonomy = $GLOBALS['taxonomy'];
|
||||
}
|
||||
|
||||
if ( ! isset( $taxonomy, $post_type ) || ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
||||
return $out;
|
||||
}
|
||||
|
||||
$term_id = (int) $term_id;
|
||||
$language = $this->model->get_language( substr( $column, 9 ) );
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
return $out;
|
||||
}
|
||||
|
||||
if ( $column == $this->get_first_language_column() ) {
|
||||
$out .= sprintf( '<div class="hidden" id="lang_%d">%s</div>', intval( $term_id ), esc_html( $lang->slug ) );
|
||||
}
|
||||
|
||||
// Link to edit term ( or a translation )
|
||||
if ( ( $id = $this->model->term->get( $term_id, $language ) ) && $term = get_term( $id, $taxonomy ) ) {
|
||||
if ( $term instanceof WP_Term && $link = get_edit_term_link( $id, $taxonomy, $post_type ) ) {
|
||||
$flag = '';
|
||||
if ( $id === $term_id ) {
|
||||
$flag = $this->get_flag_html( $language );
|
||||
$class = 'pll_column_flag';
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
$s = sprintf( __( 'Edit this item in %s', 'polylang' ), $language->name );
|
||||
} else {
|
||||
$class = esc_attr( 'pll_icon_edit translation_' . $id );
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
$s = sprintf( __( 'Edit the translation in %s', 'polylang' ), $language->name );
|
||||
}
|
||||
$out .= sprintf(
|
||||
'<a class="%1$s" title="%2$s" href="%3$s"><span class="screen-reader-text">%4$s</span>%5$s</a>',
|
||||
$class,
|
||||
esc_attr( $term->name ),
|
||||
esc_url( $link ),
|
||||
esc_html( $s ),
|
||||
$flag // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
} elseif ( $id === $term_id ) {
|
||||
$out .= sprintf(
|
||||
'<span class="pll_column_flag"><span class="screen-reader-text">%1$s</span>%2$s</span>',
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'This item is in %s', 'polylang' ), $language->name ) ),
|
||||
$this->get_flag_html( $language ) // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Link to add a new translation
|
||||
else {
|
||||
$out .= $this->links->new_term_translation_link( $term_id, $taxonomy, $post_type, $language );
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rows of translated posts when the language is modified in quick edit
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_update_post_rows() {
|
||||
check_ajax_referer( 'inlineeditnonce', '_pll_nonce' );
|
||||
|
||||
if ( ! isset( $_POST['post_type'], $_POST['post_id'], $_POST['screen'] ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
$post_type = sanitize_key( $_POST['post_type'] );
|
||||
|
||||
if ( ! post_type_exists( $post_type ) || ! $this->model->is_translated_post_type( $post_type ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
/** @var WP_Posts_List_Table $wp_list_table */
|
||||
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => sanitize_key( $_POST['screen'] ) ) );
|
||||
|
||||
$x = new WP_Ajax_Response();
|
||||
|
||||
// Collect old translations
|
||||
$translations = empty( $_POST['translations'] ) ? array() : explode( ',', $_POST['translations'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||
$translations = array_map( 'intval', $translations );
|
||||
|
||||
$translations = array_merge( $translations, array( (int) $_POST['post_id'] ) ); // Add current post
|
||||
|
||||
foreach ( $translations as $post_id ) {
|
||||
$level = is_post_type_hierarchical( $post_type ) ? count( get_ancestors( $post_id, $post_type ) ) : 0;
|
||||
if ( $post = get_post( $post_id ) ) {
|
||||
ob_start();
|
||||
$wp_list_table->single_row( $post, $level );
|
||||
$data = ob_get_clean();
|
||||
$x->add( array( 'what' => 'row', 'data' => $data, 'supplemental' => array( 'post_id' => $post_id ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
$x->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_update_term_rows() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
if ( ! isset( $_POST['taxonomy'], $_POST['term_id'], $_POST['screen'] ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
$taxonomy = sanitize_key( $_POST['taxonomy'] );
|
||||
|
||||
if ( ! taxonomy_exists( $taxonomy ) || ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
/** @var WP_Terms_List_Table $wp_list_table */
|
||||
$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => sanitize_key( $_POST['screen'] ) ) );
|
||||
|
||||
$x = new WP_Ajax_Response();
|
||||
|
||||
// Collect old translations
|
||||
$translations = empty( $_POST['translations'] ) ? array() : explode( ',', $_POST['translations'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||
$translations = array_map( 'intval', $translations );
|
||||
|
||||
$translations = array_merge( $translations, $this->model->term->get_translations( (int) $_POST['term_id'] ) ); // Add current translations
|
||||
$translations = array_unique( $translations ); // Remove duplicates
|
||||
|
||||
foreach ( $translations as $term_id ) {
|
||||
$level = is_taxonomy_hierarchical( $taxonomy ) ? count( get_ancestors( $term_id, $taxonomy ) ) : 0;
|
||||
$tag = get_term( $term_id, $taxonomy );
|
||||
|
||||
if ( ! $tag instanceof WP_Term ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
$wp_list_table->single_row( $tag, $level );
|
||||
$data = ob_get_clean();
|
||||
$x->add( array( 'what' => 'row', 'data' => $data, 'supplemental' => array( 'term_id' => $term_id ) ) );
|
||||
}
|
||||
|
||||
$x->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language flag or the language slug if there is no flag.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @param PLL_Language $language PLL_Language object.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_flag_html( $language ) {
|
||||
return $language->flag ? $language->flag : sprintf( '<abbr>%s</abbr>', esc_html( $language->slug ) );
|
||||
}
|
||||
}
|
||||
132
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-media.php
vendored
Normal file
132
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-media.php
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to media on admin side
|
||||
* Capability to edit / create media is checked before loading this class
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
||||
/**
|
||||
* @var PLL_CRUD_Posts|null
|
||||
*/
|
||||
public $posts;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->posts = &$polylang->posts;
|
||||
|
||||
// Adds the language field and translations tables in the 'Edit Media' panel
|
||||
add_filter( 'attachment_fields_to_edit', array( $this, 'attachment_fields_to_edit' ), 10, 2 );
|
||||
|
||||
// Adds actions related to languages when creating, saving or deleting media
|
||||
add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
|
||||
|
||||
// Creates a media translation
|
||||
if ( isset( $_GET['action'], $_GET['new_lang'], $_GET['from_media'] ) && 'translate_media' === $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
add_action( 'admin_init', array( $this, 'translate_media' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language field and translations tables in the 'Edit Media' panel.
|
||||
* Needs WP 3.5+
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param array $fields List of form fields.
|
||||
* @param WP_Post $post The attachment being edited.
|
||||
* @return array Modified list of form fields.
|
||||
*/
|
||||
public function attachment_fields_to_edit( $fields, $post ) {
|
||||
if ( 'post.php' == $GLOBALS['pagenow'] ) {
|
||||
return $fields; // Don't add anything on edit media panel for WP 3.5+ since we have the metabox
|
||||
}
|
||||
|
||||
$post_id = $post->ID;
|
||||
$lang = $this->model->post->get_language( $post_id );
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
$fields['language'] = array(
|
||||
'label' => __( 'Language', 'polylang' ),
|
||||
'input' => 'html',
|
||||
'html' => $dropdown->walk(
|
||||
$this->model->get_languages_list(),
|
||||
-1,
|
||||
array(
|
||||
'name' => sprintf( 'attachments[%d][language]', $post_id ),
|
||||
'class' => 'media_lang_choice',
|
||||
'selected' => $lang ? $lang->slug : '',
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a media translation
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function translate_media() {
|
||||
if ( isset( $_GET['from_media'], $_GET['new_lang'] ) ) {
|
||||
// Security check
|
||||
check_admin_referer( 'translate_media' );
|
||||
$post_id = (int) $_GET['from_media'];
|
||||
|
||||
// Bails if the translations already exists
|
||||
// See https://wordpress.org/support/topic/edit-translation-in-media-attachments?#post-7322303
|
||||
// Or if the source media does not exist
|
||||
if ( $this->model->post->get_translation( $post_id, sanitize_key( $_GET['new_lang'] ) ) || ! get_post( $post_id ) ) {
|
||||
wp_safe_redirect( wp_get_referer() );
|
||||
exit;
|
||||
}
|
||||
|
||||
$tr_id = $this->posts->create_media_translation( $post_id, sanitize_key( $_GET['new_lang'] ) );
|
||||
wp_safe_redirect( admin_url( sprintf( 'post.php?post=%d&action=edit', $tr_id ) ) ); // WP 3.5+
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a media is saved
|
||||
* Saves language and translations
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param array $post An array of post data.
|
||||
* @param array $attachment An array of attachment metadata.
|
||||
* @return array Unmodified $post
|
||||
*/
|
||||
public function save_media( $post, $attachment ) {
|
||||
// Language is filled in attachment by the function applying the filter 'attachment_fields_to_save'
|
||||
// All security checks have been done by functions applying this filter
|
||||
if ( empty( $attachment['language'] ) || ! current_user_can( 'edit_post', $post['ID'] ) ) {
|
||||
return $post;
|
||||
}
|
||||
|
||||
$language = $this->model->get_language( $attachment['language'] );
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
return $post;
|
||||
}
|
||||
|
||||
$this->model->post->set_language( $post['ID'], $language );
|
||||
|
||||
return $post;
|
||||
}
|
||||
}
|
||||
65
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-post-base.php
vendored
Normal file
65
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-post-base.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some common code for PLL_Admin_Filters_Post and PLL_Admin_Filters_Media
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
abstract class PLL_Admin_Filters_Post_Base {
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* @var PLL_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* Language selected in the admin language filter.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $filter_lang;
|
||||
|
||||
/**
|
||||
* Preferred language to assign to new contents.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $pref_lang;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links = &$polylang->links;
|
||||
$this->model = &$polylang->model;
|
||||
$this->pref_lang = &$polylang->pref_lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save translations from the languages metabox.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $post_id Post id of the post being saved.
|
||||
* @param int[] $arr An array with language codes as key and post id as value.
|
||||
* @return int[] The array of translated post ids.
|
||||
*/
|
||||
protected function save_translations( $post_id, $arr ) {
|
||||
// Security check as 'wp_insert_post' can be called from outside WP admin.
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$translations = $this->model->post->save_translations( $post_id, $arr );
|
||||
return $translations;
|
||||
}
|
||||
}
|
||||
223
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-post.php
vendored
Normal file
223
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-post.php
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to posts on admin side
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
||||
/**
|
||||
* Current language (used to filter the content).
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
$this->curlang = &$polylang->curlang;
|
||||
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
|
||||
// Filters posts, pages and media by language
|
||||
add_action( 'parse_query', array( $this, 'parse_query' ) );
|
||||
|
||||
// Adds actions and filters related to languages when creating, saving or deleting posts and pages
|
||||
add_action( 'load-post.php', array( $this, 'edit_post' ) );
|
||||
add_action( 'load-edit.php', array( $this, 'bulk_edit_posts' ) );
|
||||
add_action( 'wp_ajax_inline-save', array( $this, 'inline_edit_post' ), 0 ); // Before WordPress
|
||||
|
||||
// Sets the language in Tiny MCE
|
||||
add_filter( 'tiny_mce_before_init', array( $this, 'tiny_mce_before_init' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a javascript list of terms ordered by language and hierarchical taxonomies
|
||||
* to filter the category checklist per post language in quick edit
|
||||
* Outputs a javascript list of pages ordered by language
|
||||
* to filter the parent dropdown per post language in quick edit
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_enqueue_scripts() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( empty( $screen ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hierarchical taxonomies
|
||||
if ( 'edit' == $screen->base && $taxonomies = get_object_taxonomies( $screen->post_type, 'objects' ) ) {
|
||||
// Get translated hierarchical taxonomies
|
||||
$hierarchical_taxonomies = array();
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
if ( $taxonomy->hierarchical && $taxonomy->show_in_quick_edit && $this->model->is_translated_taxonomy( $taxonomy->name ) ) {
|
||||
$hierarchical_taxonomies[] = $taxonomy->name;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $hierarchical_taxonomies ) ) {
|
||||
$terms = get_terms( array( 'taxonomy' => $hierarchical_taxonomies, 'get' => 'all' ) );
|
||||
$term_languages = array();
|
||||
|
||||
if ( is_array( $terms ) ) {
|
||||
foreach ( $terms as $term ) {
|
||||
if ( $lang = $this->model->term->get_language( $term->term_id ) ) {
|
||||
$term_languages[ $lang->slug ][ $term->taxonomy ][] = $term->term_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send all these data to javascript
|
||||
if ( ! empty( $term_languages ) ) {
|
||||
wp_localize_script( 'pll_post', 'pll_term_languages', $term_languages );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hierarchical post types
|
||||
if ( 'edit' == $screen->base && is_post_type_hierarchical( $screen->post_type ) ) {
|
||||
$pages = get_pages( array( 'sort_column' => 'menu_order, post_title' ) ); // Same arguments as the parent pages dropdown to avoid an extra query.
|
||||
|
||||
update_post_caches( $pages, $screen->post_type, true, false );
|
||||
|
||||
$page_languages = array();
|
||||
|
||||
foreach ( $pages as $page ) {
|
||||
if ( $lang = $this->model->post->get_language( $page->ID ) ) {
|
||||
$page_languages[ $lang->slug ][] = $page->ID;
|
||||
}
|
||||
}
|
||||
|
||||
// Send all these data to javascript
|
||||
if ( ! empty( $page_languages ) ) {
|
||||
wp_localize_script( 'pll_post', 'pll_page_languages', $page_languages );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters posts, pages and media by language.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param WP_Query $query WP_Query object.
|
||||
* @return void
|
||||
*/
|
||||
public function parse_query( $query ) {
|
||||
$pll_query = new PLL_Query( $query, $this->model );
|
||||
$pll_query->filter_query( $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language and translation when editing a post (post.php)
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit_post() {
|
||||
if ( isset( $_POST['post_lang_choice'], $_POST['post_ID'] ) && $post_id = (int) $_POST['post_ID'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( empty( $post ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type_object = get_post_type_object( $post->post_type );
|
||||
|
||||
if ( empty( $post_type_object ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$language = $this->model->get_language( sanitize_key( $_POST['post_lang_choice'] ) );
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->model->post->set_language( $post_id, $language );
|
||||
|
||||
if ( ! isset( $_POST['post_tr_lang'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->save_translations( $post_id, array_map( 'absint', $_POST['post_tr_lang'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language when bulk editing a post
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function bulk_edit_posts() {
|
||||
if ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'], $_REQUEST['post'] ) && -1 !== $_GET['inline_lang_choice'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
check_admin_referer( 'bulk-posts' );
|
||||
|
||||
if ( $lang = $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ) ) {
|
||||
$post_ids = array_map( 'intval', (array) $_REQUEST['post'] );
|
||||
foreach ( $post_ids as $post_id ) {
|
||||
if ( current_user_can( 'edit_post', $post_id ) ) {
|
||||
$this->model->post->set_language( $post_id, $lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language when inline editing a post
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function inline_edit_post() {
|
||||
check_admin_referer( 'inlineeditnonce', '_inline_edit' );
|
||||
|
||||
if ( isset( $_POST['post_ID'], $_POST['inline_lang_choice'] ) ) {
|
||||
$post_id = (int) $_POST['post_ID'];
|
||||
$lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) );
|
||||
if ( $post_id && $lang && current_user_can( 'edit_post', $post_id ) ) {
|
||||
$this->model->post->set_language( $post_id, $lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language attribute and text direction for Tiny MCE
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
* @param array $mce_init TinyMCE config
|
||||
* @return array
|
||||
*/
|
||||
public function tiny_mce_before_init( $mce_init ) {
|
||||
if ( ! empty( $this->curlang ) ) {
|
||||
$mce_init['wp_lang_attr'] = $this->curlang->get_locale( 'display' );
|
||||
$mce_init['directionality'] = $this->curlang->is_rtl ? 'rtl' : 'ltr';
|
||||
}
|
||||
return $mce_init;
|
||||
}
|
||||
}
|
||||
716
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-term.php
vendored
Normal file
716
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-term.php
vendored
Normal file
@@ -0,0 +1,716 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to terms on admin side
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters_Term {
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* Language selected in the admin language filter.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $filter_lang;
|
||||
|
||||
/**
|
||||
* Preferred language to assign to the new terms.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $pref_lang;
|
||||
|
||||
/**
|
||||
* Stores the current post_id when bulk editing posts.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $post_id = 0;
|
||||
|
||||
/**
|
||||
* A reference to the PLL_Admin_Default_Term instance.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @var PLL_Admin_Default_Term|null
|
||||
*/
|
||||
protected $default_term;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links = &$polylang->links;
|
||||
$this->model = &$polylang->model;
|
||||
$this->pref_lang = &$polylang->pref_lang;
|
||||
$this->default_term = &$polylang->default_term;
|
||||
|
||||
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
||||
// Adds the language field in the 'Categories' and 'Post Tags' panels
|
||||
add_action( $tax . '_add_form_fields', array( $this, 'add_term_form' ) );
|
||||
|
||||
// Adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels
|
||||
add_action( $tax . '_edit_form_fields', array( $this, 'edit_term_form' ) );
|
||||
}
|
||||
|
||||
// Adds actions related to languages when creating or saving categories and post tags
|
||||
add_filter( 'wp_dropdown_cats', array( $this, 'wp_dropdown_cats' ) );
|
||||
add_action( 'create_term', array( $this, 'save_term' ), 900, 3 );
|
||||
add_action( 'edit_term', array( $this, 'save_term' ), 900, 3 ); // Late as it may conflict with other plugins, see http://wordpress.org/support/topic/polylang-and-wordpress-seo-by-yoast
|
||||
add_action( 'pre_post_update', array( $this, 'pre_post_update' ) );
|
||||
add_filter( 'pll_inserted_term_language', array( $this, 'get_inserted_term_language' ) );
|
||||
add_filter( 'pll_inserted_term_parent', array( $this, 'get_inserted_term_parent' ), 10, 2 );
|
||||
|
||||
// Ajax response for edit term form
|
||||
add_action( 'wp_ajax_term_lang_choice', array( $this, 'term_lang_choice' ) );
|
||||
add_action( 'wp_ajax_pll_terms_not_translated', array( $this, 'ajax_terms_not_translated' ) );
|
||||
|
||||
// Updates the translations term ids when splitting a shared term
|
||||
add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 ); // WP 4.2
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language field in the 'Categories' and 'Post Tags' panels
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_term_form() {
|
||||
if ( isset( $_GET['taxonomy'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$taxonomy = sanitize_key( $_GET['taxonomy'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$post_type = sanitize_key( $_REQUEST['post_type'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $GLOBALS['post_type'] ) ) {
|
||||
$post_type = $GLOBALS['post_type'];
|
||||
}
|
||||
|
||||
if ( ! isset( $taxonomy, $post_type ) || ! taxonomy_exists( $taxonomy ) || ! post_type_exists( $post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$from_term_id = isset( $_GET['from_tag'] ) ? (int) $_GET['from_tag'] : 0; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
$lang = isset( $_GET['new_lang'] ) ? $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ) : $this->pref_lang; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
|
||||
$dropdown_html = $dropdown->walk(
|
||||
$this->model->get_languages_list(),
|
||||
-1,
|
||||
array(
|
||||
'name' => 'term_lang_choice',
|
||||
'value' => 'term_id',
|
||||
'selected' => $lang ? $lang->term_id : '',
|
||||
'flag' => true,
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'pll_language', '_pll_nonce' );
|
||||
|
||||
printf(
|
||||
'<div class="form-field">
|
||||
<label for="term_lang_choice">%s</label>
|
||||
<div id="select-add-term-language">%s</div>
|
||||
<p>%s</p>
|
||||
</div>',
|
||||
esc_html__( 'Language', 'polylang' ),
|
||||
$dropdown_html, // phpcs:ignore
|
||||
esc_html__( 'Sets the language', 'polylang' )
|
||||
);
|
||||
|
||||
if ( ! empty( $from_term_id ) ) {
|
||||
printf( '<input type="hidden" name="from_tag" value="%d" />', (int) $from_term_id );
|
||||
}
|
||||
|
||||
// Adds translation fields
|
||||
echo '<div id="term-translations" class="form-field">';
|
||||
if ( $lang ) {
|
||||
include __DIR__ . '/view-translations-term.php';
|
||||
}
|
||||
echo '</div>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param WP_Term $tag The term being edited.
|
||||
* @return void
|
||||
*/
|
||||
public function edit_term_form( $tag ) {
|
||||
if ( isset( $_REQUEST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$post_type = sanitize_key( $_REQUEST['post_type'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $GLOBALS['post_type'] ) ) {
|
||||
$post_type = $GLOBALS['post_type'];
|
||||
}
|
||||
|
||||
if ( ! isset( $post_type ) || ! post_type_exists( $post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$term_id = $tag->term_id;
|
||||
$taxonomy = $tag->taxonomy; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
|
||||
$lang = $this->model->term->get_language( $term_id );
|
||||
$lang = empty( $lang ) ? $this->pref_lang : $lang;
|
||||
|
||||
// Disable the language dropdown and the translations input fields for default terms to prevent removal
|
||||
$disabled = $this->default_term->is_default_term( $term_id );
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
|
||||
$dropdown_html = $dropdown->walk(
|
||||
$this->model->get_languages_list(),
|
||||
-1,
|
||||
array(
|
||||
'name' => 'term_lang_choice',
|
||||
'value' => 'term_id',
|
||||
'selected' => $lang->term_id,
|
||||
'disabled' => $disabled,
|
||||
'flag' => true,
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'pll_language', '_pll_nonce' );
|
||||
|
||||
printf(
|
||||
'<tr class="form-field">
|
||||
<th scope="row">
|
||||
<label for="term_lang_choice">%s</label>
|
||||
</th>
|
||||
<td id="select-edit-term-language">
|
||||
%s<br />
|
||||
<p class="description">%s</p>
|
||||
</td>
|
||||
</tr>',
|
||||
esc_html__( 'Language', 'polylang' ),
|
||||
$dropdown_html, // phpcs:ignore
|
||||
esc_html__( 'Sets the language', 'polylang' )
|
||||
);
|
||||
|
||||
echo '<tr id="term-translations" class="form-field">';
|
||||
include __DIR__ . '/view-translations-term.php';
|
||||
echo '</tr>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates term parent if exists when using "Add new" ( translation )
|
||||
*
|
||||
* @since 0.7
|
||||
*
|
||||
* @param string $output html markup for dropdown list of categories
|
||||
* @return string modified html
|
||||
*/
|
||||
public function wp_dropdown_cats( $output ) {
|
||||
if ( isset( $_GET['taxonomy'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$taxonomy = sanitize_key( $_GET['taxonomy'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
if ( isset( $taxonomy, $_GET['from_tag'], $_GET['new_lang'] ) && taxonomy_exists( $taxonomy ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$term = get_term( (int) $_GET['from_tag'], $taxonomy ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
if ( $term instanceof WP_Term && $id = $term->parent ) {
|
||||
$lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
if ( $parent = $this->model->term->get_translation( $id, $lang ) ) {
|
||||
return str_replace( '"' . $parent . '"', '"' . $parent . '" selected="selected"', $output );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the current post_id when bulk editing posts for use in save_language and get_inserted_term_language.
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return void
|
||||
*/
|
||||
public function pre_post_update( $post_id ) {
|
||||
if ( isset( $_GET['bulk_edit'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->post_id = $post_id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the language of a term.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $term_id Term ID.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @return void
|
||||
*/
|
||||
protected function save_language( $term_id, $taxonomy ) {
|
||||
global $wpdb;
|
||||
// Security checks are necessary to accept language modifications
|
||||
// as 'wp_update_term' can be called from outside WP admin
|
||||
|
||||
// Edit tags
|
||||
if ( isset( $_POST['term_lang_choice'] ) ) {
|
||||
if ( isset( $_POST['action'] ) && sanitize_key( $_POST['action'] ) === 'add-' . $taxonomy ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
check_ajax_referer( 'add-' . $taxonomy, '_ajax_nonce-add-' . $taxonomy ); // Category metabox
|
||||
} else {
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' ); // Edit tags or tags metabox
|
||||
}
|
||||
|
||||
$language = $this->model->get_language( sanitize_key( $_POST['term_lang_choice'] ) );
|
||||
|
||||
if ( ! empty( $language ) ) {
|
||||
$this->model->term->set_language( $term_id, $language );
|
||||
}
|
||||
}
|
||||
|
||||
// *Post* bulk edit, in case a new term is created
|
||||
elseif ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) {
|
||||
check_admin_referer( 'bulk-posts' );
|
||||
|
||||
// Bulk edit does not modify the language
|
||||
// So we possibly create a tag in several languages
|
||||
if ( -1 === (int) $_GET['inline_lang_choice'] ) {
|
||||
// The language of the current term is set a according to the language of the current post.
|
||||
$language = $this->model->post->get_language( $this->post_id );
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->model->term->set_language( $term_id, $language );
|
||||
$term = get_term( $term_id, $taxonomy );
|
||||
$terms = array();
|
||||
|
||||
// Get all terms with the same name
|
||||
// FIXME backward compatibility WP < 4.2
|
||||
// No WP function to get all terms with the exact same name so let's use a custom query
|
||||
// $terms = get_terms( $taxonomy, array( 'name' => $term->name, 'hide_empty' => false, 'fields' => 'ids' ) ); should be OK in 4.2
|
||||
// I may need to rework the loop below
|
||||
if ( $term instanceof WP_Term ) {
|
||||
$terms = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT t.term_id FROM $wpdb->terms AS t
|
||||
INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
|
||||
WHERE tt.taxonomy = %s AND t.name = %s",
|
||||
$taxonomy,
|
||||
$term->name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// If we have several terms with the same name, they are translations of each other
|
||||
if ( count( $terms ) > 1 ) {
|
||||
$translations = array();
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
$translations[ $this->model->term->get_language( $term->term_id )->slug ] = $term->term_id;
|
||||
}
|
||||
|
||||
$this->model->term->save_translations( $term_id, $translations );
|
||||
}
|
||||
}
|
||||
|
||||
elseif ( current_user_can( 'edit_term', $term_id ) ) {
|
||||
$this->model->term->set_language( $term_id, $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Quick edit
|
||||
elseif ( isset( $_POST['inline_lang_choice'] ) ) {
|
||||
check_ajax_referer(
|
||||
isset( $_POST['action'] ) && 'inline-save' == $_POST['action'] ? 'inlineeditnonce' : 'taxinlineeditnonce', // Post quick edit or tag quick edit ?
|
||||
'_inline_edit'
|
||||
);
|
||||
|
||||
$lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) );
|
||||
$this->model->term->set_language( $term_id, $lang );
|
||||
}
|
||||
|
||||
// Edit post
|
||||
elseif ( isset( $_POST['post_lang_choice'] ) ) { // FIXME should be useless now
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$language = $this->model->get_language( sanitize_key( $_POST['post_lang_choice'] ) );
|
||||
|
||||
if ( ! empty( $language ) ) {
|
||||
$this->model->term->set_language( $term_id, $language );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save translations from our form.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $term_id The term id of the term being saved.
|
||||
* @return int[] The array of translated term ids.
|
||||
*/
|
||||
protected function save_translations( $term_id ) {
|
||||
// Security check as 'wp_update_term' can be called from outside WP admin.
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$translations = array();
|
||||
|
||||
// Save translations after checking the translated term is in the right language ( as well as cast id to int ).
|
||||
if ( isset( $_POST['term_tr_lang'] ) ) {
|
||||
foreach ( array_map( 'absint', $_POST['term_tr_lang'] ) as $lang => $tr_id ) {
|
||||
$tr_lang = $this->model->term->get_language( $tr_id );
|
||||
$translations[ $lang ] = $tr_lang && $tr_lang->slug == $lang ? $tr_id : 0;
|
||||
}
|
||||
}
|
||||
|
||||
$this->model->term->save_translations( $term_id, $translations );
|
||||
|
||||
return $translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a category or post tag is created or edited
|
||||
* Saves language and translations
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param int $term_id Term ID.
|
||||
* @param int $tt_id Term taxonomy ID.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @return void
|
||||
*/
|
||||
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
||||
// Does nothing except on taxonomies which are filterable
|
||||
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tax = get_taxonomy( $taxonomy );
|
||||
|
||||
if ( empty( $tax ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Capability check
|
||||
// As 'wp_update_term' can be called from outside WP admin
|
||||
// 2nd test for creating tags when creating / editing a post
|
||||
if ( current_user_can( $tax->cap->edit_terms ) || ( isset( $_POST['tax_input'][ $taxonomy ] ) && current_user_can( $tax->cap->assign_terms ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->save_language( $term_id, $taxonomy );
|
||||
|
||||
if ( isset( $_POST['term_tr_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->save_translations( $term_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax response for edit term form
|
||||
*
|
||||
* @since 0.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function term_lang_choice() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
if ( ! isset( $_POST['taxonomy'], $_POST['post_type'], $_POST['lang'] ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
$lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
|
||||
$term_id = isset( $_POST['term_id'] ) ? (int) $_POST['term_id'] : null; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
$taxonomy = sanitize_key( $_POST['taxonomy'] );
|
||||
$post_type = sanitize_key( $_POST['post_type'] );
|
||||
|
||||
if ( empty( $lang ) || ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
include __DIR__ . '/view-translations-term.php';
|
||||
$x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
|
||||
ob_end_clean();
|
||||
|
||||
// Parent dropdown list ( only for hierarchical taxonomies )
|
||||
// $args copied from edit_tags.php except echo
|
||||
if ( is_taxonomy_hierarchical( $taxonomy ) ) {
|
||||
$args = array(
|
||||
'hide_empty' => 0,
|
||||
'hide_if_empty' => false,
|
||||
'taxonomy' => $taxonomy,
|
||||
'name' => 'parent',
|
||||
'orderby' => 'name',
|
||||
'hierarchical' => true,
|
||||
'show_option_none' => __( 'None', 'polylang' ),
|
||||
'echo' => 0,
|
||||
);
|
||||
$x->Add( array( 'what' => 'parent', 'data' => wp_dropdown_categories( $args ) ) );
|
||||
}
|
||||
|
||||
// Tag cloud
|
||||
// Tests copied from edit_tags.php
|
||||
else {
|
||||
$tax = get_taxonomy( $taxonomy );
|
||||
if ( ! empty( $tax ) && ! is_null( $tax->labels->popular_items ) ) {
|
||||
$args = array( 'taxonomy' => $taxonomy, 'echo' => false );
|
||||
if ( current_user_can( $tax->cap->edit_terms ) ) {
|
||||
$args = array_merge( $args, array( 'link' => 'edit' ) );
|
||||
}
|
||||
|
||||
$tag_cloud = wp_tag_cloud( $args );
|
||||
|
||||
if ( ! empty( $tag_cloud ) ) {
|
||||
/** @phpstan-var non-falsy-string $tag_cloud */
|
||||
$html = sprintf( '<div class="tagcloud"><h2>%1$s</h2>%2$s</div>', esc_html( $tax->labels->popular_items ), $tag_cloud );
|
||||
$x->Add( array( 'what' => 'tag_cloud', 'data' => $html ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flag
|
||||
$x->Add( array( 'what' => 'flag', 'data' => empty( $lang->flag ) ? esc_html( $lang->slug ) : $lang->flag ) );
|
||||
|
||||
$x->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax response for input in translation autocomplete input box.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_terms_not_translated() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
if ( ! isset( $_GET['term'], $_GET['post_type'], $_GET['taxonomy'], $_GET['term_language'], $_GET['translation_language'] ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
$s = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||
$post_type = sanitize_key( $_GET['post_type'] );
|
||||
$taxonomy = sanitize_key( $_GET['taxonomy'] );
|
||||
|
||||
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
||||
wp_die( 0 );
|
||||
}
|
||||
|
||||
$term_language = $this->model->get_language( sanitize_key( $_GET['term_language'] ) );
|
||||
$translation_language = $this->model->get_language( sanitize_key( $_GET['translation_language'] ) );
|
||||
|
||||
$terms = array();
|
||||
$return = array();
|
||||
|
||||
// Add current translation in list.
|
||||
// Not in add term as term_id is not set.
|
||||
if ( isset( $_GET['term_id'] ) && 'undefined' !== $_GET['term_id'] && $term_id = $this->model->term->get_translation( (int) $_GET['term_id'], $translation_language ) ) {
|
||||
$terms = array( get_term( $term_id, $taxonomy ) );
|
||||
}
|
||||
|
||||
// It is more efficient to use one common query for all languages as soon as there are more than 2.
|
||||
$all_terms = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false, 'lang' => '', 'name__like' => $s ) );
|
||||
if ( is_array( $all_terms ) ) {
|
||||
foreach ( $all_terms as $term ) {
|
||||
$lang = $this->model->term->get_language( $term->term_id );
|
||||
|
||||
if ( $lang && $lang->slug == $translation_language->slug && ! $this->model->term->get_translation( $term->term_id, $term_language ) ) {
|
||||
$terms[] = $term;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format the ajax response.
|
||||
foreach ( $terms as $term ) {
|
||||
if ( ! $term instanceof WP_Term ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parents_list = get_term_parents_list(
|
||||
$term->term_id,
|
||||
$term->taxonomy,
|
||||
array(
|
||||
'separator' => ' > ',
|
||||
'link' => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! is_string( $parents_list ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$return[] = array(
|
||||
'id' => $term->term_id,
|
||||
'value' => rtrim( $parents_list, ' >' ), // Trim the separator added at the end by WP.
|
||||
'link' => $this->links->edit_term_translation_link( $term->term_id, $term->taxonomy, $post_type ),
|
||||
);
|
||||
}
|
||||
|
||||
wp_die( wp_json_encode( $return ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the translations term ids when splitting a shared term
|
||||
* Splits translations if these are shared terms too
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param int $term_id ID of the formerly shared term.
|
||||
* @param int $new_term_id ID of the new term created for the $term_taxonomy_id.
|
||||
* @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @return void
|
||||
*/
|
||||
public function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
|
||||
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid recursion
|
||||
static $avoid_recursion = false;
|
||||
if ( $avoid_recursion ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lang = $this->model->term->get_language( $term_id );
|
||||
if ( empty( $lang ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$avoid_recursion = true;
|
||||
$translations = array();
|
||||
|
||||
foreach ( $this->model->term->get_translations( $term_id ) as $key => $tr_id ) {
|
||||
if ( $lang->slug == $key ) {
|
||||
$translations[ $key ] = $new_term_id;
|
||||
}
|
||||
else {
|
||||
$tr_term = get_term( $tr_id, $taxonomy );
|
||||
|
||||
if ( ! $tr_term instanceof WP_Term ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$split_term_id = _split_shared_term( $tr_id, $tr_term->term_taxonomy_id );
|
||||
|
||||
if ( is_int( $split_term_id ) ) {
|
||||
$translations[ $key ] = $split_term_id;
|
||||
} else {
|
||||
$translations[ $key ] = $tr_id;
|
||||
}
|
||||
|
||||
// Hack translation ids sent by the form to avoid overwrite in PLL_Admin_Filters_Term::save_translations
|
||||
if ( isset( $_POST['term_tr_lang'][ $key ] ) && $_POST['term_tr_lang'][ $key ] == $tr_id ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$_POST['term_tr_lang'][ $key ] = $translations[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
$this->model->term->set_language( $translations[ $key ], $key );
|
||||
}
|
||||
|
||||
$this->model->term->save_translations( $new_term_id, $translations );
|
||||
$avoid_recursion = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language for subsequently inserted term in admin.
|
||||
*
|
||||
* @since 3.3
|
||||
*
|
||||
* @param PLL_Language|null $lang Term language object if found, null otherwise.
|
||||
* @return PLL_Language|null Language object, null if none found.
|
||||
*/
|
||||
public function get_inserted_term_language( $lang ) {
|
||||
if ( $lang instanceof PLL_Language ) {
|
||||
return $lang;
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['term_lang_choice'] ) && is_string( $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang_slug = sanitize_key( $_POST['term_lang_choice'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $this->model->get_language( $lang_slug );
|
||||
return $lang instanceof PLL_Language ? $lang : null;
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['inline_lang_choice'] ) && is_string( $_POST['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang_slug = sanitize_key( $_POST['inline_lang_choice'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $this->model->get_language( $lang_slug );
|
||||
return $lang instanceof PLL_Language ? $lang : null;
|
||||
}
|
||||
|
||||
// *Post* bulk edit, in case a new term is created
|
||||
if ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
// Bulk edit does not modify the language
|
||||
if ( -1 === (int) $_GET['inline_lang_choice'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $this->model->post->get_language( $this->post_id );
|
||||
return $lang instanceof PLL_Language ? $lang : null;
|
||||
} elseif ( is_string( $_GET['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang_slug = sanitize_key( $_GET['inline_lang_choice'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $this->model->get_language( $lang_slug );
|
||||
return $lang instanceof PLL_Language ? $lang : null;
|
||||
}
|
||||
}
|
||||
|
||||
// Special cases for default categories as the select is disabled.
|
||||
$default_term = get_option( 'default_category' );
|
||||
|
||||
if ( ! is_numeric( $default_term ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['tag_ID'] ) && in_array( (int) $default_term, $this->model->term->get_translations( (int) $_POST['tag_ID'] ), true ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $this->model->term->get_language( (int) $_POST['tag_ID'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
return $lang instanceof PLL_Language ? $lang : null;
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['tax_ID'] ) && in_array( (int) $default_term, $this->model->term->get_translations( (int) $_POST['tax_ID'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$lang = $this->model->term->get_language( (int) $_POST['tax_ID'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
return $lang instanceof PLL_Language ? $lang : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the subsequently inserted term parent in admin.
|
||||
*
|
||||
* @since 3.3
|
||||
*
|
||||
* @param int $parent Parent term ID, 0 if none found.
|
||||
* @param string $taxonomy Term taxonomy.
|
||||
* @return int Parent term ID if found, 0 otherwise.
|
||||
*/
|
||||
public function get_inserted_term_parent( $parent, $taxonomy ) {
|
||||
if ( $parent ) {
|
||||
return $parent;
|
||||
}
|
||||
|
||||
if ( isset( $_POST['parent'], $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$parent = intval( $_POST['parent'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
} elseif ( isset( $_POST[ "new{$taxonomy}_parent" ], $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$parent = intval( $_POST[ "new{$taxonomy}_parent" ] ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
return $parent;
|
||||
}
|
||||
}
|
||||
34
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-widgets-options.php
vendored
Normal file
34
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters-widgets-options.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class PLL_Widgets_Filters
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* Adds new options to {@see https://developer.wordpress.org/reference/classes/wp_widget/ WP_Widget} and saves them.
|
||||
*/
|
||||
class PLL_Admin_Filters_Widgets_Options extends PLL_Filters_Widgets_Options {
|
||||
/**
|
||||
* Modifies the widgets forms to add our language dropdown list.
|
||||
*
|
||||
* @since 0.3
|
||||
* @since 3.0 Moved from PLL_Admin_Filters
|
||||
*
|
||||
* @param WP_Widget $widget Widget instance.
|
||||
* @param null $return Not used.
|
||||
* @param array $instance Widget settings.
|
||||
* @return void
|
||||
*/
|
||||
public function in_widget_form( $widget, $return, $instance ) {
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Test the Widgets screen and the Customizer to avoid displaying the option in page builders
|
||||
// Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, nor in $_GET.
|
||||
if ( ( isset( $screen ) && 'widgets' === $screen->base ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
parent::in_widget_form( $widget, $return, $instance );
|
||||
}
|
||||
}
|
||||
}
|
||||
127
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters.php
vendored
Normal file
127
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-filters.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Setup miscellaneous admin filters as well as filters common to admin and frontend
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters extends PLL_Filters {
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
// Language management for users
|
||||
add_action( 'personal_options_update', array( $this, 'personal_options_update' ) );
|
||||
add_action( 'edit_user_profile_update', array( $this, 'personal_options_update' ) );
|
||||
add_action( 'personal_options', array( $this, 'personal_options' ) );
|
||||
|
||||
// Upgrades plugins and themes translations files
|
||||
add_filter( 'themes_update_check_locales', array( $this, 'update_check_locales' ) );
|
||||
add_filter( 'plugins_update_check_locales', array( $this, 'update_check_locales' ) );
|
||||
|
||||
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
|
||||
|
||||
// Add post state for translations of the privacy policy page
|
||||
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user biographies.
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @return void
|
||||
*/
|
||||
public function personal_options_update( $user_id ) {
|
||||
// Biography translations
|
||||
foreach ( $this->model->get_languages_list() as $lang ) {
|
||||
$meta = $lang->is_default ? 'description' : 'description_' . $lang->slug;
|
||||
$description = empty( $_POST[ 'description_' . $lang->slug ] ) ? '' : trim( $_POST[ 'description_' . $lang->slug ] ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
|
||||
|
||||
/** This filter is documented in wp-includes/user.php */
|
||||
$description = apply_filters( 'pre_user_description', $description ); // Applies WP default filter wp_filter_kses
|
||||
update_user_meta( $user_id, $meta, $description );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs hidden information to modify the biography form with js.
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param WP_User $profileuser The current WP_User object.
|
||||
* @return void
|
||||
*/
|
||||
public function personal_options( $profileuser ) {
|
||||
foreach ( $this->model->get_languages_list() as $lang ) {
|
||||
$meta = $lang->is_default ? 'description' : 'description_' . $lang->slug;
|
||||
$description = get_user_meta( $profileuser->ID, $meta, true );
|
||||
|
||||
printf(
|
||||
'<input type="hidden" class="biography" name="%s___%s" value="%s" />',
|
||||
esc_attr( $lang->slug ),
|
||||
esc_attr( $lang->name ),
|
||||
sanitize_user_field( 'description', $description, $profileuser->ID, 'edit' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to update translations files for plugins and themes.
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param string[] $locales List of locales to update for plugins and themes.
|
||||
* @return string[]
|
||||
*/
|
||||
public function update_check_locales( $locales ) {
|
||||
return array_merge( $locales, $this->model->get_languages_list( array( 'fields' => 'locale' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom classes to the body
|
||||
*
|
||||
* @since 2.2 Adds a text direction dependent class to the body.
|
||||
* @since 3.4 Adds a language dependent class to the body.
|
||||
*
|
||||
* @param string $classes Space-separated list of CSS classes.
|
||||
* @return string
|
||||
*/
|
||||
public function admin_body_class( $classes ) {
|
||||
if ( ! empty( $this->curlang ) ) {
|
||||
$classes .= ' pll-dir-' . ( $this->curlang->is_rtl ? 'rtl' : 'ltr' );
|
||||
$classes .= ' pll-lang-' . $this->curlang->slug;
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds post state for translations of the privacy policy page.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param string[] $post_states An array of post display states.
|
||||
* @param WP_Post $post The current post object.
|
||||
* @return string[]
|
||||
*/
|
||||
public function display_post_states( $post_states, $post ) {
|
||||
$page_for_privacy_policy = get_option( 'wp_page_for_privacy_policy' );
|
||||
|
||||
if ( $page_for_privacy_policy && in_array( $post->ID, $this->model->post->get_translations( $page_for_privacy_policy ) ) ) {
|
||||
$post_states['page_for_privacy_policy'] = __( 'Privacy Policy Page', 'polylang' );
|
||||
}
|
||||
|
||||
return $post_states;
|
||||
}
|
||||
}
|
||||
226
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-links.php
vendored
Normal file
226
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-links.php
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages links related functions.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
class PLL_Admin_Links extends PLL_Links {
|
||||
|
||||
/**
|
||||
* Returns the html markup for a new translation link.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $link The new translation link.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @return string
|
||||
*/
|
||||
protected function new_translation_link( $link, $language ) {
|
||||
$str = '';
|
||||
|
||||
if ( $link ) {
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
$hint = sprintf( __( 'Add a translation in %s', 'polylang' ), $language->name );
|
||||
|
||||
$str = sprintf(
|
||||
'<a href="%1$s" title="%2$s" class="pll_icon_add"><span class="screen-reader-text">%3$s</span></a>',
|
||||
esc_url( $link ),
|
||||
esc_attr( $hint ),
|
||||
esc_html( $hint )
|
||||
);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the html markup for a translation link.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $link The translation link.
|
||||
* @param PLL_Language $language The language of the translation.
|
||||
* @return string
|
||||
*/
|
||||
public function edit_translation_link( $link, $language ) {
|
||||
return $link ? sprintf(
|
||||
'<a href="%1$s" class="pll_icon_edit"><span class="screen-reader-text">%2$s</span></a>',
|
||||
esc_url( $link ),
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'Edit the translation in %s', 'polylang' ), $language->name ) )
|
||||
) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link to create a new post translation.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $post_id The source post id.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @param string $context Optional. Defaults to 'display' which encodes '&' to '&'.
|
||||
* Otherwise, preserves '&'.
|
||||
* @return string
|
||||
*/
|
||||
public function get_new_post_translation_link( $post_id, $language, $context = 'display' ) {
|
||||
$post_type = get_post_type( $post_id );
|
||||
$post_type_object = get_post_type_object( get_post_type( $post_id ) );
|
||||
if ( empty( $post_type_object ) || ! current_user_can( $post_type_object->cap->create_posts ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Special case for the privacy policy page which is associated to a specific capability
|
||||
if ( 'page' === $post_type_object->name && ! current_user_can( 'manage_privacy_options' ) ) {
|
||||
$privacy_page = get_option( 'wp_page_for_privacy_policy' );
|
||||
if ( $privacy_page && in_array( $post_id, $this->model->post->get_translations( $privacy_page ) ) ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'attachment' === $post_type ) {
|
||||
$args = array(
|
||||
'action' => 'translate_media',
|
||||
'from_media' => $post_id,
|
||||
'new_lang' => $language->slug,
|
||||
);
|
||||
|
||||
$link = add_query_arg( $args, admin_url( 'admin.php' ) );
|
||||
|
||||
// Add nonce for media as we will directly publish a new attachment from a click on this link
|
||||
if ( 'display' === $context ) {
|
||||
$link = wp_nonce_url( $link, 'translate_media' );
|
||||
} else {
|
||||
$link = add_query_arg( '_wpnonce', wp_create_nonce( 'translate_media' ), $link );
|
||||
}
|
||||
} else {
|
||||
$args = array(
|
||||
'post_type' => $post_type,
|
||||
'from_post' => $post_id,
|
||||
'new_lang' => $language->slug,
|
||||
);
|
||||
|
||||
$link = add_query_arg( $args, admin_url( 'post-new.php' ) );
|
||||
|
||||
if ( 'display' === $context ) {
|
||||
$link = wp_nonce_url( $link, 'new-post-translation' );
|
||||
} else {
|
||||
$link = add_query_arg( '_wpnonce', wp_create_nonce( 'new-post-translation' ), $link );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the new post translation link.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $link The new post translation link.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @param int $post_id The source post id.
|
||||
*/
|
||||
return apply_filters( 'pll_get_new_post_translation_link', $link, $language, $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the html markup for a new post translation link.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_id The source post id.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @return string
|
||||
*/
|
||||
public function new_post_translation_link( $post_id, $language ) {
|
||||
$link = $this->get_new_post_translation_link( $post_id, $language );
|
||||
return $this->new_translation_link( $link, $language );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the html markup for a post translation link.
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @param int $post_id The translation post id.
|
||||
* @return string
|
||||
*/
|
||||
public function edit_post_translation_link( $post_id ) {
|
||||
$link = get_edit_post_link( $post_id );
|
||||
$language = $this->model->post->get_language( $post_id );
|
||||
return $this->edit_translation_link( $link, $language );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link to create a new term translation.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $term_id Source term id.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @param string $post_type Post type name.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @return string
|
||||
*/
|
||||
public function get_new_term_translation_link( $term_id, $taxonomy, $post_type, $language ) {
|
||||
$tax = get_taxonomy( $taxonomy );
|
||||
if ( ! $tax || ! current_user_can( $tax->cap->edit_terms ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'taxonomy' => $taxonomy,
|
||||
'post_type' => $post_type,
|
||||
'from_tag' => $term_id,
|
||||
'new_lang' => $language->slug,
|
||||
);
|
||||
|
||||
$link = add_query_arg( $args, admin_url( 'edit-tags.php' ) );
|
||||
|
||||
/**
|
||||
* Filters the new term translation link.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $link The new term translation link.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @param int $term_id The source term id.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @param string $post_type Post type name.
|
||||
*/
|
||||
return apply_filters( 'pll_get_new_term_translation_link', $link, $language, $term_id, $taxonomy, $post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the html markup for a new term translation.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $term_id Source term id.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @param string $post_type Post type name.
|
||||
* @param PLL_Language $language The language of the new translation.
|
||||
* @return string
|
||||
*/
|
||||
public function new_term_translation_link( $term_id, $taxonomy, $post_type, $language ) {
|
||||
$link = $this->get_new_term_translation_link( $term_id, $taxonomy, $post_type, $language );
|
||||
return $this->new_translation_link( $link, $language );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the html markup for a term translation link.
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @param int $term_id Translation term id.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @param string $post_type Post type name.
|
||||
* @return string
|
||||
*/
|
||||
public function edit_term_translation_link( $term_id, $taxonomy, $post_type ) {
|
||||
$link = get_edit_term_link( $term_id, $taxonomy, $post_type );
|
||||
$language = $this->model->term->get_language( $term_id );
|
||||
return $this->edit_translation_link( $link, $language );
|
||||
}
|
||||
}
|
||||
540
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-model.php
vendored
Normal file
540
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-model.php
vendored
Normal file
@@ -0,0 +1,540 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extends the PLL_Model class with methods needed only in Polylang settings pages.
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Model extends PLL_Model {
|
||||
|
||||
/**
|
||||
* Adds a new language
|
||||
* and creates a default category for this language.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param array $args {
|
||||
* @type string $name Language name (used only for display).
|
||||
* @type string $slug Language code (ideally 2-letters ISO 639-1 language code).
|
||||
* @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will
|
||||
* not be loaded...
|
||||
* @type int $rtl 1 if rtl language, 0 otherwise.
|
||||
* @type int $term_group Language order when displayed.
|
||||
* @type string $no_default_cat Optional, if set, no default category will be created for this language.
|
||||
* @type string $flag Optional, country code, {@see settings/flags.php}.
|
||||
* }
|
||||
* @return WP_Error|true true if success / WP_Error if failed.
|
||||
*/
|
||||
public function add_language( $args ) {
|
||||
$errors = $this->validate_lang( $args );
|
||||
if ( $errors->has_errors() ) {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// First the language taxonomy
|
||||
$r = wp_insert_term(
|
||||
$args['name'],
|
||||
'language',
|
||||
array(
|
||||
'slug' => $args['slug'],
|
||||
'description' => $this->build_language_metas( $args ),
|
||||
)
|
||||
);
|
||||
if ( is_wp_error( $r ) ) {
|
||||
// Avoid an ugly fatal error if something went wrong ( reported once in the forum )
|
||||
return new WP_Error( 'pll_add_language', __( 'Impossible to add the language.', 'polylang' ) );
|
||||
}
|
||||
wp_update_term( (int) $r['term_id'], 'language', array( 'term_group' => (int) $args['term_group'] ) ); // can't set the term group directly in wp_insert_term
|
||||
|
||||
// The other language taxonomies.
|
||||
$this->update_secondary_language_terms( $args['slug'], $args['name'] );
|
||||
|
||||
if ( ! isset( $this->options['default_lang'] ) ) {
|
||||
// If this is the first language created, set it as default language
|
||||
$this->options['default_lang'] = $args['slug'];
|
||||
update_option( 'polylang', $this->options );
|
||||
}
|
||||
|
||||
// Refresh languages.
|
||||
$this->clean_languages_cache();
|
||||
$this->get_languages_list();
|
||||
|
||||
flush_rewrite_rules(); // Refresh rewrite rules.
|
||||
|
||||
/**
|
||||
* Fires when a language is added.
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param array $args Arguments used to create the language. @see PLL_Admin_Model::add_language().
|
||||
*/
|
||||
do_action( 'pll_add_language', $args );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a language.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param int $lang_id Language term_id.
|
||||
* @return bool
|
||||
*/
|
||||
public function delete_language( $lang_id ) {
|
||||
$lang = $this->get_language( (int) $lang_id );
|
||||
|
||||
if ( empty( $lang ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Oops ! we are deleting the default language...
|
||||
// Need to do this before loosing the information for default category translations
|
||||
if ( $lang->is_default ) {
|
||||
$slugs = $this->get_languages_list( array( 'fields' => 'slug' ) );
|
||||
$slugs = array_diff( $slugs, array( $lang->slug ) );
|
||||
|
||||
if ( ! empty( $slugs ) ) {
|
||||
$this->update_default_lang( reset( $slugs ) ); // Arbitrary choice...
|
||||
} else {
|
||||
unset( $this->options['default_lang'] );
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the translations
|
||||
$this->update_translations( $lang->slug );
|
||||
|
||||
// Delete language option in widgets
|
||||
foreach ( $GLOBALS['wp_registered_widgets'] as $widget ) {
|
||||
if ( ! empty( $widget['callback'][0] ) && ! empty( $widget['params'][0]['number'] ) ) {
|
||||
$obj = $widget['callback'][0];
|
||||
$number = $widget['params'][0]['number'];
|
||||
if ( is_object( $obj ) && method_exists( $obj, 'get_settings' ) && method_exists( $obj, 'save_settings' ) ) {
|
||||
$settings = $obj->get_settings();
|
||||
if ( isset( $settings[ $number ]['pll_lang'] ) && $settings[ $number ]['pll_lang'] == $lang->slug ) {
|
||||
unset( $settings[ $number ]['pll_lang'] );
|
||||
$obj->save_settings( $settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete menus locations
|
||||
if ( ! empty( $this->options['nav_menus'] ) ) {
|
||||
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
||||
foreach ( array_keys( $locations ) as $location ) {
|
||||
unset( $this->options['nav_menus'][ $theme ][ $location ][ $lang->slug ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete users options
|
||||
delete_metadata( 'user', 0, 'pll_filter_content', '', true );
|
||||
delete_metadata( 'user', 0, "description_{$lang->slug}", '', true );
|
||||
|
||||
// Delete domain
|
||||
unset( $this->options['domains'][ $lang->slug ] );
|
||||
|
||||
/*
|
||||
* Delete the language itself.
|
||||
*
|
||||
* Reverses the language taxonomies order is required to make sure 'language' is deleted in last.
|
||||
*
|
||||
* The initial order with the 'language' taxonomy at the beginning of 'PLL_Language::term_props' property
|
||||
* is done by {@see PLL_Model::filter_language_terms_orderby()}
|
||||
*/
|
||||
foreach ( array_reverse( $lang->get_tax_props( 'term_id' ) ) as $taxonomy_name => $term_id ) {
|
||||
wp_delete_term( $term_id, $taxonomy_name );
|
||||
}
|
||||
|
||||
// Refresh languages.
|
||||
$this->clean_languages_cache();
|
||||
$this->get_languages_list();
|
||||
|
||||
update_option( 'polylang', $this->options );
|
||||
flush_rewrite_rules(); // refresh rewrite rules
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates language properties.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param array $args {
|
||||
* @type int $lang_id Id of the language to modify.
|
||||
* @type string $name Language name ( used only for display ).
|
||||
* @type string $slug Language code ( ideally 2-letters ISO 639-1 language code ).
|
||||
* @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
||||
* @type int $rtl 1 if rtl language, 0 otherwise.
|
||||
* @type int $term_group Language order when displayed.
|
||||
* @type string $flag Optional, country code, @see flags.php.
|
||||
* }
|
||||
* @return WP_Error|true true if success / WP_Error if failed.
|
||||
*/
|
||||
public function update_language( $args ) {
|
||||
$lang = $this->get_language( (int) $args['lang_id'] );
|
||||
|
||||
if ( empty( $lang ) ) {
|
||||
return new WP_Error( 'pll_invalid_language_id', __( 'The language does not seem to exist.', 'polylang' ) );
|
||||
}
|
||||
|
||||
$errors = $this->validate_lang( $args, $lang );
|
||||
if ( $errors->get_error_code() ) { // Using has_errors() would be more meaningful but is available only since WP 5.0
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// Update links to this language in posts and terms in case the slug has been modified
|
||||
$slug = $args['slug'];
|
||||
$old_slug = $lang->slug;
|
||||
|
||||
if ( $old_slug != $slug ) {
|
||||
// Update the language slug in translations
|
||||
$this->update_translations( $old_slug, $slug );
|
||||
|
||||
// Update language option in widgets
|
||||
foreach ( $GLOBALS['wp_registered_widgets'] as $widget ) {
|
||||
if ( ! empty( $widget['callback'][0] ) && ! empty( $widget['params'][0]['number'] ) ) {
|
||||
$obj = $widget['callback'][0];
|
||||
$number = $widget['params'][0]['number'];
|
||||
if ( is_object( $obj ) && method_exists( $obj, 'get_settings' ) && method_exists( $obj, 'save_settings' ) ) {
|
||||
$settings = $obj->get_settings();
|
||||
if ( isset( $settings[ $number ]['pll_lang'] ) && $settings[ $number ]['pll_lang'] == $old_slug ) {
|
||||
$settings[ $number ]['pll_lang'] = $slug;
|
||||
$obj->save_settings( $settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update menus locations
|
||||
if ( ! empty( $this->options['nav_menus'] ) ) {
|
||||
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
||||
foreach ( array_keys( $locations ) as $location ) {
|
||||
if ( ! empty( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] ) ) {
|
||||
$this->options['nav_menus'][ $theme ][ $location ][ $slug ] = $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ];
|
||||
unset( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update domains
|
||||
if ( ! empty( $this->options['domains'][ $old_slug ] ) ) {
|
||||
$this->options['domains'][ $slug ] = $this->options['domains'][ $old_slug ];
|
||||
unset( $this->options['domains'][ $old_slug ] );
|
||||
}
|
||||
|
||||
// Update the default language option if necessary
|
||||
if ( $lang->is_default ) {
|
||||
$this->options['default_lang'] = $slug;
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'polylang', $this->options );
|
||||
|
||||
// And finally update the language itself.
|
||||
$this->update_secondary_language_terms( $args['slug'], $args['name'], $lang );
|
||||
|
||||
$description = $this->build_language_metas( $args );
|
||||
wp_update_term( $lang->get_tax_prop( 'language', 'term_id' ), 'language', array( 'slug' => $slug, 'name' => $args['name'], 'description' => $description, 'term_group' => (int) $args['term_group'] ) );
|
||||
|
||||
// Refresh languages.
|
||||
$this->clean_languages_cache();
|
||||
$this->get_languages_list();
|
||||
|
||||
// Refresh rewrite rules.
|
||||
flush_rewrite_rules();
|
||||
|
||||
/**
|
||||
* Fires after a language is updated.
|
||||
*
|
||||
* @since 1.9
|
||||
* @since 3.2 Added $lang parameter.
|
||||
*
|
||||
* @param array $args {
|
||||
* Arguments used to modify the language. @see PLL_Admin_Model::update_language().
|
||||
*
|
||||
* @type string $name Language name (used only for display).
|
||||
* @type string $slug Language code (ideally 2-letters ISO 639-1 language code).
|
||||
* @type string $locale WordPress locale.
|
||||
* @type int $rtl 1 if rtl language, 0 otherwise.
|
||||
* @type int $term_group Language order when displayed.
|
||||
* @type string $no_default_cat Optional, if set, no default category has been created for this language.
|
||||
* @type string $flag Optional, country code, @see flags.php.
|
||||
* }
|
||||
* @param PLL_Language $lang Previous value of the language being edited.
|
||||
*/
|
||||
do_action( 'pll_update_language', $args, $lang );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the language metas into an array and serializes it, to be stored in the term description.
|
||||
*
|
||||
* @since 3.4
|
||||
*
|
||||
* @param array $args {
|
||||
* @type string $name Language name (used only for display).
|
||||
* @type string $slug Language code (ideally 2-letters ISO 639-1 language code).
|
||||
* @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be
|
||||
* loaded...
|
||||
* @type int $rtl 1 if rtl language, 0 otherwise.
|
||||
* @type int $term_group Language order when displayed.
|
||||
* @type int $lang_id Optional, ID of the language to modify. An empty value means the language is being
|
||||
* created.
|
||||
* @type string $flag Optional, country code, {@see settings/flags.php}.
|
||||
* }
|
||||
* @return string The serialized description array updated.
|
||||
*/
|
||||
protected function build_language_metas( array $args ) {
|
||||
if ( ! empty( $args['lang_id'] ) ) {
|
||||
$language_term = get_term( (int) $args['lang_id'] );
|
||||
|
||||
if ( $language_term instanceof WP_Term ) {
|
||||
$old_data = maybe_unserialize( $language_term->description );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $old_data ) || ! is_array( $old_data ) ) {
|
||||
$old_data = array();
|
||||
}
|
||||
|
||||
$new_data = array(
|
||||
'locale' => $args['locale'],
|
||||
'rtl' => ! empty( $args['rtl'] ) ? 1 : 0,
|
||||
'flag_code' => empty( $args['flag'] ) ? '' : $args['flag'],
|
||||
);
|
||||
|
||||
/**
|
||||
* Allow to add data to store for a language.
|
||||
* `$locale`, `$rtl`, and `$flag_code` cannot be overwritten.
|
||||
*
|
||||
* @since 3.4
|
||||
*
|
||||
* @param mixed[] $add_data Data to add.
|
||||
* @param mixed[] $args {
|
||||
* Arguments used to create the language.
|
||||
*
|
||||
* @type string $name Language name (used only for display).
|
||||
* @type string $slug Language code (ideally 2-letters ISO 639-1 language code).
|
||||
* @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will
|
||||
* not be loaded...
|
||||
* @type int $rtl 1 if rtl language, 0 otherwise.
|
||||
* @type int $term_group Language order when displayed.
|
||||
* @type int $lang_id Optional, ID of the language to modify. An empty value means the language is
|
||||
* being created.
|
||||
* @type string $flag Optional, country code, {@see settings/flags.php}.
|
||||
* }
|
||||
* @param mixed[] $new_data New data.
|
||||
* @param mixed[] $old_data {
|
||||
* Original data. Contains at least the following:
|
||||
*
|
||||
* @type string $locale WordPress locale.
|
||||
* @type int $rtl 1 if rtl language, 0 otherwise.
|
||||
* @type string $flag_code Country code.
|
||||
* }
|
||||
*/
|
||||
$add_data = apply_filters( 'pll_language_metas', array(), $args, $new_data, $old_data );
|
||||
// Don't allow to overwrite `$locale`, `$rtl`, and `$flag_code`.
|
||||
$new_data = array_merge( $old_data, $add_data, $new_data );
|
||||
|
||||
/** @var non-empty-string $serialized maybe_serialize() cannot return anything else than a string when fed by an array. */
|
||||
$serialized = maybe_serialize( $new_data );
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates data entered when creating or updating a language.
|
||||
*
|
||||
* @see PLL_Admin_Model::add_language().
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param array $args Parameters of {@see PLL_Admin_Model::add_language() or @see PLL_Admin_Model::update_language()}.
|
||||
* @param PLL_Language|null $lang Optional the language currently updated, the language is created if not set.
|
||||
* @return WP_Error
|
||||
*/
|
||||
protected function validate_lang( $args, $lang = null ) {
|
||||
$errors = new WP_Error();
|
||||
|
||||
// Validate locale with the same pattern as WP 4.3. See #28303
|
||||
if ( ! preg_match( '#^[a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?$#', $args['locale'], $matches ) ) {
|
||||
$errors->add( 'pll_invalid_locale', __( 'Enter a valid WordPress locale', 'polylang' ) );
|
||||
}
|
||||
|
||||
// Validate slug characters
|
||||
if ( ! preg_match( '#^[a-z_-]+$#', $args['slug'] ) ) {
|
||||
$errors->add( 'pll_invalid_slug', __( 'The language code contains invalid characters', 'polylang' ) );
|
||||
}
|
||||
|
||||
// Validate slug is unique
|
||||
foreach ( $this->get_languages_list() as $language ) {
|
||||
if ( $language->slug === $args['slug'] && ( null === $lang || $lang->term_id !== $language->term_id ) ) {
|
||||
$errors->add( 'pll_non_unique_slug', __( 'The language code must be unique', 'polylang' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Validate name
|
||||
// No need to sanitize it as wp_insert_term will do it for us
|
||||
if ( empty( $args['name'] ) ) {
|
||||
$errors->add( 'pll_invalid_name', __( 'The language must have a name', 'polylang' ) );
|
||||
}
|
||||
|
||||
// Validate flag
|
||||
if ( ! empty( $args['flag'] ) && ! is_readable( POLYLANG_DIR . '/flags/' . $args['flag'] . '.png' ) ) {
|
||||
$flag = PLL_Language::get_flag_informations( $args['flag'] );
|
||||
|
||||
if ( ! empty( $flag['url'] ) ) {
|
||||
$response = function_exists( 'vip_safe_wp_remote_get' ) ? vip_safe_wp_remote_get( esc_url_raw( $flag['url'] ) ) : wp_remote_get( esc_url_raw( $flag['url'] ) );
|
||||
}
|
||||
|
||||
if ( empty( $response ) || is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
||||
$errors->add( 'pll_invalid_flag', __( 'The flag does not exist', 'polylang' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the translations when a language slug has been modified in settings
|
||||
* or deletes them when a language is removed.
|
||||
*
|
||||
* @since 0.5
|
||||
*
|
||||
* @param string $old_slug The old language slug.
|
||||
* @param string $new_slug Optional, the new language slug, if not set it means that the language has been deleted.
|
||||
* @return void
|
||||
*/
|
||||
public function update_translations( $old_slug, $new_slug = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
$term_ids = array();
|
||||
$dr = array();
|
||||
$dt = array();
|
||||
$ut = array();
|
||||
|
||||
$taxonomies = $this->translatable_objects->get_taxonomy_names( array( 'translations' ) );
|
||||
$terms = get_terms( array( 'taxonomy' => $taxonomies ) );
|
||||
|
||||
if ( is_array( $terms ) ) {
|
||||
foreach ( $terms as $term ) {
|
||||
$term_ids[ $term->taxonomy ][] = $term->term_id;
|
||||
$tr = maybe_unserialize( $term->description );
|
||||
|
||||
/**
|
||||
* Filters the unserialized translation group description before it is
|
||||
* updated when a language is deleted or a language slug is changed.
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @param (int|string[])[] $tr {
|
||||
* List of translations with lang codes as array keys and IDs as array values.
|
||||
* Also in this array:
|
||||
*
|
||||
* @type string[] $sync List of synchronized translations with lang codes as array keys and array values.
|
||||
* }
|
||||
* @param string $old_slug The old language slug.
|
||||
* @param string $new_slug The new language slug.
|
||||
* @param WP_Term $term The term containing the post or term translation group.
|
||||
*/
|
||||
$tr = apply_filters( 'update_translation_group', $tr, $old_slug, $new_slug, $term );
|
||||
|
||||
if ( ! empty( $tr[ $old_slug ] ) ) {
|
||||
if ( $new_slug ) {
|
||||
$tr[ $new_slug ] = $tr[ $old_slug ]; // Suppress this for delete
|
||||
} else {
|
||||
$dr['id'][] = (int) $tr[ $old_slug ];
|
||||
$dr['tt'][] = (int) $term->term_taxonomy_id;
|
||||
}
|
||||
unset( $tr[ $old_slug ] );
|
||||
|
||||
if ( empty( $tr ) || 1 == count( $tr ) ) {
|
||||
$dt['t'][] = (int) $term->term_id;
|
||||
$dt['tt'][] = (int) $term->term_taxonomy_id;
|
||||
} else {
|
||||
$ut['case'][] = $wpdb->prepare( 'WHEN %d THEN %s', $term->term_id, maybe_serialize( $tr ) );
|
||||
$ut['in'][] = (int) $term->term_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete relationships
|
||||
if ( ! empty( $dr ) ) {
|
||||
// PHPCS:disable WordPress.DB.PreparedSQL.NotPrepared
|
||||
$wpdb->query(
|
||||
"DELETE FROM $wpdb->term_relationships
|
||||
WHERE object_id IN ( " . implode( ',', $dr['id'] ) . ' )
|
||||
AND term_taxonomy_id IN ( ' . implode( ',', $dr['tt'] ) . ' )'
|
||||
);
|
||||
// PHPCS:enable
|
||||
}
|
||||
|
||||
// Delete terms
|
||||
if ( ! empty( $dt ) ) {
|
||||
$wpdb->query( "DELETE FROM $wpdb->terms WHERE term_id IN ( " . implode( ',', $dt['t'] ) . ' )' ); // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
$wpdb->query( "DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ( " . implode( ',', $dt['tt'] ) . ' )' ); // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
}
|
||||
|
||||
// Update terms
|
||||
if ( ! empty( $ut ) ) {
|
||||
// PHPCS:disable WordPress.DB.PreparedSQL.NotPrepared
|
||||
$wpdb->query(
|
||||
"UPDATE $wpdb->term_taxonomy
|
||||
SET description = ( CASE term_id " . implode( ' ', $ut['case'] ) . ' END )
|
||||
WHERE term_id IN ( ' . implode( ',', $ut['in'] ) . ' )'
|
||||
);
|
||||
// PHPCS:enable
|
||||
}
|
||||
|
||||
if ( ! empty( $term_ids ) ) {
|
||||
foreach ( $term_ids as $taxonomy => $ids ) {
|
||||
clean_term_cache( $ids, $taxonomy );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the default language
|
||||
* taking care to update the default category & the nav menu locations.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $slug New language slug.
|
||||
* @return void
|
||||
*/
|
||||
public function update_default_lang( $slug ) {
|
||||
// The nav menus stored in theme locations should be in the default language
|
||||
$theme = get_stylesheet();
|
||||
if ( ! empty( $this->options['nav_menus'][ $theme ] ) ) {
|
||||
$menus = array();
|
||||
|
||||
foreach ( $this->options['nav_menus'][ $theme ] as $key => $loc ) {
|
||||
$menus[ $key ] = empty( $loc[ $slug ] ) ? 0 : $loc[ $slug ];
|
||||
}
|
||||
set_theme_mod( 'nav_menu_locations', $menus );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when a default language is updated.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param string $slug Slug.
|
||||
*/
|
||||
do_action( 'pll_update_default_lang', $slug );
|
||||
|
||||
// Update options
|
||||
$this->options['default_lang'] = $slug;
|
||||
update_option( 'polylang', $this->options );
|
||||
|
||||
$this->clean_languages_cache();
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
}
|
||||
280
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-nav-menu.php
vendored
Normal file
280
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-nav-menu.php
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages custom menus translations as well as the language switcher menu item on admin side
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
// Populates nav menus locations
|
||||
// Since WP 4.4, must be done before customize_register is fired
|
||||
add_filter( 'theme_mod_nav_menu_locations', array( $this, 'theme_mod_nav_menu_locations' ), 20 );
|
||||
|
||||
// Integration in the WP menu interface
|
||||
add_action( 'admin_init', array( $this, 'admin_init' ) ); // after Polylang upgrade
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups filters and terms
|
||||
* adds the language switcher metabox and create new nav menu locations
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_init() {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
add_action( 'wp_update_nav_menu_item', array( $this, 'wp_update_nav_menu_item' ), 10, 2 );
|
||||
|
||||
// Translation of menus based on chosen locations
|
||||
add_filter( 'pre_update_option_theme_mods_' . $this->theme, array( $this, 'pre_update_option_theme_mods' ) );
|
||||
add_action( 'delete_nav_menu', array( $this, 'delete_nav_menu' ) );
|
||||
|
||||
// FIXME is it possible to choose the order ( after theme locations in WP3.5 and older ) ?
|
||||
// FIXME not displayed if Polylang is activated before the first time the user goes to nav menus http://core.trac.wordpress.org/ticket/16828
|
||||
add_meta_box( 'pll_lang_switch_box', __( 'Language switcher', 'polylang' ), array( $this, 'lang_switch' ), 'nav-menus', 'side', 'high' );
|
||||
|
||||
$this->create_nav_menu_locations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Language switcher metabox
|
||||
* The checkbox and all hidden fields are important
|
||||
* Thanks to John Morris for his very interesting post http://www.johnmorrisonline.com/how-to-add-a-fully-functional-custom-meta-box-to-wordpress-navigation-menus/
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function lang_switch() {
|
||||
global $_nav_menu_placeholder, $nav_menu_selected_id;
|
||||
$_nav_menu_placeholder = 0 > $_nav_menu_placeholder ? $_nav_menu_placeholder - 1 : -1;
|
||||
?>
|
||||
<div id="posttype-lang-switch" class="posttypediv">
|
||||
<div id="tabs-panel-lang-switch" class="tabs-panel tabs-panel-active">
|
||||
<ul id="lang-switch-checklist" class="categorychecklist form-no-clear">
|
||||
<li>
|
||||
<label class="menu-item-title">
|
||||
<input type="checkbox" class="menu-item-checkbox" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-object-id]" value="-1"> <?php esc_html_e( 'Languages', 'polylang' ); ?>
|
||||
</label>
|
||||
<input type="hidden" class="menu-item-type" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-type]" value="custom">
|
||||
<input type="hidden" class="menu-item-title" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-title]" value="<?php esc_attr_e( 'Languages', 'polylang' ); ?>">
|
||||
<input type="hidden" class="menu-item-url" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-url]" value="#pll_switcher">
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p class="button-controls">
|
||||
<span class="add-to-menu">
|
||||
<input type="submit" <?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu', 'polylang' ); ?>" name="add-post-type-menu-item" id="submit-posttype-lang-switch">
|
||||
<span class="spinner"></span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares javascript to modify the language switcher menu item
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_enqueue_scripts() {
|
||||
$screen = get_current_screen();
|
||||
if ( empty( $screen ) || 'nav-menus' !== $screen->base ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
wp_enqueue_script( 'pll_nav_menu', plugins_url( '/js/build/nav-menu' . $suffix . '.js', POLYLANG_ROOT_FILE ), array( 'jquery' ), POLYLANG_VERSION );
|
||||
|
||||
$data = array(
|
||||
'strings' => PLL_Switcher::get_switcher_options( 'menu', 'string' ), // The strings for the options
|
||||
'title' => __( 'Languages', 'polylang' ), // The title
|
||||
'val' => array(),
|
||||
);
|
||||
|
||||
// Get all language switcher menu items
|
||||
$items = get_posts(
|
||||
array(
|
||||
'numberposts' => -1,
|
||||
'nopaging' => true,
|
||||
'post_type' => 'nav_menu_item',
|
||||
'fields' => 'ids',
|
||||
'meta_key' => '_pll_menu_item',
|
||||
)
|
||||
);
|
||||
|
||||
// The options values for the language switcher
|
||||
foreach ( $items as $item ) {
|
||||
$data['val'][ $item ] = get_post_meta( $item, '_pll_menu_item', true );
|
||||
}
|
||||
|
||||
// Send all these data to javascript
|
||||
wp_localize_script( 'pll_nav_menu', 'pll_data', $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save our menu item options.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param int $menu_id ID of the updated menu.
|
||||
* @param int $menu_item_db_id ID of the updated menu item.
|
||||
* @return void
|
||||
*/
|
||||
public function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0 ) {
|
||||
if ( empty( $_POST['menu-item-url'][ $menu_item_db_id ] ) || '#pll_switcher' !== $_POST['menu-item-url'][ $menu_item_db_id ] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
return;
|
||||
}
|
||||
|
||||
// Security check as 'wp_update_nav_menu_item' can be called from outside WP admin
|
||||
if ( current_user_can( 'edit_theme_options' ) ) {
|
||||
check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
|
||||
|
||||
$options = array( 'hide_if_no_translation' => 0, 'hide_current' => 0, 'force_home' => 0, 'show_flags' => 0, 'show_names' => 1, 'dropdown' => 0 ); // Default values
|
||||
// Our jQuery form has not been displayed
|
||||
if ( empty( $_POST['menu-item-pll-detect'][ $menu_item_db_id ] ) ) {
|
||||
if ( ! get_post_meta( $menu_item_db_id, '_pll_menu_item', true ) ) { // Our options were never saved
|
||||
update_post_meta( $menu_item_db_id, '_pll_menu_item', $options );
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ( array_keys( $options ) as $opt ) {
|
||||
$options[ $opt ] = empty( $_POST[ 'menu-item-' . $opt ][ $menu_item_db_id ] ) ? 0 : 1;
|
||||
}
|
||||
update_post_meta( $menu_item_db_id, '_pll_menu_item', $options ); // Allow us to easily identify our nav menu item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign menu languages and translations based on ( temporary ) locations
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param array $locations nav menu locations
|
||||
* @return array
|
||||
*/
|
||||
public function update_nav_menu_locations( $locations ) {
|
||||
// Extract language and menu from locations
|
||||
foreach ( $locations as $loc => $menu ) {
|
||||
$infos = $this->explode_location( $loc );
|
||||
$this->options['nav_menus'][ $this->theme ][ $infos['location'] ][ $infos['lang'] ] = $menu;
|
||||
if ( $this->options['default_lang'] != $infos['lang'] ) {
|
||||
unset( $locations[ $loc ] ); // Remove temporary locations before database update
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'polylang', $this->options );
|
||||
return $locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign menu languages and translations based on ( temporary ) locations.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param mixed $mods Theme mods.
|
||||
* @return mixed
|
||||
*/
|
||||
public function pre_update_option_theme_mods( $mods ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) && is_array( $mods ) && isset( $mods['nav_menu_locations'] ) ) {
|
||||
|
||||
// Manage Locations tab in Appearance -> Menus
|
||||
if ( isset( $_GET['action'] ) && 'locations' === $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
check_admin_referer( 'save-menu-locations' );
|
||||
$this->options['nav_menus'][ $this->theme ] = array();
|
||||
}
|
||||
|
||||
// Edit Menus tab in Appearance -> Menus
|
||||
// Add the test of $_POST['update-nav-menu-nonce'] to avoid conflict with Vantage theme
|
||||
elseif ( isset( $_POST['action'], $_POST['update-nav-menu-nonce'] ) && 'update' === $_POST['action'] ) {
|
||||
check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
|
||||
$this->options['nav_menus'][ $this->theme ] = array();
|
||||
}
|
||||
|
||||
// Customizer
|
||||
// Don't reset locations in this case.
|
||||
// see http://wordpress.org/support/topic/menus-doesnt-show-and-not-saved-in-theme-settings-multilingual-site
|
||||
elseif ( isset( $_POST['action'] ) && 'customize_save' == $_POST['action'] ) {
|
||||
check_ajax_referer( 'save-customize_' . $GLOBALS['wp_customize']->get_stylesheet(), 'nonce' );
|
||||
}
|
||||
|
||||
else {
|
||||
return $mods; // No modification for nav menu locations
|
||||
}
|
||||
|
||||
$mods['nav_menu_locations'] = $this->update_nav_menu_locations( $mods['nav_menu_locations'] );
|
||||
}
|
||||
return $mods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills temporary menu locations based on menus translations
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param bool|array $menus Associative array of registered navigation menu IDs keyed by their location name.
|
||||
* @return bool|array
|
||||
*/
|
||||
public function theme_mod_nav_menu_locations( $menus ) {
|
||||
// Prefill locations with 0 value in case a location does not exist in $menus
|
||||
$locations = get_registered_nav_menus();
|
||||
if ( is_array( $locations ) ) {
|
||||
$locations = array_fill_keys( array_keys( $locations ), 0 );
|
||||
$menus = is_array( $menus ) ? array_merge( $locations, $menus ) : $locations;
|
||||
}
|
||||
|
||||
if ( is_array( $menus ) ) {
|
||||
foreach ( array_keys( $menus ) as $loc ) {
|
||||
foreach ( $this->model->get_languages_list() as $lang ) {
|
||||
if ( ! empty( $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ] ) && term_exists( $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ], 'nav_menu' ) ) {
|
||||
$menus[ $this->combine_location( $loc, $lang ) ] = $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $menus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the nav menu term_id from the locations stored in Polylang options when a nav menu is deleted
|
||||
*
|
||||
* @since 1.7.3
|
||||
*
|
||||
* @param int $term_id nav menu id
|
||||
* @return void
|
||||
*/
|
||||
public function delete_nav_menu( $term_id ) {
|
||||
if ( isset( $this->options['nav_menus'] ) ) {
|
||||
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
||||
foreach ( $locations as $loc => $languages ) {
|
||||
foreach ( $languages as $lang => $menu_id ) {
|
||||
if ( $menu_id === $term_id ) {
|
||||
unset( $this->options['nav_menus'][ $theme ][ $loc ][ $lang ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'polylang', $this->options );
|
||||
}
|
||||
}
|
||||
}
|
||||
270
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-notices.php
vendored
Normal file
270
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-notices.php
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class to manage admin notices
|
||||
* displayed only to admin, based on 'manage_options' capability
|
||||
* and only on dashboard, plugins and Polylang admin pages
|
||||
*
|
||||
* @since 2.3.9
|
||||
* @since 2.7 Dismissed notices are stored in an option instead of a user meta
|
||||
*/
|
||||
class PLL_Admin_Notices {
|
||||
/**
|
||||
* Stores the plugin options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Stores custom notices.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private static $notices = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Setup actions
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( $polylang ) {
|
||||
$this->options = &$polylang->options;
|
||||
|
||||
add_action( 'admin_init', array( $this, 'hide_notice' ) );
|
||||
add_action( 'admin_notices', array( $this, 'display_notices' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom notice
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @param string $name Notice name
|
||||
* @param string $html Content of the notice
|
||||
* @return void
|
||||
*/
|
||||
public static function add_notice( $name, $html ) {
|
||||
self::$notices[ $name ] = $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom notices.
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function get_notices() {
|
||||
return self::$notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has a notice been dismissed?
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @param string $notice Notice name
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_dismissed( $notice ) {
|
||||
$dismissed = get_option( 'pll_dismissed_notices', array() );
|
||||
|
||||
// Handle legacy user meta
|
||||
$dismissed_meta = get_user_meta( get_current_user_id(), 'pll_dismissed_notices', true );
|
||||
if ( is_array( $dismissed_meta ) ) {
|
||||
if ( array_diff( $dismissed_meta, $dismissed ) ) {
|
||||
$dismissed = array_merge( $dismissed, $dismissed_meta );
|
||||
update_option( 'pll_dismissed_notices', $dismissed );
|
||||
}
|
||||
if ( ! is_multisite() ) {
|
||||
// Don't delete on multisite to avoid the notices to appear in other sites.
|
||||
delete_user_meta( get_current_user_id(), 'pll_dismissed_notices' );
|
||||
}
|
||||
}
|
||||
|
||||
return in_array( $notice, $dismissed );
|
||||
}
|
||||
|
||||
/**
|
||||
* Should we display notices on this screen?
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @param string $notice The notice name.
|
||||
* @return bool
|
||||
*/
|
||||
protected function can_display_notice( $notice ) {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( empty( $screen ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$screen_id = sanitize_title( __( 'Languages', 'polylang' ) );
|
||||
|
||||
/**
|
||||
* Filter admin notices which can be displayed
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param bool $display Whether the notice should be displayed or not.
|
||||
* @param string $notice The notice name.
|
||||
*/
|
||||
return apply_filters(
|
||||
'pll_can_display_notice',
|
||||
in_array(
|
||||
$screen->id,
|
||||
array(
|
||||
'dashboard',
|
||||
'plugins',
|
||||
'toplevel_page_mlang',
|
||||
$screen_id . '_page_mlang_strings',
|
||||
$screen_id . '_page_mlang_settings',
|
||||
)
|
||||
),
|
||||
$notice
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a dismissed notice in the database.
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @param string $notice Notice name.
|
||||
* @return void
|
||||
*/
|
||||
public static function dismiss( $notice ) {
|
||||
$dismissed = get_option( 'pll_dismissed_notices', array() );
|
||||
|
||||
if ( ! in_array( $notice, $dismissed ) ) {
|
||||
$dismissed[] = $notice;
|
||||
update_option( 'pll_dismissed_notices', array_unique( $dismissed ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a click on the dismiss button
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hide_notice() {
|
||||
if ( isset( $_GET['pll-hide-notice'], $_GET['_pll_notice_nonce'] ) ) {
|
||||
$notice = sanitize_key( $_GET['pll-hide-notice'] );
|
||||
check_admin_referer( $notice, '_pll_notice_nonce' );
|
||||
self::dismiss( $notice );
|
||||
wp_safe_redirect( remove_query_arg( array( 'pll-hide-notice', '_pll_notice_nonce' ), wp_get_referer() ) );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays notices
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function display_notices() {
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
// Core notices
|
||||
if ( defined( 'WOOCOMMERCE_VERSION' ) && ! defined( 'PLLWC_VERSION' ) && $this->can_display_notice( 'pllwc' ) && ! $this->is_dismissed( 'pllwc' ) ) {
|
||||
$this->pllwc_notice();
|
||||
}
|
||||
|
||||
if ( ! defined( 'POLYLANG_PRO' ) && $this->can_display_notice( 'review' ) && ! $this->is_dismissed( 'review' ) && ! empty( $this->options['first_activation'] ) && time() > $this->options['first_activation'] + 15 * DAY_IN_SECONDS ) {
|
||||
$this->review_notice();
|
||||
}
|
||||
|
||||
// Custom notices
|
||||
foreach ( $this->get_notices() as $notice => $html ) {
|
||||
if ( $this->can_display_notice( $notice ) && ! $this->is_dismissed( $notice ) ) {
|
||||
?>
|
||||
<div class="pll-notice notice notice-info">
|
||||
<?php
|
||||
$this->dismiss_button( $notice );
|
||||
echo wp_kses_post( $html );
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a dismiss button
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @param string $name Notice name
|
||||
* @return void
|
||||
*/
|
||||
public function dismiss_button( $name ) {
|
||||
printf(
|
||||
'<a class="notice-dismiss" href="%s"><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( wp_nonce_url( add_query_arg( 'pll-hide-notice', $name ), $name, '_pll_notice_nonce' ) ),
|
||||
/* translators: accessibility text */
|
||||
esc_html__( 'Dismiss this notice.', 'polylang' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a notice if WooCommerce is activated without Polylang for WooCommerce
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function pllwc_notice() {
|
||||
?>
|
||||
<div class="pll-notice notice notice-warning">
|
||||
<?php $this->dismiss_button( 'pllwc' ); ?>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
||||
esc_html__( 'We have noticed that you are using Polylang with WooCommerce. To ensure compatibility, we recommend you use %1$sPolylang for WooCommerce%2$s.', 'polylang' ),
|
||||
'<a href="https://polylang.pro/downloads/polylang-for-woocommerce/">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a notice asking for a review
|
||||
*
|
||||
* @since 2.3.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function review_notice() {
|
||||
?>
|
||||
<div class="pll-notice notice notice-info">
|
||||
<?php $this->dismiss_button( 'review' ); ?>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
||||
esc_html__( 'We have noticed that you have been using Polylang for some time. We hope you love it, and we would really appreciate it if you would %1$sgive us a 5 stars rating%2$s.', 'polylang' ),
|
||||
'<a href="https://wordpress.org/support/plugin/polylang/reviews/?rate=5#new-post">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
152
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-static-pages.php
vendored
Normal file
152
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-static-pages.php
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages the static front page and the page for posts on admin side
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
||||
/**
|
||||
* @var PLL_Admin_Links|null
|
||||
*/
|
||||
protected $links;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param object $polylang An array of attachment metadata.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->links = &$polylang->links;
|
||||
|
||||
// Add post state for translations of the front page and posts page
|
||||
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
||||
|
||||
// Refreshes the language cache when a static front page or page for for posts has been translated.
|
||||
add_action( 'pll_save_post', array( $this, 'pll_save_post' ), 10, 3 );
|
||||
|
||||
// Prevents WP resetting the option
|
||||
add_filter( 'pre_update_option_show_on_front', array( $this, 'update_show_on_front' ), 10, 2 );
|
||||
|
||||
add_action( 'admin_notices', array( $this, 'notice_must_translate' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds post state for translations of the front page and posts page.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string[] $post_states An array of post display states.
|
||||
* @param WP_Post $post The current post object.
|
||||
* @return string[]
|
||||
*/
|
||||
public function display_post_states( $post_states, $post ) {
|
||||
if ( in_array( $post->ID, $this->model->get_languages_list( array( 'fields' => 'page_on_front' ) ) ) ) {
|
||||
$post_states['page_on_front'] = __( 'Front Page', 'polylang' );
|
||||
}
|
||||
|
||||
if ( in_array( $post->ID, $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) ) ) ) {
|
||||
$post_states['page_for_posts'] = __( 'Posts Page', 'polylang' );
|
||||
}
|
||||
|
||||
return $post_states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the language cache when a static front page or page for for posts has been translated.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_id Not used.
|
||||
* @param WP_Post $post Not used.
|
||||
* @param int[] $translations Translations of the post being saved.
|
||||
* @return void
|
||||
*/
|
||||
public function pll_save_post( $post_id, $post, $translations ) {
|
||||
if ( in_array( $this->page_on_front, $translations ) || in_array( $this->page_for_posts, $translations ) ) {
|
||||
$this->model->clean_languages_cache();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents WP resetting the option if the admin language filter is active for a language with no pages.
|
||||
*
|
||||
* @since 1.9.3
|
||||
*
|
||||
* @param string $value The new, unserialized option value.
|
||||
* @param string $old_value The old option value.
|
||||
* @return string
|
||||
*/
|
||||
public function update_show_on_front( $value, $old_value ) {
|
||||
if ( ! empty( $GLOBALS['pagenow'] ) && 'options-reading.php' === $GLOBALS['pagenow'] && 'posts' === $value && ! get_pages() && get_pages( array( 'lang' => '' ) ) ) {
|
||||
$value = $old_value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a notice to translate the static front page if it is not translated in all languages
|
||||
* This is especially useful after a new language is created.
|
||||
* The notice is not dismissible and displayed on the Languages pages and the list of pages.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function notice_must_translate() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( ! empty( $screen ) && ( 'toplevel_page_mlang' === $screen->id || 'edit-page' === $screen->id ) ) {
|
||||
$message = $this->get_must_translate_message();
|
||||
|
||||
if ( ! empty( $message ) ) {
|
||||
printf(
|
||||
'<div class="error"><p>%s</p></div>',
|
||||
$message // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message asking to translate the static front page in all languages.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_must_translate_message() {
|
||||
$message = '';
|
||||
|
||||
if ( $this->page_on_front ) {
|
||||
$untranslated = array();
|
||||
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( ! $this->model->post->get( $this->page_on_front, $language ) ) {
|
||||
$untranslated[] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $this->links->get_new_post_translation_link( $this->page_on_front, $language ) ),
|
||||
esc_html( $language->name )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $untranslated ) ) {
|
||||
$message = sprintf(
|
||||
/* translators: %s is a comma separated list of native language names */
|
||||
esc_html__( 'You must translate your static front page in %s.', 'polylang' ),
|
||||
implode( ', ', $untranslated ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
136
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-strings.php
vendored
Normal file
136
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin-strings.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* A fully static class to manage strings translations on admin side
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class PLL_Admin_Strings {
|
||||
/**
|
||||
* Stores the strings to translate.
|
||||
*
|
||||
* @var array {
|
||||
* @type string $name A unique name for the string.
|
||||
* @type string $string The actual string to translate.
|
||||
* @type string $context The group in which the string is registered.
|
||||
* @type bool $multiline Whether the string table should display a multiline textarea or a single line input.
|
||||
* }
|
||||
*/
|
||||
protected static $strings = array();
|
||||
|
||||
/**
|
||||
* The strings to register by default.
|
||||
*
|
||||
* @var string[]|null
|
||||
*/
|
||||
protected static $default_strings;
|
||||
|
||||
/**
|
||||
* Add filters
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
// default strings translations sanitization
|
||||
add_filter( 'pll_sanitize_string_translation', array( __CLASS__, 'sanitize_string_translation' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register strings for translation making sure it is not duplicate or empty
|
||||
*
|
||||
* @since 0.6
|
||||
*
|
||||
* @param string $name A unique name for the string
|
||||
* @param string $string The string to register
|
||||
* @param string $context Optional, the group in which the string is registered, defaults to 'polylang'
|
||||
* @param bool $multiline Optional, whether the string table should display a multiline textarea or a single line input, defaults to single line
|
||||
* @return void
|
||||
*/
|
||||
public static function register_string( $name, $string, $context = 'Polylang', $multiline = false ) {
|
||||
if ( $string && is_scalar( $string ) ) {
|
||||
self::$strings[ md5( $string ) ] = compact( 'name', 'string', 'context', 'multiline' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get registered strings
|
||||
*
|
||||
* @since 0.6.1
|
||||
*
|
||||
* @return array list of all registered strings
|
||||
*/
|
||||
public static function &get_strings() {
|
||||
self::$default_strings = array(
|
||||
'widget_title' => __( 'Widget title', 'polylang' ),
|
||||
'widget_text' => __( 'Widget text', 'polylang' ),
|
||||
);
|
||||
|
||||
// Widgets titles
|
||||
global $wp_registered_widgets;
|
||||
$sidebars = wp_get_sidebars_widgets();
|
||||
foreach ( $sidebars as $sidebar => $widgets ) {
|
||||
if ( 'wp_inactive_widgets' == $sidebar || empty( $widgets ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $widgets as $widget ) {
|
||||
// Nothing can be done if the widget is created using pre WP2.8 API :(
|
||||
// There is no object, so we can't access it to get the widget options
|
||||
if ( ! isset( $wp_registered_widgets[ $widget ]['callback'][0] ) || ! is_object( $wp_registered_widgets[ $widget ]['callback'][0] ) || ! method_exists( $wp_registered_widgets[ $widget ]['callback'][0], 'get_settings' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$widget_settings = $wp_registered_widgets[ $widget ]['callback'][0]->get_settings();
|
||||
$number = $wp_registered_widgets[ $widget ]['params'][0]['number'];
|
||||
|
||||
// Don't enable widget translation if the widget is visible in only one language or if there is no title
|
||||
if ( empty( $widget_settings[ $number ]['pll_lang'] ) ) {
|
||||
if ( isset( $widget_settings[ $number ]['title'] ) && $title = $widget_settings[ $number ]['title'] ) {
|
||||
self::register_string( self::$default_strings['widget_title'], $title, 'Widget' );
|
||||
}
|
||||
|
||||
if ( isset( $widget_settings[ $number ]['text'] ) && $text = $widget_settings[ $number ]['text'] ) {
|
||||
self::register_string( self::$default_strings['widget_text'], $text, 'Widget', true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the list of strings registered for translation
|
||||
* Mainly for use by our PLL_WPML_Compat class
|
||||
*
|
||||
* @since 1.0.2
|
||||
*
|
||||
* @param array $strings list of strings
|
||||
*/
|
||||
self::$strings = apply_filters( 'pll_get_strings', self::$strings );
|
||||
return self::$strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the sanitization ( before saving in DB ) of default strings translations
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param string $translation translation to sanitize
|
||||
* @param string $name unique name for the string
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_string_translation( $translation, $name ) {
|
||||
if ( $name == self::$default_strings['widget_title'] ) {
|
||||
$translation = sanitize_text_field( $translation );
|
||||
}
|
||||
|
||||
if ( $name == self::$default_strings['widget_text'] && ! current_user_can( 'unfiltered_html' ) ) {
|
||||
$translation = wp_kses_post( $translation );
|
||||
}
|
||||
|
||||
return $translation;
|
||||
}
|
||||
}
|
||||
180
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin.php
vendored
Normal file
180
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/admin.php
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main Polylang class for admin (except Polylang pages), accessible from @see PLL().
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin extends PLL_Admin_Base {
|
||||
/**
|
||||
* @var PLL_Admin_Filters|null
|
||||
*/
|
||||
public $filters;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Filters_Columns|null
|
||||
*/
|
||||
public $filters_columns;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Filters_Post|null
|
||||
*/
|
||||
public $filters_post;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Filters_Term|null
|
||||
*/
|
||||
public $filters_term;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Filters_Media|null
|
||||
*/
|
||||
public $filters_media;
|
||||
|
||||
/**
|
||||
* @since 2.9
|
||||
*
|
||||
* @var PLL_Filters_Sanitization|null
|
||||
*/
|
||||
public $filters_sanitization;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Block_Editor|null
|
||||
*/
|
||||
public $block_editor;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Classic_Editor|null
|
||||
*/
|
||||
public $classic_editor;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Nav_Menu|null
|
||||
*/
|
||||
public $nav_menu;
|
||||
|
||||
/**
|
||||
* @var PLL_Admin_Filters_Widgets_Options|null
|
||||
*/
|
||||
public $filters_widgets_options;
|
||||
|
||||
/**
|
||||
* Setups filters and action needed on all admin pages and on plugins page.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param PLL_Links_Model $links_model Reference to the links model.
|
||||
*/
|
||||
public function __construct( &$links_model ) {
|
||||
parent::__construct( $links_model );
|
||||
|
||||
// Adds a 'settings' link in the plugins table
|
||||
add_filter( 'plugin_action_links_' . POLYLANG_BASENAME, array( $this, 'plugin_action_links' ) );
|
||||
add_action( 'in_plugin_update_message-' . POLYLANG_BASENAME, array( $this, 'plugin_update_message' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups filters and action needed on all admin pages and on plugins page
|
||||
* Loads the settings pages or the filters base on the request
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
// Setup filters for admin pages
|
||||
// Priority 5 to make sure filters are there before customize_register is fired
|
||||
if ( $this->model->has_languages() ) {
|
||||
add_action( 'wp_loaded', array( $this, 'add_filters' ), 5 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a 'settings' link for our plugin in the plugins list table.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string[] $links List of links associated to the plugin.
|
||||
* @return string[] Modified list of links.
|
||||
*/
|
||||
public function plugin_action_links( $links ) {
|
||||
array_unshift( $links, '<a href="admin.php?page=mlang">' . __( 'Settings', 'polylang' ) . '</a>' );
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the upgrade notice in plugins table
|
||||
*
|
||||
* @since 1.1.6
|
||||
*
|
||||
* @param array $plugin_data Not used
|
||||
* @param object $r Plugin update data
|
||||
* @return void
|
||||
*/
|
||||
public function plugin_update_message( $plugin_data, $r ) {
|
||||
if ( ! empty( $r->upgrade_notice ) ) {
|
||||
printf( '<p style="margin: 3px 0 0 0; border-top: 1px solid #ddd; padding-top: 3px">%s</p>', esc_html( $r->upgrade_notice ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup filters for admin pages
|
||||
*
|
||||
* @since 1.2
|
||||
* @since 2.7 instantiate a PLL_Bulk_Translate instance.
|
||||
* @return void
|
||||
*/
|
||||
public function add_filters() {
|
||||
$this->filters_sanitization = new PLL_Filters_Sanitization( $this->get_locale_for_sanitization() );
|
||||
$this->filters_widgets_options = new PLL_Admin_Filters_Widgets_Options( $this );
|
||||
|
||||
// All these are separated just for convenience and maintainability
|
||||
$classes = array( 'Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Classic_Editor', 'Block_Editor' );
|
||||
|
||||
// Don't load media filters if option is disabled or if user has no right
|
||||
if ( $this->options['media_support'] && ( $obj = get_post_type_object( 'attachment' ) ) && ( current_user_can( $obj->cap->edit_posts ) || current_user_can( $obj->cap->create_posts ) ) ) {
|
||||
$classes[] = 'Filters_Media';
|
||||
}
|
||||
|
||||
foreach ( $classes as $class ) {
|
||||
$obj = strtolower( $class );
|
||||
|
||||
/**
|
||||
* Filter the class to instantiate when loading admin filters
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param string $class class name
|
||||
*/
|
||||
$class = apply_filters( 'pll_' . $obj, 'PLL_Admin_' . $class );
|
||||
$this->$obj = new $class( $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the locale according to the current language instead of the language
|
||||
* of the admin interface.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_locale_for_sanitization() {
|
||||
$locale = get_locale();
|
||||
|
||||
if ( isset( $_POST['post_lang_choice'] ) && $lang = $this->model->get_language( sanitize_key( $_POST['post_lang_choice'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$locale = $lang->locale;
|
||||
} elseif ( isset( $_POST['term_lang_choice'] ) && $lang = $this->model->get_language( sanitize_key( $_POST['term_lang_choice'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$locale = $lang->locale;
|
||||
} elseif ( isset( $_POST['inline_lang_choice'] ) && $lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$locale = $lang->locale;
|
||||
} elseif ( ! empty( $this->curlang ) ) {
|
||||
$locale = $this->curlang->locale;
|
||||
}
|
||||
|
||||
return $locale;
|
||||
}
|
||||
}
|
||||
43
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/view-translations-media.php
vendored
Normal file
43
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/view-translations-media.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Displays the translations fields for media
|
||||
* Needs WP 3.5+
|
||||
*
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Don't access directly
|
||||
}
|
||||
?>
|
||||
<p><strong><?php esc_html_e( 'Translations', 'polylang' ); ?></strong></p>
|
||||
<table>
|
||||
<?php
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( $language->term_id == $lang->term_id ) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class = "pll-media-language-column"><span class = "pll-translation-flag"><?php echo $language->flag; // phpcs:ignore WordPress.Security.EscapeOutput ?></span><?php echo esc_html( $language->name ); ?></td>
|
||||
<td class = "pll-media-edit-column">
|
||||
<?php
|
||||
if ( ( $translation_id = $this->model->post->get_translation( $post_ID, $language ) ) && $translation_id !== $post_ID ) {
|
||||
// The translation exists
|
||||
printf(
|
||||
'<input type="hidden" name="media_tr_lang[%s]" value="%d" />',
|
||||
esc_attr( $language->slug ),
|
||||
esc_attr( $translation_id )
|
||||
);
|
||||
echo $this->links->edit_post_translation_link( $translation_id ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
} else {
|
||||
// No translation
|
||||
echo $this->links->new_post_translation_link( $post_ID, $language ); // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // End foreach
|
||||
?>
|
||||
</table>
|
||||
69
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/view-translations-post.php
vendored
Normal file
69
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/view-translations-post.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Displays the translations fields for posts
|
||||
*
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
?>
|
||||
<p><strong><?php esc_html_e( 'Translations', 'polylang' ); ?></strong></p>
|
||||
<table>
|
||||
<?php
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( $language->term_id === $lang->term_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$translation_id = $this->model->post->get_translation( $post_ID, $language );
|
||||
if ( ! $translation_id || $translation_id === $post_ID ) { // $translation_id == $post_ID happens if the post has been (auto)saved before changing the language.
|
||||
$translation_id = 0;
|
||||
}
|
||||
|
||||
if ( ! empty( $from_post_id ) ) {
|
||||
$translation_id = $this->model->post->get( $from_post_id, $language );
|
||||
}
|
||||
|
||||
$add_link = $this->links->new_post_translation_link( $post_ID, $language );
|
||||
$link = $add_link;
|
||||
$translation = null;
|
||||
if ( $translation_id ) {
|
||||
$translation = get_post( $translation_id );
|
||||
$link = $this->links->edit_post_translation_link( $translation_id );
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th class = "pll-language-column"><?php echo $language->flag ? $language->flag : esc_html( $language->slug ); // phpcs:ignore WordPress.Security.EscapeOutput ?></th>
|
||||
<td class = "hidden"><?php echo $add_link; // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
|
||||
<td class = "pll-edit-column pll-column-icon"><?php echo $link; // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Fires before the translation column is outputted in the language metabox.
|
||||
* The dynamic portion of the hook name, `$lang`, refers to the language code.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
do_action( 'pll_before_post_translation_' . $language->slug );
|
||||
?>
|
||||
<td class = "pll-translation-column">
|
||||
<?php
|
||||
printf(
|
||||
'<label class="screen-reader-text" for="tr_lang_%1$s">%2$s</label>
|
||||
<input type="hidden" name="post_tr_lang[%1$s]" id="htr_lang_%1$s" value="%3$s" />
|
||||
<span lang="%5$s" dir="%6$s"><input type="text" class="tr_lang" id="tr_lang_%1$s" value="%4$s" /></span>',
|
||||
esc_attr( $language->slug ),
|
||||
/* translators: accessibility text */
|
||||
esc_html__( 'Translation', 'polylang' ),
|
||||
( empty( $translation ) ? 0 : esc_attr( $translation->ID ) ),
|
||||
( empty( $translation ) ? '' : esc_attr( $translation->post_title ) ),
|
||||
esc_attr( $language->get_locale( 'display' ) ),
|
||||
( $language->is_rtl ? 'rtl' : 'ltr' )
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
98
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/view-translations-term.php
vendored
Normal file
98
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/admin/view-translations-term.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* Displays the translations fields for terms
|
||||
*
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Don't access directly
|
||||
}
|
||||
|
||||
if ( isset( $term_id ) ) {
|
||||
// Edit term form ?>
|
||||
<th scope="row"><?php esc_html_e( 'Translations', 'polylang' ); ?></th>
|
||||
<td>
|
||||
<?php
|
||||
}
|
||||
else {
|
||||
// Add term form
|
||||
?>
|
||||
<p><?php esc_html_e( 'Translations', 'polylang' ); ?></p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<table class="widefat term-translations" id="<?php echo isset( $term_id ) ? 'edit' : 'add'; ?>-term-translations">
|
||||
<?php
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( $language->term_id == $lang->term_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for any existing translation in this language
|
||||
// Take care not to propose a self link
|
||||
$translation = 0;
|
||||
if ( isset( $term_id ) && ( $translation_id = $this->model->term->get_translation( $term_id, $language ) ) && $translation_id != $term_id ) {
|
||||
$translation = get_term( $translation_id, $taxonomy );
|
||||
}
|
||||
if ( ! empty( $from_term_id ) && ( $translation_id = $this->model->term->get( $from_term_id, $language ) ) && ! $this->model->term->get_translation( $translation_id, $lang ) ) {
|
||||
$translation = get_term( $translation_id, $taxonomy );
|
||||
}
|
||||
|
||||
if ( isset( $term_id ) ) { // Do not display the add new link in add term form ( $term_id not set !!! )
|
||||
$link = $add_link = $this->links->new_term_translation_link( $term_id, $taxonomy, $post_type, $language );
|
||||
}
|
||||
|
||||
if ( $translation ) {
|
||||
$link = $this->links->edit_term_translation_link( $translation->term_id, $taxonomy, $post_type );
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th class = "pll-language-column">
|
||||
<span class = "pll-translation-flag"><?php echo $language->flag ? $language->flag : esc_html( $language->slug ); // phpcs:ignore WordPress.Security.EscapeOutput ?></span>
|
||||
<?php
|
||||
printf(
|
||||
'<span class="pll-language-name%1$s">%2$s</span>',
|
||||
isset( $term_id ) ? '' : ' screen-reader-text',
|
||||
esc_html( $language->name )
|
||||
);
|
||||
?>
|
||||
</th>
|
||||
<?php
|
||||
if ( isset( $term_id ) ) {
|
||||
?>
|
||||
<td class = "hidden"><?php echo $add_link; // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
|
||||
<td class = "pll-edit-column"><?php echo $link; // phpcs:ignore WordPress.Security.EscapeOutput ?></td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<td class = "pll-translation-column">
|
||||
<?php
|
||||
printf(
|
||||
'<label class="screen-reader-text" for="tr_lang_%1$s">%2$s</label>
|
||||
<input type="hidden" class="htr_lang" name="term_tr_lang[%1$s]" id="htr_lang_%1$s" value="%3$s" />
|
||||
<span lang="%6$s" dir="%7$s"><input type="text" class="tr_lang" id="tr_lang_%1$s" value="%4$s"%5$s /></span>',
|
||||
esc_attr( $language->slug ),
|
||||
/* translators: accessibility text */
|
||||
esc_html__( 'Translation', 'polylang' ),
|
||||
( empty( $translation ) ? 0 : esc_attr( $translation->term_id ) ),
|
||||
( empty( $translation ) ? '' : esc_attr( $translation->name ) ),
|
||||
disabled( empty( $disabled ), false, false ),
|
||||
esc_attr( $language->get_locale( 'display' ) ),
|
||||
( $language->is_rtl ? 'rtl' : 'ltr' )
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // End foreach
|
||||
?>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
if ( isset( $term_id ) ) {
|
||||
// Edit term form
|
||||
?>
|
||||
</td>
|
||||
<?php
|
||||
}
|
||||
Reference in New Issue
Block a user