1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) 2010 Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12class Twig_Extensions_Extension_Intl extends Twig_Extension
13{
14    public function __construct()
15    {
16        if (!class_exists('IntlDateFormatter')) {
17            throw new RuntimeException('The native PHP intl extension (http://php.net/manual/en/book.intl.php) is needed to use intl-based filters.');
18        }
19    }
20
21    /**
22     * {@inheritdoc}
23     */
24    public function getFilters()
25    {
26        return array(
27            new Twig_SimpleFilter('localizeddate', 'twig_localized_date_filter', array('needs_environment' => true)),
28            new Twig_SimpleFilter('localizednumber', 'twig_localized_number_filter'),
29            new Twig_SimpleFilter('localizedcurrency', 'twig_localized_currency_filter'),
30        );
31    }
32
33    /**
34     * {@inheritdoc}
35     */
36    public function getName()
37    {
38        return 'intl';
39    }
40}
41
42function twig_localized_date_filter(Twig_Environment $env, $date, $dateFormat = 'medium', $timeFormat = 'medium', $locale = null, $timezone = null, $format = null, $calendar = 'gregorian')
43{
44    $date = twig_date_converter($env, $date, $timezone);
45
46    $formatValues = array(
47        'none' => IntlDateFormatter::NONE,
48        'short' => IntlDateFormatter::SHORT,
49        'medium' => IntlDateFormatter::MEDIUM,
50        'long' => IntlDateFormatter::LONG,
51        'full' => IntlDateFormatter::FULL,
52    );
53
54    if (PHP_VERSION_ID < 50500 || !class_exists('IntlTimeZone')) {
55        $formatter = IntlDateFormatter::create(
56            $locale,
57            $formatValues[$dateFormat],
58            $formatValues[$timeFormat],
59            $date->getTimezone()->getName(),
60            'gregorian' === $calendar ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL,
61            $format
62        );
63
64        return $formatter->format($date->getTimestamp());
65    }
66
67    $formatter = IntlDateFormatter::create(
68        $locale,
69        $formatValues[$dateFormat],
70        $formatValues[$timeFormat],
71        IntlTimeZone::createTimeZone($date->getTimezone()->getName()),
72        'gregorian' === $calendar ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL,
73        $format
74    );
75
76    return $formatter->format($date->getTimestamp());
77}
78
79function twig_localized_number_filter($number, $style = 'decimal', $type = 'default', $locale = null)
80{
81    static $typeValues = array(
82        'default' => NumberFormatter::TYPE_DEFAULT,
83        'int32' => NumberFormatter::TYPE_INT32,
84        'int64' => NumberFormatter::TYPE_INT64,
85        'double' => NumberFormatter::TYPE_DOUBLE,
86        'currency' => NumberFormatter::TYPE_CURRENCY,
87    );
88
89    $formatter = twig_get_number_formatter($locale, $style);
90
91    if (!isset($typeValues[$type])) {
92        throw new Twig_Error_Syntax(sprintf('The type "%s" does not exist. Known types are: "%s"', $type, implode('", "', array_keys($typeValues))));
93    }
94
95    return $formatter->format($number, $typeValues[$type]);
96}
97
98function twig_localized_currency_filter($number, $currency = null, $locale = null)
99{
100    $formatter = twig_get_number_formatter($locale, 'currency');
101
102    return $formatter->formatCurrency($number, $currency);
103}
104
105/**
106 * Gets a number formatter instance according to given locale and formatter.
107 *
108 * @param string $locale Locale in which the number would be formatted
109 * @param int    $style  Style of the formatting
110 *
111 * @return NumberFormatter A NumberFormatter instance
112 */
113function twig_get_number_formatter($locale, $style)
114{
115    static $formatter, $currentStyle;
116
117    $locale = null !== $locale ? $locale : Locale::getDefault();
118
119    if ($formatter && $formatter->getLocale() === $locale && $currentStyle === $style) {
120        // Return same instance of NumberFormatter if parameters are the same
121        // to those in previous call
122        return $formatter;
123    }
124
125    static $styleValues = array(
126        'decimal' => NumberFormatter::DECIMAL,
127        'currency' => NumberFormatter::CURRENCY,
128        'percent' => NumberFormatter::PERCENT,
129        'scientific' => NumberFormatter::SCIENTIFIC,
130        'spellout' => NumberFormatter::SPELLOUT,
131        'ordinal' => NumberFormatter::ORDINAL,
132        'duration' => NumberFormatter::DURATION,
133    );
134
135    if (!isset($styleValues[$style])) {
136        throw new Twig_Error_Syntax(sprintf('The style "%s" does not exist. Known styles are: "%s"', $style, implode('", "', array_keys($styleValues))));
137    }
138
139    $currentStyle = $style;
140
141    $formatter = NumberFormatter::create($locale, $styleValues[$style]);
142
143    return $formatter;
144}
145
146class_alias('Twig_Extensions_Extension_Intl', 'Twig\Extensions\IntlExtension', false);
147