HEX
Server: nginx/1.28.1
System: Linux iZgw8b5bpgd4jyptfmmmxgZ 6.6.102-5.2.alnx4.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Nov 27 23:11:10 CST 2025 x86_64
User: www (1000)
PHP: 8.2.28
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/www.scdc-marine.com/wp-content/plugins/Polylang-Pro/modules/import/import-action.php
<?php
/**
 * @package Polylang-Pro
 */

/**
 * A class that handle the import action.
 *
 * @since 2.7
 *
 * Class PLL_Import_Action
 */
class PLL_Import_Action {

	/**
	 * Used to set import action name in forms.
	 *
	 * @var string
	 */
	const ACTION_NAME = 'pll_import';

	/**
	 * Used to create nonce for this action.
	 *
	 * @var string
	 */
	const NONCE_NAME = '_pll_import_nonce';

	/**
	 * Used to query languages and translations.
	 *
	 * @var PLL_Model
	 */
	private $model;

	/**
	 * @var PLL_Import_Uploader
	 */
	private $import_factory;

	/**
	 * PLL_Import_Action constructor.
	 *
	 * @since 2.7
	 *
	 * @param PLL_Model $model Polylang model, used to query languages and translations.
	 */
	public function __construct( $model ) {
		$this->model = $model;
		$this->import_factory = new PLL_Import_Uploader();
	}

	/**
	 * Processes the import and redirects.
	 *
	 * @since 2.7
	 *
	 * @return void
	 */
	public function import() {
		$error = $this->_import();

		if ( is_wp_error( $error ) ) {
			add_settings_error(
				'import-action',
				'settings_updated',
				$error->get_error_message() // Expects that the message is already escaped.
			);
		}

		PLL_Settings::redirect();
	}

	/**
	 * Processes the imported objects retrieved in an import file.
	 *
	 * @since 2.7
	 *
	 * @return WP_Error|true
	 */
	protected function _import() {
		if ( empty( $_FILES['importFileToUpload']['name'] ) ) {
			return new WP_Error( 'pll_import_no_file', esc_html__( "Error: You haven't selected a file to be uploaded.", 'polylang-pro' ) );
		}

		$import = $this->import_factory->load( $_FILES['importFileToUpload'] ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

		if ( is_wp_error( $import ) ) {
			return $import;
		}

		$error = $this->is_data_valid_for_import( $import );
		if ( is_wp_error( $error ) ) {
			return $error;
		}

		$entry = $import->get_next_entry();

		if ( PLL_Import_Export::STRINGS_TRANSLATIONS === $entry['type'] ) {
			$updated = $this->create_string_translations_on_import( $entry['data'], $this->model->get_language( $import->get_target_language() ) );

			if ( is_wp_error( $updated ) ) {
				return $updated;
			}

			add_settings_error(
				'import-action',
				'settings_updated',
				esc_html(
					sprintf(
						/* translators: %d is a number of strings translations */
						_n( '%d string translation updated.', '%d string translations updated.', $updated, 'polylang-pro' ),
						$updated
					)
				),
				'updated'
			);
		}

		return true;
	}

	/**
	 * Check the data's validity for the import.
	 *
	 * @since 2.7
	 *
	 * @param PLL_Import_File_Interface $import Import file.
	 * @return bool|WP_Error
	 */
	public function is_data_valid_for_import( $import ) {
		if ( $import->get_site_reference() !== get_site_url() ) {
			return new WP_Error( 'pll_import_wrong_site', esc_html__( 'Error: The site targeted in the imported file does not match the current site.', 'polylang-pro' ) );
		}

		$locale = $import->get_target_language();

		if ( false === $locale ) {
			return new WP_Error( 'pll_import_no_language', esc_html__( 'Error: No target languages have been provided in the imported file.', 'polylang-pro' ) );
		}
		if ( ! $this->model->get_language( $locale ) ) {
			return new WP_Error( 'pll_import_wrong_language', esc_html__( "Error: You are trying to import a file in a language which doesn't exist on your site.", 'polylang-pro' ) );
		}

		return true;
	}

	/**
	 * Remove the context for the translation entries.
	 *
	 * @since 3.2
	 *
	 * @param  array $translations Array containing the entries.
	 * @return array               The same entries with an empty context.
	 */
	private function remove_context_from_translations( $translations ) {
		foreach ( $translations as $translation_entry ) {
			$translation_entry->context = '';
		}
		return $translations;
	}

	/**
	 * Handles the strings translations saving in the database.
	 *
	 * @since 2.7
	 *
	 * @param PO           $translations Contains all translations entries.
	 * @param PLL_Language $language     Target Language.
	 * @return int|WP_Error The number of updated strings.
	 */
	public function create_string_translations_on_import( $translations, $language ) {
		$pll_mo = new PLL_MO();
		$pll_mo->import_from_db( $language );
		$updated = 0;
		$errors = array();
		$strings = '';

		// Clone the $pll_mo element to avoid modifying the original one since we will then update it.
		$pll_mo_clone = clone $pll_mo;

		// Remove the context for the translation entries to generate the same key between the translation strings
		// and the database strings.
		$translations->entries = $this->remove_context_from_translations( $translations->entries );

		foreach ( $translations->entries as $entry ) {
			if ( empty( $entry->translations ) ) {
				$entry->translations[0] = '';
			}

			/** This filter is documented in /polylang/settings/table-string.php */
			$sanitized_translation = apply_filters( 'pll_sanitize_string_translation', $entry->translations[0], $entry->extracted_comments, $entry->context );
			$security_check = wp_kses_post( $sanitized_translation );
			if ( $security_check === $sanitized_translation ) {

				// Set a unique key for each entry to compare the original and translated strings.
				$key = $entry->key();

				// Check if there is already an original string existing before comparison.
				if ( isset( $pll_mo_clone->entries[ $key ]->translations[0] ) ) {
					// Check that the string has been edited before updating.
					if ( $pll_mo_clone->entries[ $key ]->translations[0] !== $sanitized_translation ) {
						$pll_mo->add_entry( $pll_mo->make_entry( $entry->singular, $sanitized_translation ) );
						$updated ++;
					}
				}
			} else {
				$errors[] = $entry->singular;
			}
		}

		if ( $updated ) {
			$pll_mo->export_to_db( $language );
		}

		if ( ! empty( $errors ) ) {
			$message = esc_html(
				_n(
					'The translation of the following string was not imported for security reasons:',
					'The translation of the following strings were not imported for security reasons:',
					count( $errors ),
					'polylang-pro'
				)
			);
			foreach ( $errors as $error ) {
				$strings .= sprintf( '<br /><span class="pll-icon pll-circle" ></span>%s', esc_html( $error ) );
			}
			$message = sprintf( '%s<br/>%s', $message, $strings );
			return new WP_Error( 'pll_import_security', $message );
		}

		return $updated;
	}
}