Fallback implementation for MessageFormatter::formatMessage

@param string $pattern
@param array $parameters
@param string $locale
@return string
189214
protected function fallbackFormat($pattern, $parameters, $locale)
    {
        $tokens = $this->tokenizePattern($pattern);

        foreach ($tokens as $key => $token) {
            if (! is_array($token)) {
                continue;
            }

            // The token is an ICU command.
            else if (($value = $this->parseToken($token, $parameters, $locale)) === false) {
                throw new LogicException('Message pattern is invalid.');
            }

            $tokens[$key] = $value;
        }

        return implode('', $tokens);
    }
1140944
public static Format getFormatter(@Nonnull final Locale locale, @Nonnull final String format,
                                      @Nullable final Class<?>... type) {
        Format formatter = null;
        Pattern TEXT_FORMAT_STRING = Pattern.compile("^\\{([^}]+)}(.+)$");
        Matcher matcher = TEXT_FORMAT_STRING.matcher(format);
        if (matcher.matches()) {
            switch (matcher.group(1)) {
                case "Message":
                    formatter = new MessageFormat(matcher.group(2), locale);
                    break;
                case "Date":
                    formatter = new SimpleDateFormat(matcher.group(2), locale);
                    break;
                case "String":
                    formatter = new FormatterFormat(matcher.group(2), locale);
                    break;
                default:
                case "Log":
                    formatter = new LoggerFormat(matcher.group(2));
                    break;
            }
        } else {
            if (type != null && type.length == 1 && type[0] != null &&
                    (Calendar.class.isAssignableFrom(type[0]) || Date.class.isAssignableFrom(type[0]))) {
                formatter = new SimpleDateFormat(format, locale);
            } else {
                formatter = new LoggerFormat(format);
            }
        }
        return formatter;
    }
1006876
public function format($value, $params = null, $locale = null) {
		if ($locale === null) {
			$locale = 'en';
		}
		
		$formatter = $this->getFormatter($locale);
		
		if (isset($params['primary'])) {
			return $formatter->formatCurrency($value, $params['primary']);
		}

		if (isset($params['currency'])) {
			return $formatter->formatCurrency($value, $params['currency']);
		}
		
		trigger_error('The "currency" parameter was not specified');
		
		return $formatter->format($value);
	}
237768
private function formatMessage(string $message, array $params): string
    {
        $params = \array_values($params);
        \array_unshift($params, $message);
        
        return \sprintf(...$params);
    }
110988
public static String format(TemporalAccessor localDate, String pattern) {
        return DateTimeFormatter.ofPattern(pattern).format(localDate);
    }
1332801
public function formatDatetime($time, $pattern = null, $locale = null, $timezone = null, $dateType = null, $timeType = null)
    {
        if ($pattern) {
            return $this->helper->format($time, $pattern, $locale, $timezone);
        }

        return $this->helper->formatDateTime($time, $locale, $timezone, $dateType, $timeType);
    }
440823
public function translate($locale, TranslatableResource $resource)
    {
        $canonicalLocale = \Locale::canonicalize($locale);
        $messageFormatter = new \MessageFormatter(
            $canonicalLocale,
            $this->retrievePattern($canonicalLocale, $resource->getKey())
        );

        return $messageFormatter->format($resource->getParameters());
    }
881581
public static String format(final LocalTime self, String pattern) {
        return self.format(DateTimeFormatter.ofPattern(pattern));
    }
1313596
public static String format(Locale locale, TimeZone timeZone, String pattern, Date date) {
	synchronized (data) {
	    String key = locale.toString() + '-' + timeZone.getID() + '-' + pattern;
	    Object obj = data.get(key);
	    if (obj != null) {
		return ((SimpleDateFormat) obj).format(date);
	    }
	    SimpleDateFormat sdf = new SimpleDateFormat(pattern, locale);
	    sdf.setTimeZone(timeZone);
	    data.put(key, sdf);
	    return sdf.format(date);
	}
    }
488914
private function parseToken($token, $parameters, $locale)
    {
        $key = trim($token[0]);

        if (isset($parameters[$key])) {
            $parameter = $parameters[$key];
        } else {
            return '{' .implode(',', $token) .'}';
        }

        $type = isset($token[1]) ? trim($token[1]) : 'none';

        switch ($type) {
            case 'none':
                return $parameter;

            case 'number':
                if (is_integer($parameter) && (! isset($token[2]) || (trim($token[2]) == 'integer'))) {
                    return $parameter;
                }

                throw new LogicException("Message format [number] is only supported for integer values.");

                break;
            case 'date':
            case 'time':
            case 'spellout':
            case 'ordinal':
            case 'duration':
            case 'choice':
            case 'selectordinal':
                throw new LogicException("Message format [$type] is not supported.");
        };

        if (! isset($token[2])) {
            return false;
        }

        $tokens = $this->tokenizePattern($token[2]);

        if ($type == 'select') {
            $message = $this->parseSelect($tokens, $parameter);
        } else if ($type == 'plural') {
            $message = $this->parsePlural($tokens, $parameter);
        }

        if ($message !== false) {
            return $this->fallbackFormat($message, $parameters, $locale);
        }

        return false;
    }
586258
public function replacePattern($pattern, Siteroot $siteroot, ElementVersion $elementVersion, $language)
    {
        $replace = [
            '%s' => $siteroot->getTitle(),
            '%b' => $elementVersion->getBackendTitle($language),
            '%p' => $elementVersion->getPageTitle($language),
            '%n' => $elementVersion->getNavigationTitle($language),
            '%r' => $this->projectTitle,
        ];

        return str_replace(array_keys($replace), array_values($replace), $pattern);
    }
387291
protected function formatExceptionErrorForLocal(Exception $e, $fallbackMessage = null)
    {
        $message = $e->getMessage() ?: $fallbackMessage;

        return [
            'message' => $message,
            'code'    => $e->getCode(),
            'file'    => $e->getFile(),
            'line'    => $e->getLine(),
            'trace'   => array_map(function($trace) {
                return trim(
                    (isset($trace['file']) ? $trace['file'] . ' : ' . $trace['line'] : '')
                    . '   '
                    . (isset($trace['function']) ? $trace['function']
                        . (isset($trace['class']) ? ' on ' . $trace['class'] : '')
                    : '')
                );
            }, $e->getTrace()),
        ];
    }
891586
public String formatAsString(final String formatPattern, final String value, final Locale locale) {
        return format(formatPattern, value, locale).getText();
    }
1019125
public static String format(final String messagePattern, final Object[] arguments) {
        return ParameterFormatter.format(messagePattern, arguments);
    }
1037827
private function getSnippetTemplate($pattern, $methodName, array $methodArguments)
    {
        return sprintf(
            self::$templateTemplate,
            str_replace('%', '%%', $pattern),
            $methodName,
            implode(', ', $methodArguments)
        );
    }
915875
private function retrievePattern($locale, $key)
    {
        $resBundle = $this->getResourceBundle($locale);

        $pattern = $resBundle->get($key);

        if ($pattern === null) {
            throw new \IntlException($resBundle->getErrorMessage(), $resBundle->getErrorCode());
        }

        return $pattern;
    }
836061
public static function formatLocale($locale)
    {
        if (\is_string($locale)) {
            $locale = strtolower($locale);
            $locale = str_replace('-', '_', $locale);
        }

        return $locale;
    }