Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pluralization translations fail at ParsePlaceHolders due to array expectation with an int passed. #1090

Closed
georanma opened this issue Apr 27, 2020 · 4 comments
Assignees
Labels
internationalization Related to the localization feature needs more info Incomplete issue, missing details troubleshooting Support with current features

Comments

@georanma
Copy link

georanma commented Apr 27, 2020

Problem:
When using the default Userfrosting Twig translation function, passing an int as the second parameter to request a plural message results in a TypeError.
app/sprinkles/admin/templates/pages/dashboard.html.twig:77
{{ translate("USER", [2]) }}

Stack Trace:


Stacktrace:
#59 TypeError in /home/vagrant/code/glamorise-marketing/app/vendor/userfrosting/i18n/src/Translator.php:261
#58 UserFrosting\I18n\Translator:parsePlaceHolders in /home/vagrant/code/glamorise-marketing/app/vendor/userfrosting/i18n/src/Translator.php:93
#57 UserFrosting\I18n\Translator:translate in /home/vagrant/code/glamorise-marketing/app/sprinkles/core/src/Twig/CoreExtension.php:70
#56 UserFrosting\Sprinkle\Core\Twig\CoreExtension:UserFrosting\Sprinkle\Core\Twig\{closure} in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#55 __TwigTemplate_0b1afe73bc3c81ccc6d818d11b8d330f8ed24e129a63be32c643a3111f817cbb:block_navigation in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:184
#54 Twig\Template:displayBlock in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#53 __TwigTemplate_0b1afe73bc3c81ccc6d818d11b8d330f8ed24e129a63be32c643a3111f817cbb:doDisplay in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:407
#52 Twig\Template:displayWithErrorHandling in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:380
#51 Twig\Template:display in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#50 __TwigTemplate_c1bae9718940f67185cd3c3532a197af1c232ab695e70e5499a1d20611479637:block_sidebar_menu in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:184
#49 Twig\Template:displayBlock in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#48 __TwigTemplate_c1bae9718940f67185cd3c3532a197af1c232ab695e70e5499a1d20611479637:doDisplay in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:407
#47 Twig\Template:displayWithErrorHandling in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:380
#46 Twig\Template:display in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#45 __TwigTemplate_390cb93ecd73118086f06905e64423decbbc1ee721fc8e78114f0fbb76d8c707:block_content in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:184
#44 Twig\Template:displayBlock in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#43 __TwigTemplate_60f203056e6b8539f9806912399f2e67f10dd4450454ab25aacd054f559814a4:block_body in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:184
#42 Twig\Template:displayBlock in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#41 __TwigTemplate_60f203056e6b8539f9806912399f2e67f10dd4450454ab25aacd054f559814a4:block_page in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:184
#40 Twig\Template:displayBlock in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#39 __TwigTemplate_60f203056e6b8539f9806912399f2e67f10dd4450454ab25aacd054f559814a4:doDisplay in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:407
#38 Twig\Template:displayWithErrorHandling in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:380
#37 Twig\Template:display in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#36 __TwigTemplate_390cb93ecd73118086f06905e64423decbbc1ee721fc8e78114f0fbb76d8c707:doDisplay in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:407
#35 Twig\Template:displayWithErrorHandling in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:380
#34 Twig\Template:display in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:418
#33 __TwigTemplate_b96ed29bf0ec23ba3becea3c93eca352c077c930d4f4abf69ea32f9f0f290281:doDisplay in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:407
#32 Twig\Template:displayWithErrorHandling in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:380
#31 Twig\Template:display in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Template.php:392
#30 Twig\Template:render in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/TemplateWrapper.php:45
#29 Twig\TemplateWrapper:render in /home/vagrant/code/glamorise-marketing/app/vendor/twig/twig/src/Environment.php:318
#28 Twig\Environment:render in /home/vagrant/code/glamorise-marketing/app/vendor/slim/twig-view/src/Twig.php:92
#27 Slim\Views\Twig:fetch in /home/vagrant/code/glamorise-marketing/app/vendor/slim/twig-view/src/Twig.php:136
#26 Slim\Views\Twig:render in /home/vagrant/code/glamorise-marketing/app/sprinkles/admin/src/Controller/UserController.php:1131
#25 UserFrosting\Sprinkle\Admin\Controller\UserController:pageList in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php:40
#24 call_user_func in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php:40
#23 Slim\Handlers\Strategies\RequestResponse:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/Route.php:281
#22 Slim\Route:__invoke in /home/vagrant/code/glamorise-marketing/app/sprinkles/account/src/Authenticate/AuthGuard.php:53
#21 UserFrosting\Sprinkle\Account\Authenticate\AuthGuard:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/DeferredCallable.php:57
#20 call_user_func_array in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/DeferredCallable.php:57
#19 Slim\DeferredCallable:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:70
#18 call_user_func in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:70
#17 Slim\Route:Slim\{closure} in /home/vagrant/code/glamorise-marketing/app/sprinkles/core/src/Util/NoCache.php:36
#16 UserFrosting\Sprinkle\Core\Util\NoCache:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/DeferredCallable.php:57
#15 call_user_func_array in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/DeferredCallable.php:57
#14 Slim\DeferredCallable:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:70
#13 call_user_func in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:70
#12 Slim\Route:Slim\{closure} in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:117
#11 Slim\Route:callMiddlewareStack in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/Route.php:268
#10 Slim\Route:run in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/App.php:503
#9 Slim\App:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/csrf/src/Guard.php:171
#8 Slim\Csrf\Guard:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/DeferredCallable.php:57
#7 call_user_func_array in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/DeferredCallable.php:57
#6 Slim\DeferredCallable:__invoke in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:70
#5 call_user_func in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:70
#4 Slim\App:Slim\{closure} in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/MiddlewareAwareTrait.php:117
#3 Slim\App:callMiddlewareStack in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/App.php:392
#2 Slim\App:process in /home/vagrant/code/glamorise-marketing/app/vendor/slim/slim/Slim/App.php:297
#1 Slim\App:run in /home/vagrant/code/glamorise-marketing/app/system/UserFrosting.php:97
#0 UserFrosting\System\UserFrosting:run in /home/vagrant/code/glamorise-marketing/public/index.php:24

