├── .gitignore ├── Locale.php ├── README.md └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /Locale.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Component\Intl; 13 | 14 | /** 15 | * Provides access to locale-related data. 16 | * 17 | * @author Bernhard Schussek 18 | * 19 | * @internal 20 | */ 21 | final class Locale extends \Locale 22 | { 23 | /** 24 | * @var string|null 25 | */ 26 | private static $defaultFallback = 'en'; 27 | 28 | /** 29 | * Sets the default fallback locale. 30 | * 31 | * The default fallback locale is used as fallback for locales that have no 32 | * fallback otherwise. 33 | * 34 | * @param string|null $locale The default fallback locale 35 | * 36 | * @see getFallback() 37 | */ 38 | public static function setDefaultFallback($locale) 39 | { 40 | self::$defaultFallback = $locale; 41 | } 42 | 43 | /** 44 | * Returns the default fallback locale. 45 | * 46 | * @return string|null The default fallback locale 47 | * 48 | * @see setDefaultFallback() 49 | * @see getFallback() 50 | */ 51 | public static function getDefaultFallback() 52 | { 53 | return self::$defaultFallback; 54 | } 55 | 56 | /** 57 | * Returns the fallback locale for a given locale. 58 | * 59 | * For example, the fallback of "fr_FR" is "fr". The fallback of "fr" is 60 | * the default fallback locale configured with {@link setDefaultFallback()}. 61 | * The default fallback locale has no fallback. 62 | * 63 | * @param string $locale The ICU locale code to find the fallback for 64 | * 65 | * @return string|null The ICU locale code of the fallback locale, or null 66 | * if no fallback exists 67 | */ 68 | public static function getFallback($locale) 69 | { 70 | if (\function_exists('locale_parse')) { 71 | $localeSubTags = locale_parse($locale); 72 | if (1 === \count($localeSubTags)) { 73 | if (self::$defaultFallback === $localeSubTags['language']) { 74 | return 'root'; 75 | } 76 | 77 | // Don't return default fallback for "root", "meta" or others 78 | // Normal locales have two or three letters 79 | if (\strlen($locale) < 4) { 80 | return self::$defaultFallback; 81 | } 82 | 83 | return null; 84 | } 85 | 86 | array_pop($localeSubTags); 87 | 88 | $fallback = locale_compose($localeSubTags); 89 | 90 | return false !== $fallback ? $fallback : null; 91 | } 92 | 93 | if (false !== $pos = strrpos($locale, '_')) { 94 | return substr($locale, 0, $pos); 95 | } 96 | 97 | if (false !== $pos = strrpos($locale, '-')) { 98 | return substr($locale, 0, $pos); 99 | } 100 | 101 | if (self::$defaultFallback === $locale) { 102 | return 'root'; 103 | } 104 | 105 | // Don't return default fallback for "root", "meta" or others 106 | // Normal locales have two or three letters 107 | if (\strlen($locale) < 4) { 108 | return self::$defaultFallback; 109 | } 110 | 111 | return null; 112 | } 113 | 114 | /** 115 | * This class must not be instantiated. 116 | */ 117 | private function __construct() 118 | { 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fix symfony/intl for newer PHP Versions 2 | 3 | ```bash 4 | composer require sulu/symfony-intl-fix 5 | ``` 6 | 7 | To avoid problems you should also exclude the default Locale class from the classmap in your `composer.json`: 8 | 9 | ```json 10 | { 11 | "autoload": { 12 | "exclude-from-classmap": [ 13 | "vendor/symfony/intl/Locale.php", 14 | "vendor/symfony/symfony/src/Symfony/Component/Intl/Locale.php" 15 | ] 16 | } 17 | } 18 | ``` 19 | 20 | **Affected PHP Versions:** 21 | 22 | - `^7.3.4` 23 | - `^7.2.17` 24 | - `^7.1.28` 25 | 26 | If you use one of the above PHP Version and an older Symfony Intl version than 27 | `^3.4.24` or `^4.2.7` symfony/intl will end up in an infinite loop. 28 | 29 | This package will overwrite the Symfony [Locale][locale] to avoid this infinite 30 | loop. Projects using Symfony 3 or 4 should just update there symfony package. 31 | This fix is mainly provided for Symfony 2 projects. 32 | 33 | **What was changed to fix the issue?** 34 | 35 | The change in `Locale.php` is really simple: 36 | 37 | ```diff 38 | - return locale_compose($localeSubTags); 39 | + $fallback = locale_compose($localeSubTags); 40 | + 41 | + return false !== $fallback ? $fallback : null; 42 | ``` 43 | 44 | See [original commit][oc]. 45 | 46 | [locale]: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Intl/Locale.php 47 | [oc]: https://github.com/symfony/intl/commit/d2ac83703951bc3206e9ea3f6114b355de14e3ce#diff-272fb631cccddf1d11988bec3fb7aa15 48 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sulu/symfony-intl-fix", 3 | "description": "Provides the symfony/intl fix for new php version also for symfony 2.8", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Alexander Schranz", 9 | "email": "alexander@sulu.io" 10 | } 11 | ], 12 | "require": { 13 | "php": "^5.5 || ^7.0" 14 | }, 15 | "autoload": { 16 | "files": [ 17 | "./Locale.php" 18 | ] 19 | } 20 | } 21 | --------------------------------------------------------------------------------