HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux vmi1674223.contaboserver.net 5.4.0-182-generic #202-Ubuntu SMP Fri Apr 26 12:29:36 UTC 2024 x86_64
User: root (0)
PHP: 7.4.3-4ubuntu2.22
Disabled: 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_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/ojs/lib/pkp/tools/xmlToPo.php
<?php

/**
 * @file tools/xmlToPo.php
 *
 * Copyright (c) 2014-2021 Simon Fraser University
 * Copyright (c) 2003-2021 John Willinsky
 * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
 *
 * @class xmlToPo
 * @ingroup tools
 */

require(dirname(dirname(dirname(dirname(__FILE__)))) . '/tools/bootstrap.inc.php');

class xmlToPo extends CommandLineTool {
	/** @var string Name of source file/directory */
	protected $source;

	/** @var string Name of target file/directory */
	protected $target;

	/**
	 * Constructor
	 */
	function __construct($argv = array()) {
		parent::__construct($argv);

		array_shift($argv); // Shift the tool name off the top

		$this->source = array_shift($argv);
		$this->target = array_shift($argv);

		// The source file/directory must be specified and exist.
		if (empty($this->source) || !file_exists($this->source)) {
			$this->usage();
			exit(2);
		}

		// The target file must be specified, unless we're converting an entire directory.
		if (empty($this->target)) {
			if (is_file($this->source)) {
				$this->usage();
				exit(3);
			} else {
				// If we're converting a directory and no target was specified, we use the source dir.
				$this->target = $this->source;
			}
		}

		// If the target file/directory exists, it must be like the source file/directory.
		if (file_exists($this->target) && (is_dir($this->source) != is_dir($this->target))) {
			$this->usage();
			exit(4);
		}
	}

	/**
	 * Print command usage information.
	 */
	function usage() {
		echo "Script to convert XML locale file to PO format\n\n"
			. "Usage: {$this->scriptName} input-locale-file.xml output-file.po\n\n"
			. "or, to convert all locale files in a specified directory:\n\n"
			. "{$this->scriptName} input-path [output-path]\n\n"
			. "When specifying a path, the output path is optional. If it is not specified, the input path will be used.\n";
	}

	/**
	 * Parse a locale file into an array.
	 * @param $filename string Filename to locale file
	 * @return array? (key => message)
	 */
	static function parseLocaleFile($filename) {
		$localeData = null;
		$xmlDao = new XMLDAO();
		$data = $xmlDao->parseStruct($filename, array('message'));

		// Build array with ($key => $string)
		if (isset($data['message'])) {
			foreach ($data['message'] as $messageData) {
				$localeData[$messageData['attributes']['key']] = $messageData['value'];
			}
		}

		return $localeData;
	}

	/**
	 * Convert a file from XML to PO.
	 * @param $source Source filename
	 * @param $target Target filename
	 */
	static function convertFile($source, $target) {
		$localeData = array();

		$sourceData = self::parseLocaleFile($source);
		if (!$sourceData) throw new Exception('Unable to load source file ' . $source);

		$translations = new \Gettext\Translations();
		foreach ($sourceData as $key => $sourceTranslation) {
			$translation = new \Gettext\Translation('', $key);
			$translation->setTranslation("$sourceTranslation");
			$translations->append($translation);
		}

		return $translations->toPoFile($target);
	}

	/**
	 * Convert XML locale content to PO format.
	 */
	function execute() {
		if (is_dir($this->source)) {
			// The caller specified a directory of files.
			import('lib.pkp.classes.file.FileManager');
			$fileManager = new FileManager();

			// Look recursively for files to convert.
			$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->source));
			foreach ($iterator as $file) {
				if ($file->isDir()) continue;
				$pathname = $file->getPathname();
				if (strrchr($pathname, '.') != '.xml') continue;

				// If we can't glean any data from the file, skip it.
				if (!self::parseLocaleFile($pathname)) continue;

				// This seems to be a locale file. Try to convert it.
				if (substr($pathname, 0, strlen($this->source)) !== $this->source) continue;
				$targetPath = $this->target . dirname(substr($pathname, strlen($this->source)));
				$targetFile = $targetPath . '/' . basename($pathname, '.xml') . '.po';

				// Ensure the target directory exists.
				$fileManager->mkdirtree($targetPath);

				echo "$pathname => $targetFile\n";
				self::convertFile($pathname, $targetFile);
			}
		} else {
			// Convert just a single file, as specified.
			self::convertFile($this->source, $this->target);
		}
	}
}

$tool = new xmlToPo(isset($argv) ? $argv : array());
$tool->execute();