Steps to Reproduce:

  1. Install new instance of Userfrosting 4.4 (I downloaded the repo zip from github)
  2. Process installation guidelines and create new admin user
  3. Log into the dashboard.

Userfrosting Version: 4.4

app/vendor/userfrosting/i18n/src/Translator.php:93
$message = $this->parsePlaceHolders($message, $placeholders);
in our case, $placeholders is an int, which is defined as allowed, but parsePlaceHolders expects an array as the parameter type.

@lcharette lcharette self-assigned this Apr 27, 2020
@lcharette lcharette added internationalization Related to the localization feature possible bug We suspect something isn't working labels Apr 27, 2020
@lcharette lcharette added this to the 4.4.2 milestone Apr 27, 2020
@lcharette
Copy link
Member

I can't replicate this issue... I'll need more information about your env :

  • PHP Version
  • Server OS
  • UF Version
  • Result of composer info

You're right the parsePlaceHolders methods accept an array, while the translate method accept both an array and an int. The change is made here :
https://github.com/userfrosting/i18n/blob/9f2e2551c88c5a92871c1cc69a4e7110b2ccf269/src/Translator.php#L147

See : fa5aea2#diff-5f22e91b94980404a15e8089985507caR26-R27

@lcharette lcharette added the needs more info Incomplete issue, missing details label Apr 27, 2020
@georanma
Copy link
Author

@lcharette
PHP Version:

  1. Cli: 7.4.4
  2. FPM: 7.4.4

Server OS: Laravel Homestead (Ubuntu 18.04)
UF Version: 4.4
Result of composer info:

