: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
class SitePress_EditLanguages {
const ACCEPTED_MIME_TYPES = [
'jpg|jpeg|jpe' => 'image/jpg',
'svg' => 'image/svg+xml',
public $active_languages;
public $is_writable = false;
public $required_fields = [
'translations' => 'array',
private $validation_action = null;
public $validation_failed = false;
private $built_in_languages = [];
private $max_locale_length = 35;
private $wpml_flag_files;
/** @var bool $update_language_packs_if_needed */
private $update_language_packs_if_needed;
* @param WPML_Flags $wpml_flags
* @param bool $update_language_packs_if_needed
public function __construct( WPML_Flags $wpml_flags, $update_language_packs_if_needed = true ) {
$this->wpml_flags = $wpml_flags;
$this->wpml_flag_files = $this->wpml_flags->get_wpml_flags( array_keys( self::ACCEPTED_MIME_TYPES ) );
$this->update_language_packs_if_needed = $update_language_packs_if_needed;
ICL_PLUGIN_URL . '/res/js/languages/edit-languages.js',
[ 'jquery', 'sitepress-scripts' ],
$this->max_file_size = 100000;
$lang_codes = icl_get_languages_codes();
$this->built_in_languages = array_values( $lang_codes );
if ( $this->is_delete_language_action() ) {
$lang_id = (int) $_GET['id'];
$this->delete_language( $lang_id );
$wp_upload_dir = wp_upload_dir();
$this->upload_dir = $wp_upload_dir['basedir'] . '/flags';
if ( ! is_dir( $this->upload_dir ) ) {
$this->is_writable = is_writable( $wp_upload_dir['basedir'] );
if ( $this->is_writable ) {
mkdir( $this->upload_dir );
} catch ( Exception $ex ) {
$this->set_errors( __( 'Upload directory cannot be created. Check your permissions.', 'sitepress' ) );
$this->set_errors( __( 'Upload dir is not writable', 'sitepress' ) );
$this->is_writable = is_writable( $this->upload_dir );
$this->get_active_languages();
if ( isset( $_POST['icl_edit_languages_action'] ) && $_POST['icl_edit_languages_action'] === 'update' ) {
if ( wp_verify_nonce( $_POST['_wpnonce'], 'icl_edit_languages' ) ) {
<h2><?php echo esc_html_x( 'Edit Languages', 'Edit languages page: page title', 'sitepress' ); ?></h2>
<div id="icl_edit_languages_info">
<?php echo esc_html_x( 'This table allows you to edit languages for your site. Each row represents a language.', 'Edit languages page: sentence #1', 'sitepress' ); ?>
<?php echo esc_html_x( 'For each language, you need to enter the following information:', 'Edit languages page: sentence #2', 'sitepress' ); ?>
<strong><?php echo esc_html_x( 'Code:', 'Edit languages page: subtitle #1', 'sitepress' ); ?></strong> <?php echo esc_html_x( 'a unique value that identifies the language. Once entered, the language code cannot be changed.', 'Edit languages page: subtitle #1, description', 'sitepress' ); ?>
<strong><?php echo esc_html_x( 'Translations:', 'Edit languages page: subtitle #2', 'sitepress' ); ?></strong> <?php echo esc_html_x( 'the way the language name will be displayed in different languages.', 'Edit languages page: subtitle #2, description', 'sitepress' ); ?>
<strong><?php echo esc_html_x( 'Flag:', 'Edit languages page: subtitle #3', 'sitepress' ); ?></strong> <?php echo esc_html_x( 'the flag to display next to the language (optional). You can either upload your own flag or use one of WPML\'s built in flag images.', 'Edit languages page: subtitle #3, description', 'sitepress' ); ?>
<strong><?php echo esc_html_x( 'Default locale:', 'Edit languages page: subtitle #4', 'sitepress' ); ?></strong> <?php echo esc_html_x( 'This determines the locale value for this language. You should check the name of WordPress localization file to set this correctly.', 'Edit languages page: subtitle #4, description', 'sitepress' ); ?>
<strong><?php echo esc_html_x( 'Encode URLs:', 'Edit languages page: subtitle #5', 'sitepress' ); ?></strong> <?php echo esc_html_x( 'yes/no, determines if URLs in this language are encoded or use ASCII characters (leave ‘no’ if you are not sure).', 'Edit languages page: subtitle #5, description', 'sitepress' ); ?>
<strong><?php echo esc_html_x( 'hreflang:', 'Edit languages page: subtitle #6', 'sitepress' ); ?></strong> <?php echo esc_html_x( 'the code Google expects for this language. The hreflang should contain at least the language code (usually, made of two letters), or, if you want to specify the country/region, it sould be the same information as the locale name, but in a slightly different format. If the locale for Canadian French is fr_CA, the corresponding hreflang would be fr-ca. Instead of an underscore, use a dash (-) and all letters should be lowercase.', 'Edit languages page: subtitle #6, description', 'sitepress' ); ?>
echo ' <div class="below-h2 error"><p>' . $this->error . '</p></div>';
echo ' <div class="below-h2 updated"><p>' . $this->message . '</p></div>';
<?php $this->edit_table(); ?>
<form enctype="multipart/form-data" action="<?php echo admin_url( 'admin.php?page=' . WPML_PLUGIN_FOLDER . '/menu/languages.php&trop=1' ); ?>" method="post" id="icl_edit_languages_form">
<input type="hidden" name="icl_edit_languages_action" value="update"/>
<input type="hidden" name="icl_edit_languages_ignore_add" id="icl_edit_languages_ignore_add" value="<?php echo ( $this->is_new_data_and_invalid() ) ? 'false' : 'true'; ?>"/>
<?php wp_nonce_field( 'icl_edit_languages' ); ?>
<table id="icl_edit_languages_table" class="widefat" cellspacing="0">
<th><?php esc_html_e( 'Language name', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Code', 'sitepress' ); ?></th>
if ( $this->must_display_new_language_translation_column() ) {
echo 'style="display:none;" ';
class="icl_edit_languages_show"><?php esc_html_e( 'Translation (new)', 'sitepress' ); ?></th>
<?php foreach ( $this->active_languages as $lang ) { ?>
<th><?php esc_html_e( 'Translation', 'sitepress' ); ?> (<?php echo esc_html( $lang['english_name'] ); ?>)</th>
<th><?php esc_html_e( 'Flag', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Default locale', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Encode URLs', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'hreflang', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Language name', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Code', 'sitepress' ); ?></th>
if ( $this->must_display_new_language_translation_column() ) {
echo 'style="display:none;" ';
class="icl_edit_languages_show"><?php _e( 'Translation (new)', 'sitepress' ); ?></th>
<?php foreach ( $this->active_languages as $lang ) { ?>
<th><?php esc_html_e( 'Translation', 'sitepress' ); ?> (<?php echo $lang['english_name']; ?>)</th>
<th><?php esc_html_e( 'Flag', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Default locale', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'Encode URLs', 'sitepress' ); ?></th>
<th><?php esc_html_e( 'hreflang', 'sitepress' ); ?></th>
foreach ( $this->active_languages as $lang ) {
$this->table_row( $lang );
if ( $this->is_new_data_and_invalid() ) {
$_POST['icl_edit_languages']['add']['id'] = 'add';
$new_lang = $this->prepare_new_lang_data( $_POST['icl_edit_languages']['add'] );
$new_lang = $this->prepare_new_lang_data( [ 'id' => 'add' ] );
$this->table_row( $new_lang, true, true );
<span class="icl_error_text icl_edit_languages_show"
style="display: none; margin:10px;"><p><?php esc_html_e( 'Please note: language codes cannot be changed after adding languages. Make sure you enter the correct code.', 'sitepress' ); ?></p></span>
<p class="submit"><a href="admin.php?page=<?php echo WPML_PLUGIN_FOLDER; ?>/menu/languages.php">« <?php esc_html_e( 'Back to languages', 'sitepress' ); ?></a></p>
<p class="submit alignright">
<input type="button" name="icl_edit_languages_add_language_button" id="icl_edit_languages_add_language_button"
value="<?php esc_html_e( 'Add Language', 'sitepress' ); ?>" class="button-secondary"
if ( $this->is_new_data_and_invalid() ) {
style="display:none;"<?php } ?> />
<input type="button" name="icl_edit_languages_cancel_button" id="icl_edit_languages_cancel_button"
value="<?php esc_html_e( 'Cancel', 'sitepress' ); ?>" class="button-secondary icl_edit_languages_show"
if ( ! $this->validation_failed ) {
style="display:none;"<?php } ?> />
<input disabled="disabled" type="submit" class="button-primary" value="<?php _e( 'Save', 'sitepress' ); ?>"/>
<?php wp_nonce_field( 'reset_languages_nonce', '_icl_nonce_rl' ); ?>
<input class="button-primary" type="button" id="icl_reset_languages" value="<?php esc_html_e( 'Reset languages', 'sitepress' ); ?>"/>
<span class="hidden"><?php esc_html_e( 'WPML will reset all language information to its default values. Any languages that you added or edited will be lost.', 'sitepress' ); ?></span>
private function prepare_new_lang_data( $new_lang ) {
$new_lang = stripslashes_deep( $new_lang );
$keys = [ 'english_name', 'code', 'default_locale', 'tag' ];
foreach ( $keys as $key ) {
if ( isset( $new_lang[ $key ] ) ) {
$new_lang[ $key ] = filter_var( $new_lang[ $key ], FILTER_SANITIZE_STRING );
$new_lang['from_template'] = true;
private function table_row( $lang, $echo = true, $add = false ) {
if ( ( $this->is_new_data_and_valid() ) || 'add' !== $this->validation_action ) {
$styles[] = 'display:none';
$styles[] = 'background-color:yellow';
$classes[] = 'icl_edit_languages_show';
$style = 'style="' . implode( ';', $styles ) . '"';
$class = 'class="' . implode( ' ', $classes ) . '"';
<tr <?php echo $style; ?> <?php echo $class; ?>>
<input type="text" name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][english_name]" value="<?php echo esc_attr( $lang['english_name'] ); ?>"/>
<div class="read-only" id="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][english_name]"><?php echo esc_attr( $lang['english_name'] ); ?> <input type="hidden"
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][english_name]"
value="<?php echo esc_attr( $lang['english_name'] ); ?>"/>
<input type="text" name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][code]" value="<?php echo esc_attr( $lang['code'] ); ?>" maxlength="7" style="width:30px; max-width: 7em"/>
<div class="read-only" id="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][code]"><?php echo esc_attr( $lang['code'] ); ?> <input type="hidden"
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][code]"
value="<?php echo esc_attr( $lang['code'] ); ?>"
if ( $this->must_display_new_language_translation_column() ) {
echo 'style="display:none;" ';
class="icl_edit_languages_show"><input type="text"
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][translations][add]"
value="<?php echo esc_attr( $this->get_add_language_from_post_data( $lang['id'] ) ); ?>"/>
foreach ( $this->active_languages as $translation ) {
<td><input type="text" name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][translations][<?php echo esc_attr( $translation['code'] ); ?>]"
value="<?php echo esc_attr( $this->get_translations_data( $lang, $translation ) ); ?>"/></td>
if ( $this->is_writable ) {
$allowed_types = array_keys( self::ACCEPTED_MIME_TYPES );
<div style="float:left;">
id="wpm-edit-languages-<?php echo esc_attr( $lang['id'] ); ?>-flag-upload"
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][flag_upload]"
class="radio icl_edit_languages_use_upload"
if ( esc_attr( $lang['from_template'] ) ) {
checked="checked"<?php } ?> />
<label for="wpm-edit-languages-<?php echo esc_attr( $lang['id'] ); ?>-flag-upload">
<?php if ( $lang['code'] && $lang['from_template'] ) : ?>
<img src="<?php echo $this->wpml_flags->get_flag_url( $lang['code'] ); ?>"
alt="<?php echo esc_attr( $lang ['code'] ); ?>"/>
<?php _e( 'Custom flag', 'sitepress' ); ?>
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo esc_attr( $this->max_file_size ); ?>"/>
<div class="wpml-edit-languages-flag-upload-wrapper"
if ( ! $lang['from_template'] ) {
style="display: none;"<?php } ?>>
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][flag]"
value="<?php echo esc_attr( $lang['flag'] ); ?>"
class="icl_edit_languages_flag_enter_field" style="width: auto;"/>
<input type="file" name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][flag_file]" class="icl_edit_languages_flag_upload_field file" style="width: 200px;"/>
<?php echo sprintf( esc_html__( '(allowed: %s)', 'sitepress' ), implode( ', ', $allowed_types ) ); ?>
<?php if ( $lang['code'] && in_array( $lang['code'], $this->built_in_languages ) ) : ?>
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][flag_upload]"
class="radio icl_edit_languages_use_field"
if ( ! $lang['from_template'] ) {
checked="checked"<?php } ?> />
src="<?php echo $this->wpml_flags->get_wpml_flags_url() . $lang['code'] . '.png'; ?>"
alt="<?php echo esc_attr( $lang ['code'] ); ?>"/>
<?php esc_html_e( 'WPML flag', 'sitepress' ); ?>
<div class="wpml-edit-languages-flag-use-field">
name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][default_locale]"
value="<?php echo esc_attr( $lang['default_locale'] ); ?>"
maxlength="<?php echo esc_attr( $this->max_locale_length ); ?>"
style="width: auto; max-width: 5em;"/>
<select name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][encode_url]">
if ( empty( $lang['encode_url'] ) ) :
><?php esc_html_e( 'No', 'sitepress' ); ?></option>
if ( ! empty( $lang['encode_url'] ) ) :
><?php esc_html_e( 'Yes', 'sitepress' ); ?></option>
<td><input type="text" name="icl_edit_languages[<?php echo esc_attr( $lang['id'] ); ?>][tag]" maxlength="<?php echo esc_attr( $this->max_locale_length ); ?>" value="<?php echo esc_html( $lang['tag'] ); ?>"
style="width: auto; max-width: 5em;"/></td>
&& ! in_array( $lang['code'], $this->built_in_languages )
&& $lang['code'] != $sitepress->get_default_language()
&& count( $this->active_languages ) > 1
'admin.php?page=' . WPML_PLUGIN_FOLDER . '/menu/languages.php&trop=1&action=delete-language&id=' .
urlencode( $lang['id'] ) . '&icl_nonce=' . wp_create_nonce( 'delete-language' . $lang['id'] )
esc_attr_e( 'Delete', 'sitepress' )
echo esc_js( sprintf( __( 'Are you sure you want to delete this language?%sALL the data associated with this language will be ERASED!', 'sitepress' ), "\n" ) )
')) return false;"><img src="<?php echo ICL_PLUGIN_URL; ?>/res/img/close.png" alt="
esc_attr_e( 'Delete', 'sitepress' )
" width="16" height="16"/></a>
function get_active_languages() {
global $sitepress, $wpdb;
$this->active_languages = $sitepress->get_active_languages( true );
foreach ( $this->active_languages as $lang ) {
foreach ( $this->active_languages as $lang_translation ) {
$this->active_languages[ $lang['code'] ]['translation'][ $lang_translation['id'] ] = $sitepress->get_display_language_name( $lang['code'], $lang_translation['code'] );
$flag = $sitepress->get_flag( $lang['code'] );
$this->active_languages[ $lang['code'] ]['flag'] = $flag->flag;
$this->active_languages[ $lang['code'] ]['from_template'] = $flag->from_template;
$this->active_languages[ $lang['code'] ]['default_locale'] = $wpdb->get_var( $wpdb->prepare( "SELECT default_locale FROM {$wpdb->prefix}icl_languages WHERE code=%s", $lang['code'] ) );
$this->active_languages[ $lang['code'] ]['encode_url'] = $lang['encode_url'];
$this->active_languages[ $lang['code'] ]['tag'] = $lang['tag'];
function insert_main_table( $code, $english_name, $default_locale, $major = 0, $active = 0, $encode_url = 0, $tag = '' ) {
$wpdb->prefix . 'icl_languages', [
'english_name' => $english_name,
'default_locale' => $default_locale,