Traduction
370
pole-sbv-content/plugins/polylang/admin/admin-base.php
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Base class for both admin
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
class PLL_Admin_Base extends PLL_Base {
|
||||
public $filter_lang, $curlang, $pref_lang;
|
||||
|
||||
/**
|
||||
* Loads the polylang text domain
|
||||
* Setups actions needed on all admin pages
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param object $links_model
|
||||
*/
|
||||
public function __construct( &$links_model ) {
|
||||
parent::__construct( $links_model );
|
||||
|
||||
// Plugin i18n, only needed for backend
|
||||
load_plugin_textdomain( 'polylang', false, basename( POLYLANG_DIR ) . '/languages' );
|
||||
|
||||
// Adds the link to the languages panel in the WordPress admin menu
|
||||
add_action( 'admin_menu', array( $this, 'add_menus' ) );
|
||||
|
||||
// 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
|
||||
|
||||
// Lingotek
|
||||
if ( ! defined( 'PLL_LINGOTEK_AD' ) || PLL_LINGOTEK_AD ) {
|
||||
require_once POLYLANG_DIR . '/lingotek/lingotek.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
if ( ! $this->model->get_languages_list() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
|
||||
$this->static_pages = new PLL_Admin_Static_Pages( $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_filter( '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
|
||||
*/
|
||||
public function add_menus() {
|
||||
// Prepare the list of tabs
|
||||
$tabs = array( 'lang' => __( 'Languages','polylang' ) );
|
||||
|
||||
// Only if at least one language has been created
|
||||
if ( $this->model->get_languages_list() ) {
|
||||
$tabs['strings'] = __( '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 );
|
||||
|
||||
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, null , 'dashicons-translation' );
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
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 => 1 if loaded even if languages have not been defined yet, 0 otherwise
|
||||
// 3 => 1 if loaded in footer
|
||||
// FIXME: check if I can load more scripts in footer
|
||||
$scripts = array(
|
||||
'post' => array( array( 'post', 'media', 'async-upload', 'edit' ), array( 'jquery', 'wp-ajax-response', 'post', 'jquery-ui-autocomplete' ), 0, 1 ),
|
||||
'media' => array( array( 'upload' ), array( 'jquery' ), 0, 1 ),
|
||||
'term' => array( array( 'edit-tags', 'term' ), array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), 0, 1 ),
|
||||
'user' => array( array( 'profile', 'user-edit' ), array( 'jquery' ), 0, 0 ),
|
||||
);
|
||||
|
||||
foreach ( $scripts as $script => $v ) {
|
||||
if ( in_array( $screen->base, $v[0] ) && ( $v[2] || $this->model->get_languages_list() ) ) {
|
||||
wp_enqueue_script( 'pll_' . $script, plugins_url( '/js/' . $script . $suffix . '.js', POLYLANG_FILE ), $v[1], POLYLANG_VERSION, $v[3] );
|
||||
}
|
||||
}
|
||||
|
||||
wp_enqueue_style( 'polylang_admin', plugins_url( '/css/admin' . $suffix . '.css', POLYLANG_FILE ), array(), POLYLANG_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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 ) );
|
||||
}
|
||||
|
||||
$str = http_build_query( $params );
|
||||
$arr = json_encode( $params );
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
if (typeof jQuery != 'undefined') {
|
||||
(function($){
|
||||
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
|
||||
if ( -1 != options.url.indexOf( ajaxurl ) || -1 != ajaxurl.indexOf( options.url ) ) {
|
||||
if ( 'undefined' === typeof options.data ) {
|
||||
options.data = ( 'get' === options.type.toLowerCase() ) ? '<?php echo $str; ?>' : <?php echo $arr; ?>;
|
||||
} else {
|
||||
if ( 'string' === typeof options.data ) {
|
||||
if ( '' === options.data && 'get' === options.type.toLowerCase() ) {
|
||||
options.url = options.url+'&<?php echo $str; ?>';
|
||||
} else {
|
||||
try {
|
||||
o = $.parseJSON(options.data);
|
||||
o = $.extend(o, <?php echo $arr; ?>);
|
||||
options.data = JSON.stringify(o);
|
||||
}
|
||||
catch(e) {
|
||||
options.data = '<?php echo $str; ?>&'+options.data;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
options.data = $.extend(options.data, <?php echo $arr; ?>);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})(jQuery)
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the admin current language, used to filter the content
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function set_current_language() {
|
||||
$this->curlang = $this->filter_lang;
|
||||
|
||||
// POST
|
||||
if ( isset( $_POST['post_lang_choice'] ) && $lang = $this->model->get_language( $_POST['post_lang_choice'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
} elseif ( isset( $_POST['term_lang_choice'] ) && $lang = $this->model->get_language( $_POST['term_lang_choice'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
} elseif ( isset( $_POST['inline_lang_choice'] ) && $lang = $this->model->get_language( $_POST['inline_lang_choice'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
}
|
||||
|
||||
// Edit Post
|
||||
if ( isset( $_REQUEST['pll_post_id'] ) && $lang = $this->model->post->get_language( (int) $_REQUEST['pll_post_id'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
} elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_GET['post'] ) && is_numeric( $_GET['post'] ) && $lang = $this->model->post->get_language( (int) $_GET['post'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
} elseif ( 'post-new.php' === $GLOBALS['pagenow'] && ( empty( $_GET['post_type'] ) || $this->model->is_translated_post_type( $_GET['post_type'] ) ) ) {
|
||||
$this->curlang = empty( $_GET['new_lang'] ) ? $this->pref_lang : $this->model->get_language( $_GET['new_lang'] );
|
||||
}
|
||||
|
||||
// Edit Term
|
||||
// FIXME 'edit-tags.php' for backward compatibility with WP < 4.5
|
||||
elseif ( in_array( $GLOBALS['pagenow'], array( 'edit-tags.php', 'term.php' ) ) && isset( $_GET['tag_ID'] ) && $lang = $this->model->term->get_language( (int) $_GET['tag_ID'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
} elseif ( isset( $_REQUEST['pll_term_id'] ) && $lang = $this->model->term->get_language( (int) $_REQUEST['pll_term_id'] ) ) {
|
||||
$this->curlang = $lang;
|
||||
} elseif ( 'edit-tags.php' === $GLOBALS['pagenow'] && isset( $_GET['taxonomy'] ) && $this->model->is_translated_taxonomy( $_GET['taxonomy'] ) ) {
|
||||
if ( ! empty( $_GET['new_lang'] ) ) {
|
||||
$this->curlang = $this->model->get_language( $_GET['new_lang'] );
|
||||
} elseif ( empty( $this->curlang ) ) {
|
||||
$this->curlang = $this->pref_lang;
|
||||
}
|
||||
}
|
||||
|
||||
// Ajax
|
||||
if ( wp_doing_ajax() && ! empty( $_REQUEST['lang'] ) ) {
|
||||
$this->curlang = $this->model->get_language( $_REQUEST['lang'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the backend language and the admin language filter based on user preferences
|
||||
*
|
||||
* @since 1.2.3
|
||||
*/
|
||||
public function init_user() {
|
||||
// Backend locale
|
||||
// FIXME: Backward compatibility with WP < 4.7
|
||||
if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
|
||||
add_filter( 'locale', array( $this, 'get_locale' ) );
|
||||
}
|
||||
|
||||
// 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
|
||||
if ( ! wp_doing_ajax() && ! empty( $_GET['lang'] ) && ! is_numeric( $_GET['lang'] ) && current_user_can( 'edit_user', $user_id = get_current_user_id() ) ) {
|
||||
update_user_meta( $user_id, 'pll_filter_content', ( $lang = $this->model->get_language( $_GET['lang'] ) ) ? $lang->slug : '' );
|
||||
}
|
||||
|
||||
$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_language( $this->options['default_lang'] ) : $this->filter_lang;
|
||||
|
||||
/**
|
||||
* Filter the preferred language on amin side
|
||||
* The preferred language is used for example to determine the language of a new post
|
||||
*
|
||||
* @since 1.2.3
|
||||
*
|
||||
* @param object $pref_lang preferred language
|
||||
*/
|
||||
$this->pref_lang = apply_filters( 'pll_admin_preferred_language', $this->pref_lang );
|
||||
|
||||
$this->set_current_language();
|
||||
|
||||
// Inform that the admin language has been set
|
||||
// Only if the admin language is one of the Polylang defined language
|
||||
// FIXME test get_user_locale for backward compatibility with WP 4.7
|
||||
if ( $curlang = $this->model->get_language( function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale() ) ) {
|
||||
// FIXME: Backward compatibility with WP < 4.7
|
||||
if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
|
||||
$GLOBALS['text_direction'] = $curlang->is_rtl ? 'rtl' : 'ltr'; // force text direction according to language setting
|
||||
}
|
||||
|
||||
/** This action is documented in frontend/choose-lang.php */
|
||||
do_action( 'pll_language_defined', $curlang->slug, $curlang );
|
||||
} else {
|
||||
/** This action is documented in include/class-polylang.php */
|
||||
do_action( 'pll_no_language_defined' ); // to load overriden textdomains
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 the suggestion of @boonebgorges, https://core.trac.wordpress.org/ticket/31246
|
||||
*
|
||||
* @since 1.6.5
|
||||
*
|
||||
* @param array $qvars
|
||||
* @return array
|
||||
*/
|
||||
public function request( $qvars ) {
|
||||
if ( isset( $qvars['lang'] ) && 'all' === $qvars['lang'] ) {
|
||||
unset( $qvars['lang'] );
|
||||
}
|
||||
|
||||
return $qvars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale based on user preference
|
||||
* FIXME: Backward compatibility with WP < 4.7
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param string $locale
|
||||
* @return string modified locale
|
||||
*/
|
||||
public function get_locale( $locale ) {
|
||||
return ( $loc = get_user_meta( get_current_user_id(), 'locale', 'true' ) ) ? $loc : $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the languages list in admin bar for the admin languages filter
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param object $wp_admin_bar
|
||||
*/
|
||||
public function admin_bar_menu( $wp_admin_bar ) {
|
||||
$url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
|
||||
$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>',
|
||||
'all' === $selected->slug ? '' : sprintf( ' lang="%s"', esc_attr( $selected->get_locale( 'display' ) ) ),
|
||||
__( 'Filters content by language', 'polylang' ),
|
||||
esc_html( $selected->name )
|
||||
);
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'languages',
|
||||
'title' => $selected->flag . $title,
|
||||
'href' => esc_url( add_query_arg( 'lang', $selected->slug, remove_query_arg( 'paged', $url ) ) ),
|
||||
'meta' => array( 'title' => __( 'Filters content by language', 'polylang' ) ),
|
||||
) );
|
||||
|
||||
foreach ( array_merge( array( $all_item ), $this->model->get_languages_list() ) 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', $url ) ) ),
|
||||
'meta' => 'all' === $lang->slug ? array() : array( 'lang' => esc_attr( $lang->get_locale( 'display' ) ) ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
public $links, $model, $filter_lang;
|
||||
|
||||
/**
|
||||
* constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links = &$polylang->links;
|
||||
$this->model = &$polylang->model;
|
||||
$this->filter_lang = &$polylang->filter_lang;
|
||||
|
||||
// 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' ), 10, 2 );
|
||||
add_filter( 'bulk_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 );
|
||||
|
||||
// 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 array $columns List of table columns
|
||||
* @param string $before The column before which we want to add our languages
|
||||
* @return array 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 ) {
|
||||
// don't add the column for the filtered language
|
||||
if ( empty( $this->filter_lang ) || $language->slug != $this->filter_lang->slug ) {
|
||||
$columns[ 'language_' . $language->slug ] = $language->flag ? $language->flag . '<span class="screen-reader-text">' . esc_html( $language->name ) . '</span>' : esc_html( $language->slug );
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( empty( $this->filter_lang ) || $language->slug != $this->filter_lang->slug ) {
|
||||
$columns[] = 'language_' . $language->slug;
|
||||
}
|
||||
}
|
||||
|
||||
return empty( $columns ) ? '' : reset( $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* adds the language and translations columns ( before the comments column ) in the posts, pages and media library tables
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param array $columns list of posts table columns
|
||||
* @return array modified list of columns
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public function post_column( $column, $post_id ) {
|
||||
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save' === $_REQUEST['action'];
|
||||
$lang = $inline ? $this->model->get_language( $_POST['inline_lang_choice'] ) : $this->model->post->get_language( $post_id );
|
||||
|
||||
if ( false === strpos( $column, 'language_' ) || ! $lang ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$language = $this->model->get_language( substr( $column, 9 ) );
|
||||
|
||||
// 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 ) );
|
||||
}
|
||||
|
||||
$post_type_object = get_post_type_object( get_post_type( $post_id ) );
|
||||
|
||||
// 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 ) ) {
|
||||
if ( $id === $post_id ) {
|
||||
$class = 'pll_icon_tick';
|
||||
/* 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 );
|
||||
}
|
||||
printf(
|
||||
'<a class="%1$s" title="%2$s" href="%3$s"><span class="screen-reader-text">%4$s</span></a>',
|
||||
esc_attr( $class ), esc_attr( get_post( $id )->post_title ), esc_url( $link ), esc_html( $s )
|
||||
);
|
||||
} elseif ( $id === $post_id ) {
|
||||
printf(
|
||||
'<span class="pll_icon_tick"><span class="screen-reader-text">%s</span></span>',
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'This item is in %s', 'polylang' ), $language->name ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
// link to add a new translation
|
||||
else {
|
||||
echo $this->links->new_post_translation_link( $post_id, $language );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* quick edit & bulk edit
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param string $column column name
|
||||
* @param string $type either 'edit-tags' for terms list table or post type for posts list table
|
||||
* @return string unmodified $column
|
||||
*/
|
||||
public function quick_edit_custom_box( $column, $type ) {
|
||||
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 —' ) ) );
|
||||
}
|
||||
|
||||
$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, array( 'name' => 'inline_lang_choice', 'id' => '' ) )
|
||||
);
|
||||
}
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds the language column ( before the posts column ) in the 'Categories' or 'Post Tags' table
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param array $columns list of terms table columns
|
||||
* @return array modified list of columns
|
||||
*/
|
||||
public function add_term_column( $columns ) {
|
||||
return $this->add_column( $columns, 'posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* fills the language column in the 'Categories' or 'Post Tags' table
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string $out
|
||||
* @param string $column Column name
|
||||
* @param int $term_id
|
||||
*/
|
||||
public function term_column( $out, $column, $term_id ) {
|
||||
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save-tax' === $_REQUEST['action'];
|
||||
if ( false === strpos( $column, 'language_' ) || ! ( $lang = $inline ? $this->model->get_language( $_POST['inline_lang_choice'] ) : $this->model->term->get_language( $term_id ) ) ) {
|
||||
return $out;
|
||||
}
|
||||
|
||||
$post_type = isset( $GLOBALS['post_type'] ) ? $GLOBALS['post_type'] : $_REQUEST['post_type']; // 2nd case for quick edit
|
||||
$taxonomy = isset( $GLOBALS['taxonomy'] ) ? $GLOBALS['taxonomy'] : $_REQUEST['taxonomy'];
|
||||
|
||||
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
||||
return $out;
|
||||
}
|
||||
|
||||
$term_id = (int) $term_id;
|
||||
$language = $this->model->get_language( substr( $column, 9 ) );
|
||||
|
||||
if ( $column == $this->get_first_language_column() ) {
|
||||
$out = sprintf( '<div class="hidden" id="lang_%d">%s</div>', intval( $term_id ), esc_html( $lang->slug ) );
|
||||
|
||||
// identify the default categories to disable the language dropdown in js
|
||||
if ( in_array( get_option( 'default_category' ), $this->model->term->get_translations( $term_id ) ) ) {
|
||||
$out .= sprintf( '<div class="hidden" id="default_cat_%1$d">%1$d</div>', intval( $term_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
// link to edit term ( or a translation )
|
||||
if ( ( $id = $this->model->term->get( $term_id, $language ) ) && $term = get_term( $id, $taxonomy ) ) {
|
||||
if ( $link = get_edit_term_link( $id, $taxonomy, $post_type ) ) {
|
||||
if ( $id === $term_id ) {
|
||||
$class = 'pll_icon_tick';
|
||||
/* 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></a>',
|
||||
$class, esc_attr( $term->name ), esc_url( $link ), esc_html( $s )
|
||||
);
|
||||
} elseif ( $id === $term_id ) {
|
||||
$out .= printf(
|
||||
'<span class="pll_icon_tick"><span class="screen-reader-text">%s</span></span>',
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'This item is in %s', 'polylang' ), $language->name ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
*/
|
||||
public function ajax_update_post_rows() {
|
||||
global $wp_list_table;
|
||||
|
||||
if ( ! post_type_exists( $post_type = $_POST['post_type'] ) || ! $this->model->is_translated_post_type( $post_type ) ) {
|
||||
die( 0 );
|
||||
}
|
||||
|
||||
check_ajax_referer( 'inlineeditnonce', '_pll_nonce' );
|
||||
|
||||
$x = new WP_Ajax_Response();
|
||||
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
|
||||
|
||||
$translations = empty( $_POST['translations'] ) ? array() : explode( ',', $_POST['translations'] ); // collect old translations
|
||||
$translations = array_merge( $translations, array( $_POST['post_id'] ) ); // add current post
|
||||
$translations = array_map( 'intval', $translations );
|
||||
|
||||
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
|
||||
*/
|
||||
public function ajax_update_term_rows() {
|
||||
global $wp_list_table;
|
||||
|
||||
if ( ! taxonomy_exists( $taxonomy = $_POST['taxonomy'] ) || ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
||||
die( 0 );
|
||||
}
|
||||
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$x = new WP_Ajax_Response();
|
||||
$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
|
||||
|
||||
$translations = empty( $_POST['translations'] ) ? array() : explode( ',', $_POST['translations'] ); // collect old translations
|
||||
$translations = array_merge( $translations, $this->model->term->get_translations( (int) $_POST['term_id'] ) ); // add current translations
|
||||
$translations = array_unique( $translations ); // remove doublons
|
||||
$translations = array_map( 'intval', $translations );
|
||||
|
||||
foreach ( $translations as $term_id ) {
|
||||
$level = is_taxonomy_hierarchical( $taxonomy ) ? count( get_ancestors( $term_id, $taxonomy ) ) : 0;
|
||||
if ( $tag = get_term( $term_id, $taxonomy ) ) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
195
pole-sbv-content/plugins/polylang/admin/admin-filters-media.php
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
// 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_action( 'add_attachment', array( $this, 'set_default_language' ) );
|
||||
add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
|
||||
add_filter( 'wp_delete_file', array( $this, 'wp_delete_file' ) );
|
||||
|
||||
// Creates a media translation
|
||||
if ( isset( $_GET['action'], $_GET['new_lang'], $_GET['from_media'] ) && 'translate_media' === $_GET['action'] ) {
|
||||
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 object $post
|
||||
* @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(), array(
|
||||
'name' => sprintf( 'attachments[%d][language]', $post_id ),
|
||||
'class' => 'media_lang_choice',
|
||||
'selected' => $lang ? $lang->slug : '',
|
||||
) ),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a media translation
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param string|object $lang
|
||||
* @return int id of the translated media
|
||||
*/
|
||||
public function create_media_translation( $post_id, $lang ) {
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( empty( $post ) ) {
|
||||
return $post;
|
||||
}
|
||||
|
||||
$lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug
|
||||
|
||||
// Create a new attachment ( translate attachment parent if exists )
|
||||
$post->ID = null; // Will force the creation
|
||||
$post->post_parent = ( $post->post_parent && $tr_parent = $this->model->post->get_translation( $post->post_parent, $lang->slug ) ) ? $tr_parent : 0;
|
||||
$post->tax_input = array( 'language' => array( $lang->slug ) ); // Assigns the language
|
||||
$tr_id = wp_insert_attachment( $post );
|
||||
|
||||
// Copy metadata, attached file and alternative text
|
||||
foreach ( array( '_wp_attachment_metadata', '_wp_attached_file', '_wp_attachment_image_alt' ) as $key ) {
|
||||
if ( $meta = get_post_meta( $post_id, $key , true ) ) {
|
||||
add_post_meta( $tr_id, $key, $meta );
|
||||
}
|
||||
}
|
||||
|
||||
$this->model->post->set_language( $tr_id, $lang );
|
||||
|
||||
$translations = $this->model->post->get_translations( $post_id );
|
||||
if ( ! $translations && $src_lang = $this->model->post->get_language( $post_id ) ) {
|
||||
$translations[ $src_lang->slug ] = $post_id;
|
||||
}
|
||||
|
||||
$translations[ $lang->slug ] = $tr_id;
|
||||
$this->model->post->save_translations( $tr_id, $translations );
|
||||
|
||||
/**
|
||||
* Fires after a media translation is created
|
||||
*
|
||||
* @since 1.6.4
|
||||
*
|
||||
* @param int $post_id post id of the source media
|
||||
* @param int $tr_id post id of the new media translation
|
||||
* @param string $slug language code of the new translation
|
||||
*/
|
||||
do_action( 'pll_translate_media', $post_id, $tr_id, $lang->slug );
|
||||
return $tr_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a media translation
|
||||
*
|
||||
* @since 0.9
|
||||
*/
|
||||
public function translate_media() {
|
||||
// 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, $_GET['new_lang'] ) || ! get_post( $post_id ) ) {
|
||||
wp_safe_redirect( wp_get_referer() );
|
||||
exit;
|
||||
}
|
||||
|
||||
$tr_id = $this->create_media_translation( $post_id, $_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
|
||||
* @param array $attachment
|
||||
* @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'] ) ) {
|
||||
$this->model->post->set_language( $post['ID'], $attachment['language'] );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['media_tr_lang'] ) ) {
|
||||
$this->save_translations( $post['ID'], $_POST['media_tr_lang'] );
|
||||
}
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents WP deleting files when there are still media using them
|
||||
* Thanks to Bruno "Aesqe" Babic and its plugin file gallery in which I took all the ideas for this function
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param string $file
|
||||
* @return string unmodified $file
|
||||
*/
|
||||
public function wp_delete_file( $file ) {
|
||||
global $wpdb;
|
||||
|
||||
$uploadpath = wp_upload_dir();
|
||||
|
||||
$ids = $wpdb->get_col( $wpdb->prepare( "
|
||||
SELECT post_id FROM $wpdb->postmeta
|
||||
WHERE meta_key = '_wp_attached_file' AND meta_value = '%s'",
|
||||
substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) )
|
||||
) );
|
||||
|
||||
if ( ! empty( $ids ) ) {
|
||||
// Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before )
|
||||
wp_update_attachment_metadata( $ids[0], wp_generate_attachment_metadata( $ids[0], $file ) );
|
||||
return ''; // Prevent deleting the main file
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* some common code for PLL_Admin_Filters_Post and PLL_Admin_Filters_Media
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
abstract class PLL_Admin_Filters_Post_Base {
|
||||
public $links, $model, $pref_lang;
|
||||
|
||||
/**
|
||||
* constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links = &$polylang->links;
|
||||
$this->model = &$polylang->model;
|
||||
$this->pref_lang = &$polylang->pref_lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* allows to set a language by default for posts if it has no language yet
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public function set_default_language( $post_id ) {
|
||||
if ( ! $this->model->post->get_language( $post_id ) ) {
|
||||
if ( isset( $_GET['new_lang'] ) && $lang = $this->model->get_language( $_GET['new_lang'] ) ) {
|
||||
$this->model->post->set_language( $post_id, $lang );
|
||||
}
|
||||
|
||||
elseif ( ( $parent_id = wp_get_post_parent_id( $post_id ) ) && $parent_lang = $this->model->post->get_language( $parent_id ) ) {
|
||||
$this->model->post->set_language( $post_id, $parent_lang );
|
||||
}
|
||||
|
||||
else {
|
||||
$this->model->post->set_language( $post_id, $this->pref_lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save translations from language metabox
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param array $arr
|
||||
* @return array
|
||||
*/
|
||||
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' );
|
||||
|
||||
// save translations after checking the translated post is in the right language
|
||||
foreach ( $arr as $lang => $tr_id ) {
|
||||
$translations[ $lang ] = ( $tr_id && $this->model->post->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
|
||||
}
|
||||
|
||||
$this->model->post->save_translations( $post_id, $translations );
|
||||
return $translations;
|
||||
}
|
||||
}
|
||||
546
pole-sbv-content/plugins/polylang/admin/admin-filters-post.php
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to posts on admin side
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
||||
public $options, $curlang;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
$this->options = &$polylang->options;
|
||||
$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 the Languages box in the 'Edit Post' and 'Edit Page' panels
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 );
|
||||
|
||||
// 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' ) );
|
||||
|
||||
// Adds actions and filters related to languages when creating, saving or deleting posts and pages
|
||||
add_action( 'save_post', array( $this, 'save_post' ), 21, 3 ); // Priority 21 to come after advanced custom fields ( 20 ) and before the event calendar which breaks everything after 25
|
||||
add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 4 );
|
||||
add_action( 'before_delete_post', array( $this, 'delete_post' ) );
|
||||
if ( $this->options['media_support'] ) {
|
||||
add_action( 'delete_attachment', array( $this, 'delete_post' ) ); // Action shared with media
|
||||
}
|
||||
|
||||
// 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 );
|
||||
|
||||
// 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
|
||||
*/
|
||||
public function admin_enqueue_scripts() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Hierarchical taxonomies
|
||||
if ( 'edit' == $screen->base && $taxonomies = get_object_taxonomies( $screen->post_type, 'object' ) ) {
|
||||
// Get translated hierarchical taxonomies
|
||||
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( $hierarchical_taxonomies, array( 'get' => 'all' ) );
|
||||
|
||||
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();
|
||||
|
||||
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 object $query a WP_Query object
|
||||
*/
|
||||
public function parse_query( $query ) {
|
||||
$pll_query = new PLL_Query( $query, $this->model );
|
||||
$pll_query->filter_query( $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param object $post Current post
|
||||
*/
|
||||
public function add_meta_boxes( $post_type, $post ) {
|
||||
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
||||
add_meta_box( 'ml_box', __( 'Languages','polylang' ), array( $this, 'post_language' ), $post_type, 'side', 'high' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the Languages metabox in the 'Edit Post' and 'Edit Page' panels
|
||||
*
|
||||
* @since 0.1
|
||||
*/
|
||||
public function post_language() {
|
||||
global $post_ID;
|
||||
$post_id = $post_ID;
|
||||
$post_type = get_post_type( $post_ID );
|
||||
|
||||
$lang = ( $lg = $this->model->post->get_language( $post_ID ) ) ? $lg :
|
||||
( isset( $_GET['new_lang'] ) ? $this->model->get_language( $_GET['new_lang'] ) :
|
||||
$this->pref_lang );
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
|
||||
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' ),
|
||||
$id = ( 'attachment' === $post_type ) ? sprintf( 'attachments[%d][language]', $post_ID ) : 'post_lang_choice',
|
||||
'attachment' === $post_type ? 'media' : 'post',
|
||||
$dropdown->walk( $this->model->get_languages_list(), array(
|
||||
'name' => $id,
|
||||
'class' => 'post_lang_choice tags-input',
|
||||
'selected' => $lang ? $lang->slug : '',
|
||||
'flag' => true,
|
||||
) )
|
||||
);
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
include PLL_ADMIN_INC . '/view-translations-' . ( 'attachment' == $post_type ? 'media' : 'post' ) . '.php';
|
||||
}
|
||||
echo '</div>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax response for changing the language in the post metabox
|
||||
*
|
||||
* @since 0.2
|
||||
*/
|
||||
public function post_lang_choice() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
|
||||
$post_id = $post_ID = (int) $_POST['post_id'];
|
||||
$lang = $this->model->get_language( $_POST['lang'] );
|
||||
|
||||
$post_type = $_POST['post_type'];
|
||||
$post_type_object = get_post_type_object( $post_type );
|
||||
if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
|
||||
wp_die( -1 );
|
||||
}
|
||||
|
||||
$this->model->post->set_language( $post_ID, $lang ); // Save language, useful to set the language when uploading media from post
|
||||
|
||||
ob_start();
|
||||
if ( $lang ) {
|
||||
include PLL_ADMIN_INC . '/view-translations-' . ( 'attachment' == $post_type ? 'media' : '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
|
||||
foreach ( $_POST['taxonomies'] as $taxname ) {
|
||||
$taxonomy = get_taxonomy( $taxname );
|
||||
|
||||
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 ckecked 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 );
|
||||
|
||||
// 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)' ),
|
||||
'sort_column' => 'menu_order, post_title',
|
||||
'echo' => 0,
|
||||
);
|
||||
|
||||
/** This filter is documented in wp-admin/includes/meta-boxes.php */
|
||||
$dropdown_args = apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post ); // Since WP 3.3
|
||||
|
||||
$x->Add( array( 'what' => 'pages', 'data' => wp_dropdown_pages( $dropdown_args ) ) );
|
||||
}
|
||||
|
||||
// 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
|
||||
*/
|
||||
public function ajax_posts_not_translated() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
if ( ! post_type_exists( $_GET['post_type'] ) ) {
|
||||
die( 0 );
|
||||
}
|
||||
|
||||
$post_language = $this->model->get_language( $_GET['post_language'] );
|
||||
$translation_language = $this->model->get_language( $_GET['translation_language'] );
|
||||
|
||||
// Don't order by title: see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
|
||||
$args = array(
|
||||
's' => wp_unslash( $_GET['term'] ),
|
||||
'suppress_filters' => 0, // To make the post_fields filter work
|
||||
'lang' => 0, // Avoid admin language filter
|
||||
'numberposts' => 20, // Limit to 20 posts
|
||||
'post_status' => 'any',
|
||||
'post_type' => $_GET['post_type'],
|
||||
'tax_query' => array(
|
||||
array(
|
||||
'taxonomy' => 'language',
|
||||
'field' => 'term_taxonomy_id', // WP 3.5+
|
||||
'terms' => $translation_language->term_taxonomy_id,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter the query args when auto suggesting untranslated posts in the Languages metabox
|
||||
* This should help plugins to fix some edge cases
|
||||
*
|
||||
* @see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param array $args WP_Query arguments
|
||||
*/
|
||||
$args = apply_filters( 'pll_ajax_posts_not_translated_args', $args );
|
||||
$posts = get_posts( $args );
|
||||
|
||||
$return = array();
|
||||
|
||||
foreach ( $posts as $key => $post ) {
|
||||
if ( ! $this->model->post->get_translation( $post->ID, $post_language ) ) {
|
||||
$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 );
|
||||
array_unshift( $return, array(
|
||||
'id' => $post_id,
|
||||
'value' => $post->post_title,
|
||||
'link' => $this->links->edit_post_translation_link( $post_id ),
|
||||
) );
|
||||
}
|
||||
|
||||
wp_die( json_encode( $return ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves language
|
||||
* Checks the terms saved are in the right language
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param array $post
|
||||
*/
|
||||
protected function save_language( $post_id, $post ) {
|
||||
// Security checks are necessary to accept language modifications as 'wp_insert_post' can be called from outside WP admin
|
||||
|
||||
// Edit post
|
||||
if ( isset( $_POST['post_lang_choice'], $_POST['post_ID'] ) && $_POST['post_ID'] == $post_id ) {
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' );
|
||||
$this->model->post->set_language( $post_id, $lang = $this->model->get_language( $_POST['post_lang_choice'] ) );
|
||||
}
|
||||
|
||||
// Quick edit and bulk edit
|
||||
// POST for quick edit, GET for bulk edit
|
||||
elseif ( isset( $_REQUEST['inline_lang_choice'] ) ) {
|
||||
// Bulk edit does not modify the language
|
||||
if ( isset( $_GET['bulk_edit'] ) && -1 == $_REQUEST['inline_lang_choice'] ) {
|
||||
check_admin_referer( 'bulk-posts' );
|
||||
$lang = $this->model->post->get_language( $post_id ); // Get the post language for later use when saving terms
|
||||
}
|
||||
// A language is set in the language dropdown
|
||||
else {
|
||||
isset( $_GET['bulk_edit'] ) ? check_admin_referer( 'bulk-posts' ) : check_admin_referer( 'inlineeditnonce', '_inline_edit' );
|
||||
|
||||
$old_lang = $this->model->post->get_language( $post_id ); // Stores the old language
|
||||
$this->model->post->set_language( $post_id, $lang = $this->model->get_language( $_REQUEST['inline_lang_choice'] ) ); // set new language
|
||||
|
||||
// Checks if the new language already exists in the translation group
|
||||
if ( $old_lang && $old_lang->slug != $lang->slug ) {
|
||||
$translations = $this->model->post->get_translations( $post_id );
|
||||
|
||||
// If yes, separate this post from the translation group
|
||||
if ( array_key_exists( $lang->slug, $translations ) ) {
|
||||
$this->model->post->delete_translation( $post_id );
|
||||
}
|
||||
|
||||
elseif ( array_key_exists( $old_lang->slug, $translations ) ) {
|
||||
unset( $translations[ $old_lang->slug ] );
|
||||
$this->model->post->save_translations( $post_id, $translations );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Quick press
|
||||
// 'post-quickpress-save', 'post-quickpress-publish' = backward compatibility WP < 3.8
|
||||
elseif ( isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array( 'post-quickpress-save', 'post-quickpress-publish', 'post-quickdraft-save' ) ) ) {
|
||||
check_admin_referer( 'add-' . $post->post_type );
|
||||
$this->model->post->set_language( $post_id, $lang = $this->pref_lang ); // Default language for Quick draft
|
||||
}
|
||||
|
||||
else {
|
||||
$this->set_default_language( $post_id );
|
||||
}
|
||||
|
||||
// Make sure we get save terms in the right language (especially tags with same name in different languages)
|
||||
if ( ! empty( $lang ) ) {
|
||||
// FIXME quite a lot of queries in foreach
|
||||
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
||||
$terms = get_the_terms( $post_id, $tax );
|
||||
|
||||
if ( is_array( $terms ) ) {
|
||||
$newterms = array();
|
||||
foreach ( $terms as $term ) {
|
||||
// Check if the term is in the correct language or if a translation exist ( mainly for default category )
|
||||
if ( $newterm = $this->model->term->get( $term->term_id, $lang ) ) {
|
||||
$newterms[] = (int) $newterm;
|
||||
}
|
||||
|
||||
// Or choose the correct language for tags ( initially defined by name )
|
||||
elseif ( $newterm = $this->model->term_exists( $term->name, $tax, $term->parent, $lang ) ) {
|
||||
$newterms[] = (int) $newterm; // Cast is important otherwise we get 'numeric' tags
|
||||
}
|
||||
|
||||
// Or create the term in the correct language
|
||||
elseif ( ! is_wp_error( $term_info = wp_insert_term( $term->name, $tax ) ) ) {
|
||||
$newterms[] = (int) $term_info['term_id'];
|
||||
}
|
||||
}
|
||||
|
||||
wp_set_object_terms( $post_id, $newterms, $tax );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a post ( or page ) is saved, published or updated
|
||||
* saves languages and translations
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param object $post
|
||||
* @param bool $update Whether it is an update or not
|
||||
*/
|
||||
public function save_post( $post_id, $post, $update ) {
|
||||
// Does nothing except on post types which are filterable
|
||||
if ( ! $this->model->is_translated_post_type( $post->post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $id = wp_is_post_revision( $post_id ) ) {
|
||||
$post_id = $id;
|
||||
}
|
||||
|
||||
// Capability check
|
||||
// As 'wp_insert_post' can be called from outside WP admin
|
||||
$post_type_object = get_post_type_object( $post->post_type );
|
||||
if ( ( $update && current_user_can( $post_type_object->cap->edit_post, $post_id ) ) || ( ! $update && current_user_can( $post_type_object->cap->create_posts ) ) ) {
|
||||
$this->save_language( $post_id, $post );
|
||||
|
||||
// Make sure we are saving translations only for the main post currently being edited
|
||||
if ( isset( $_POST['post_tr_lang'], $_POST['post_ID'] ) && $_POST['post_ID'] == $post_id ) {
|
||||
$translations = $this->save_translations( $post_id, $_POST['post_tr_lang'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after the post language and translations are saved
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param int $post_id Post id
|
||||
* @param object $post Post object
|
||||
* @param array $translations The list of translations post ids
|
||||
*/
|
||||
do_action( 'pll_save_post', $post_id, $post, empty( $translations ) ? $this->model->post->get_translations( $post_id ) : $translations );
|
||||
}
|
||||
|
||||
// Attempts to set a default language even if no capability
|
||||
else {
|
||||
$this->set_default_language( $post_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the post parent is in the correct language when using bulk edit
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_parent Post parent ID.
|
||||
* @param int $post_id Post ID.
|
||||
* @param array $new_postarr Array of parsed post data.
|
||||
* @param array $postarr Array of sanitized, but otherwise unmodified post data.
|
||||
* @return int
|
||||
*/
|
||||
public function wp_insert_post_parent( $post_parent, $post_id, $new_postarr, $postarr ) {
|
||||
if ( isset( $postarr['bulk_edit'] ) ) {
|
||||
check_admin_referer( 'bulk-posts' );
|
||||
$lang = -1 == $postarr['inline_lang_choice'] ?
|
||||
$this->model->post->get_language( $post_id ) :
|
||||
$this->model->get_language( $postarr['inline_lang_choice'] );
|
||||
$post_parent = $this->model->post->get_translation( $post_parent, $lang );
|
||||
}
|
||||
return $post_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a post, page or media is deleted
|
||||
* Don't delete translations if this is a post revision thanks to AndyDeGroo who catched this bug
|
||||
* http://wordpress.org/support/topic/plugin-polylang-quick-edit-still-breaks-translation-linking-of-pages-in-072
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public function delete_post( $post_id ) {
|
||||
if ( ! wp_is_post_revision( $post_id ) ) {
|
||||
$this->model->post->delete_translation( $post_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 object $post
|
||||
* @return array Modified arguments
|
||||
*/
|
||||
public function page_attributes_dropdown_pages_args( $dropdown_args, $post ) {
|
||||
$dropdown_args['lang'] = isset( $_POST['lang'] ) ? $this->model->get_language( $_POST['lang'] ) : $this->model->post->get_language( $post->ID ); // ajax or not ?
|
||||
if ( ! $dropdown_args['lang'] ) {
|
||||
$dropdown_args['lang'] = $this->pref_lang;
|
||||
}
|
||||
|
||||
return $dropdown_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
729
pole-sbv-content/plugins/polylang/admin/admin-filters-term.php
Normal file
|
|
@ -0,0 +1,729 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manages filters and actions related to terms on admin side
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin_Filters_Term {
|
||||
public $links, $model, $options, $curlang, $filter_lang, $pref_lang;
|
||||
protected $pre_term_name; // Used to store the term name before creating a slug if needed
|
||||
protected $post_id; // Used to store the current post_id when bulk editing posts
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @param object $polylang
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links = &$polylang->links;
|
||||
$this->model = &$polylang->model;
|
||||
$this->options = &$polylang->options;
|
||||
$this->curlang = &$polylang->curlang;
|
||||
$this->filter_lang = &$polylang->filter_lang;
|
||||
$this->pref_lang = &$polylang->pref_lang;
|
||||
|
||||
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 action related to languages when deleting categories and post tags
|
||||
add_action( 'delete_' . $tax, array( $this, 'delete_term' ) );
|
||||
}
|
||||
|
||||
// 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' ), 999, 3 );
|
||||
add_action( 'edit_term', array( $this, 'save_term' ), 999, 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( 'pre_term_name', array( $this, 'pre_term_name' ) );
|
||||
add_filter( 'pre_term_slug', array( $this, 'pre_term_slug' ), 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' ) );
|
||||
|
||||
// Adds cache domain when querying terms
|
||||
add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
|
||||
|
||||
// Filters categories and post tags by language
|
||||
add_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10, 3 );
|
||||
|
||||
// Allows to get the default categories in all languages
|
||||
add_filter( 'option_default_category', array( $this, 'option_default_category' ) );
|
||||
add_action( 'update_option_default_category', array( $this, 'update_option_default_category' ), 10, 2 );
|
||||
|
||||
// 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
|
||||
*/
|
||||
public function add_term_form() {
|
||||
$taxonomy = $_GET['taxonomy'];
|
||||
$post_type = isset( $GLOBALS['post_type'] ) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
||||
|
||||
if ( ! taxonomy_exists( $taxonomy ) || ! post_type_exists( $post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lang = isset( $_GET['new_lang'] ) ? $this->model->get_language( $_GET['new_lang'] ) : $this->pref_lang;
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
|
||||
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->walk( $this->model->get_languages_list(), array(
|
||||
'name' => 'term_lang_choice',
|
||||
'value' => 'term_id',
|
||||
'selected' => $lang ? $lang->term_id : '',
|
||||
'flag' => true,
|
||||
) ),
|
||||
esc_html__( 'Sets the language', 'polylang' )
|
||||
);
|
||||
|
||||
if ( ! empty( $_GET['from_tag'] ) ) {
|
||||
printf( '<input type="hidden" name="from_tag" value="%d" />', (int) $_GET['from_tag'] );
|
||||
}
|
||||
|
||||
// Adds translation fields
|
||||
echo '<div id="term-translations" class="form-field">';
|
||||
if ( $lang ) {
|
||||
include PLL_ADMIN_INC . '/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 object $tag
|
||||
*/
|
||||
public function edit_term_form( $tag ) {
|
||||
$post_type = isset( $GLOBALS['post_type'] ) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
||||
|
||||
if ( ! post_type_exists( $post_type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$term_id = $tag->term_id;
|
||||
$taxonomy = $tag->taxonomy;
|
||||
|
||||
$lang = $this->model->term->get_language( $term_id );
|
||||
$lang = empty( $lang ) ? $this->pref_lang : $lang;
|
||||
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
|
||||
// Disable the language dropdown and the translations input fields for default categories to prevent removal
|
||||
$disabled = in_array( get_option( 'default_category' ), $this->model->term->get_translations( $term_id ) );
|
||||
|
||||
printf( '
|
||||
<tr class="form-field">
|
||||
<th scope="row">
|
||||
%s
|
||||
<label for="term_lang_choice">%s</label>
|
||||
</th>
|
||||
<td id="select-edit-term-language">
|
||||
%s<br />
|
||||
<p class="description">%s</p>
|
||||
</td>
|
||||
</tr>',
|
||||
wp_nonce_field( 'pll_language', '_pll_nonce', true , false ),
|
||||
esc_html__( 'Language', 'polylang' ),
|
||||
$dropdown->walk( $this->model->get_languages_list(), array(
|
||||
'name' => 'term_lang_choice',
|
||||
'value' => 'term_id',
|
||||
'selected' => $lang ? $lang->term_id : '',
|
||||
'disabled' => $disabled,
|
||||
'flag' => true,
|
||||
) ),
|
||||
esc_html__( 'Sets the language', 'polylang' )
|
||||
);
|
||||
|
||||
echo '<tr id="term-translations" class="form-field">';
|
||||
if ( $lang ) {
|
||||
include PLL_ADMIN_INC . '/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'], $_GET['from_tag'], $_GET['new_lang'] ) && taxonomy_exists( $_GET['taxonomy'] ) ) {
|
||||
$term = get_term( (int) $_GET['from_tag'], $_GET['taxonomy'] );
|
||||
if ( $term && $id = $term->parent ) {
|
||||
$lang = $this->model->get_language( $_GET['new_lang'] );
|
||||
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 pre_term_slug
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public function pre_post_update( $post_id ) {
|
||||
if ( isset( $_GET['bulk_edit'] ) ) {
|
||||
$this->post_id = $post_id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set a language by default for terms if it has no language yet
|
||||
*
|
||||
* @since 1.5.4
|
||||
*
|
||||
* @param int $term_id
|
||||
* @param string $taxonomy
|
||||
*/
|
||||
protected function set_default_language( $term_id, $taxonomy ) {
|
||||
if ( ! $this->model->term->get_language( $term_id ) ) {
|
||||
// Sets language from term parent if exists thanks to Scott Kingsley Clark
|
||||
if ( ( $term = get_term( $term_id, $taxonomy ) ) && ! empty( $term->parent ) && $parent_lang = $this->model->term->get_language( $term->parent ) ) {
|
||||
$this->model->term->set_language( $term_id, $parent_lang );
|
||||
}
|
||||
else {
|
||||
$this->model->term->set_language( $term_id, $this->pref_lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves language
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $term_id
|
||||
* @param string $taxonomy
|
||||
*/
|
||||
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 ( 'add-' . $taxonomy == $_POST['action'] ) {
|
||||
check_ajax_referer( $_POST['action'], '_ajax_nonce-add-' . $taxonomy ); // category metabox
|
||||
}
|
||||
else {
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' ); // edit tags or tags metabox
|
||||
}
|
||||
|
||||
$this->model->term->set_language( $term_id, $this->model->get_language( $_POST['term_lang_choice'] ) );
|
||||
}
|
||||
|
||||
// *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 == $_GET['inline_lang_choice'] ) {
|
||||
// The language of the current term is set a according to the language of the current post
|
||||
$this->model->term->set_language( $term_id, $this->model->post->get_language( $this->post_id ) );
|
||||
$term = get_term( $term_id, $taxonomy );
|
||||
|
||||
// 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
|
||||
$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 ) {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$this->model->term->set_language( $term_id, $this->model->get_language( $_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'
|
||||
);
|
||||
|
||||
$old_lang = $this->model->term->get_language( $term_id ); // Stores the old language
|
||||
$lang = $this->model->get_language( $_POST['inline_lang_choice'] ); // New language
|
||||
$translations = $this->model->term->get_translations( $term_id );
|
||||
|
||||
// Checks if the new language already exists in the translation group
|
||||
if ( $old_lang && $old_lang->slug != $lang->slug ) {
|
||||
if ( array_key_exists( $lang->slug, $translations ) ) {
|
||||
$this->model->term->delete_translation( $term_id );
|
||||
}
|
||||
|
||||
elseif ( array_key_exists( $old_lang->slug, $translations ) ) {
|
||||
unset( $translations[ $old_lang->slug ] );
|
||||
$this->model->term->save_translations( $term_id, $translations );
|
||||
}
|
||||
}
|
||||
|
||||
$this->model->term->set_language( $term_id, $lang ); // Set new language
|
||||
}
|
||||
|
||||
// Edit post
|
||||
elseif ( isset( $_POST['post_lang_choice'] ) ) { // FIXME should be useless now
|
||||
check_admin_referer( 'pll_language', '_pll_nonce' );
|
||||
$this->model->term->set_language( $term_id, $this->model->get_language( $_POST['post_lang_choice'] ) );
|
||||
}
|
||||
|
||||
else {
|
||||
$this->set_default_language( $term_id, $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save translations from our form
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $term_id
|
||||
* @return array
|
||||
*/
|
||||
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' );
|
||||
|
||||
// Save translations after checking the translated term is in the right language ( as well as cast id to int )
|
||||
foreach ( $_POST['term_tr_lang'] as $lang => $tr_id ) {
|
||||
$tr_lang = $this->model->term->get_language( (int) $tr_id );
|
||||
$translations[ $lang ] = $tr_lang && $tr_lang->slug == $lang ? (int) $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
|
||||
* @param int $tt_id term taxononomy id
|
||||
* @param string $taxonomy
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
// Capability check
|
||||
// As 'wp_update_term' can be called from outside WP admin
|
||||
// 2nd test for creating tags when creating / editing a post
|
||||
$tax = get_taxonomy( $taxonomy );
|
||||
if ( current_user_can( $tax->cap->edit_terms ) || ( isset( $_POST['tax_input'][ $taxonomy ] ) && current_user_can( $tax->cap->assign_terms ) ) ) {
|
||||
$this->save_language( $term_id, $taxonomy );
|
||||
|
||||
if ( isset( $_POST['term_tr_lang'] ) ) {
|
||||
$translations = $this->save_translations( $term_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after the term language and translations are saved
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param int $term_id term id
|
||||
* @param string $taxonomy taxonomy name
|
||||
* @param array $translations the list of translations term ids
|
||||
*/
|
||||
do_action( 'pll_save_term', $term_id, $taxonomy, empty( $translations ) ? $this->model->term->get_translations( $term_id ) : $translations );
|
||||
}
|
||||
|
||||
// Attempts to set a default language even if no capability
|
||||
else {
|
||||
$this->set_default_language( $term_id, $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the term name for use in pre_term_slug
|
||||
*
|
||||
* @since 0.9.5
|
||||
*
|
||||
* @param string $name term name
|
||||
* @return string unmodified term name
|
||||
*/
|
||||
public function pre_term_name( $name ) {
|
||||
return $this->pre_term_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the term slug in case the term already exists in another language
|
||||
*
|
||||
* @since 0.9.5
|
||||
*
|
||||
* @param string $slug
|
||||
* @param string $taxonomy
|
||||
* @return string
|
||||
*/
|
||||
public function pre_term_slug( $slug, $taxonomy ) {
|
||||
$name = sanitize_title( $this->pre_term_name );
|
||||
|
||||
// If the term already exists in another language
|
||||
if ( ! $slug && $this->model->is_translated_taxonomy( $taxonomy ) && term_exists( $name, $taxonomy ) ) {
|
||||
if ( isset( $_POST['term_lang_choice'] ) ) {
|
||||
$slug = $name . '-' . $this->model->get_language( $_POST['term_lang_choice'] )->slug;
|
||||
}
|
||||
|
||||
elseif ( isset( $_POST['inline_lang_choice'] ) ) {
|
||||
$slug = $name . '-' . $this->model->get_language( $_POST['inline_lang_choice'] )->slug;
|
||||
}
|
||||
|
||||
// *Post* bulk edit, in case a new term is created
|
||||
elseif ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) {
|
||||
// Bulk edit does not modify the language
|
||||
if ( -1 == $_GET['inline_lang_choice'] ) {
|
||||
$slug = $name . '-' . $this->model->post->get_language( $this->post_id )->slug;
|
||||
} else {
|
||||
$slug = $name . '-' . $this->model->get_language( $_GET['inline_lang_choice'] )->slug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a category or post tag is deleted
|
||||
* Deletes language and translations
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param int $term_id
|
||||
*/
|
||||
public function delete_term( $term_id ) {
|
||||
$this->model->term->delete_translation( $term_id );
|
||||
$this->model->term->delete_language( $term_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax response for edit term form
|
||||
*
|
||||
* @since 0.2
|
||||
*/
|
||||
public function term_lang_choice() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$lang = $this->model->get_language( $_POST['lang'] );
|
||||
$term_id = isset( $_POST['term_id'] ) ? (int) $_POST['term_id'] : null;
|
||||
$taxonomy = $_POST['taxonomy'];
|
||||
$post_type = $_POST['post_type'];
|
||||
|
||||
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
||||
die( 0 );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
if ( $lang ) {
|
||||
include PLL_ADMIN_INC . '/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' ),
|
||||
'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 ( ! 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' ) );
|
||||
}
|
||||
|
||||
if ( $tag_cloud = wp_tag_cloud( $args ) ) {
|
||||
$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
|
||||
*/
|
||||
public function ajax_terms_not_translated() {
|
||||
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
||||
|
||||
$s = wp_unslash( $_GET['term'] );
|
||||
$post_type = $_GET['post_type'];
|
||||
$taxonomy = $_GET['taxonomy'];
|
||||
|
||||
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
||||
die( 0 );
|
||||
}
|
||||
|
||||
$term_language = $this->model->get_language( $_GET['term_language'] );
|
||||
$translation_language = $this->model->get_language( $_GET['translation_language'] );
|
||||
|
||||
$return = array();
|
||||
|
||||
// It is more efficient to use one common query for all languages as soon as there are more than 2
|
||||
foreach ( get_terms( $taxonomy, 'hide_empty=0&lang=0&name__like=' . $s ) 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 ) ) {
|
||||
$return[] = array(
|
||||
'id' => $term->term_id,
|
||||
'value' => $term->name,
|
||||
'link' => $this->links->edit_term_translation_link( $term->term_id, $taxonomy, $post_type ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add current translation in list
|
||||
// Not in add term for as term_id is not set
|
||||
if ( 'undefined' !== $_GET['term_id'] && $term_id = $this->model->term->get_translation( (int) $_GET['term_id'], $translation_language ) ) {
|
||||
$term = get_term( $term_id, $taxonomy );
|
||||
array_unshift( $return, array(
|
||||
'id' => $term_id,
|
||||
'value' => $term->name,
|
||||
'link' => $this->links->edit_term_translation_link( $term->term_id, $taxonomy, $post_type ),
|
||||
) );
|
||||
}
|
||||
|
||||
wp_die( json_encode( $return ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language(s) to filter get_terms
|
||||
*
|
||||
* @since 1.7.6
|
||||
*
|
||||
* @param array $taxonomies queried taxonomies
|
||||
* @param array $args get_terms arguments
|
||||
* @return object|string|bool the language(s) to use in the filter, false otherwise
|
||||
*/
|
||||
protected function get_queried_language( $taxonomies, $args ) {
|
||||
// Does nothing except on taxonomies which are filterable
|
||||
// Since WP 4.7, make sure not to filter wp_get_object_terms()
|
||||
if ( ! $this->model->is_translated_taxonomy( $taxonomies ) || ! empty( $args['object_ids'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If get_terms is queried with a 'lang' parameter
|
||||
if ( isset( $args['lang'] ) ) {
|
||||
return $args['lang'];
|
||||
}
|
||||
|
||||
// On tags page, everything should be filtered according to the admin language filter except the parent dropdown
|
||||
if ( 'edit-tags.php' === $GLOBALS['pagenow'] && empty( $args['class'] ) ) {
|
||||
return $this->filter_lang;
|
||||
}
|
||||
|
||||
return $this->curlang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds language dependent cache domain when querying terms
|
||||
* Useful as the 'lang' parameter is not included in cache key by WordPress
|
||||
*
|
||||
* @since 1.3
|
||||
*
|
||||
* @param array $args
|
||||
* @param array $taxonomies
|
||||
* @return array modified arguments
|
||||
*/
|
||||
public function get_terms_args( $args, $taxonomies ) {
|
||||
// don't break _get_term_hierarchy()
|
||||
if ( 'all' === $args['get'] && 'id' === $args['orderby'] && 'id=>parent' === $args['fields'] ) {
|
||||
$args['lang'] = '';
|
||||
}
|
||||
|
||||
if ( $lang = $this->get_queried_language( $taxonomies, $args ) ) {
|
||||
$key = '_' . ( is_array( $lang ) ? implode( ',', $lang ) : $this->model->get_language( $lang )->slug );
|
||||
$args['cache_domain'] = empty( $args['cache_domain'] ) ? 'pll' . $key : $args['cache_domain'] . $key;
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters categories and post tags by language(s) when needed on admin side
|
||||
*
|
||||
* @since 0.5
|
||||
*
|
||||
* @param array $clauses list of sql clauses
|
||||
* @param array $taxonomies list of taxonomies
|
||||
* @param array $args get_terms arguments
|
||||
* @return array modified sql clauses
|
||||
*/
|
||||
public function terms_clauses( $clauses, $taxonomies, $args ) {
|
||||
$lang = $this->get_queried_language( $taxonomies, $args );
|
||||
return ! empty( $lang ) ? $this->model->terms_clauses( $clauses, $lang ) : $clauses; // adds our clauses to filter by current language
|
||||
}
|
||||
|
||||
/**
|
||||
* Hack to avoid displaying delete link for the default category in all languages
|
||||
* Also returns the default category in the right language when called from wp_delete_term
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param int $value
|
||||
* @return int
|
||||
*/
|
||||
public function option_default_category( $value ) {
|
||||
// Filters the default category in note below the category list table and in settings->writing dropdown
|
||||
if ( isset( $this->pref_lang ) && $tr = $this->model->term->get( $value, $this->pref_lang ) ) {
|
||||
$value = $tr;
|
||||
}
|
||||
|
||||
// FIXME backward compatibility with WP < 4.7
|
||||
if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
|
||||
$traces = debug_backtrace();
|
||||
$n = version_compare( PHP_VERSION, '7', '>=' ) ? 3 : 4; // PHP 7 does not include call_user_func_array
|
||||
|
||||
if ( isset( $traces[ $n ] ) ) {
|
||||
// FIXME 'column_name' for backward compatibility with WP < 4.3
|
||||
if ( in_array( $traces[ $n ]['function'], array( 'column_cb', 'column_name', 'handle_row_actions' ) ) && in_array( $traces[ $n ]['args'][0]->term_id, $this->model->term->get_translations( $value ) ) ) {
|
||||
return $traces[ $n ]['args'][0]->term_id;
|
||||
}
|
||||
|
||||
if ( 'wp_delete_term' == $traces[ $n ]['function'] ) {
|
||||
return $this->model->term->get( $value, $this->model->term->get_language( $traces[ $n ]['args'][0] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the new default category is translated in all languages
|
||||
* If not, create the translations
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param int $old_value
|
||||
* @param int $value
|
||||
*/
|
||||
public function update_option_default_category( $old_value, $value ) {
|
||||
$default_cat_lang = $this->model->term->get_language( $value );
|
||||
|
||||
// Assign a default language to default category
|
||||
if ( ! $default_cat_lang ) {
|
||||
$default_cat_lang = $this->model->get_language( $this->options['default_lang'] );
|
||||
$this->model->term->set_language( (int) $value, $default_cat_lang );
|
||||
}
|
||||
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( $language->slug != $default_cat_lang->slug && ! $this->model->term->get_translation( $value, $language ) ) {
|
||||
$this->model->create_default_category( $language );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Shared term_id
|
||||
* @param int $new_term_id
|
||||
* @param int $term_taxonomy_id
|
||||
* @param string $taxonomy
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
$avoid_recursion = true;
|
||||
$lang = $this->model->term->get_language( $term_id );
|
||||
|
||||
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 );
|
||||
$translations[ $key ] = _split_shared_term( $tr_id, $tr_term->term_taxonomy_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 ) {
|
||||
$_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;
|
||||
}
|
||||
}
|
||||
281
pole-sbv-content/plugins/polylang/admin/admin-filters.php
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
// Widgets languages filter
|
||||
add_action( 'in_widget_form', array( $this, 'in_widget_form' ), 10, 3 );
|
||||
add_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ), 10, 4 );
|
||||
|
||||
// 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' ) );
|
||||
|
||||
// Ugrades languages files after a core upgrade ( timing is important )
|
||||
// Backward compatibility WP < 4.0 *AND* Polylang < 1.6
|
||||
add_action( '_core_updated_successfully', array( $this, 'upgrade_languages' ), 1 ); // since WP 3.3
|
||||
|
||||
// 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' ) );
|
||||
|
||||
// We need specific filters for German and Danish
|
||||
$specific_locales = array( 'da_DK', 'de_DE', 'de_DE_formal', 'de_CH', 'de_CH_informal', 'ca', 'sr_RS', 'bs_BA' );
|
||||
if ( array_intersect( $this->model->get_languages_list( array( 'fields' => 'locale' ) ), $specific_locales ) ) {
|
||||
add_filter( 'sanitize_title', array( $this, 'sanitize_title' ), 10, 3 );
|
||||
add_filter( 'sanitize_user', array( $this, 'sanitize_user' ), 10, 3 );
|
||||
}
|
||||
|
||||
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the widgets forms to add our language dropdwown list
|
||||
*
|
||||
* @since 0.3
|
||||
*
|
||||
* @param object $widget Widget instance
|
||||
* @param null $return Not used
|
||||
* @param array $instance Widget settings
|
||||
*/
|
||||
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, not in $_GET.
|
||||
if ( ( isset( $screen ) && 'widgets' === $screen->base ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) {
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
printf( '<p><label for="%1$s">%2$s %3$s</label></p>',
|
||||
esc_attr( $widget->id . '_lang_choice' ),
|
||||
esc_html__( 'The widget is displayed for:', 'polylang' ),
|
||||
$dropdown->walk(
|
||||
array_merge(
|
||||
array( (object) array( 'slug' => 0, 'name' => __( 'All languages', 'polylang' ) ) ),
|
||||
$this->model->get_languages_list()
|
||||
),
|
||||
array(
|
||||
'name' => $widget->id . '_lang_choice',
|
||||
'class' => 'tags-input',
|
||||
'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'],
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when widget options are saved
|
||||
* saves the language associated to the widget
|
||||
*
|
||||
* @since 0.3
|
||||
*
|
||||
* @param array $instance Widget options
|
||||
* @param array $new_instance Not used
|
||||
* @param array $old_instance Not used
|
||||
* @param object $widget WP_Widget object
|
||||
* @return array Widget options
|
||||
*/
|
||||
public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) {
|
||||
if ( ! empty( $_POST[ $key = $widget->id . '_lang_choice' ] ) && in_array( $_POST[ $key ], $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) ) {
|
||||
$instance['pll_lang'] = $_POST[ $key ];
|
||||
} else {
|
||||
unset( $instance['pll_lang'] );
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates language user preference set in user profile
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param int $user_id
|
||||
*/
|
||||
public function personal_options_update( $user_id ) {
|
||||
// Admin language
|
||||
// FIXME Backward compatibility with WP < 4.7
|
||||
if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
|
||||
$user_lang = in_array( $_POST['user_lang'], $this->model->get_languages_list( array( 'fields' => 'locale' ) ) ) ? $_POST['user_lang'] : 0;
|
||||
update_user_meta( $user_id, 'locale', $user_lang );
|
||||
}
|
||||
|
||||
// Biography translations
|
||||
foreach ( $this->model->get_languages_list() as $lang ) {
|
||||
$meta = $lang->slug == $this->options['default_lang'] ? 'description' : 'description_' . $lang->slug;
|
||||
$description = empty( $_POST[ 'description_' . $lang->slug ] ) ? '' : trim( $_POST[ 'description_' . $lang->slug ] );
|
||||
|
||||
/** 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 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form for language user preference in user profile
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param object $profileuser
|
||||
*/
|
||||
public function personal_options( $profileuser ) {
|
||||
// FIXME: Backward compatibility with WP < 4.7
|
||||
if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
|
||||
$dropdown = new PLL_Walker_Dropdown();
|
||||
printf( '
|
||||
<tr>
|
||||
<th><label for="user_lang">%s</label></th>
|
||||
<td>%s</td>
|
||||
</tr>',
|
||||
esc_html__( 'Admin language', 'polylang' ),
|
||||
$dropdown->walk(
|
||||
array_merge(
|
||||
array( (object) array( 'locale' => 0, 'name' => __( 'WordPress default', 'polylang' ) ) ),
|
||||
$this->model->get_languages_list()
|
||||
),
|
||||
array(
|
||||
'name' => 'user_lang',
|
||||
'value' => 'locale',
|
||||
'selected' => get_user_meta( $profileuser->ID, 'locale', true ),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Hidden informations to modify the biography form with js
|
||||
foreach ( $this->model->get_languages_list() as $lang ) {
|
||||
$meta = $lang->slug == $this->options['default_lang'] ? 'description' : 'description_' . $lang->slug;
|
||||
|
||||
/** This filter is documented in wp-includes/user.php */
|
||||
$description = apply_filters( 'user_description', get_user_meta( $profileuser->ID, $meta, true ) ); // Applies WP default filter wp_kses_data
|
||||
|
||||
printf( '<input type="hidden" class="biography" name="%s___%s" value="%s" />',
|
||||
esc_attr( $lang->slug ),
|
||||
esc_attr( $lang->name ),
|
||||
esc_attr( $description )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ugprades languages files after a core upgrade
|
||||
* only for backward compatibility WP < 4.0 *AND* Polylang < 1.6
|
||||
*
|
||||
* @since 0.6
|
||||
*
|
||||
* @param string $version new WP version
|
||||
*/
|
||||
public function upgrade_languages( $version ) {
|
||||
// $GLOBALS['wp_version'] is the old WP version
|
||||
if ( version_compare( $version, '4.0', '>=' ) && version_compare( $GLOBALS['wp_version'], '4.0', '<' ) ) {
|
||||
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', __( 'Upgrading language files…', 'polylang' ) );
|
||||
PLL_Upgrade::download_language_packs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to update translations files for plugins and themes
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param array $locales Not used
|
||||
* @return array list of locales to update
|
||||
*/
|
||||
function update_check_locales( $locales ) {
|
||||
return $this->model->get_languages_list( array( 'fields' => 'locale' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the locale according to the current language instead of the language
|
||||
* of the admin interface
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param string $locale
|
||||
* @return string
|
||||
*/
|
||||
public function get_locale( $locale ) {
|
||||
return $this->curlang->locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe fix the result of sanitize_title() in case the languages include German or Danish
|
||||
* Without this filter, if language of the title being sanitized is different from the language
|
||||
* used for the admin interface and if one this language is German or Danish, some specific
|
||||
* characters such as ä, ö, ü, ß are incorrectly sanitized.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param string $title Sanitized title.
|
||||
* @param string $raw_title The title prior to sanitization.
|
||||
* @param string $context The context for which the title is being sanitized.
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_title( $title, $raw_title, $context ) {
|
||||
static $once = false;
|
||||
|
||||
if ( ! $once && 'save' == $context && ! empty( $this->curlang ) && ! empty( $title ) ) {
|
||||
$once = true;
|
||||
add_filter( 'locale', array( $this, 'get_locale' ), 20 ); // After the filter for the admin interface
|
||||
$title = sanitize_title( $raw_title, '', $context );
|
||||
remove_filter( 'locale', array( $this, 'get_locale' ), 20 );
|
||||
$once = false;
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe fix the result of sanitize_user() in case the languages include German or Danish
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param string $username Sanitized username.
|
||||
* @param string $raw_username The username prior to sanitization.
|
||||
* @param bool $strict Whether to limit the sanitization to specific characters. Default false.
|
||||
* @return string
|
||||
*/
|
||||
public function sanitize_user( $username, $raw_username, $strict ) {
|
||||
static $once = false;
|
||||
|
||||
if ( ! $once && ! empty( $this->curlang ) ) {
|
||||
$once = true;
|
||||
add_filter( 'locale', array( $this, 'get_locale' ), 20 ); // After the filter for the admin interface
|
||||
$username = sanitize_user( $raw_username, '', $strict );
|
||||
remove_filter( 'locale', array( $this, 'get_locale' ), 20 );
|
||||
$once = false;
|
||||
}
|
||||
return $username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text direction dependent class to the body
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
* @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' );
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
}
|
||||
177
pole-sbv-content/plugins/polylang/admin/admin-links.php
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* manages links related functions
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
class PLL_Admin_Links extends PLL_Links {
|
||||
|
||||
/**
|
||||
* get the link to create a new post translation
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $post_id the source post id
|
||||
* @param object $language the language of the new translation
|
||||
* @return string
|
||||
*/
|
||||
public function get_new_post_translation_link( $post_id, $language ) {
|
||||
$post_type = get_post_type( $post_id );
|
||||
$post_type_object = get_post_type_object( get_post_type( $post_id ) );
|
||||
if ( ! current_user_can( $post_type_object->cap->create_posts ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( 'attachment' == $post_type ) {
|
||||
$args = array(
|
||||
'action' => 'translate_media',
|
||||
'from_media' => $post_id,
|
||||
'new_lang' => $language->slug,
|
||||
);
|
||||
|
||||
// add nonce for media as we will directly publish a new attachment from a clic on this link
|
||||
$link = wp_nonce_url( add_query_arg( $args, admin_url( 'admin.php' ) ), 'translate_media' );
|
||||
} 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' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the new post translation link
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $link the new post translation link
|
||||
* @param object $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 html markup for a new post translation link
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param object $language
|
||||
* @return string
|
||||
*/
|
||||
public function new_post_translation_link( $post_id, $language ) {
|
||||
$link = $this->get_new_post_translation_link( $post_id, $language );
|
||||
return $link ? sprintf(
|
||||
'<a href="%1$s" class="pll_icon_add"><span class="screen-reader-text">%2$s</span></a>',
|
||||
esc_url( $link ),
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'Add a translation in %s', 'polylang' ), $language->name ) )
|
||||
) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* returns html markup for a translation link
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @param int $post_id 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 $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 term translation
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param int $term_id
|
||||
* @param string $taxonomy
|
||||
* @param string $post_type
|
||||
* @param object $language
|
||||
* @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' ) );
|
||||
|
||||
/**
|
||||
* Filter the new term translation link
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $link the new term translation link
|
||||
* @param object $language the language of the new translation
|
||||
* @param int $term_id the source term id
|
||||
* @param string $taxonomy
|
||||
* @param string $post_type
|
||||
*/
|
||||
return apply_filters( 'pll_get_new_term_translation_link', $link, $language, $term_id, $taxonomy, $post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* returns html markup for a new term translation
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $term_id
|
||||
* @param string $taxonomy
|
||||
* @param string $post_type
|
||||
* @param object $language
|
||||
* @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 $link ? sprintf(
|
||||
'<a href="%1$s" class="pll_icon_add"><span class="screen-reader-text">%2$s</span></a>',
|
||||
esc_url( $link ),
|
||||
/* translators: accessibility text, %s is a native language name */
|
||||
esc_html( sprintf( __( 'Add a translation in %s', 'polylang' ), $language->name ) )
|
||||
) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* returns html markup for a term translation link
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @param object $term_id translation term id
|
||||
* @param string $taxonomy
|
||||
* @param string $post_type
|
||||
* @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 $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 ) )
|
||||
) : '';
|
||||
}
|
||||
}
|
||||
|
||||
540
pole-sbv-content/plugins/polylang/admin/admin-model.php
Normal file
|
|
@ -0,0 +1,540 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Creates a default category for this language
|
||||
*
|
||||
* List of arguments that $args must contain:
|
||||
* name -> language name ( used only for display )
|
||||
* slug -> language code ( ideally 2-letters ISO 639-1 language code )
|
||||
* locale -> WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
||||
* rtl -> 1 if rtl language, 0 otherwise
|
||||
* term_group -> language order when displayed
|
||||
*
|
||||
* Optional arguments that $args can contain:
|
||||
* no_default_cat -> if set, no default category will be created for this language
|
||||
* flag -> country code, see flags.php
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param array $args
|
||||
* @return bool true if success / false if failed
|
||||
*/
|
||||
public function add_language( $args ) {
|
||||
if ( ! $this->validate_lang( $args ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First the language taxonomy
|
||||
$description = serialize( array( 'locale' => $args['locale'], 'rtl' => (int) $args['rtl'], 'flag_code' => empty( $args['flag'] ) ? '' : $args['flag'] ) );
|
||||
$r = wp_insert_term( $args['name'], 'language', array( 'slug' => $args['slug'], 'description' => $description ) );
|
||||
if ( is_wp_error( $r ) ) {
|
||||
// Avoid an ugly fatal error if something went wrong ( reported once in the forum )
|
||||
add_settings_error( 'general', 'pll_add_language', __( 'Impossible to add the language.', 'polylang' ) );
|
||||
return false;
|
||||
}
|
||||
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 term_language taxonomy
|
||||
// Don't want shared terms so use a different slug
|
||||
wp_insert_term( $args['name'], 'term_language', array( 'slug' => 'pll_' . $args['slug'] ) );
|
||||
|
||||
$this->clean_languages_cache(); // Udpate the languages list now !
|
||||
|
||||
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 );
|
||||
|
||||
// And assign default language to default category
|
||||
$this->term->set_language( (int) get_option( 'default_category' ), (int) $r['term_id'] );
|
||||
} elseif ( empty( $args['no_default_cat'] ) ) {
|
||||
$this->create_default_category( $args['slug'] );
|
||||
}
|
||||
|
||||
// Init a mo_id for this language
|
||||
$mo = new PLL_MO();
|
||||
$mo->export_to_db( $this->get_language( $args['slug'] ) );
|
||||
|
||||
/**
|
||||
* Fires when a language is added
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param array $args arguments used to create the language
|
||||
*/
|
||||
do_action( 'pll_add_language', $args );
|
||||
|
||||
$this->clean_languages_cache(); // Again to set add mo_id in the cached languages list
|
||||
flush_rewrite_rules(); // Refresh rewrite rules
|
||||
|
||||
add_settings_error( 'general', 'pll_languages_created', __( 'Language added.', 'polylang' ), 'updated' );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a language
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param int $lang_id language term_id
|
||||
*/
|
||||
public function delete_language( $lang_id ) {
|
||||
$lang = $this->get_language( (int) $lang_id );
|
||||
|
||||
if ( empty( $lang ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Oops ! we are deleting the default language...
|
||||
// Need to do this before loosing the information for default category translations
|
||||
if ( $this->options['default_lang'] == $lang->slug ) {
|
||||
$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 ( $locations as $location => $languages ) {
|
||||
unset( $this->options['nav_menus'][ $theme ][ $location ][ $lang->slug ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete users options
|
||||
foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) {
|
||||
delete_user_meta( $user_id, 'pll_filter_content', $lang->slug );
|
||||
delete_user_meta( $user_id, 'description_' . $lang->slug );
|
||||
}
|
||||
|
||||
// Delete the string translations
|
||||
$post = wpcom_vip_get_page_by_title( 'polylang_mo_' . $lang->term_id, OBJECT, 'polylang_mo' );
|
||||
if ( ! empty( $post ) ) {
|
||||
wp_delete_post( $post->ID );
|
||||
}
|
||||
|
||||
// Delete domain
|
||||
unset( $this->options['domains'][ $lang->slug ] );
|
||||
|
||||
// Delete the language itself
|
||||
wp_delete_term( $lang->term_id, 'language' );
|
||||
wp_delete_term( $lang->tl_term_id, 'term_language' );
|
||||
|
||||
// Update languages list
|
||||
$this->clean_languages_cache();
|
||||
|
||||
update_option( 'polylang', $this->options );
|
||||
flush_rewrite_rules(); // refresh rewrite rules
|
||||
add_settings_error( 'general', 'pll_languages_deleted', __( 'Language deleted.', 'polylang' ), 'updated' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update language properties
|
||||
*
|
||||
* List of arguments that $args must contain:
|
||||
* lang_id -> term_id of the language to modify
|
||||
* name -> language name ( used only for display )
|
||||
* slug -> language code ( ideally 2-letters ISO 639-1 language code
|
||||
* locale -> WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
||||
* rtl -> 1 if rtl language, 0 otherwise
|
||||
* term_group -> language order when displayed
|
||||
*
|
||||
* Optional arguments that $args can contain:
|
||||
* flag -> country code, see flags.php
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param array $args
|
||||
* @return bool true if success / false if failed
|
||||
*/
|
||||
public function update_language( $args ) {
|
||||
$lang = $this->get_language( (int) $args['lang_id'] );
|
||||
if ( ! $this->validate_lang( $args, $lang ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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 ( $locations as $location => $languages ) {
|
||||
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 ( $this->options['default_lang'] == $old_slug ) {
|
||||
$this->options['default_lang'] = $slug;
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'polylang', $this->options );
|
||||
|
||||
// And finally update the language itself
|
||||
$description = serialize( array( 'locale' => $args['locale'], 'rtl' => (int) $args['rtl'], 'flag_code' => empty( $args['flag'] ) ? '' : $args['flag'] ) );
|
||||
wp_update_term( (int) $lang->term_id, 'language', array( 'slug' => $slug, 'name' => $args['name'], 'description' => $description, 'term_group' => (int) $args['term_group'] ) );
|
||||
wp_update_term( (int) $lang->tl_term_id, 'term_language', array( 'slug' => 'pll_' . $slug, 'name' => $args['name'] ) );
|
||||
|
||||
/**
|
||||
* Fires when a language is added
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param array $args arguments used to modify the language
|
||||
*/
|
||||
do_action( 'pll_update_language', $args );
|
||||
|
||||
$this->clean_languages_cache();
|
||||
flush_rewrite_rules(); // Refresh rewrite rules
|
||||
add_settings_error( 'general', 'pll_languages_updated', __( 'Language updated.', 'polylang' ), 'updated' );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates data entered when creating or updating a language
|
||||
* @see PLL_Admin_Model::add_language
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param array $args
|
||||
* @param object $lang optional the language currently updated, the language is created if not set
|
||||
* @return bool true if success / false if failed
|
||||
*/
|
||||
protected function validate_lang( $args, $lang = null ) {
|
||||
// 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 ) ) {
|
||||
add_settings_error( 'general', 'pll_invalid_locale', __( 'Enter a valid WordPress locale', 'polylang' ) );
|
||||
}
|
||||
|
||||
// Validate slug characters
|
||||
if ( ! preg_match( '#^[a-z_-]+$#', $args['slug'] ) ) {
|
||||
add_settings_error( 'general', 'pll_invalid_slug', __( 'The language code contains invalid characters', 'polylang' ) );
|
||||
}
|
||||
|
||||
// Validate slug is unique
|
||||
if ( $this->get_language( $args['slug'] ) && ( null === $lang || ( isset( $lang ) && $lang->slug != $args['slug'] ) ) ) {
|
||||
add_settings_error( 'general', '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'] ) ) {
|
||||
add_settings_error( 'general', 'pll_invalid_name', __( 'The language must have a name', 'polylang' ) );
|
||||
}
|
||||
|
||||
// Validate flag
|
||||
if ( ! empty( $args['flag'] ) && ! file_exists( POLYLANG_DIR . '/flags/' . $args['flag'] . '.png' ) ) {
|
||||
add_settings_error( 'general', 'pll_invalid_flag', __( 'The flag does not exist', 'polylang' ) );
|
||||
}
|
||||
|
||||
return get_settings_errors() ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the language of posts or terms in mass
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param string $type either 'post' or 'term'
|
||||
* @param array $ids array of post ids or term ids
|
||||
* @param object|string $lang object or slug
|
||||
*/
|
||||
public function set_language_in_mass( $type, $ids, $lang ) {
|
||||
global $wpdb;
|
||||
|
||||
$ids = array_map( 'intval', $ids );
|
||||
$lang = $this->get_language( $lang );
|
||||
$tt_id = 'term' === $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
|
||||
|
||||
foreach ( $ids as $id ) {
|
||||
$values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
|
||||
}
|
||||
|
||||
if ( ! empty( $values ) ) {
|
||||
$values = array_unique( $values );
|
||||
$wpdb->query( "INSERT INTO $wpdb->term_relationships ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $values ) );
|
||||
$lang->update_count(); // Updating term count is mandatory ( thanks to AndyDeGroo )
|
||||
}
|
||||
|
||||
if ( 'term' === $type ) {
|
||||
clean_term_cache( $ids, 'term_language' );
|
||||
|
||||
foreach ( $ids as $id ) {
|
||||
$translations[] = array( $lang->slug => $id );
|
||||
}
|
||||
|
||||
if ( ! empty( $translations ) ) {
|
||||
$this->set_translation_in_mass( 'term', $translations );
|
||||
}
|
||||
} else {
|
||||
clean_term_cache( $ids, 'language' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a translations groups in mass
|
||||
*
|
||||
* @since 1.6.3
|
||||
*
|
||||
* @param string $type either 'post' or 'term'
|
||||
* @param array $translations array of translations arrays
|
||||
*/
|
||||
public function set_translation_in_mass( $type, $translations ) {
|
||||
global $wpdb;
|
||||
|
||||
$taxonomy = $type . '_translations';
|
||||
|
||||
foreach ( $translations as $t ) {
|
||||
$term = uniqid( 'pll_' ); // the term name
|
||||
$terms[] = $wpdb->prepare( '( "%s", "%s" )', $term, $term );
|
||||
$slugs[] = $wpdb->prepare( '"%s"', $term );
|
||||
$description[ $term ] = serialize( $t );
|
||||
$count[ $term ] = count( $t );
|
||||
}
|
||||
|
||||
// Insert terms
|
||||
if ( ! empty( $terms ) ) {
|
||||
$terms = array_unique( $terms );
|
||||
$wpdb->query( "INSERT INTO $wpdb->terms ( slug, name ) VALUES " . implode( ',', $terms ) );
|
||||
}
|
||||
|
||||
// Get all terms with their term_id
|
||||
$terms = $wpdb->get_results( "SELECT term_id, slug FROM $wpdb->terms WHERE slug IN ( " . implode( ',', $slugs ) . ' )' );
|
||||
|
||||
// Prepare terms taxonomy relationship
|
||||
foreach ( $terms as $term ) {
|
||||
$term_ids[] = $term->term_id;
|
||||
$tts[] = $wpdb->prepare( '( %d, "%s", "%s", %d )', $term->term_id, $taxonomy, $description[ $term->slug ], $count[ $term->slug ] );
|
||||
}
|
||||
|
||||
// Insert term_taxonomy
|
||||
if ( ! empty( $tts ) ) {
|
||||
$tts = array_unique( $tts );
|
||||
$wpdb->query( "INSERT INTO $wpdb->term_taxonomy ( term_id, taxonomy, description, count ) VALUES " . implode( ',', $tts ) );
|
||||
}
|
||||
|
||||
// Get all terms with term_taxonomy_id
|
||||
$terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
|
||||
|
||||
// Prepare objects relationships
|
||||
foreach ( $terms as $term ) {
|
||||
$t = unserialize( $term->description );
|
||||
if ( in_array( $t, $translations ) ) {
|
||||
foreach ( $t as $object_id ) {
|
||||
if ( ! empty( $object_id ) ) {
|
||||
$trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert term_relationships
|
||||
if ( ! empty( $trs ) ) {
|
||||
$wpdb->query( "INSERT INTO $wpdb->term_relationships ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $trs ) );
|
||||
$trs = array_unique( $trs );
|
||||
}
|
||||
|
||||
clean_term_cache( $term_ids, $taxonomy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unstranslated posts and terms ids ( used in settings )
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @return array array made of an array of post ids and an array of term ids
|
||||
*/
|
||||
public function get_objects_with_no_lang() {
|
||||
$posts = get_posts( array(
|
||||
'numberposts' => -1,
|
||||
'nopaging' => true,
|
||||
'post_type' => $this->get_translated_post_types(),
|
||||
'post_status' => 'any',
|
||||
'fields' => 'ids',
|
||||
'tax_query' => array(
|
||||
array(
|
||||
'taxonomy' => 'language',
|
||||
'terms' => $this->get_languages_list( array( 'fields' => 'term_id' ) ),
|
||||
'operator' => 'NOT IN',
|
||||
),
|
||||
),
|
||||
) );
|
||||
|
||||
$terms = get_terms( $this->get_translated_taxonomies(), array( 'get' => 'all', 'fields' => 'ids' ) );
|
||||
$groups = $this->get_languages_list( array( 'fields' => 'tl_term_id' ) );
|
||||
$tr_terms = get_objects_in_term( $groups, 'term_language' );
|
||||
$terms = array_unique( array_diff( $terms, $tr_terms ) ); // array_unique to avoid duplicates if a term is in more than one taxonomy
|
||||
$terms = array_map( 'intval', $terms );
|
||||
|
||||
/**
|
||||
* Filter the list of untranslated posts ids and terms ids
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param bool|array $objects false if no ids found, list of post and/or term ids otherwise
|
||||
*/
|
||||
return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to delete translations or update the translations when a language slug has been modified in settings
|
||||
*
|
||||
* @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 the correspondant has been deleted
|
||||
*/
|
||||
public function update_translations( $old_slug, $new_slug = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
$terms = get_terms( array( 'post_translations', 'term_translations' ) );
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
$term_ids[ $term->taxonomy ][] = $term->term_id;
|
||||
$tr = unserialize( $term->description );
|
||||
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, serialize( $tr ) );
|
||||
$ut['in'][] = (int) $term->term_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete relationships
|
||||
if ( ! empty( $dr ) ) {
|
||||
$wpdb->query( "
|
||||
DELETE FROM $wpdb->term_relationships
|
||||
WHERE object_id IN ( " . implode( ',', $dr['id'] ) . ' )
|
||||
AND term_taxonomy_id IN ( ' . implode( ',', $dr['tt'] ) . ' )
|
||||
' );
|
||||
}
|
||||
|
||||
// Delete terms
|
||||
if ( ! empty( $dt ) ) {
|
||||
$wpdb->query( "DELETE FROM $wpdb->terms WHERE term_id IN ( " . implode( ',', $dt['t'] ) . ' )' );
|
||||
$wpdb->query( "DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ( " . implode( ',', $dt['tt'] ) . ' )' );
|
||||
}
|
||||
|
||||
// Update terms
|
||||
if ( ! empty( $ut ) ) {
|
||||
$wpdb->query( "
|
||||
UPDATE $wpdb->term_taxonomy
|
||||
SET description = ( CASE term_id " . implode( ' ', $ut['case'] ) . ' END )
|
||||
WHERE term_id IN ( ' . implode( ',', $ut['in'] ) . ' )
|
||||
' );
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
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 ] ) ) {
|
||||
foreach ( $this->options['nav_menus'][ $theme ] as $key => $loc ) {
|
||||
$menus[ $key ] = empty( $loc[ $slug ] ) ? 0 : $loc[ $slug ];
|
||||
}
|
||||
set_theme_mod( 'nav_menu_locations', $menus );
|
||||
}
|
||||
|
||||
// The default category should be in the default language
|
||||
$default_cats = $this->term->get_translations( get_option( 'default_category' ) );
|
||||
if ( isset( $default_cats[ $slug ] ) ) {
|
||||
update_option( 'default_category', $default_cats[ $slug ] );
|
||||
}
|
||||
|
||||
// Update options
|
||||
$this->options['default_lang'] = $slug;
|
||||
update_option( 'polylang', $this->options );
|
||||
|
||||
$this->clean_languages_cache();
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
}
|
||||
331
pole-sbv-content/plugins/polylang/admin/admin-nav-menu.php
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->theme = get_option( 'stylesheet' );
|
||||
|
||||
// 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
|
||||
*/
|
||||
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 );
|
||||
add_filter( 'wp_get_nav_menu_items', array( $this, 'translate_switcher_title' ) );
|
||||
|
||||
// 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' ) );
|
||||
|
||||
// Filter _wp_auto_add_pages_to_menu by language
|
||||
add_action( 'transition_post_status', array( $this, 'auto_add_pages_to_menu' ), 5, 3 ); // before _wp_auto_add_pages_to_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
|
||||
*/
|
||||
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 $_nav_menu_placeholder; ?>][menu-item-object-id]" value="-1"> <?php esc_html_e( 'Language switcher', 'polylang' ); ?>
|
||||
</label>
|
||||
<input type="hidden" class="menu-item-type" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-type]" value="custom">
|
||||
<input type="hidden" class="menu-item-title" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-title]" value="<?php esc_html_e( 'Language switcher', 'polylang' ); ?>">
|
||||
<input type="hidden" class="menu-item-url" name="menu-item[<?php echo $_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' ); ?>" 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
|
||||
*/
|
||||
public function admin_enqueue_scripts() {
|
||||
$screen = get_current_screen();
|
||||
if ( 'nav-menus' != $screen->base ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
wp_enqueue_script( 'pll_nav_menu', plugins_url( '/js/nav-menu' . $suffix . '.js', POLYLANG_FILE ), array( 'jquery' ), POLYLANG_VERSION );
|
||||
|
||||
$data['strings'] = PLL_Switcher::get_switcher_options( 'menu', 'string' ); // The strings for the options
|
||||
$data['title'] = __( 'Language switcher', 'polylang' ); // The title
|
||||
|
||||
// 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
|
||||
$data['val'] = array();
|
||||
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 not used
|
||||
* @param int $menu_item_db_id
|
||||
*/
|
||||
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 ] ) {
|
||||
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 ( $options as $opt => $v ) {
|
||||
$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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the language switcher menu items title in case the user switches the admin language
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @param array $items
|
||||
* @return array modified $items
|
||||
*/
|
||||
public function translate_switcher_title( $items ) {
|
||||
foreach ( $items as $item ) {
|
||||
if ( '#pll_switcher' == $item->url ) {
|
||||
$item->post_title = __( 'Language switcher', 'polylang' );
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
$default = $this->options['default_lang'];
|
||||
|
||||
// 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 array $mods theme mods
|
||||
* @return unmodified $mods
|
||||
*/
|
||||
public function pre_update_option_theme_mods( $mods ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) && isset( $mods['nav_menu_locations'] ) ) {
|
||||
|
||||
// Manage Locations tab in Appearance -> Menus
|
||||
if ( isset( $_GET['action'] ) && 'locations' == $_GET['action'] ) {
|
||||
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
|
||||
* @return bool|array modified list of menu locations
|
||||
*/
|
||||
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 ( $menus as $loc => $menu ) {
|
||||
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
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the option nav_menu_options for auto added pages to menu
|
||||
*
|
||||
* @since 0.9.4
|
||||
*
|
||||
* @param array $options
|
||||
* @return array Modified options
|
||||
*/
|
||||
public function nav_menu_options( $options ) {
|
||||
$options['auto_add'] = array_intersect( $options['auto_add'], $this->auto_add_menus );
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters _wp_auto_add_pages_to_menu by language
|
||||
*
|
||||
* @since 0.9.4
|
||||
*
|
||||
* @param string $new_status Transition to this post status.
|
||||
* @param string $old_status Previous post status.
|
||||
* @param object $post Post data.
|
||||
*/
|
||||
public function auto_add_pages_to_menu( $new_status, $old_status, $post ) {
|
||||
if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type || ! empty( $post->post_parent ) || ! ( $lang = $this->model->post->get_language( $post->ID ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->options['nav_menus'][ $this->theme ] ) ) {
|
||||
$this->auto_add_menus = array();
|
||||
|
||||
// Get all the menus in the page language
|
||||
foreach ( $this->options['nav_menus'][ $this->theme ] as $loc ) {
|
||||
if ( ! empty( $loc[ $lang->slug ] ) ) {
|
||||
$this->auto_add_menus[] = $loc[ $lang->slug ];
|
||||
}
|
||||
}
|
||||
|
||||
add_filter( 'option_nav_menu_options', array( $this, 'nav_menu_options' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
165
pole-sbv-content/plugins/polylang/admin/admin-static-pages.php
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param object $polylang
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
// Removes the editor and the template select dropdown for pages for posts
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 );
|
||||
|
||||
// Add post state for translations of the front page and posts page
|
||||
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
||||
|
||||
// Refresh language cache when a static front page has been translated
|
||||
add_action( 'pll_save_post', array( $this, 'pll_save_post' ), 10, 3 );
|
||||
|
||||
// Checks if chosen page on front is translated
|
||||
add_filter( 'pre_update_option_page_on_front', array( $this, 'update_page_on_front' ), 10, 2 );
|
||||
add_filter( 'customize_validate_page_on_front', array( $this, 'customize_validate_page_on_front' ), 10, 2 );
|
||||
|
||||
// Prevents WP resetting the option
|
||||
add_filter( 'pre_update_option_show_on_front', array( $this, 'update_show_on_front' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the editor for translations of the pages for posts
|
||||
* Removes the page template select dropdown in page attributes metabox too
|
||||
*
|
||||
* @since 2.2.2
|
||||
*
|
||||
* @param string $post_type Current post type
|
||||
* @param object $post Current post
|
||||
*/
|
||||
function add_meta_boxes( $post_type, $post ) {
|
||||
if ( 'page' === $post_type ) {
|
||||
add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) );
|
||||
|
||||
if ( ( get_option( 'page_for_posts' ) == $post->ID ) && empty( $post->post_content ) ) {
|
||||
add_action( 'edit_form_after_title', '_wp_posts_page_notice' );
|
||||
remove_post_type_support( $post_type, 'editor' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add post state for translations of the front page and posts page
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param array $post_states
|
||||
* @param object $post
|
||||
* @return array
|
||||
*/
|
||||
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' );
|
||||
}
|
||||
|
||||
if ( in_array( $post->ID, $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) ) ) ) {
|
||||
$post_states['page_for_posts'] = __( 'Posts Page' );
|
||||
}
|
||||
|
||||
return $post_states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh language cache when a static front page has been translated
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_id Not used
|
||||
* @param object $post Not used
|
||||
* @param array $translations
|
||||
*/
|
||||
public function pll_save_post( $post_id, $post, $translations ) {
|
||||
if ( in_array( $this->page_on_front, $translations ) ) {
|
||||
$this->model->clean_languages_cache();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a page is translted in all languages
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
* @param int $page_id
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_page_translated( $page_id ) {
|
||||
if ( $page_id ) {
|
||||
$translations = count( $this->model->post->get_translations( $page_id ) );
|
||||
$languages = count( $this->model->get_languages_list() );
|
||||
|
||||
if ( $languages > 1 && $translations != $languages ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents choosing an untranslated static front page
|
||||
* Displays an error message
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param int $page_id New page on front page id
|
||||
* @param int $old_id Old page on front page_id
|
||||
* @return int
|
||||
*/
|
||||
public function update_page_on_front( $page_id, $old_id ) {
|
||||
if ( ! $this->is_page_translated( $page_id ) ) {
|
||||
$page_id = $old_id;
|
||||
add_settings_error( 'reading', 'pll_page_on_front_error', __( 'The chosen static front page must be translated in all languages.', 'polylang' ) );
|
||||
}
|
||||
|
||||
return $page_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an error message in the customizer when choosing an untranslated static front page
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
* @param object $validity WP_Error object
|
||||
* @param int $page_id New page on front page id
|
||||
* @return object
|
||||
*/
|
||||
public function customize_validate_page_on_front( $validity, $page_id ) {
|
||||
if ( ! $this->is_page_translated( $page_id ) ) {
|
||||
return new WP_Error( 'pll_page_on_front_error', __( 'The chosen static front page must be translated in all languages.', 'polylang' ) );
|
||||
}
|
||||
|
||||
return $validity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param string $old_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;
|
||||
}
|
||||
}
|
||||
137
pole-sbv-content/plugins/polylang/admin/admin-strings.php
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* a fully static class to manage strings translations on admin side
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class PLL_Admin_Strings {
|
||||
static protected $strings = array(); // strings to translate
|
||||
static protected $default_strings; // default strings to register
|
||||
|
||||
/**
|
||||
* init: add filters
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
static public 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
|
||||
*/
|
||||
static public function register_string( $name, $string, $context = 'Polylang', $multiline = false ) {
|
||||
// backward compatibility with Polylang older than 1.1
|
||||
if ( is_bool( $context ) ) {
|
||||
$multiline = $context;
|
||||
$context = 'Polylang';
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
static public function &get_strings() {
|
||||
self::$default_strings = array(
|
||||
'options' => array(
|
||||
'blogname' => __( 'Site Title' ),
|
||||
'blogdescription' => __( 'Tagline' ),
|
||||
'date_format' => __( 'Date Format' ),
|
||||
'time_format' => __( 'Time Format' ),
|
||||
),
|
||||
'widget_title' => __( 'Widget title', 'polylang' ),
|
||||
'widget_text' => __( 'Widget text', 'polylang' ),
|
||||
);
|
||||
|
||||
// WP strings
|
||||
foreach ( self::$default_strings['options'] as $option => $string ) {
|
||||
self::register_string( $string, get_option( $option ), 'WordPress' );
|
||||
}
|
||||
|
||||
// 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
|
||||
*/
|
||||
static public function sanitize_string_translation( $translation, $name ) {
|
||||
$translation = wp_unslash( trim( $translation ) );
|
||||
|
||||
if ( false !== ( $option = array_search( $name, self::$default_strings['options'], true ) ) ) {
|
||||
$translation = sanitize_option( $option, $translation );
|
||||
}
|
||||
|
||||
if ( $name == self::$default_strings['widget_title'] ) {
|
||||
$translation = strip_tags( $translation );
|
||||
}
|
||||
|
||||
if ( $name == self::$default_strings['widget_text'] && ! current_user_can( 'unfiltered_html' ) ) {
|
||||
$translation = wp_unslash( wp_filter_post_kses( addslashes( $translation ) ) ); // wp_filter_post_kses() expects slashed
|
||||
}
|
||||
|
||||
return $translation;
|
||||
}
|
||||
}
|
||||
116
pole-sbv-content/plugins/polylang/admin/admin.php
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* admin side controller
|
||||
* accessible in $polylang global object
|
||||
*
|
||||
* properties:
|
||||
* options => inherited, reference to Polylang options array
|
||||
* model => inherited, reference to PLL_Model object
|
||||
* links_model => inherited, reference to PLL_Links_Model object
|
||||
* links => inherited, reference to PLL_Admin_Links object
|
||||
* static_pages => inherited, reference to PLL_Admin_Static_Pages object
|
||||
* filters_links => inherited, reference to PLL_Filters_Links object
|
||||
* curlang => inherited, optional, current language used to filter the content (language of the post or term being edited, equal to filter_lang otherwise)
|
||||
* filter_lang => inherited, optional, current status of the admin languages filter (in the admin bar)
|
||||
* pref_lang => inherited, preferred language used as default when saving posts or terms
|
||||
* filters => reference to PLL_Filters object
|
||||
* filters_columns => reference to PLL_Admin_Filters_Columns object
|
||||
* filters_post => reference to PLL_Admin_Filters_Post object
|
||||
* filters_term => reference to PLL_Admin_filters_Term object
|
||||
* nav_menu => reference to PLL_Admin_Nav_Menu object
|
||||
* filters_media => optional, reference to PLL_Admin_Filters_Media object
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Admin extends PLL_Admin_Base {
|
||||
public $filters, $filters_columns, $filters_post, $filters_term, $nav_menu, $sync, $filters_media;
|
||||
|
||||
/**
|
||||
* loads the polylang text domain
|
||||
* setups filters and action needed on all admin pages and on plugins page
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $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->get_languages_list() ) {
|
||||
add_action( 'wp_loaded', array( $this, 'add_filters' ), 5 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a 'settings' link in the plugins table
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param array $links list of links associated to the plugin
|
||||
* @return array 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
|
||||
*/
|
||||
function plugin_update_message( $plugin_data, $r ) {
|
||||
if ( isset( $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
|
||||
*/
|
||||
public function add_filters() {
|
||||
// all these are separated just for convenience and maintainability
|
||||
$classes = array( 'Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Sync' );
|
||||
|
||||
// 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 loding admin filters
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param string $class class name
|
||||
*/
|
||||
$class = apply_filters( 'pll_' . $obj, 'PLL_Admin_' . $class );
|
||||
$this->$obj = new $class( $this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Displays the translations fields for media
|
||||
* Needs WP 3.5+
|
||||
*/
|
||||
|
||||
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; ?></span><?php echo esc_html( $language->name ); ?></td>
|
||||
<td class = "pll-media-edit-column">
|
||||
<?php
|
||||
// The translation exists
|
||||
if ( ( $translation_id = $this->model->post->get_translation( $post_id, $language ) ) && $translation_id !== $post_id ) {
|
||||
printf(
|
||||
'<input type="hidden" name="media_tr_lang[%s]" value="%d" />%s',
|
||||
esc_attr( $language->slug ),
|
||||
esc_attr( $translation_id ),
|
||||
$this->links->edit_post_translation_link( $translation_id )
|
||||
);
|
||||
}
|
||||
|
||||
// No translation
|
||||
else {
|
||||
echo $this->links->new_post_translation_link( $post_id, $language );
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // End foreach
|
||||
?>
|
||||
</table>
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* displays the translations fields for posts
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
$value = $this->model->post->get_translation( $post_ID, $language );
|
||||
if ( ! $value || $value == $post_ID ) { // $value == $post_ID happens if the post has been ( auto )saved before changing the language
|
||||
$value = '';
|
||||
}
|
||||
|
||||
if ( isset( $_GET['from_post'] ) ) {
|
||||
$value = $this->model->post->get( (int) $_GET['from_post'], $language );
|
||||
}
|
||||
|
||||
$link = $add_link = $this->links->new_post_translation_link( $post_ID, $language );
|
||||
|
||||
if ( $value ) {
|
||||
$selected = get_post( $value );
|
||||
$link = $this->links->edit_post_translation_link( $value );
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th class = "pll-language-column"><?php echo $language->flag ? $language->flag : esc_html( $language->slug ); ?></th>
|
||||
<td class = "hidden"><?php echo $add_link; ?></td>
|
||||
<td class = "pll-edit-column pll-column-icon"><?php echo $link; ?></td>
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Fires before the translation colummn is outputed 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="%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( $value ) ? 0 : esc_attr( $selected->ID ),
|
||||
empty( $value ) ? '' : esc_attr( $selected->post_title ),
|
||||
empty( $link ) ? ' disabled="disabled"' : '',
|
||||
esc_attr( $language->get_locale( 'display' ) ),
|
||||
$language->is_rtl ? 'rtl' : 'ltr'
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Displays the translations fields for terms
|
||||
*/
|
||||
|
||||
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 ( isset( $_GET['from_tag'] ) && ( $translation_id = $this->model->term->get( (int) $_GET['from_tag'], $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; ?></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; ?></td>
|
||||
<td class = "pll-edit-column"><?php echo $link; ?></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 ),
|
||||
empty( $disabled ) ? '' : ' disabled="disabled"',
|
||||
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
|
||||
}
|
||||
1363
pole-sbv-content/plugins/polylang/changelog.txt
Normal file
400
pole-sbv-content/plugins/polylang/css/admin.css
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
/* languages admin panel */
|
||||
#add-lang select {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.column-locale,
|
||||
.languages .column-slug {
|
||||
width : 15%
|
||||
}
|
||||
|
||||
.column-default_lang {
|
||||
width : 5%;
|
||||
}
|
||||
|
||||
.column-term_group,
|
||||
.column-flag, .column-count {
|
||||
width : 10%;
|
||||
}
|
||||
|
||||
.icon-default-lang:before {
|
||||
font-family: 'dashicons';
|
||||
content: "\f155";
|
||||
}
|
||||
|
||||
.form-field input[type="radio"] {
|
||||
width: auto;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
/* about Polylang metabox */
|
||||
#pll-about-box p,
|
||||
#pll-recommended p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
#pll-about-box input {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* strings translation table */
|
||||
.stringstranslations .column-name,
|
||||
.stringstranslations .column-context {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.stringstranslations .column-string {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.translation label {
|
||||
display: inline-block;
|
||||
width: 23%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.translation input,
|
||||
.translation textarea {
|
||||
width: 72%;
|
||||
}
|
||||
|
||||
/* settings */
|
||||
.pll-settings {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.pll-settings .plugin-title {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
#wpbody-content .pll-settings .pll-configure tr {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
#wpbody-content .pll-settings .pll-configure td {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
#wpbody-content .pll-settings .pll-configure > td {
|
||||
padding: 20px 20px 20px 40px;
|
||||
}
|
||||
|
||||
.pll-configure legend {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.pll-configure td .description {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.pll-configure p.submit {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.pll-configure .button {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.pll-configure fieldset {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.pll-inline-block-list {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.pll-inline-block-list li {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
/* settings URL modifications */
|
||||
#pll-domains-table td {
|
||||
padding: 2px 2px 2px 1.5em;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.pll-settings-url-col {
|
||||
display: inline-block;
|
||||
width: 49%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* settings Activation keys */
|
||||
#pll-licenses-table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#pll-licenses-table label {
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.pll-configure .pll-deactivate-license {
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
/* language columns in edit.php and edit-tags.php */
|
||||
th[class*='column-language_'],
|
||||
td[class*='column-language_'] {
|
||||
width: 1.5em;
|
||||
}
|
||||
|
||||
/* Text direcction in post.php and edit-tags.php */
|
||||
.pll-dir-rtl textarea,
|
||||
.pll-dir-rtl input[type="text"] {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.pll-dir-ltr textarea,
|
||||
.pll-dir-ltr input[type="text"] {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.pll-dir-ltr .tr_lang,
|
||||
.pll-dir-rtl .tr_lang {
|
||||
direction: inherit;
|
||||
}
|
||||
|
||||
/* languages metabox in post.php */
|
||||
#post-translations p {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#post-translations table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#post-translations a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#post-translations .pll-language-column,
|
||||
#post-translations .pll-column-icon {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
#post-translations .tr_lang {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#post-translations td {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#post-translations .spinner,
|
||||
#term-translations .spinner {
|
||||
float: none;
|
||||
margin: 0;
|
||||
background-position: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.pll-column-icon {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#select-post-language .pll-select-flag {
|
||||
padding: 4px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
/* specific cases for media */
|
||||
#select-media-language .pll-select-flag {
|
||||
padding: 4px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.pll-media-edit-column {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* language and translations in edit-tags.php */
|
||||
.pll-translation-flag { /* also for media */
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
#select-add-term-language .pll-select-flag {
|
||||
padding: 11px;
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
#select-edit-term-language .pll-select-flag {
|
||||
padding: 11px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
#term-translations p {
|
||||
/* same style as label */
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
padding: 2px;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
#add-term-translations,
|
||||
#edit-term-translations {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
#term-translations .pll-language-column {
|
||||
line-height: 28px;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
#term-translations .pll-edit-column,
|
||||
#add-term-translations .pll-language-column {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
#edit-term-translations .pll-language-column {
|
||||
padding: 15px 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* icon fonts */
|
||||
.pll_icon_tick:before {
|
||||
content: "\f147";
|
||||
}
|
||||
.pll_icon_add:before {
|
||||
content: "\f132";
|
||||
}
|
||||
.pll_icon_edit:before {
|
||||
content: "\f464";
|
||||
}
|
||||
|
||||
[class^="pll_icon_"] {
|
||||
font: 20px/1 'dashicons';
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* admin bar */
|
||||
#wpadminbar #wp-admin-bar-languages .ab-item img {
|
||||
margin: 0 8px 0 2px;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon {
|
||||
float: none;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-languages .ab-icon:before {
|
||||
content: "\f326";
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
@media screen and ( max-width: 782px ) {
|
||||
/* settings */
|
||||
#wpbody-content .pll-settings .pll-configure > td {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#wpbody-content .pll-settings #cb {
|
||||
padding: 20px 9px;
|
||||
}
|
||||
|
||||
/* settings URL modifications */
|
||||
.pll-inline-block {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.pll-settings-url-col {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* settings licenses */
|
||||
#wpbody-content .pll-settings #pll-licenses-table td {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pll-configure .pll-deactivate-license {
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
|
||||
/* strings translations table */
|
||||
.stringstranslations .column-context,
|
||||
.stringstranslations .column-name {
|
||||
display: none; /* backward compatibility WP < 4.3 */
|
||||
}
|
||||
|
||||
.translation label {
|
||||
display: block;
|
||||
width: 95%;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.translation input {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/* hide selected language flag and translations language name */
|
||||
#select-add-term-language .pll-select-flag,
|
||||
#select-edit-term-language .pll-select-flag,
|
||||
#edit-term-translations .pll-language-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#edit-term-translations {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#add-term-translations .pll-language-column {
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
#edit-term-translations td {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
#edit-term-translations .pll-language-column,
|
||||
#edit-term-translations .pll-edit-column {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/* translations tables should be kept as table */
|
||||
.term-translations .pll-language-column,
|
||||
.term-translations .pll-edit-column,
|
||||
.term-translations .pll-translation-column {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.term-translations .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* admin bar */
|
||||
#wpadminbar #wp-admin-bar-languages {
|
||||
display: block; /*shows our menu on mobile devices */
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-languages > .ab-item {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-languages > .ab-item .ab-icon:before {
|
||||
font: 32px/1 'dashicons';
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-languages > .ab-item img {
|
||||
margin: 19px 0;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon {
|
||||
margin-right: 6px;
|
||||
font-size: 20px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
}
|
||||
1
pole-sbv-content/plugins/polylang/css/admin.min.css
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
#pll-licenses-table td,.translation label{vertical-align:top}#add-lang select{width:95%}.column-locale,.languages .column-slug{width:15%}.column-default_lang{width:5%}.column-count,.column-flag,.column-term_group{width:10%}.icon-default-lang:before{font-family:dashicons;content:"\f155"}.form-field input[type=radio]{width:auto;margin-right:2px}#pll-about-box p,#pll-recommended p{text-align:justify}#pll-about-box input{margin:0;padding:0;float:right}.stringstranslations .column-context,.stringstranslations .column-name{width:10%}.stringstranslations .column-string{width:33%}.translation label{display:inline-block;width:23%}.translation input,.translation textarea{width:72%}.pll-settings{margin-top:20px}.pll-settings .plugin-title{width:25%}#wpbody-content .pll-settings .pll-configure tr{display:table-row}#wpbody-content .pll-settings .pll-configure td{display:table-cell}#wpbody-content .pll-settings .pll-configure>td{padding:20px 20px 20px 40px}.pll-configure legend{font-size:14px;font-weight:600;margin-bottom:.5em}.pll-configure td .description{margin-top:2px;margin-bottom:.5em}.pll-configure p.submit{margin-top:20px}.pll-configure .button{margin-right:20px}.pll-configure fieldset{margin-bottom:1.5em}.pll-inline-block-list{margin:0}.pll-inline-block-list li{display:inline-block;margin:0;width:250px}#pll-domains-table td{padding:2px 2px 2px 1.5em;-webkit-box-shadow:none;box-shadow:none;border:none}.pll-settings-url-col{display:inline-block;width:49%;vertical-align:top}#pll-licenses-table label{font-size:1em;font-weight:600}.pll-configure .pll-deactivate-license{margin:0 0 0 20px}td[class*=column-language_],th[class*=column-language_]{width:1.5em}.pll-dir-rtl input[type=text],.pll-dir-rtl textarea{direction:rtl}.pll-dir-ltr input[type=text],.pll-dir-ltr textarea{direction:ltr}.pll-dir-ltr .tr_lang,.pll-dir-rtl .tr_lang{direction:inherit}#post-translations p{float:left}#post-translations table{table-layout:fixed;width:100%;clear:both}#post-translations a{text-decoration:none}#post-translations .pll-column-icon,#post-translations .pll-language-column{width:20px}#post-translations .tr_lang{width:100%}#post-translations td{padding:2px}#post-translations .spinner,#term-translations .spinner{float:none;margin:0;background-position:center;width:auto}.pll-column-icon{text-align:center}#select-post-language .pll-select-flag{padding:4px;margin-right:32px}#select-media-language .pll-select-flag{padding:4px;margin-right:10px}.pll-media-edit-column{float:right}.pll-translation-flag{margin-right:14px}#select-add-term-language .pll-select-flag{padding:11px;margin-right:13px}#select-edit-term-language .pll-select-flag{padding:11px;margin-right:4px}#term-translations p{font-size:12px;font-style:normal;padding:2px;color:#23282d}#add-term-translations,#edit-term-translations{width:95%}#term-translations .pll-language-column{line-height:28px;width:20%}#add-term-translations .pll-language-column,#term-translations .pll-edit-column{width:20px}#edit-term-translations .pll-language-column{padding:15px 10px;font-weight:400}.pll_icon_tick:before{content:"\f147"}.pll_icon_add:before{content:"\f132"}.pll_icon_edit:before{content:"\f464"}[class^=pll_icon_]{font:20px/1 dashicons;vertical-align:middle}#wpadminbar #wp-admin-bar-languages .ab-item img{margin:0 8px 0 2px}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{float:none;top:4px}#wpadminbar #wp-admin-bar-languages .ab-icon:before{content:"\f326";top:1px}@media screen and (max-width:782px){#wpbody-content .pll-settings .pll-configure>td{padding:20px}#wpbody-content .pll-settings #cb{padding:20px 9px}.pll-inline-block{width:auto}.pll-settings-url-col{display:block;width:100%}#wpbody-content .pll-settings #pll-licenses-table td{display:block}.pll-configure .pll-deactivate-license{margin:10px 0 5px}.stringstranslations .column-context,.stringstranslations .column-name{display:none}.translation label{display:block;width:95%;padding-left:0}.translation input{width:95%}#edit-term-translations .pll-language-name,#select-add-term-language .pll-select-flag,#select-edit-term-language .pll-select-flag{display:none}#edit-term-translations{width:100%}#add-term-translations .pll-language-column{line-height:38px}#edit-term-translations td{padding:8px 10px}#edit-term-translations .pll-edit-column,#edit-term-translations .pll-language-column{width:20px}.term-translations .pll-edit-column,.term-translations .pll-language-column,.term-translations .pll-translation-column{display:table-cell}.term-translations .hidden{display:none}#wpadminbar #wp-admin-bar-languages{display:block}#wpadminbar #wp-admin-bar-languages>.ab-item{width:50px;text-align:center}#wpadminbar #wp-admin-bar-languages>.ab-item .ab-icon:before{font:32px/1 dashicons;top:-1px}#wpadminbar #wp-admin-bar-languages>.ab-item img{margin:19px 0}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{margin-right:6px;font-size:20px!important;line-height:20px!important}}
|
||||
140
pole-sbv-content/plugins/polylang/css/selectmenu.css
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/* Greatly modified version of the jquery-ui.css */
|
||||
|
||||
.ui-widget-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ui-menu .ui-menu {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.ui-menu .ui-menu-item {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 3px 1em 3px .4em;
|
||||
min-height: 0; /* support: IE7 */
|
||||
/* support: IE10, see #8844 */
|
||||
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
}
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-menu-icons .ui-menu-item {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
/* left-aligned */
|
||||
.ui-selectmenu-text .ui-icon,
|
||||
.ui-menu .ui-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: .2em;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ui-selectmenu-menu {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui-selectmenu-menu .ui-menu {
|
||||
overflow: auto;
|
||||
/* Support: IE7 */
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
line-height: 23px;
|
||||
padding: 2px 0.4em;
|
||||
margin: 0.5em 0 0 0;
|
||||
height: auto;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ui-selectmenu-open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui-selectmenu-button {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-selectmenu-button span.ui-icon {
|
||||
right: 0.5em;
|
||||
left: auto;
|
||||
margin-top: -10px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.ui-selectmenu-button span.ui-selectmenu-text {
|
||||
text-align: left;
|
||||
padding: 0.4em 2.1em 0.4em 2em;
|
||||
display: block;
|
||||
line-height: 23px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ui-widget-content,
|
||||
.ui-state-default,
|
||||
.ui-widget-content .ui-state-default,
|
||||
.ui-widget-header .ui-state-default {
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
|
||||
color: #32373c;
|
||||
}
|
||||
|
||||
.ui-widget-content .ui-state-hover,
|
||||
.ui-widget-content .ui-state-focus {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.ui-selectmenu-button.ui-state-focus {
|
||||
border: 1px solid #5b9dd9;
|
||||
box-shadow: 0 0 2px rgba(30, 140, 190, 0.8);
|
||||
}
|
||||
|
||||
.ui-icon-triangle-1-s:before {
|
||||
content: "\f140";
|
||||
font: 20px/1 'dashicons';
|
||||
}
|
||||
|
||||
.ui-widget-content {
|
||||
max-height: 231px;
|
||||
box-shadow: 0 2px 6px rgba(100, 100, 100, 0.3);
|
||||
}
|
||||
1
pole-sbv-content/plugins/polylang/css/selectmenu.min.css
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;min-height:0;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon,.ui-selectmenu-text .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:700;line-height:23px;padding:2px .4em;margin:.5em 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;margin-top:-10px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:.4em 2.1em .4em 2em;display:block;line-height:23px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-state-default,.ui-widget-content,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{background:#fff;border:1px solid #ddd;box-shadow:0 1px 2px rgba(0,0,0,.07) inset;color:#32373c}.ui-widget-content .ui-state-focus,.ui-widget-content .ui-state-hover{background:#f5f5f5}.ui-selectmenu-button.ui-state-focus{border:1px solid #5b9dd9;box-shadow:0 0 2px rgba(30,140,190,.8)}.ui-icon-triangle-1-s:before{content:"\f140";font:20px/1 dashicons}.ui-widget-content{max-height:231px;box-shadow:0 2px 6px rgba(100,100,100,.3)}
|
||||
BIN
pole-sbv-content/plugins/polylang/flags/ad.png
Normal file
|
After Width: | Height: | Size: 643 B |
BIN
pole-sbv-content/plugins/polylang/flags/ae.png
Normal file
|
After Width: | Height: | Size: 408 B |
BIN
pole-sbv-content/plugins/polylang/flags/af.png
Normal file
|
After Width: | Height: | Size: 604 B |
BIN
pole-sbv-content/plugins/polylang/flags/ag.png
Normal file
|
After Width: | Height: | Size: 591 B |
BIN
pole-sbv-content/plugins/polylang/flags/ai.png
Normal file
|
After Width: | Height: | Size: 643 B |
BIN
pole-sbv-content/plugins/polylang/flags/al.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
pole-sbv-content/plugins/polylang/flags/am.png
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
pole-sbv-content/plugins/polylang/flags/an.png
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
pole-sbv-content/plugins/polylang/flags/ao.png
Normal file
|
After Width: | Height: | Size: 428 B |
BIN
pole-sbv-content/plugins/polylang/flags/ar.png
Normal file
|
After Width: | Height: | Size: 506 B |
BIN
pole-sbv-content/plugins/polylang/flags/arab.png
Normal file
|
After Width: | Height: | Size: 401 B |
BIN
pole-sbv-content/plugins/polylang/flags/as.png
Normal file
|
After Width: | Height: | Size: 647 B |
BIN
pole-sbv-content/plugins/polylang/flags/at.png
Normal file
|
After Width: | Height: | Size: 403 B |
BIN
pole-sbv-content/plugins/polylang/flags/au.png
Normal file
|
After Width: | Height: | Size: 673 B |
BIN
pole-sbv-content/plugins/polylang/flags/aw.png
Normal file
|
After Width: | Height: | Size: 524 B |
BIN
pole-sbv-content/plugins/polylang/flags/ax.png
Normal file
|
After Width: | Height: | Size: 663 B |
BIN
pole-sbv-content/plugins/polylang/flags/az.png
Normal file
|
After Width: | Height: | Size: 589 B |
BIN
pole-sbv-content/plugins/polylang/flags/ba.png
Normal file
|
After Width: | Height: | Size: 593 B |
BIN
pole-sbv-content/plugins/polylang/flags/basque.png
Normal file
|
After Width: | Height: | Size: 565 B |
BIN
pole-sbv-content/plugins/polylang/flags/bb.png
Normal file
|
After Width: | Height: | Size: 585 B |
BIN
pole-sbv-content/plugins/polylang/flags/bd.png
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
pole-sbv-content/plugins/polylang/flags/be.png
Normal file
|
After Width: | Height: | Size: 449 B |
BIN
pole-sbv-content/plugins/polylang/flags/bf.png
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
pole-sbv-content/plugins/polylang/flags/bg.png
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
pole-sbv-content/plugins/polylang/flags/bh.png
Normal file
|
After Width: | Height: | Size: 457 B |
BIN
pole-sbv-content/plugins/polylang/flags/bi.png
Normal file
|
After Width: | Height: | Size: 675 B |
BIN
pole-sbv-content/plugins/polylang/flags/bj.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
pole-sbv-content/plugins/polylang/flags/bm.png
Normal file
|
After Width: | Height: | Size: 611 B |
BIN
pole-sbv-content/plugins/polylang/flags/bn.png
Normal file
|
After Width: | Height: | Size: 639 B |
BIN
pole-sbv-content/plugins/polylang/flags/bo.png
Normal file
|
After Width: | Height: | Size: 500 B |
BIN
pole-sbv-content/plugins/polylang/flags/br.png
Normal file
|
After Width: | Height: | Size: 593 B |
BIN
pole-sbv-content/plugins/polylang/flags/bs.png
Normal file
|
After Width: | Height: | Size: 526 B |
BIN
pole-sbv-content/plugins/polylang/flags/bt.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
pole-sbv-content/plugins/polylang/flags/bw.png
Normal file
|
After Width: | Height: | Size: 443 B |
BIN
pole-sbv-content/plugins/polylang/flags/by.png
Normal file
|
After Width: | Height: | Size: 514 B |
BIN
pole-sbv-content/plugins/polylang/flags/bz.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
pole-sbv-content/plugins/polylang/flags/ca.png
Normal file
|
After Width: | Height: | Size: 628 B |
BIN
pole-sbv-content/plugins/polylang/flags/catalonia.png
Normal file
|
After Width: | Height: | Size: 398 B |
BIN
pole-sbv-content/plugins/polylang/flags/cc.png
Normal file
|
After Width: | Height: | Size: 625 B |
BIN
pole-sbv-content/plugins/polylang/flags/cd.png
Normal file
|
After Width: | Height: | Size: 528 B |
BIN
pole-sbv-content/plugins/polylang/flags/cf.png
Normal file
|
After Width: | Height: | Size: 614 B |
BIN
pole-sbv-content/plugins/polylang/flags/cg.png
Normal file
|
After Width: | Height: | Size: 521 B |
BIN
pole-sbv-content/plugins/polylang/flags/ch.png
Normal file
|
After Width: | Height: | Size: 367 B |
BIN
pole-sbv-content/plugins/polylang/flags/ci.png
Normal file
|
After Width: | Height: | Size: 453 B |
BIN
pole-sbv-content/plugins/polylang/flags/ck.png
Normal file
|
After Width: | Height: | Size: 586 B |
BIN
pole-sbv-content/plugins/polylang/flags/cl.png
Normal file
|
After Width: | Height: | Size: 450 B |
BIN
pole-sbv-content/plugins/polylang/flags/cm.png
Normal file
|
After Width: | Height: | Size: 525 B |
BIN
pole-sbv-content/plugins/polylang/flags/cn.png
Normal file
|
After Width: | Height: | Size: 472 B |
BIN
pole-sbv-content/plugins/polylang/flags/co.png
Normal file
|
After Width: | Height: | Size: 483 B |
BIN
pole-sbv-content/plugins/polylang/flags/cr.png
Normal file
|
After Width: | Height: | Size: 477 B |
BIN
pole-sbv-content/plugins/polylang/flags/cu.png
Normal file
|
After Width: | Height: | Size: 563 B |
BIN
pole-sbv-content/plugins/polylang/flags/cv.png
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
pole-sbv-content/plugins/polylang/flags/cx.png
Normal file
|
After Width: | Height: | Size: 608 B |
BIN
pole-sbv-content/plugins/polylang/flags/cy.png
Normal file
|
After Width: | Height: | Size: 428 B |
BIN
pole-sbv-content/plugins/polylang/flags/cz.png
Normal file
|
After Width: | Height: | Size: 476 B |
BIN
pole-sbv-content/plugins/polylang/flags/de.png
Normal file
|
After Width: | Height: | Size: 545 B |
BIN
pole-sbv-content/plugins/polylang/flags/dj.png
Normal file
|
After Width: | Height: | Size: 572 B |
BIN
pole-sbv-content/plugins/polylang/flags/dk.png
Normal file
|
After Width: | Height: | Size: 495 B |
BIN
pole-sbv-content/plugins/polylang/flags/dm.png
Normal file
|
After Width: | Height: | Size: 620 B |
BIN
pole-sbv-content/plugins/polylang/flags/do.png
Normal file
|
After Width: | Height: | Size: 508 B |
BIN
pole-sbv-content/plugins/polylang/flags/dz.png
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
pole-sbv-content/plugins/polylang/flags/ec.png
Normal file
|
After Width: | Height: | Size: 500 B |
BIN
pole-sbv-content/plugins/polylang/flags/ee.png
Normal file
|
After Width: | Height: | Size: 429 B |
BIN
pole-sbv-content/plugins/polylang/flags/eg.png
Normal file
|
After Width: | Height: | Size: 465 B |
BIN
pole-sbv-content/plugins/polylang/flags/eh.png
Normal file
|
After Width: | Height: | Size: 508 B |
BIN
pole-sbv-content/plugins/polylang/flags/england.png
Normal file
|
After Width: | Height: | Size: 496 B |
BIN
pole-sbv-content/plugins/polylang/flags/er.png
Normal file
|
After Width: | Height: | Size: 653 B |
BIN
pole-sbv-content/plugins/polylang/flags/es.png
Normal file
|
After Width: | Height: | Size: 469 B |
BIN
pole-sbv-content/plugins/polylang/flags/esperanto.png
Normal file
|
After Width: | Height: | Size: 319 B |
BIN
pole-sbv-content/plugins/polylang/flags/et.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
pole-sbv-content/plugins/polylang/flags/fi.png
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
pole-sbv-content/plugins/polylang/flags/fj.png
Normal file
|
After Width: | Height: | Size: 610 B |
BIN
pole-sbv-content/plugins/polylang/flags/fk.png
Normal file
|
After Width: | Height: | Size: 648 B |
BIN
pole-sbv-content/plugins/polylang/flags/fm.png
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
pole-sbv-content/plugins/polylang/flags/fo.png
Normal file
|
After Width: | Height: | Size: 474 B |
BIN
pole-sbv-content/plugins/polylang/flags/fr.png
Normal file
|
After Width: | Height: | Size: 545 B |
BIN
pole-sbv-content/plugins/polylang/flags/ga.png
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
pole-sbv-content/plugins/polylang/flags/galicia.png
Normal file
|
After Width: | Height: | Size: 589 B |
BIN
pole-sbv-content/plugins/polylang/flags/gb.png
Normal file
|
After Width: | Height: | Size: 599 B |