birke/rememberme                    2.0.1   Secure "Remember Me" functionality
composer/installers                 v1.9.0  A multi-framework Composer library installer
composer/semver                     1.5.1   Semver library that offers utilities, version constraint parsing and validation.
composer/xdebug-handler             1.4.1   Restarts a process without Xdebug.
doctrine/annotations                1.10.2  Docblock Annotations Parser
doctrine/cache                      1.10.0  PHP Doctrine Cache library is a popular cache implementation that supports many different drivers s...
doctrine/dbal                       2.10.2  Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection...
doctrine/event-manager              1.1.0   The Doctrine Event Manager is a simple PHP event system that was built to be used with the various ...
doctrine/inflector                  1.3.1   Common String Manipulations with regard to casing and singular/plural rules.
doctrine/instantiator               1.3.0   A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer                      1.2.0   PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.
ezyang/htmlpurifier                 v4.12.0 Standards compliant HTML filter written in PHP
filp/whoops                         2.7.1   php error handling for cool kids
friendsofphp/php-cs-fixer           v2.16.3 A tool to automatically fix PHP code style
fzaninotto/faker                    v1.9.1  Faker is a PHP library that generates fake data for you.
hamcrest/hamcrest-php               v2.0.0  This is the PHP port of Hamcrest Matchers
illuminate/cache                    v5.8.36 The Illuminate Cache package.
illuminate/config                   v5.8.36 The Illuminate Config package.
illuminate/container                v5.8.36 The Illuminate Container package.
illuminate/contracts                v5.8.36 The Illuminate Contracts package.
illuminate/database                 v5.8.36 The Illuminate Database package.
illuminate/events                   v5.8.36 The Illuminate Events package.
illuminate/filesystem               v5.8.36 The Illuminate Filesystem package.
illuminate/redis                    v5.8.36 The Illuminate Redis package.
illuminate/session                  v5.8.36 The Illuminate Session package.
illuminate/support                  v5.8.36 The Illuminate Support package.
jackiedo/dotenv-editor              1.0.9   The .env file editor tool for Laravel 5+
league/csv                          9.6.0   CSV data manipulation made easy in PHP
league/factory-muffin               v3.2.1  The goal of this package is to enable the rapid creation of objects for the purpose of testing.
league/factory-muffin-faker         v2.2.2  The goal of this package is to wrap faker to make it super easy to use with factory muffin.
league/flysystem                    1.0.67  Filesystem abstraction: Many filesystems, one API.
league/flysystem-cached-adapter     1.0.9   An adapter decorator to enable meta-data caching.
league/flysystem-sftp               1.0.22  Flysystem adapter for SFTP
mockery/mockery                     1.3.1   Mockery is a simple yet flexible PHP mock object framework
monolog/monolog                     1.25.3  Sends your logs to files, sockets, inboxes, databases and various web services
myclabs/deep-copy                   1.9.5   Create deep copies (clones) of your objects
nesbot/carbon                       2.32.2  An API extension for DateTime that supports 281 different languages.
nikic/fast-route                    v1.3.0  Fast request router for PHP
nikic/php-parser                    v4.4.0  A PHP parser written in PHP
paragonie/random_compat             v2.0.18 PHP 5.x polyfill for random_bytes() and random_int() from PHP 7
phar-io/manifest                    1.0.3   Component for reading phar.io manifest information from a PHP Archive (PHAR)
phar-io/version                     2.0.1   Library for handling version information and constraints
php-cs-fixer/diff                   v1.3.0  sebastian/diff v2 backport support for PHP5.6
phpdocumentor/reflection-common     2.1.0   Common reflection classes used by phpdocumentor to reflect the code structure
phpdocumentor/reflection-docblock   5.1.0   With this component, a library can provide support for annotations via DocBlocks or otherwise retri...
phpdocumentor/type-resolver         1.1.0   A PSR-5 based resolver of Class names, Types and Structural Element Names
phpmailer/phpmailer                 v6.1.5  PHPMailer is a full-featured email creation and transfer class for PHP
phpoption/phpoption                 1.7.3   Option Type for PHP
phpseclib/phpseclib                 2.0.27  PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.
phpspec/prophecy                    v1.10.3 Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage           7.0.10  Library that provides collection, processing, and rendering functionality for PHP code coverage inf...
phpunit/php-file-iterator           2.0.2   FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-text-template           1.2.1   Simple template engine.
phpunit/php-timer                   2.1.2   Utility class for timing
phpunit/php-token-stream            3.1.1   Wrapper around PHP's tokenizer extension.
phpunit/phpunit                     8.5.4   The PHP Unit Testing framework.
pimple/pimple                       v3.3.0  Pimple, a simple Dependency Injection Container
predis/predis                       v1.1.1  Flexible and feature-complete Redis client for PHP and HHVM
psr/cache                           1.0.1   Common interface for caching libraries
psr/container                       1.0.0   Common Container Interface (PHP FIG PSR-11)
psr/http-message                    1.0.1   Common interface for HTTP messages
psr/log                             1.1.3   Common interface for logging libraries
psr/simple-cache                    1.0.1   Common interfaces for simple caching
rockettheme/toolbox                 1.4.7   RocketTheme Toolbox Library
sebastian/code-unit-reverse-lookup  1.0.1   Looks up which function or method a line of code belongs to
sebastian/comparator                3.0.2   Provides the functionality to compare PHP values for equality
sebastian/diff                      3.0.2   Diff implementation
sebastian/environment               4.2.3   Provides functionality to handle HHVM/PHP environments
sebastian/exporter                  3.1.2   Provides the functionality to export PHP variables for visualization
sebastian/global-state              3.0.0   Snapshotting of global state
sebastian/object-enumerator         3.0.3   Traverses array structures and object graphs to enumerate all referenced objects
sebastian/object-reflector          1.1.1   Allows reflection of object attributes, including inherited and non-public ones
sebastian/recursion-context         3.0.0   Provides functionality to recursively process PHP variables
sebastian/resource-operations       2.0.1   Provides a list of PHP built-in functions that operate on resources
sebastian/type                      1.1.3   Collection of value objects that represent the types of the PHP type system
sebastian/version                   2.0.1   Library that helps with managing the version number of Git-hosted PHP projects
slim/csrf                           0.8.3   Slim Framework 3 CSRF protection middleware
slim/slim                           3.12.3  Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and...
slim/twig-view                      2.5.1   Slim Framework 3 view helper built on top of the Twig 2 templating component
symfony/console                     v4.4.7  Symfony Console Component
symfony/event-dispatcher            v4.4.7  Symfony EventDispatcher Component
symfony/event-dispatcher-contracts  v1.1.7  Generic abstractions related to dispatching event
symfony/filesystem                  v5.0.7  Symfony Filesystem Component
symfony/finder                      v4.4.7  Symfony Finder Component
symfony/http-foundation             v4.4.7  Symfony HttpFoundation Component
symfony/mime                        v5.0.7  A library to manipulate MIME messages
symfony/options-resolver            v5.0.7  Symfony OptionsResolver Component
symfony/polyfill-ctype              v1.15.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-idn           v1.15.0 Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions
symfony/polyfill-mbstring           v1.15.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php70              v1.15.0 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-php72              v1.15.0 Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions
symfony/polyfill-php73              v1.15.0 Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions
symfony/process                     v5.0.7  Symfony Process Component
symfony/service-contracts           v2.0.1  Generic abstractions related to writing services
symfony/stopwatch                   v5.0.7  Symfony Stopwatch Component
symfony/translation                 v5.0.7  Symfony Translation Component
symfony/translation-contracts       v2.0.1  Generic abstractions related to translation
symfony/yaml                        v5.0.7  Symfony Yaml Component
theseer/tokenizer                   1.1.3   A small library for converting tokenized PHP source code into XML and potentially other formats
twig/twig                           v2.12.5 Twig, the flexible, fast, and secure template language for PHP
userfrosting/assets                 6.1.0   Assets module for UserFrosting
userfrosting/cache                  4.4.0   Cache module for UserFrosting
userfrosting/config                 4.4.0   Configuration module for UserFrosting
userfrosting/fortress               4.4.0   A PHP library for whitelisting, validating, and canonicalizing HTTP request data against a JSON Schema
userfrosting/i18n                   4.4.0   Internationalization module for UserFrosting
userfrosting/session                4.4.0   Uniform interface for storing sessions in a variety of mediums, based on illuminate/session
userfrosting/support                4.4.0   Support classes for UserFrosting and UF modules
userfrosting/uniformresourcelocator 4.4.2   Uniform Resource Locator module for UserFrosting
vlucas/phpdotenv                    v3.6.3  Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.
vlucas/valitron                     v1.4.7  Simple, elegant, stand-alone validation library with NO dependencies
webmozart/assert                    1.8.0   Assertions to validate method input/output with nice error messages.
wikimedia/composer-merge-plugin     v1.4.1  Composer plugin to merge multiple composer.json files

@lcharette lcharette added troubleshooting Support with current features and removed possible bug We suspect something isn't working labels Apr 28, 2020
@lcharette
Copy link
Member

As discussed in chat, this issue is not present when no custom sprinkle are loaded. It's related to placeholder being used on a non array message.

See https://chat.userfrosting.com/channel/support?msg=KG8JRYZTAPL8MjmYt

@lcharette
Copy link
Member

Should be fixed with the release of i18n 4.4.1.

It will default to ['plural' => 1] just like a message with plural values even if the message is a simple string. I also added an exception in case a non-array and non-numeric is passed as a placeholder (so no more translate('FOO', '1'), use proper typing people !)

@lcharette lcharette removed this from the 4.4.2 milestone Apr 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internationalization Related to the localization feature needs more info Incomplete issue, missing details troubleshooting Support with current features
Projects
None yet
Development

No branches or pull requests

2 participants