pax_global_header00006660000000000000000000000064135561353120014516gustar00rootroot0000000000000052 comment=c2fc15b0d21cabd42653c76ca8c06154c59e9cbd twig-extensions-1.5.4/000077500000000000000000000000001355613531200146745ustar00rootroot00000000000000twig-extensions-1.5.4/.gitignore000066400000000000000000000000431355613531200166610ustar00rootroot00000000000000phpunit.xml vendor/ composer.lock twig-extensions-1.5.4/.travis.yml000066400000000000000000000011401355613531200170010ustar00rootroot00000000000000language: php sudo: false cache: directories: - vendor - $HOME/.composer/cache/files env: - DEPS=no before_install: - phpenv config-rm xdebug.ini before_script: - if [ "$DEPS" == "low" ]; then composer --prefer-lowest --prefer-stable update; fi; - if [ "$DEPS" == "no" ]; then composer install; fi; script: | ./vendor/bin/simple-phpunit matrix: include: - php: 5.3 dist: precise - php: 5.4 - php: 5.5 - php: 5.6 env: DEPS=low - php: 7.0 - php: 7.1 - php: 7.2 fast_finish: true twig-extensions-1.5.4/LICENSE000066400000000000000000000020511355613531200156770ustar00rootroot00000000000000Copyright (c) 2010-2017 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. twig-extensions-1.5.4/README.rst000066400000000000000000000006151355613531200163650ustar00rootroot00000000000000Twig Extensions Repository ========================== This repository hosts Twig Extensions that do not belong to the core but can be nonetheless interesting to share with other developers. Fork this repository, add your extension, and request a pull. More Information ---------------- Read the `documentation`_ for more information. .. _documentation: http://twig-extensions.readthedocs.io/ twig-extensions-1.5.4/composer.json000066400000000000000000000014661355613531200174250ustar00rootroot00000000000000{ "name": "twig/extensions", "description": "Common additional features for Twig that do not directly belong in core", "keywords": ["i18n","text"], "type": "library", "license": "MIT", "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" } ], "require": { "twig/twig": "^1.27|^2.0" }, "require-dev": { "symfony/phpunit-bridge": "^3.4", "symfony/translation": "^2.7|^3.4" }, "suggest": { "symfony/translation": "Allow the time_diff output to be translated" }, "autoload": { "psr-0": { "Twig_Extensions_": "lib/" }, "psr-4": { "Twig\\Extensions\\": "src/" } }, "extra": { "branch-alias": { "dev-master": "1.5-dev" } } } twig-extensions-1.5.4/doc/000077500000000000000000000000001355613531200154415ustar00rootroot00000000000000twig-extensions-1.5.4/doc/array.rst000066400000000000000000000004561355613531200173160ustar00rootroot00000000000000The Array Extension =================== The Array extensions provides the following filters: * ``shuffle`` Installation ------------ First, :ref:`install the Extensions library`. Next, add the extension to Twig:: $twig->addExtension(new Twig_Extensions_Extension_Array()); twig-extensions-1.5.4/doc/date.rst000066400000000000000000000023241355613531200171110ustar00rootroot00000000000000The Date Extension =================== The *Date* extension provides the ``time_diff`` filter. You need to register this extension before using the ``time_diff`` filter:: $twig->addExtension(new Twig_Extensions_Extension_Date()); ``time_diff`` ------------- Use the ``time_diff`` filter to render the difference between a date and now. .. code-block:: jinja {{ post.published_at|time_diff }} The example above will output a string like ``4 seconds ago`` or ``in 1 month``, depending on the filtered date. .. note:: Internally, Twig uses the PHP ``DateTime::diff()`` method for calculating the difference between dates, this means that PHP 5.3+ is required. Arguments ~~~~~~~~~ * ``date``: The date for calculate the difference from now. Can be a string or a DateTime instance. * ``now``: The date that should be used as now. Can be a string or a DateTime instance. Do not set this argument to use current date. Translation ~~~~~~~~~~~ To get a translatable output, give a ``Symfony\Component\Translation\TranslatorInterface`` as constructor argument. The returned string is formatted as ``diff.ago.XXX`` or ``diff.in.XXX`` where ``XXX`` can be any valid unit: second, minute, hour, day, month, year. twig-extensions-1.5.4/doc/i18n.rst000066400000000000000000000132361355613531200167570ustar00rootroot00000000000000The i18n Extension ================== Configuration ------------- The ``i18n`` extension adds `gettext`_ support to Twig. It defines one tag, ``trans``. To use it, first, :ref:`install the Extensions library`. You need to register this extension before using the ``trans`` block:: $twig->addExtension(new Twig_Extensions_Extension_I18n()); Note that you must configure the ``gettext`` extension before rendering any internationalized template. Here is a simple configuration example from the PHP `documentation`_:: // Set language to French putenv('LC_ALL=fr_FR'); setlocale(LC_ALL, 'fr_FR'); // Specify the location of the translation tables bindtextdomain('myAppPhp', 'includes/locale'); bind_textdomain_codeset('myAppPhp', 'UTF-8'); // Choose domain textdomain('myAppPhp'); .. caution:: The ``i18n`` extension only works if the PHP `gettext`_ extension is enabled. Usage ----- Use the ``trans`` block to mark parts in the template as translatable: .. code-block:: jinja {% trans "Hello World!" %} {% trans string_var %} {% trans %} Hello World! {% endtrans %} In a translatable string, you can embed variables: .. code-block:: jinja {% trans %} Hello {{ name }}! {% endtrans %} During the gettext lookup these placeholders are converted. ``{{ name }}`` becomes ``%name%`` so the gettext ``msgid`` for this string would be ``Hello %name%!``. .. note:: ``{% trans "Hello {{ name }}!" %}`` is not a valid statement. If you need to apply filters to the variables, you first need to assign the result to a variable: .. code-block:: jinja {% set name = name|capitalize %} {% trans %} Hello {{ name }}! {% endtrans %} To pluralize a translatable string, use the ``plural`` block: .. code-block:: jinja {% trans %} Hey {{ name }}, I have one apple. {% plural apple_count %} Hey {{ name }}, I have {{ count }} apples. {% endtrans %} The ``plural`` tag should provide the ``count`` used to select the right string. Within the translatable string, the special ``count`` variable always contain the count value (here the value of ``apple_count``). To add notes for translators, use the ``notes`` block: .. code-block:: jinja {% trans %} Hey {{ name }}, I have one apple. {% plural apple_count %} Hey {{ name }}, I have {{ count }} apples. {% notes %} This is shown in the user menu. This string should be shorter than 30 chars {% endtrans %} You can use ``notes`` with or without ``plural``. Once you get your templates compiled you should configure the ``gettext`` parser to get something like this: ``xgettext --add-comments=notes`` Within an expression or in a tag, you can use the ``trans`` filter to translate simple strings or variables: .. code-block:: jinja {{ var|default(default_value|trans) }} Complex Translations within an Expression or Tag ------------------------------------------------ Translations can be done with both the ``trans`` tag and the ``trans`` filter. The filter is less powerful as it only works for simple variables or strings. For more complex scenario, like pluralization, you can use a two-step strategy: .. code-block:: jinja {# assign the translation to a temporary variable #} {% set default_value %} {% trans %} Hey {{ name }}, I have one apple. {% plural apple_count %} Hey {{ name }}, I have {{ count }} apples. {% endtrans %} {% endset %} {# use the temporary variable within an expression #} {{ var|default(default_value|trans) }} Extracting Template Strings --------------------------- If you use the Twig I18n extension, you will probably need to extract the template strings at some point. Using Poedit 2 ~~~~~~~~~~~~~~ Poedit 2 has native support for extracting from Twig files and no extra setup is necessary (Pro version). Using ``xgettext`` or Poedit 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unfortunately, the ``xgettext`` utility does not understand Twig templates natively and neither do tools based on it such as free versions of Poedit. But there is a simple workaround: as Twig converts templates to PHP files, you can use ``xgettext`` on the template cache instead. Create a script that forces the generation of the cache for all your templates. Here is a simple example to get you started:: $tplDir = dirname(__FILE__).'/templates'; $tmpDir = '/tmp/cache/'; $loader = new Twig_Loader_Filesystem($tplDir); // force auto-reload to always have the latest version of the template $twig = new Twig_Environment($loader, array( 'cache' => $tmpDir, 'auto_reload' => true )); $twig->addExtension(new Twig_Extensions_Extension_I18n()); // configure Twig the way you want // iterate over all your templates foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tplDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { // force compilation if ($file->isFile()) { $twig->loadTemplate(str_replace($tplDir.'/', '', $file)); } } Use the standard ``xgettext`` utility as you would have done with plain PHP code: .. code-block:: text xgettext --default-domain=messages -p ./locale --from-code=UTF-8 -n --omit-header -L PHP /tmp/cache/*.php Another workaround is to use `Twig Gettext Extractor`_ and extract the template strings right from `Poedit`_. .. _`gettext`: http://www.php.net/gettext .. _`documentation`: http://fr.php.net/manual/en/function.gettext.php .. _`Twig Gettext Extractor`: https://github.com/umpirsky/Twig-Gettext-Extractor .. _`Poedit`: http://www.poedit.net/ twig-extensions-1.5.4/doc/index.rst000066400000000000000000000016731355613531200173110ustar00rootroot00000000000000Twig Extensions =============== .. toctree:: :hidden: text i18n intl array date The Twig Extensions is a library that provides several useful extensions for Twig. You can find it's code at `GitHub.com/twigphp/Twig-extensions`_. .. _extensions-install: Installation ------------ This library can be installed via Composer running the following from the command line: .. code-block:: bash composer require twig/extensions * :doc:`Text `: Provides useful filters for text manipulation; * :doc:`I18n `: Adds internationalization support via the ``gettext`` library; * :doc:`Intl `: Adds a filter for localization of ``DateTime`` objects, numbers and currency; * :doc:`Array `: Provides useful filters for array manipulation; * :doc:`Date `: Adds a filter for rendering the difference between dates. .. _`GitHub.com/twigphp/Twig-extensions`: https://github.com/twigphp/Twig-extensions twig-extensions-1.5.4/doc/intl.rst000066400000000000000000000147031355613531200171460ustar00rootroot00000000000000The Intl Extension ================== The *Intl* extensions provides the ``localizeddate``, ``localizednumber`` and ``localizedcurrency`` filters. Installation ------------ First, :ref:`install the Extensions library`. Next, add the extension to Twig:: $twig->addExtension(new Twig_Extensions_Extension_Intl()); ``localizeddate`` ----------------- Use the ``localizeddate`` filter to format dates into a localized string representating the date. .. code-block:: jinja {{ post.published_at|localizeddate('medium', 'none', locale) }} The ``localizeddate`` filter accepts strings (it must be in a format supported by the `strtotime`_ function), `DateTime`_ instances, or `Unix timestamps`_. .. note:: Internally, Twig uses the PHP `IntlDateFormatter::create()`_ function for the date. Arguments ~~~~~~~~~ * ``date_format``: The date format. Choose one of these formats: * 'none': `IntlDateFormatter::NONE`_ * 'short': `IntlDateFormatter::SHORT`_ * 'medium': `IntlDateFormatter::MEDIUM`_ * 'long': `IntlDateFormatter::LONG`_ * 'full': `IntlDateFormatter::FULL`_ * ``time_format``: The time format. Same formats possible as above. * ``locale``: The locale used for the format. If ``NULL`` is given, Twig will use ``Locale::getDefault()`` * ``timezone``: The date timezone * ``format``: Optional pattern to use when formatting or parsing. Possible patterns are documented in the `ICU user guide`_. * ``calendar``: Calendar to use for formatting. The default value is 'gregorian', which corresponds to IntlDateFormatter::GREGORIAN. Choose one of these formats: * 'gregorian': `IntlDateFormatter::GREGORIAN`_ * 'traditional': `IntlDateFormatter::TRADITIONAL`_ For the following calendars should use 'traditional': * Japanese * Buddhist * Chinese * Persian * Indian * Islamic * Hebrew * Coptic * Ethiopic Also for non-Gregorian calendars need to be specified in locale. Examples might include locale="fa_IR@calendar=PERSIAN". ``localizednumber`` ------------------- Use the ``localizednumber`` filter to format numbers into a localized string representating the number. .. code-block:: jinja {{ product.quantity|localizednumber }} .. note:: Internally, Twig uses the PHP `NumberFormatter::create()`_ function for the number. Arguments ~~~~~~~~~ * ``style``: Optional number format (default: 'decimal'). Choose one of these formats: * 'decimal': `NumberFormatter::DECIMAL`_ * 'currency': `NumberFormatter::CURRENCY`_ * 'percent': `NumberFormatter::PERCENT`_ * 'scientific': `NumberFormatter::SCIENTIFIC`_ * 'spellout': `NumberFormatter::SPELLOUT`_ * 'ordinal': `NumberFormatter::ORDINAL`_ * 'duration': `NumberFormatter::DURATION`_ * ``type``: Optional formatting type to use (default: 'default'). Choose one of these types: * 'default': `NumberFormatter::TYPE_DEFAULT`_ * 'int32': `NumberFormatter::TYPE_INT32`_ * 'int64': `NumberFormatter::TYPE_INT64`_ * 'double': `NumberFormatter::TYPE_DOUBLE`_ * 'currency': `NumberFormatter::TYPE_CURRENCY`_ * ``locale``: The locale used for the format. If ``NULL`` is given, Twig will use ``Locale::getDefault()`` ``localizedcurrency`` --------------------- Use the ``localizedcurrency`` filter to format a currency value into a localized string. .. code-block:: jinja {{ product.price|localizedcurrency('EUR') }} .. note:: Internally, Twig uses the PHP `NumberFormatter::create()`_ function for the number. Arguments ~~~~~~~~~ * ``currency``: The 3-letter ISO 4217 currency code indicating the currency to use. * ``locale``: The locale used for the format. If ``NULL`` is given, Twig will use ``Locale::getDefault()`` .. _`strtotime`: http://php.net/strtotime .. _`DateTime`: http://php.net/DateTime .. _`Unix timestamps`: http://en.wikipedia.org/wiki/Unix_time .. _`IntlDateFormatter::create()`: http://php.net/manual/en/intldateformatter.create.php .. _`IntlDateFormatter::NONE`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.none .. _`IntlDateFormatter::SHORT`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.short .. _`IntlDateFormatter::MEDIUM`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.medium .. _`IntlDateFormatter::LONG`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.long .. _`IntlDateFormatter::FULL`: http://php.net/manual/en/class.intldateformatter.php#intldateformatter.constants.full .. _`IntlDateFormatter::GREGORIAN`: http://php.net/IntlDateFormatter#intldateformatter.constants.gregorian .. _`IntlDateFormatter::TRADITIONAL`: http://php.net/IntlDateFormatter#intldateformatter.constants.traditional .. _`ICU user guide`: http://userguide.icu-project.org/formatparse/datetime .. _`NumberFormatter::create()`: http://php.net/manual/en/numberformatter.create.php .. _`NumberFormatter::DECIMAL`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.decimal .. _`NumberFormatter::CURRENCY`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.currency .. _`NumberFormatter::PERCENT`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.percent .. _`NumberFormatter::SCIENTIFIC`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.scientific .. _`NumberFormatter::SPELLOUT`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.spellout .. _`NumberFormatter::ORDINAL`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.ordinal .. _`NumberFormatter::DURATION`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.duration .. _`NumberFormatter::TYPE_DEFAULT`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-default .. _`NumberFormatter::TYPE_INT32`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-int32 .. _`NumberFormatter::TYPE_INT64`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-int64 .. _`NumberFormatter::TYPE_DOUBLE`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-double .. _`NumberFormatter::TYPE_CURRENCY`: http://php.net/manual/en/class.numberformatter.php#numberformatter.constants.type-currency twig-extensions-1.5.4/doc/text.rst000066400000000000000000000031741355613531200171640ustar00rootroot00000000000000The Text Extension ================== The Text extension provides the following filters: * ``truncate`` * ``wordwrap`` Installation ------------ First, :ref:`install the Extensions library`. Next, add the extension to Twig:: $twig->addExtension(new Twig_Extensions_Extension_Text()); Wrapping Words -------------- Use the ``wordwrap`` filter to split your text in lines with equal length. .. code-block:: jinja {{ "Lorem ipsum dolor sit amet, consectetur adipiscing"|wordwrap(10) }} This example would print:: Lorem ipsu m dolor si t amet, co nsectetur adipiscing The default separator is "\\n", but you can easily change that by providing one: .. code-block:: jinja {{ "Lorem ipsum dolor sit amet, consectetur adipiscing"|wordwrap(10, "zz\n") }} This would result in:: Lorem ipsuzz m dolor sizz t amet, cozz nsectetur zz adipiscing Truncating Text --------------- Use the ``truncate`` filter to cut off a string after limit is reached .. code-block:: jinja {{ "Hello World!"|truncate(5) }} The example would output ``Hello...``, as ``...`` is the default separator. You can also tell truncate to preserve whole words by setting the second parameter to ``true``. If the last Word is on the the separator, truncate will print out the whole Word. .. code-block:: jinja {{ "Hello World!"|truncate(7, true) }} Here ``Hello World!`` would be printed. If you want to change the separator, just set the third parameter to your desired separator. .. code-block:: jinja {{ "Hello World!"|truncate(7, false, "??") }} This example would print ``Hello W??``. twig-extensions-1.5.4/lib/000077500000000000000000000000001355613531200154425ustar00rootroot00000000000000twig-extensions-1.5.4/lib/Twig/000077500000000000000000000000001355613531200163545ustar00rootroot00000000000000twig-extensions-1.5.4/lib/Twig/Extensions/000077500000000000000000000000001355613531200205135ustar00rootroot00000000000000twig-extensions-1.5.4/lib/Twig/Extensions/Autoloader.php000066400000000000000000000022511355613531200233230ustar00rootroot00000000000000 * * @deprecated since version 1.5, use Composer instead. */ class Twig_Extensions_Autoloader { /** * Registers Twig_Extensions_Autoloader as an SPL autoloader. */ public static function register() { spl_autoload_register(array(new self(), 'autoload')); } /** * Handles autoloading of classes. * * @param string $class a class name * * @return bool Returns true if the class has been loaded */ public static function autoload($class) { if (0 !== strpos($class, 'Twig_Extensions')) { return; } if (file_exists($file = __DIR__.'/../../'.str_replace('_', '/', $class).'.php')) { require $file; } } } twig-extensions-1.5.4/lib/Twig/Extensions/Extension/000077500000000000000000000000001355613531200224675ustar00rootroot00000000000000twig-extensions-1.5.4/lib/Twig/Extensions/Extension/Array.php000066400000000000000000000017701355613531200242630ustar00rootroot00000000000000 */ class Twig_Extensions_Extension_Array extends Twig_Extension { /** * {@inheritdoc} */ public function getFilters() { $filters = array( new Twig_SimpleFilter('shuffle', 'twig_shuffle_filter'), ); return $filters; } /** * {@inheritdoc} */ public function getName() { return 'array'; } } /** * Shuffles an array. * * @param array|Traversable $array An array * * @return array */ function twig_shuffle_filter($array) { if ($array instanceof Traversable) { $array = iterator_to_array($array, false); } shuffle($array); return $array; } class_alias('Twig_Extensions_Extension_Array', 'Twig\Extensions\ArrayExtension', false); twig-extensions-1.5.4/lib/Twig/Extensions/Extension/Date.php000066400000000000000000000056121355613531200240610ustar00rootroot00000000000000 */ class Twig_Extensions_Extension_Date extends Twig_Extension { public static $units = array( 'y' => 'year', 'm' => 'month', 'd' => 'day', 'h' => 'hour', 'i' => 'minute', 's' => 'second', ); /** * @var TranslatorInterface */ private $translator; public function __construct(TranslatorInterface $translator = null) { // Ignore the IdentityTranslator, otherwise the parameters won't be replaced properly if ($translator instanceof IdentityTranslator) { $translator = null; } $this->translator = $translator; } /** * {@inheritdoc} */ public function getFilters() { return array( new Twig_SimpleFilter('time_diff', array($this, 'diff'), array('needs_environment' => true)), ); } /** * Filter for converting dates to a time ago string like Facebook and Twitter has. * * @param Twig_Environment $env a Twig_Environment instance * @param string|DateTime $date a string or DateTime object to convert * @param string|DateTime $now A string or DateTime object to compare with. If none given, the current time will be used. * * @return string the converted time */ public function diff(Twig_Environment $env, $date, $now = null) { // Convert both dates to DateTime instances. $date = twig_date_converter($env, $date); $now = twig_date_converter($env, $now); // Get the difference between the two DateTime objects. $diff = $date->diff($now); // Check for each interval if it appears in the $diff object. foreach (self::$units as $attribute => $unit) { $count = $diff->$attribute; if (0 !== $count) { return $this->getPluralizedInterval($count, $diff->invert, $unit); } } return ''; } protected function getPluralizedInterval($count, $invert, $unit) { if ($this->translator) { $id = sprintf('diff.%s.%s', $invert ? 'in' : 'ago', $unit); return $this->translator->transChoice($id, $count, array('%count%' => $count), 'date'); } if (1 !== $count) { $unit .= 's'; } return $invert ? "in $count $unit" : "$count $unit ago"; } /** * {@inheritdoc} */ public function getName() { return 'date'; } } class_alias('Twig_Extensions_Extension_Date', 'Twig\Extensions\DateExtension', false); twig-extensions-1.5.4/lib/Twig/Extensions/Extension/I18n.php000066400000000000000000000014201355613531200237140ustar00rootroot00000000000000 true)), new Twig_SimpleFilter('localizednumber', 'twig_localized_number_filter'), new Twig_SimpleFilter('localizedcurrency', 'twig_localized_currency_filter'), ); } /** * {@inheritdoc} */ public function getName() { return 'intl'; } } function twig_localized_date_filter(Twig_Environment $env, $date, $dateFormat = 'medium', $timeFormat = 'medium', $locale = null, $timezone = null, $format = null, $calendar = 'gregorian') { $date = twig_date_converter($env, $date, $timezone); $formatValues = array( 'none' => IntlDateFormatter::NONE, 'short' => IntlDateFormatter::SHORT, 'medium' => IntlDateFormatter::MEDIUM, 'long' => IntlDateFormatter::LONG, 'full' => IntlDateFormatter::FULL, ); if (PHP_VERSION_ID < 50500 || !class_exists('IntlTimeZone')) { $formatter = IntlDateFormatter::create( $locale, $formatValues[$dateFormat], $formatValues[$timeFormat], $date->getTimezone()->getName(), 'gregorian' === $calendar ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL, $format ); return $formatter->format($date->getTimestamp()); } $formatter = IntlDateFormatter::create( $locale, $formatValues[$dateFormat], $formatValues[$timeFormat], IntlTimeZone::createTimeZone($date->getTimezone()->getName()), 'gregorian' === $calendar ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL, $format ); return $formatter->format($date->getTimestamp()); } function twig_localized_number_filter($number, $style = 'decimal', $type = 'default', $locale = null) { static $typeValues = array( 'default' => NumberFormatter::TYPE_DEFAULT, 'int32' => NumberFormatter::TYPE_INT32, 'int64' => NumberFormatter::TYPE_INT64, 'double' => NumberFormatter::TYPE_DOUBLE, 'currency' => NumberFormatter::TYPE_CURRENCY, ); $formatter = twig_get_number_formatter($locale, $style); if (!isset($typeValues[$type])) { throw new Twig_Error_Syntax(sprintf('The type "%s" does not exist. Known types are: "%s"', $type, implode('", "', array_keys($typeValues)))); } return $formatter->format($number, $typeValues[$type]); } function twig_localized_currency_filter($number, $currency = null, $locale = null) { $formatter = twig_get_number_formatter($locale, 'currency'); return $formatter->formatCurrency($number, $currency); } /** * Gets a number formatter instance according to given locale and formatter. * * @param string $locale Locale in which the number would be formatted * @param int $style Style of the formatting * * @return NumberFormatter A NumberFormatter instance */ function twig_get_number_formatter($locale, $style) { static $formatter, $currentStyle; $locale = null !== $locale ? $locale : Locale::getDefault(); if ($formatter && $formatter->getLocale() === $locale && $currentStyle === $style) { // Return same instance of NumberFormatter if parameters are the same // to those in previous call return $formatter; } static $styleValues = array( 'decimal' => NumberFormatter::DECIMAL, 'currency' => NumberFormatter::CURRENCY, 'percent' => NumberFormatter::PERCENT, 'scientific' => NumberFormatter::SCIENTIFIC, 'spellout' => NumberFormatter::SPELLOUT, 'ordinal' => NumberFormatter::ORDINAL, 'duration' => NumberFormatter::DURATION, ); if (!isset($styleValues[$style])) { throw new Twig_Error_Syntax(sprintf('The style "%s" does not exist. Known styles are: "%s"', $style, implode('", "', array_keys($styleValues)))); } $currentStyle = $style; $formatter = NumberFormatter::create($locale, $styleValues[$style]); return $formatter; } class_alias('Twig_Extensions_Extension_Intl', 'Twig\Extensions\IntlExtension', false); twig-extensions-1.5.4/lib/Twig/Extensions/Extension/Text.php000066400000000000000000000055401355613531200241300ustar00rootroot00000000000000 */ class Twig_Extensions_Extension_Text extends Twig_Extension { /** * {@inheritdoc} */ public function getFilters() { return array( new Twig_SimpleFilter('truncate', 'twig_truncate_filter', array('needs_environment' => true)), new Twig_SimpleFilter('wordwrap', 'twig_wordwrap_filter', array('needs_environment' => true)), ); } /** * {@inheritdoc} */ public function getName() { return 'Text'; } } if (function_exists('mb_get_info')) { function twig_truncate_filter(Twig_Environment $env, $value, $length = 30, $preserve = false, $separator = '...') { if (mb_strlen($value, $env->getCharset()) > $length) { if ($preserve) { // If breakpoint is on the last word, return the value without separator. if (false === ($breakpoint = mb_strpos($value, ' ', $length, $env->getCharset()))) { return $value; } $length = $breakpoint; } return rtrim(mb_substr($value, 0, $length, $env->getCharset())).$separator; } return $value; } function twig_wordwrap_filter(Twig_Environment $env, $value, $length = 80, $separator = "\n", $preserve = false) { $sentences = array(); $previous = mb_regex_encoding(); mb_regex_encoding($env->getCharset()); $pieces = mb_split($separator, $value); mb_regex_encoding($previous); foreach ($pieces as $piece) { while (!$preserve && mb_strlen($piece, $env->getCharset()) > $length) { $sentences[] = mb_substr($piece, 0, $length, $env->getCharset()); $piece = mb_substr($piece, $length, 2048, $env->getCharset()); } $sentences[] = $piece; } return implode($separator, $sentences); } } else { function twig_truncate_filter(Twig_Environment $env, $value, $length = 30, $preserve = false, $separator = '...') { if (strlen($value) > $length) { if ($preserve) { if (false !== ($breakpoint = strpos($value, ' ', $length))) { $length = $breakpoint; } } return rtrim(substr($value, 0, $length)).$separator; } return $value; } function twig_wordwrap_filter(Twig_Environment $env, $value, $length = 80, $separator = "\n", $preserve = false) { return wordwrap($value, $length, $separator, !$preserve); } } class_alias('Twig_Extensions_Extension_Text', 'Twig\Extensions\TextExtension', false); twig-extensions-1.5.4/lib/Twig/Extensions/Grammar.php000066400000000000000000000013671355613531200226210ustar00rootroot00000000000000name = $name; } /** * @param Twig_Parser $parser */ public function setParser(Twig_Parser $parser) { $this->parser = $parser; } /** * @return string */ public function getName() { return $this->name; } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/000077500000000000000000000000001355613531200221015ustar00rootroot00000000000000twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Arguments.php000066400000000000000000000010511355613531200245540ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { return $this->parser->getExpressionParser()->parseArguments(); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Array.php000066400000000000000000000010471355613531200236720ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { return $this->parser->getExpressionParser()->parseArrayExpression(); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Body.php000066400000000000000000000016521355613531200235130ustar00rootroot00000000000000end = null === $end ? 'end'.$name : $end; } public function __toString() { return sprintf('<%s:body>', $this->name); } public function parse(Twig_Token $token) { $stream = $this->parser->getStream(); $stream->expect(Twig_Token::BLOCK_END_TYPE); return $this->parser->subparse(array($this, 'decideBlockEnd'), true); } public function decideBlockEnd(Twig_Token $token) { return $token->test($this->end); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Boolean.php000066400000000000000000000012551355613531200241740ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, array('true', 'false')); return new Twig_Node_Expression_Constant('true' === $token->getValue() ? true : false, $token->getLine()); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Constant.php000066400000000000000000000014531355613531200244060ustar00rootroot00000000000000name = $name; $this->type = null === $type ? Twig_Token::NAME_TYPE : $type; } public function __toString() { return $this->name; } public function parse(Twig_Token $token) { $this->parser->getStream()->expect($this->type, $this->name); return $this->name; } public function getType() { return $this->type; } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Expression.php000066400000000000000000000010411355613531200247450ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { return $this->parser->getExpressionParser()->parseExpression(); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Hash.php000066400000000000000000000010441355613531200234740ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { return $this->parser->getExpressionParser()->parseHashExpression(); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Number.php000066400000000000000000000011731355613531200240440ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { $this->parser->getStream()->expect(Twig_Token::NUMBER_TYPE); return new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Optional.php000066400000000000000000000040061355613531200243770ustar00rootroot00000000000000grammar = array(); foreach (func_get_args() as $grammar) { $this->addGrammar($grammar); } } public function __toString() { $repr = array(); foreach ($this->grammar as $grammar) { $repr[] = (string) $grammar; } return sprintf('[%s]', implode(' ', $repr)); } public function addGrammar(Twig_Extensions_GrammarInterface $grammar) { $this->grammar[] = $grammar; } public function parse(Twig_Token $token) { // test if we have the optional element before consuming it if ($this->grammar[0] instanceof Twig_Extensions_Grammar_Constant) { if (!$this->parser->getStream()->test($this->grammar[0]->getType(), $this->grammar[0]->getName())) { return array(); } } elseif ($this->grammar[0] instanceof Twig_Extensions_Grammar_Name) { if (!$this->parser->getStream()->test(Twig_Token::NAME_TYPE)) { return array(); } } elseif ($this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { // if this is not a Constant or a Name, it must be the last element of the tag return array(); } $elements = array(); foreach ($this->grammar as $grammar) { $grammar->setParser($this->parser); $element = $grammar->parse($token); if (is_array($element)) { $elements = array_merge($elements, $element); } else { $elements[$grammar->getName()] = $element; } } return $elements; } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Switch.php000066400000000000000000000011701355613531200240520ustar00rootroot00000000000000', $this->name); } public function parse(Twig_Token $token) { $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, $this->name); return new Twig_Node_Expression_Constant(true, $token->getLine()); } } twig-extensions-1.5.4/lib/Twig/Extensions/Grammar/Tag.php000066400000000000000000000025531355613531200233320ustar00rootroot00000000000000grammar = array(); foreach (func_get_args() as $grammar) { $this->addGrammar($grammar); } } public function __toString() { $repr = array(); foreach ($this->grammar as $grammar) { $repr[] = (string) $grammar; } return implode(' ', $repr); } public function addGrammar(Twig_Extensions_GrammarInterface $grammar) { $this->grammar[] = $grammar; } public function parse(Twig_Token $token) { $elements = array(); foreach ($this->grammar as $grammar) { $grammar->setParser($this->parser); $element = $grammar->parse($token); if (is_array($element)) { $elements = array_merge($elements, $element); } else { $elements[$grammar->getName()] = $element; } } $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); return $elements; } } twig-extensions-1.5.4/lib/Twig/Extensions/GrammarInterface.php000066400000000000000000000006521355613531200244360ustar00rootroot00000000000000 */ class Twig_Extensions_Node_Trans extends Twig_Node { public function __construct(Twig_Node $body, Twig_Node $plural = null, Twig_Node_Expression $count = null, Twig_Node $notes = null, $lineno, $tag = null) { $nodes = array('body' => $body); if (null !== $count) { $nodes['count'] = $count; } if (null !== $plural) { $nodes['plural'] = $plural; } if (null !== $notes) { $nodes['notes'] = $notes; } parent::__construct($nodes, array(), $lineno, $tag); } /** * {@inheritdoc} */ public function compile(Twig_Compiler $compiler) { $compiler->addDebugInfo($this); list($msg, $vars) = $this->compileString($this->getNode('body')); if ($this->hasNode('plural')) { list($msg1, $vars1) = $this->compileString($this->getNode('plural')); $vars = array_merge($vars, $vars1); } $function = $this->getTransFunction($this->hasNode('plural')); if ($this->hasNode('notes')) { $message = trim($this->getNode('notes')->getAttribute('data')); // line breaks are not allowed cause we want a single line comment $message = str_replace(array("\n", "\r"), ' ', $message); $compiler->write("// notes: {$message}\n"); } if ($vars) { $compiler ->write('echo strtr('.$function.'(') ->subcompile($msg) ; if ($this->hasNode('plural')) { $compiler ->raw(', ') ->subcompile($msg1) ->raw(', abs(') ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) ->raw(')') ; } $compiler->raw('), array('); foreach ($vars as $var) { if ('count' === $var->getAttribute('name')) { $compiler ->string('%count%') ->raw(' => abs(') ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) ->raw('), ') ; } else { $compiler ->string('%'.$var->getAttribute('name').'%') ->raw(' => ') ->subcompile($var) ->raw(', ') ; } } $compiler->raw("));\n"); } else { $compiler ->write('echo '.$function.'(') ->subcompile($msg) ; if ($this->hasNode('plural')) { $compiler ->raw(', ') ->subcompile($msg1) ->raw(', abs(') ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) ->raw(')') ; } $compiler->raw(");\n"); } } /** * @param Twig_Node $body A Twig_Node instance * * @return array */ protected function compileString(Twig_Node $body) { if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant || $body instanceof Twig_Node_Expression_TempName) { return array($body, array()); } $vars = array(); if (count($body)) { $msg = ''; foreach ($body as $node) { if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof Twig_Node_SetTemp) { $node = $node->getNode(1); } if ($node instanceof Twig_Node_Print) { $n = $node->getNode('expr'); while ($n instanceof Twig_Node_Expression_Filter) { $n = $n->getNode('node'); } $msg .= sprintf('%%%s%%', $n->getAttribute('name')); $vars[] = new Twig_Node_Expression_Name($n->getAttribute('name'), $n->getTemplateLine()); } else { $msg .= $node->getAttribute('data'); } } } else { $msg = $body->getAttribute('data'); } return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $body->getTemplateLine()))), $vars); } /** * @param bool $plural Return plural or singular function to use * * @return string */ protected function getTransFunction($plural) { return $plural ? 'ngettext' : 'gettext'; } } class_alias('Twig_Extensions_Node_Trans', 'Twig\Extensions\Node\TransNode', false); twig-extensions-1.5.4/lib/Twig/Extensions/SimpleTokenParser.php000066400000000000000000000112721355613531200246360ustar00rootroot00000000000000getGrammar(); if (!is_object($grammar)) { $grammar = self::parseGrammar($grammar); } $grammar->setParser($this->parser); $values = $grammar->parse($token); return $this->getNode($values, $token->getLine()); } /** * Gets the grammar as an object or as a string. * * @return string|Twig_Extensions_Grammar A Twig_Extensions_Grammar instance or a string */ abstract protected function getGrammar(); /** * Gets the nodes based on the parsed values. * * @param array $values An array of values * @param int $line The parser line */ abstract protected function getNode(array $values, $line); protected function getAttribute($node, $attribute, $arguments = array(), $type = Twig_Node_Expression_GetAttr::TYPE_ANY, $line = -1) { return new Twig_Node_Expression_GetAttr( $node instanceof Twig_Node ? $node : new Twig_Node_Expression_Name($node, $line), $attribute instanceof Twig_Node ? $attribute : new Twig_Node_Expression_Constant($attribute, $line), $arguments instanceof Twig_Node ? $arguments : new Twig_Node($arguments), $type, $line ); } protected function call($node, $attribute, $arguments = array(), $line = -1) { return $this->getAttribute($node, $attribute, $arguments, Twig_Node_Expression_GetAttr::TYPE_METHOD, $line); } protected function markAsSafe(Twig_Node $node, $line = -1) { return new Twig_Node_Expression_Filter( $node, new Twig_Node_Expression_Constant('raw', $line), new Twig_Node(), $line ); } protected function output(Twig_Node $node, $line = -1) { return new Twig_Node_Print($node, $line); } protected function getNodeValues(array $values) { $nodes = array(); foreach ($values as $value) { if ($value instanceof Twig_Node) { $nodes[] = $value; } } return $nodes; } public static function parseGrammar($str, $main = true) { static $cursor; if (true === $main) { $cursor = 0; $grammar = new Twig_Extensions_Grammar_Tag(); } else { $grammar = new Twig_Extensions_Grammar_Optional(); } while ($cursor < strlen($str)) { if (preg_match('/\s+/A', $str, $match, null, $cursor)) { $cursor += strlen($match[0]); } elseif (preg_match('/<(\w+)(?:\:(\w+))?>/A', $str, $match, null, $cursor)) { $class = sprintf('Twig_Extensions_Grammar_%s', ucfirst(isset($match[2]) ? $match[2] : 'Expression')); if (!class_exists($class)) { throw new Twig_Error_Runtime(sprintf('Unable to understand "%s" in grammar (%s class does not exist)', $match[0], $class)); } $grammar->addGrammar(new $class($match[1])); $cursor += strlen($match[0]); } elseif (preg_match('/\w+/A', $str, $match, null, $cursor)) { $grammar->addGrammar(new Twig_Extensions_Grammar_Constant($match[0])); $cursor += strlen($match[0]); } elseif (preg_match('/,/A', $str, $match, null, $cursor)) { $grammar->addGrammar(new Twig_Extensions_Grammar_Constant($match[0], Twig_Token::PUNCTUATION_TYPE)); $cursor += strlen($match[0]); } elseif (preg_match('/\[/A', $str, $match, null, $cursor)) { $cursor += strlen($match[0]); $grammar->addGrammar(self::parseGrammar($str, false)); } elseif (true !== $main && preg_match('/\]/A', $str, $match, null, $cursor)) { $cursor += strlen($match[0]); return $grammar; } else { throw new Twig_Error_Runtime(sprintf('Unable to parse grammar "%s" near "...%s..."', $str, substr($str, $cursor, 10))); } } return $grammar; } } twig-extensions-1.5.4/lib/Twig/Extensions/TokenParser/000077500000000000000000000000001355613531200227505ustar00rootroot00000000000000twig-extensions-1.5.4/lib/Twig/Extensions/TokenParser/Trans.php000066400000000000000000000053151355613531200245540ustar00rootroot00000000000000getLine(); $stream = $this->parser->getStream(); $count = null; $plural = null; $notes = null; if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) { $body = $this->parser->getExpressionParser()->parseExpression(); } else { $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideForFork')); $next = $stream->next()->getValue(); if ('plural' === $next) { $count = $this->parser->getExpressionParser()->parseExpression(); $stream->expect(Twig_Token::BLOCK_END_TYPE); $plural = $this->parser->subparse(array($this, 'decideForFork')); if ('notes' === $stream->next()->getValue()) { $stream->expect(Twig_Token::BLOCK_END_TYPE); $notes = $this->parser->subparse(array($this, 'decideForEnd'), true); } } elseif ('notes' === $next) { $stream->expect(Twig_Token::BLOCK_END_TYPE); $notes = $this->parser->subparse(array($this, 'decideForEnd'), true); } } $stream->expect(Twig_Token::BLOCK_END_TYPE); $this->checkTransString($body, $lineno); return new Twig_Extensions_Node_Trans($body, $plural, $count, $notes, $lineno, $this->getTag()); } public function decideForFork(Twig_Token $token) { return $token->test(array('plural', 'notes', 'endtrans')); } public function decideForEnd(Twig_Token $token) { return $token->test('endtrans'); } /** * {@inheritdoc} */ public function getTag() { return 'trans'; } protected function checkTransString(Twig_Node $body, $lineno) { foreach ($body as $i => $node) { if ( $node instanceof Twig_Node_Text || ($node instanceof Twig_Node_Print && $node->getNode('expr') instanceof Twig_Node_Expression_Name) ) { continue; } throw new Twig_Error_Syntax(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno); } } } class_alias('Twig_Extensions_TokenParser_Trans', 'Twig\Extensions\TokenParser\TransTokenParser', false); twig-extensions-1.5.4/phpunit.xml.dist000066400000000000000000000012731355613531200200520ustar00rootroot00000000000000 ./test/Twig/ ./lib/Twig/ twig-extensions-1.5.4/src/000077500000000000000000000000001355613531200154635ustar00rootroot00000000000000twig-extensions-1.5.4/src/ArrayExtension.php000066400000000000000000000002631355613531200211500ustar00rootroot00000000000000assertTrue(in_array($element, twig_shuffle_filter($data), true)); // assertContains() would not consider the type } } public function testShuffleFilterOnEmptyArray() { $this->assertEquals(array(), twig_shuffle_filter(array())); } public function getShuffleFilterTestData() { return array( array( array(1, 2, 3), array(1, 2, 3), ), array( array('a' => 'apple', 'b' => 'orange', 'c' => 'citrus'), array('apple', 'orange', 'citrus'), ), array( new ArrayObject(array('apple', 'orange', 'citrus')), array('apple', 'orange', 'citrus'), ), ); } } twig-extensions-1.5.4/test/Twig/Tests/Extension/DateTest.php000066400000000000000000000110231355613531200240660ustar00rootroot00000000000000 */ class Twig_Tests_Extension_DateTest extends \PHPUnit\Framework\TestCase { /** * @var TwigEnvironment */ private $env; public function setUp() { $this->env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); } /** * @dataProvider getDiffTestData() */ public function testDiffWithStringsFromGivenNow($expected, $translated, $date, $now) { $extension = new Twig_Extensions_Extension_Date(); $this->assertEquals($expected, $extension->diff($this->env, $date, $now)); } public function testDiffWithStringsFromNow() { $extension = new Twig_Extensions_Extension_Date(); $this->assertRegExp('/^[0-9]+ (second|minute|hour|day|month|year)s* ago$/', $extension->diff($this->env, '24-07-2014')); } /** * @dataProvider getDiffTestData() */ public function testDiffWithDateTimeFromGivenNow($expected, $translated, $date, $now) { $extension = new Twig_Extensions_Extension_Date(); $this->assertEquals($expected, $extension->diff($this->env, new DateTime($date), new DateTime($now))); } public function testDiffWithDateTimeFromNow() { $extension = new Twig_Extensions_Extension_Date(); $this->assertRegExp('/^[0-9]+ (second|minute|hour|day|month|year)s* ago$/', $extension->diff($this->env, new DateTime('24-07-2014'))); } /** * @dataProvider getDiffTestData() */ public function testDiffCanReturnTranslatableString($expected, $translated, $date, $now) { $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock(); $translator ->expects($this->once()) ->method('transChoice') ->with($translated); $extension = new Twig_Extensions_Extension_Date($translator); $extension->diff($this->env, $date, $now); } public function getDiffTestData() { return array_merge($this->getDiffAgoTestData(), $this->getDiffInTestData()); } public function getDiffAgoTestData() { return array( array('1 second ago', 'diff.ago.second', '24-07-2014 17:28:01', '24-07-2014 17:28:02'), array('5 seconds ago', 'diff.ago.second', '24-07-2014 17:28:01', '24-07-2014 17:28:06'), array('1 minute ago', 'diff.ago.minute', '24-07-2014 17:28:01', '24-07-2014 17:29:01'), array('5 minutes ago', 'diff.ago.minute', '24-07-2014 17:28:01', '24-07-2014 17:33:03'), array('1 hour ago', 'diff.ago.hour', '24-07-2014 17:28:01', '24-07-2014 18:29:01'), array('9 hours ago', 'diff.ago.hour', '24-07-2014 17:28:01', '25-07-2014 02:33:03'), array('1 day ago', 'diff.ago.day', '23-07-2014', '24-07-2014'), array('5 days ago', 'diff.ago.day', '19-07-2014', '24-07-2014'), array('1 month ago', 'diff.ago.month', '23-07-2014', '24-08-2014'), array('6 months ago', 'diff.ago.month', '19-07-2014', '24-01-2015'), array('1 year ago', 'diff.ago.year', '19-07-2014', '20-08-2015'), array('3 years ago', 'diff.ago.year', '19-07-2014', '20-08-2017'), ); } public function getDiffInTestData() { return array( array('in 1 second', 'diff.in.second', '24-07-2014 17:28:02', '24-07-2014 17:28:01'), array('in 5 seconds', 'diff.in.second', '24-07-2014 17:28:06', '24-07-2014 17:28:01'), array('in 1 minute', 'diff.in.minute', '24-07-2014 17:29:01', '24-07-2014 17:28:01'), array('in 5 minutes', 'diff.in.minute', '24-07-2014 17:33:03', '24-07-2014 17:28:01'), array('in 1 hour', 'diff.in.hour', '24-07-2014 18:29:01', '24-07-2014 17:28:01'), array('in 9 hours', 'diff.in.hour', '25-07-2014 02:33:03', '24-07-2014 17:28:01'), array('in 1 day', 'diff.in.day', '24-07-2014', '23-07-2014'), array('in 5 days', 'diff.in.day', '24-07-2014', '19-07-2014'), array('in 1 month', 'diff.in.month', '24-08-2014', '23-07-2014'), array('in 6 months', 'diff.in.month', '24-01-2015', '19-07-2014'), array('in 1 year', 'diff.in.year', '20-08-2015', '19-07-2014'), array('in 3 years', 'diff.in.year', '20-08-2017', '19-07-2014'), ); } } twig-extensions-1.5.4/test/Twig/Tests/Extension/IntlTest.php000066400000000000000000000023731355613531200241270ustar00rootroot00000000000000getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock(); $date = twig_localized_date_filter($env, new DateTime('2015-01-01T00:00:00', new DateTimeZone('UTC')), 'short', 'long', 'en', '+01:00'); $this->assertEquals('1/1/15 1:00:00 AM GMT+01:00', $date); } /** * @requires extension intl * @requires PHP 5.5 */ public function testLocalizedDateFilterWithDateTimeZoneZ() { class_exists('Twig_Extensions_Extension_Intl'); $env = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock(); $date = twig_localized_date_filter($env, new DateTime('2017-11-19T00:00:00Z'), 'short', 'long', 'fr', 'Z'); $this->assertEquals('19/11/2017 00:00:00 UTC', $date); } } twig-extensions-1.5.4/test/Twig/Tests/Extension/TextTest.php000066400000000000000000000031221355613531200241360ustar00rootroot00000000000000env = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock(); $this->env ->expects($this->any()) ->method('getCharset') ->will($this->returnValue('utf-8')) ; } /** * @dataProvider getTruncateTestData */ public function testTruncate($input, $length, $preserve, $separator, $expectedOutput) { $output = twig_truncate_filter($this->env, $input, $length, $preserve, $separator); $this->assertEquals($expectedOutput, $output); } public function getTruncateTestData() { return array( array('This is a very long sentence.', 2, false, '...', 'Th...'), array('This is a very long sentence.', 6, false, '...', 'This i...'), array('This is a very long sentence.', 2, true, '...', 'This...'), array('This is a very long sentence.', 2, true, '[...]', 'This[...]'), array('This is a very long sentence.', 23, false, '...', 'This is a very long sen...'), array('This is a very long sentence.', 23, true, '...', 'This is a very long sentence.'), ); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/000077500000000000000000000000001355613531200212555ustar00rootroot00000000000000twig-extensions-1.5.4/test/Twig/Tests/Grammar/ArgumentsTest.php000066400000000000000000000007211355613531200245730ustar00rootroot00000000000000assertEquals('', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/ArrayTest.php000066400000000000000000000007051355613531200237060ustar00rootroot00000000000000assertEquals('', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/BodyTest.php000066400000000000000000000007021355613531200235220ustar00rootroot00000000000000assertEquals('', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/BooleanTest.php000066400000000000000000000007131355613531200242060ustar00rootroot00000000000000assertEquals('', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/ConstantTest.php000066400000000000000000000007031355613531200244170ustar00rootroot00000000000000assertEquals('foo', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/ExpressionTest.php000066400000000000000000000007111355613531200247640ustar00rootroot00000000000000assertEquals('', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/NumberTest.php000066400000000000000000000007101355613531200240540ustar00rootroot00000000000000assertEquals('', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/OptionalTest.php000066400000000000000000000010431355613531200244110ustar00rootroot00000000000000assertEquals('[foo ]', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Grammar/TagTest.php000066400000000000000000000013261355613531200233430ustar00rootroot00000000000000assertEquals('foo [foo ]', (string) $grammar); } } twig-extensions-1.5.4/test/Twig/Tests/Node/000077500000000000000000000000001355613531200205545ustar00rootroot00000000000000twig-extensions-1.5.4/test/Twig/Tests/Node/TransTest.php000066400000000000000000000124061355613531200232170ustar00rootroot00000000000000assertEquals($body, $node->getNode('body')); $this->assertEquals($count, $node->getNode('count')); $this->assertEquals($plural, $node->getNode('plural')); } public function getTests() { $tests = array(); $body = new Twig_Node_Expression_Name('foo', 0); $node = new Twig_Extensions_Node_Trans($body, null, null, null, 0); $tests[] = array($node, sprintf('echo gettext(%s);', $this->getVariableGetter('foo'))); $body = new Twig_Node_Expression_Constant('Hello', 0); $node = new Twig_Extensions_Node_Trans($body, null, null, null, 0); $tests[] = array($node, 'echo gettext("Hello");'); $body = new Twig_Node(array( new Twig_Node_Text('Hello', 0), ), array(), 0); $node = new Twig_Extensions_Node_Trans($body, null, null, null, 0); $tests[] = array($node, 'echo gettext("Hello");'); $body = new Twig_Node(array( new Twig_Node_Text('J\'ai ', 0), new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0), new Twig_Node_Text(' pommes', 0), ), array(), 0); $node = new Twig_Extensions_Node_Trans($body, null, null, null, 0); $tests[] = array($node, sprintf('echo strtr(gettext("J\'ai %%foo%% pommes"), array("%%foo%%" => %s, ));', $this->getVariableGetter('foo'))); $count = new Twig_Node_Expression_Constant(12, 0); $body = new Twig_Node(array( new Twig_Node_Text('Hey ', 0), new Twig_Node_Print(new Twig_Node_Expression_Name('name', 0), 0), new Twig_Node_Text(', I have one apple', 0), ), array(), 0); $plural = new Twig_Node(array( new Twig_Node_Text('Hey ', 0), new Twig_Node_Print(new Twig_Node_Expression_Name('name', 0), 0), new Twig_Node_Text(', I have ', 0), new Twig_Node_Print(new Twig_Node_Expression_Name('count', 0), 0), new Twig_Node_Text(' apples', 0), ), array(), 0); $node = new Twig_Extensions_Node_Trans($body, $plural, $count, null, 0); $tests[] = array($node, sprintf('echo strtr(ngettext("Hey %%name%%, I have one apple", "Hey %%name%%, I have %%count%% apples", abs(12)), array("%%name%%" => %s, "%%name%%" => %s, "%%count%%" => abs(12), ));', $this->getVariableGetter('name'), $this->getVariableGetter('name'))); // with escaper extension set to on $body = new Twig_Node(array( new Twig_Node_Text('J\'ai ', 0), new Twig_Node_Print(new Twig_Node_Expression_Filter(new Twig_Node_Expression_Name('foo', 0), new Twig_Node_Expression_Constant('escape', 0), new Twig_Node(), 0), 0), new Twig_Node_Text(' pommes', 0), ), array(), 0); $node = new Twig_Extensions_Node_Trans($body, null, null, null, 0); $tests[] = array($node, sprintf('echo strtr(gettext("J\'ai %%foo%% pommes"), array("%%foo%%" => %s, ));', $this->getVariableGetter('foo'))); // with notes $body = new Twig_Node_Expression_Constant('Hello', 0); $notes = new Twig_Node_Text('Notes for translators', 0); $node = new Twig_Extensions_Node_Trans($body, null, null, $notes, 0); $tests[] = array($node, "// notes: Notes for translators\necho gettext(\"Hello\");"); $body = new Twig_Node_Expression_Constant('Hello', 0); $notes = new Twig_Node_Text("Notes for translators\nand line breaks", 0); $node = new Twig_Extensions_Node_Trans($body, null, null, $notes, 0); $tests[] = array($node, "// notes: Notes for translators and line breaks\necho gettext(\"Hello\");"); $count = new Twig_Node_Expression_Constant(5, 0); $body = new Twig_Node_Text('There is 1 pending task', 0); $plural = new Twig_Node(array( new Twig_Node_Text('There are ', 0), new Twig_Node_Print(new Twig_Node_Expression_Name('count', 0), 0), new Twig_Node_Text(' pending tasks', 0), ), array(), 0); $notes = new Twig_Node_Text('Notes for translators', 0); $node = new Twig_Extensions_Node_Trans($body, $plural, $count, $notes, 0); $tests[] = array($node, "// notes: Notes for translators\n".'echo strtr(ngettext("There is 1 pending task", "There are %count% pending tasks", abs(5)), array("%count%" => abs(5), ));'); return $tests; } } twig-extensions-1.5.4/test/Twig/Tests/SimpleTokenParser.php000066400000000000000000000026331355613531200240130ustar00rootroot00000000000000tag = $tag; $this->grammar = $grammar; } public function getGrammar() { return $this->grammar; } public function getTag() { return $this->tag; } public function getNode(array $values, $line) { $nodes = array(); $nodes[] = new Twig_Node_Print(new Twig_Node_Expression_Constant('|', $line), $line); foreach ($values as $value) { if ($value instanceof Twig_Node) { if ($value instanceof Twig_Node_Expression_Array) { $nodes[] = new Twig_Node_Print(new Twig_Node_Expression_Function('dump', $value, $line), $line); } else { $nodes[] = new Twig_Node_Print($value, $line); } } else { $nodes[] = new Twig_Node_Print(new Twig_Node_Expression_Constant($value, $line), $line); } $nodes[] = new Twig_Node_Print(new Twig_Node_Expression_Constant('|', $line), $line); } return new Twig_Node($nodes); } } twig-extensions-1.5.4/test/Twig/Tests/SimpleTokenParserTest.php000066400000000000000000000110701355613531200246460ustar00rootroot00000000000000assertEquals($grammar, Twig_Extensions_SimpleTokenParser::parseGrammar($str), '::parseGrammar() parses a grammar'); } public function testParseGrammarExceptions() { try { Twig_Extensions_SimpleTokenParser::parseGrammar(''); $this->fail(); } catch (Exception $e) { $this->assertEquals('Twig_Error_Runtime', get_class($e)); } try { Twig_Extensions_SimpleTokenParser::parseGrammar('fail(); } catch (Exception $e) { $this->assertEquals('Twig_Error_Runtime', get_class($e)); } try { Twig_Extensions_SimpleTokenParser::parseGrammar(' (with'); $this->fail(); } catch (Exception $e) { $this->assertEquals('Twig_Error_Runtime', get_class($e)); } } public function getTests() { return array( array('', new Twig_Extensions_Grammar_Tag()), array('const', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Constant('const') )), array(' const ', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Constant('const') )), array('', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr') )), array('', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr') )), array(' ', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr') )), array('', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Number('nb') )), array('', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Boolean('bool') )), array('', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Body('content') )), array(' [with ]', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr'), new Twig_Extensions_Grammar_Optional( new Twig_Extensions_Grammar_Constant('with'), new Twig_Extensions_Grammar_Array('arguments') ) )), array(' [ with ] ', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr'), new Twig_Extensions_Grammar_Optional( new Twig_Extensions_Grammar_Constant('with'), new Twig_Extensions_Grammar_Array('arguments') ) )), array(' [with [or ]]', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr'), new Twig_Extensions_Grammar_Optional( new Twig_Extensions_Grammar_Constant('with'), new Twig_Extensions_Grammar_Array('arguments'), new Twig_Extensions_Grammar_Optional( new Twig_Extensions_Grammar_Constant('or'), new Twig_Extensions_Grammar_Expression('optional') ) ) )), array(' [with [, ]]', new Twig_Extensions_Grammar_Tag( new Twig_Extensions_Grammar_Expression('expr'), new Twig_Extensions_Grammar_Optional( new Twig_Extensions_Grammar_Constant('with'), new Twig_Extensions_Grammar_Array('arguments'), new Twig_Extensions_Grammar_Optional( new Twig_Extensions_Grammar_Constant(',', Twig_Token::PUNCTUATION_TYPE), new Twig_Extensions_Grammar_Expression('optional') ) ) )), ); } } twig-extensions-1.5.4/test/Twig/Tests/grammarTest.php000066400000000000000000000046141355613531200226730ustar00rootroot00000000000000 $template)), array('cache' => false, 'autoescape' => false, 'debug' => true)); $twig->addExtension(new Twig_Extension_Debug()); $twig->addTokenParser(new SimpleTokenParser($tag, $grammar)); $ok = true; try { $template = $twig->loadTemplate('template'); } catch (Exception $e) { $ok = false; if (false === $exception) { $this->fail('Exception not expected'); } else { $this->assertEquals($exception, get_class($e)); } } if ($ok) { if (false !== $exception) { $this->fail(sprintf('Exception "%s" expected', $exception)); } $actual = $template->render(array()); $this->assertEquals($output, $actual); } } public function getTests() { return array( array('foo1', '', '{% foo1 %}', '|', false), array('foo2', '', '{% foo2 "bar" %}', '|', 'Twig_Error_Syntax'), array('foo3', '', '{% foo3 "bar" %}', '|bar|', false), array('foo4', '', '{% foo4 1 + 2 %}', '|3|', false), array('foo5', '', '{% foo5 1 + 2 %}', '|3|', false), array('foo6', '', '{% foo6 1 + 2 %}', '|3|', 'Twig_Error_Syntax'), array('foo7', '', '{% foo7 %}', '|3|', 'Twig_Error_Syntax'), array('foo8', '', '{% foo8 [1, 2] %}', "|int(0)\nint(1)\nint(1)\nint(2)\n|", false), array('foo9', ' with ', '{% foo9 "bar" with "foobar" %}', '|bar|with|foobar|', false), array('foo10', ' [with ]', '{% foo10 "bar" with "foobar" %}', '|bar|with|foobar|', false), array('foo11', ' [with ]', '{% foo11 "bar" %}', '|bar|', false), ); } }