<?php

/**
 * Escapes special characters that Mantis might otherwise mangle.
 *
 * @param string $text The text to process.
 *
 * @return string The text after any escaping.
 */
protected function escapeSpecialChars($text) {
	// Escape all #/@/~ inside <pre> and <code>
	$text = preg_replace_callback(
		'%(<(pre|code)(?:\s[^>]*)?>)(.+?)(</\2\s*>)%ism',
		function ($matches) {
			$matches[3] = mb_encode_numericentity(
				$matches[3],
				[
					// '#'
					0x23, 0x23, 0, 0xff,
					// '@'
					0x40, 0x40, 0, 0xff,
					// '~'
					0x7e, 0x7e, 0, 0xff,
				],
				'UTF-8'
			);
			return implode('', [
				$matches[1],
				$matches[3],
				$matches[4],
			]);
		},
		$text
	);

	// Escape all #/~ preceded by back-slashes
	$text = preg_replace_callback(
		'%(\\\\+)([#~])(\d)%',
		function ($matches) {
			$backslashes = $matches[1];
			$char        = $matches[2];
			$number      = $matches[3];

			// Even number of back-slashes
			if ( ($len = strlen($backslashes)) && $len % 2 === 0 ) {
				$backslashes = substr($backslashes, floor($len / 2));
			// Odd number of back-slashes
			} else {
				$backslashes = substr($backslashes, floor($len / 2) + 1);
				$char        = mb_encode_numericentity($char, [
					// '#'
					0x23, 0x23, 0, 0xff,
					// '~'
					0x7e, 0x7e, 0, 0xff,
				], 'UTF-8');
			}

			return implode('', [
				$backslashes,
				$char,
				$number,
			]);
		},
		$text
	);

	return $text;
}

