Вход Регистрация
Файл: system/vendor/nesbot/carbon/src/Carbon/Traits/Localization.php
Строк: 1125
<?php

/**
 * This file is part of the Carbon package.
 *
 * (c) Brian Nesbitt <brian@nesbot.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace CarbonTraits;

use 
CarbonCarbonInterface;
use 
CarbonExceptionsNotLocaleAwareException;
use 
CarbonLanguage;
use 
CarbonTranslator;
use 
Closure;
use 
InvalidArgumentException;
use 
SymfonyComponentTranslationTranslatorBagInterface;
use 
SymfonyComponentTranslationTranslatorInterface;
use 
SymfonyContractsTranslationLocaleAwareInterface;
use 
SymfonyContractsTranslationTranslatorInterface as ContractsTranslatorInterface;

if (!
interface_exists('Symfony\Component\Translation\TranslatorInterface')) {
    
class_alias(
        
'Symfony\Contracts\Translation\TranslatorInterface',
        
'Symfony\Component\Translation\TranslatorInterface'
    
);
}

/**
 * Trait Localization.
 *
 * Embed default and locale translators and translation base methods.
 */
trait Localization
{
    
/**
     * Default translator.
     *
     * @var SymfonyComponentTranslationTranslatorInterface
     */
    
protected static $translator;

    
/**
     * Specific translator of the current instance.
     *
     * @var SymfonyComponentTranslationTranslatorInterface
     */
    
protected $localTranslator;

    
/**
     * Options for diffForHumans().
     *
     * @var int
     */
    
protected static $humanDiffOptions CarbonInterface::NO_ZERO_DIFF;

    
/**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     * @see settings
     *
     * @param int $humanDiffOptions
     */
    
public static function setHumanDiffOptions($humanDiffOptions)
    {
        static::
$humanDiffOptions $humanDiffOptions;
    }

    
/**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     * @see settings
     *
     * @param int $humanDiffOption
     */
    
public static function enableHumanDiffOption($humanDiffOption)
    {
        static::
$humanDiffOptions = static::getHumanDiffOptions() | $humanDiffOption;
    }

    
/**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather use the ->settings() method.
     * @see settings
     *
     * @param int $humanDiffOption
     */
    
public static function disableHumanDiffOption($humanDiffOption)
    {
        static::
$humanDiffOptions = static::getHumanDiffOptions() & ~$humanDiffOption;
    }

    
/**
     * Return default humanDiff() options (merged flags as integer).
     *
     * @return int
     */
    
public static function getHumanDiffOptions()
    {
        return static::
$humanDiffOptions;
    }

    
/**
     * Initialize the default translator instance if necessary.
     *
     * @return SymfonyComponentTranslationTranslatorInterface
     */
    
protected static function translator()
    {
        if (static::
$translator === null) {
            static::
$translator Translator::get();
        }

        return static::
$translator;
    }

    
/**
     * Get the default translator instance in use.
     *
     * @return SymfonyComponentTranslationTranslatorInterface
     */
    
public static function getTranslator()
    {
        return static::
translator();
    }

    
/**
     * Set the default translator instance to use.
     *
     * @param SymfonyComponentTranslationTranslatorInterface $translator
     *
     * @return void
     */
    
public static function setTranslator(TranslatorInterface $translator)
    {
        static::
$translator $translator;
    }

    
/**
     * Return true if the current instance has its own translator.
     *
     * @return bool
     */
    
public function hasLocalTranslator()
    {
        return isset(
$this->localTranslator);
    }

    
/**
     * Get the translator of the current instance or the default if none set.
     *
     * @return SymfonyComponentTranslationTranslatorInterface
     */
    
public function getLocalTranslator()
    {
        return 
$this->localTranslator ?: static::translator();
    }

    
/**
     * Set the translator for the current instance.
     *
     * @param SymfonyComponentTranslationTranslatorInterface $translator
     *
     * @return $this
     */
    
public function setLocalTranslator(TranslatorInterface $translator)
    {
        
$this->localTranslator $translator;

        return 
$this;
    }

    
/**
     * Returns raw translation message for a given key.
     *
     * @param SymfonyComponentTranslationTranslatorInterface $translator the translator to use
     * @param string                                             $key        key to find
     * @param string|null                                        $locale     current locale used if null
     * @param string|null                                        $default    default value if translation returns the key
     *
     * @return string
     */
    
public static function getTranslationMessageWith($translatorstring $keystring $locale nullstring $default null)
    {
        if (!(
$translator instanceof TranslatorBagInterface && $translator instanceof TranslatorInterface)) {
            throw new 
InvalidArgumentException(
                
'Translator does not implement '.TranslatorInterface::class.' and '.TranslatorBagInterface::class.'.'
            
);
        }

        if (!
$locale && $translator instanceof LocaleAwareInterface) {
            
$locale $translator->getLocale();
        }

        
$result $translator->getCatalogue($locale)->get($key);

        return 
$result === $key $default $result;
    }

    
/**
     * Returns raw translation message for a given key.
     *
     * @param string                                             $key        key to find
     * @param string|null                                        $locale     current locale used if null
     * @param string|null                                        $default    default value if translation returns the key
     * @param SymfonyComponentTranslationTranslatorInterface $translator an optional translator to use
     *
     * @return string
     */
    
public function getTranslationMessage(string $keystring $locale nullstring $default null$translator null)
    {
        return static::
getTranslationMessageWith($translator ?: $this->getLocalTranslator(), $key$locale$default);
    }

    
/**
     * Translate using translation string or callback available.
     *
     * @param SymfonyComponentTranslationTranslatorInterface $translator
     * @param string                                             $key
     * @param array                                              $parameters
     * @param null                                               $number
     *
     * @return string
     */
    
public static function translateWith(TranslatorInterface $translatorstring $key, array $parameters = [], $number null): string
    
{
        
$message = static::getTranslationMessageWith($translator$keynull$key);
        if (
$message instanceof Closure) {
            return (string) 
$message(...array_values($parameters));
        }

        if (
$number !== null) {
            
$parameters['%count%'] = $number;
        }
        if (isset(
$parameters['%count%'])) {
            
$parameters[':count'] = $parameters['%count%'];
        }

        
// @codeCoverageIgnoreStart
        
$choice $translator instanceof ContractsTranslatorInterface
            
$translator->trans($key$parameters)
            : 
$translator->transChoice($key$number$parameters);
        
// @codeCoverageIgnoreEnd

        
return (string) $choice;
    }

    
/**
     * Translate using translation string or callback available.
     *
     * @param string                                             $key
     * @param array                                              $parameters
     * @param null                                               $number
     * @param SymfonyComponentTranslationTranslatorInterface $translator
     *
     * @return string
     */
    
public function translate(string $key, array $parameters = [], $number nullTranslatorInterface $translator nullbool $altNumbers false): string
    
{
        
$translation = static::translateWith($translator ?: $this->getLocalTranslator(), $key$parameters$number);

        if (
$number !== null && $altNumbers) {
            return 
str_replace($number$this->translateNumber($number), $translation);
        }

        return 
$translation;
    }

    
/**
     * Returns the alternative number for a given integer if available in the current locale.
     *
     * @param int $number
     *
     * @return string
     */
    
public function translateNumber(int $number): string
    
{
        
$translateKey "alt_numbers.$number";
        
$symbol $this->translate($translateKey);

        if (
$symbol !== $translateKey) {
            return 
$symbol;
        }

        if (
$number 99 && $this->translate('alt_numbers.99') !== 'alt_numbers.99') {
            
$start '';
            foreach ([
100001000100] as $exp) {
                
$key "alt_numbers_pow.$exp";
                if (
$number >= $exp && $number $exp 10 && ($pow $this->translate($key)) !== $key) {
                    
$unit floor($number $exp);
                    
$number -= $unit $exp;
                    
$start .= ($unit $this->translate("alt_numbers.$unit") : '').$pow;
                }
            }
            
$result '';
            while (
$number) {
                
$chunk $number 100;
                
$result $this->translate("alt_numbers.$chunk").$result;
                
$number floor($number 100);
            }

            return 
"$start$result";
        }

        if (
$number && $this->translate('alt_numbers.9') !== 'alt_numbers.9') {
            
$result '';
            while (
$number) {
                
$chunk $number 10;
                
$result $this->translate("alt_numbers.$chunk").$result;
                
$number floor($number 10);
            }

            return 
$result;
        }

        return 
"$number";
    }

    
/**
     * Translate a time string from a locale to an other.
     *
     * @param string      $timeString time string to translate
     * @param string|null $from       input locale of the $timeString parameter (`Carbon::getLocale()` by default)
     * @param string|null $to         output locale of the result returned (`"en"` by default)
     * @param int         $mode       specify what to translate with options:
     *                                - CarbonInterface::TRANSLATE_ALL (default)
     *                                - CarbonInterface::TRANSLATE_MONTHS
     *                                - CarbonInterface::TRANSLATE_DAYS
     *                                - CarbonInterface::TRANSLATE_UNITS
     *                                - CarbonInterface::TRANSLATE_MERIDIEM
     *                                You can use pipe to group: CarbonInterface::TRANSLATE_MONTHS | CarbonInterface::TRANSLATE_DAYS
     *
     * @return string
     */
    
public static function translateTimeString($timeString$from null$to null$mode CarbonInterface::TRANSLATE_ALL)
    {
        
$from $from ?: static::getLocale();
        
$to $to ?: 'en';

        if (
$from === $to) {
            return 
$timeString;
        }

        
$cleanWord = function ($word) {
            
$word str_replace([':count''%count'':time'], ''$word);
            
$word preg_replace('/({d+(,(d+|Inf))?}|[[]]d+(,(d+|Inf))?[[]])/'''$word);

            return 
trim($word);
        };

        
$fromTranslations = [];
        
$toTranslations = [];

        foreach ([
'from''to'] as $key) {
            
$language = $$key;
            
$translator Translator::get($language);
            
$translations $translator->getMessages();

            if (!isset(
$translations[$language])) {
                return 
$timeString;
            }

            
$translationKey $key.'Translations';
            
$messages $translations[$language];
            
$months $messages['months'];
            
$weekdays $messages['weekdays'];
            
$meridiem $messages['meridiem'] ?? ['AM''PM'];

            if (
$key === 'from') {
                foreach ([
'months''weekdays'] as $variable) {
                    
$list $messages[$variable.'_standalone'] ?? null;

                    if (
$list) {
                        foreach ($
$variable as $index => &$name) {
                            
$name .= '|'.$messages[$variable.'_standalone'][$index];
                        }
                    }
                }
            }

            $
$translationKey array_merge(
                
$mode CarbonInterface::TRANSLATE_MONTHS array_pad($months12'>>DO NOT REPLACE<<') : [],
                
$mode CarbonInterface::TRANSLATE_MONTHS array_pad($messages['months_short'], 12'>>DO NOT REPLACE<<') : [],
                
$mode CarbonInterface::TRANSLATE_DAYS array_pad($weekdays7'>>DO NOT REPLACE<<') : [],
                
$mode CarbonInterface::TRANSLATE_DAYS array_pad($messages['weekdays_short'], 7'>>DO NOT REPLACE<<') : [],
                
$mode CarbonInterface::TRANSLATE_UNITS array_map(function ($unit) use ($messages$key$cleanWord) {
                    
$parts explode('|'$messages[$unit]);

                    return 
$key === 'to'
                        
$cleanWord(end($parts))
                        : 
'(?:'.implode('|'array_map($cleanWord$parts)).')';
                }, [
                    
'year',
                    
'month',
                    
'week',
                    
'day',
                    
'hour',
                    
'minute',
                    
'second',
                ]) : [],
                
$mode CarbonInterface::TRANSLATE_MERIDIEM array_map(function ($hour) use ($meridiem) {
                    if (
is_array($meridiem)) {
                        return 
$meridiem[$hour 12 1];
                    }

                    return 
$meridiem($hour0false);
                }, 
range(023)) : []
            );
        }

        return 
substr(preg_replace_callback('/(?<=[ds+./,_-])('.implode('|'$fromTranslations).')(?=[ds+./,_-])/i', function ($match) use ($fromTranslations$toTranslations) {
            [
$chunk] = $match;

            foreach (
$fromTranslations as $index => $word) {
                if (
preg_match("/^$word$/i"$chunk)) {
                    return 
$toTranslations[$index] ?? '';
                }
            }

            return 
$chunk// @codeCoverageIgnore
        
}, $timeString "), 1, -1);
    }

    
/**
     * Translate a time string from the current locale (`$date->locale()`) to an other.
     *
     * @param string      $timeString time string to translate
     * @param string|null $to         output locale of the result returned ("en" by default)
     *
     * @return string
     */
    
public function translateTimeStringTo($timeString$to null)
    {
        return static::
translateTimeString($timeString$this->getTranslatorLocale(), $to);
    }

    
/**
     * Get/set the locale for the current instance.
     *
     * @param string|null $locale
     * @param string[]    ...$fallbackLocales
     *
     * @return $this|string
     */
    
public function locale(string $locale null, ...$fallbackLocales)
    {
        if (
$locale === null) {
            return 
$this->getTranslatorLocale();
        }

        if (!
$this->localTranslator || $this->getTranslatorLocale($this->localTranslator) !== $locale) {
            
$translator Translator::get($locale);

            if (!empty(
$fallbackLocales)) {
                
$translator->setFallbackLocales($fallbackLocales);

                foreach (
$fallbackLocales as $fallbackLocale) {
                    
$messages Translator::get($fallbackLocale)->getMessages();

                    if (isset(
$messages[$fallbackLocale])) {
                        
$translator->setMessages($fallbackLocale$messages[$fallbackLocale]);
                    }
                }
            }

            
$this->setLocalTranslator($translator);
        }

        return 
$this;
    }

    
/**
     * Get the current translator locale.
     *
     * @return string
     */
    
public static function getLocale()
    {
        return static::
getLocaleAwareTranslator()->getLocale();
    }

    
/**
     * Set the current translator locale and indicate if the source locale file exists.
     * Pass 'auto' as locale to use closest language from the current LC_TIME locale.
     *
     * @param string $locale locale ex. en
     *
     * @return bool
     */
    
public static function setLocale($locale)
    {
        return static::
getLocaleAwareTranslator()->setLocale($locale) !== false;
    }

    
/**
     * Set the fallback locale.
     *
     * @see https://symfony.com/doc/current/components/translation.html#fallback-locales
     *
     * @param string $locale
     */
    
public static function setFallbackLocale($locale)
    {
        
$translator = static::getTranslator();

        if (
method_exists($translator'setFallbackLocales')) {
            
$translator->setFallbackLocales([$locale]);

            if (
$translator instanceof Translator) {
                
$preferredLocale $translator->getLocale();
                
$translator->setMessages($preferredLocalearray_replace_recursive(
                    
$translator->getMessages()[$locale] ?? [],
                    
Translator::get($locale)->getMessages()[$locale] ?? [],
                    
$translator->getMessages($preferredLocale)
                ));
            }
        }
    }

    
/**
     * Get the fallback locale.
     *
     * @see https://symfony.com/doc/current/components/translation.html#fallback-locales
     *
     * @return string|null
     */
    
public static function getFallbackLocale()
    {
        
$translator = static::getTranslator();

        if (
method_exists($translator'getFallbackLocales')) {
            return 
$translator->getFallbackLocales()[0] ?? null;
        }

        return 
null;
    }

    
/**
     * Set the current locale to the given, execute the passed function, reset the locale to previous one,
     * then return the result of the closure (or null if the closure was void).
     *
     * @param string   $locale locale ex. en
     * @param callable $func
     *
     * @return mixed
     */
    
public static function executeWithLocale($locale$func)
    {
        
$currentLocale = static::getLocale();
        
$result call_user_func($func, static::setLocale($locale) ? static::getLocale() : false, static::translator());
        static::
setLocale($currentLocale);

        return 
$result;
    }

    
/**
     * Returns true if the given locale is internally supported and has short-units support.
     * Support is considered enabled if either year, day or hour has a short variant translated.
     *
     * @param string $locale locale ex. en
     *
     * @return bool
     */
    
public static function localeHasShortUnits($locale)
    {
        return static::
executeWithLocale($locale, function ($newLocaleTranslatorInterface $translator) {
            return 
$newLocale &&
                (
                    (
$y = static::translateWith($translator'y')) !== 'y' &&
                    
$y !== static::translateWith($translator'year')
                ) || (
                    (
$y = static::translateWith($translator'd')) !== 'd' &&
                    
$y !== static::translateWith($translator'day')
                ) || (
                    (
$y = static::translateWith($translator'h')) !== 'h' &&
                    
$y !== static::translateWith($translator'hour')
                );
        });
    }

    
/**
     * Returns true if the given locale is internally supported and has diff syntax support (ago, from now, before, after).
     * Support is considered enabled if the 4 sentences are translated in the given locale.
     *
     * @param string $locale locale ex. en
     *
     * @return bool
     */
    
public static function localeHasDiffSyntax($locale)
    {
        return static::
executeWithLocale($locale, function ($newLocaleTranslatorInterface $translator) {
            if (!
$newLocale) {
                return 
false;
            }

            foreach ([
'ago''from_now''before''after'] as $key) {
                if (
$translator instanceof TranslatorBagInterface && $translator->getCatalogue($newLocale)->get($key) instanceof Closure) {
                    continue;
                }

                if (
$translator->trans($key) === $key) {
                    return 
false;
                }
            }

            return 
true;
        });
    }

    
/**
     * Returns true if the given locale is internally supported and has words for 1-day diff (just now, yesterday, tomorrow).
     * Support is considered enabled if the 3 words are translated in the given locale.
     *
     * @param string $locale locale ex. en
     *
     * @return bool
     */
    
public static function localeHasDiffOneDayWords($locale)
    {
        return static::
executeWithLocale($locale, function ($newLocaleTranslatorInterface $translator) {
            return 
$newLocale &&
                
$translator->trans('diff_now') !== 'diff_now' &&
                
$translator->trans('diff_yesterday') !== 'diff_yesterday' &&
                
$translator->trans('diff_tomorrow') !== 'diff_tomorrow';
        });
    }

    
/**
     * Returns true if the given locale is internally supported and has words for 2-days diff (before yesterday, after tomorrow).
     * Support is considered enabled if the 2 words are translated in the given locale.
     *
     * @param string $locale locale ex. en
     *
     * @return bool
     */
    
public static function localeHasDiffTwoDayWords($locale)
    {
        return static::
executeWithLocale($locale, function ($newLocaleTranslatorInterface $translator) {
            return 
$newLocale &&
                
$translator->trans('diff_before_yesterday') !== 'diff_before_yesterday' &&
                
$translator->trans('diff_after_tomorrow') !== 'diff_after_tomorrow';
        });
    }

    
/**
     * Returns true if the given locale is internally supported and has period syntax support (X times, every X, from X, to X).
     * Support is considered enabled if the 4 sentences are translated in the given locale.
     *
     * @param string $locale locale ex. en
     *
     * @return bool
     */
    
public static function localeHasPeriodSyntax($locale)
    {
        return static::
executeWithLocale($locale, function ($newLocaleTranslatorInterface $translator) {
            return 
$newLocale &&
                
$translator->trans('period_recurrences') !== 'period_recurrences' &&
                
$translator->trans('period_interval') !== 'period_interval' &&
                
$translator->trans('period_start_date') !== 'period_start_date' &&
                
$translator->trans('period_end_date') !== 'period_end_date';
        });
    }

    
/**
     * Returns the list of internally available locales and already loaded custom locales.
     * (It will ignore custom translator dynamic loading.)
     *
     * @return array
     */
    
public static function getAvailableLocales()
    {
        
$translator = static::getLocaleAwareTranslator();

        return 
$translator instanceof Translator
            
$translator->getAvailableLocales()
            : [
$translator->getLocale()];
    }

    
/**
     * Returns list of Language object for each available locale. This object allow you to get the ISO name, native
     * name, region and variant of the locale.
     *
     * @return Language[]
     */
    
public static function getAvailableLocalesInfo()
    {
        
$languages = [];
        foreach (static::
getAvailableLocales() as $id) {
            
$languages[$id] = new Language($id);
        }

        return 
$languages;
    }

    protected function 
getTranslatorLocale($translator null): ?string
    
{
        if (
func_num_args() === 0) {
            
$translator $this->getLocalTranslator();
        }

        
$translator = static::getLocaleAwareTranslator($translator);

        return 
$translator $translator->getLocale() : null;
    }

    
/**
     * Throw an error if passed object is not LocaleAwareInterface.
     *
     * @param LocaleAwareInterface|null $translator
     *
     * @return LocaleAwareInterface|null
     */
    
protected static function getLocaleAwareTranslator($translator null)
    {
        if (
func_num_args() === 0) {
            
$translator = static::translator();
        }

        if (
$translator && !($translator instanceof LocaleAwareInterface || method_exists($translator'getLocale'))) {
            throw new 
NotLocaleAwareException($translator);
        }

        return 
$translator;
    }
}
Онлайн: 0
Реклама