From 4f5b44bd3bd490309eb2ba7b44df4769816ba729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Sat, 3 Aug 2013 19:26:54 +0200 Subject: twig implementation --- .../symfony/intl/Symfony/Component/Intl/.gitignore | 3 + .../intl/Symfony/Component/Intl/CONTRIBUTING.md | 91 ++ .../Symfony/Component/Intl/Collator/Collator.php | 295 +++++++ .../DateFormatter/DateFormat/AmPmTransformer.php | 46 + .../DateFormat/DayOfWeekTransformer.php | 59 ++ .../DateFormat/DayOfYearTransformer.php | 46 + .../DateFormatter/DateFormat/DayTransformer.php | 46 + .../DateFormatter/DateFormat/FullTransformer.php | 356 ++++++++ .../DateFormat/Hour1200Transformer.php | 62 ++ .../DateFormat/Hour1201Transformer.php | 62 ++ .../DateFormat/Hour2400Transformer.php | 61 ++ .../DateFormat/Hour2401Transformer.php | 64 ++ .../DateFormatter/DateFormat/HourTransformer.php | 30 + .../DateFormatter/DateFormat/MinuteTransformer.php | 48 ++ .../DateFormatter/DateFormat/MonthTransformer.php | 143 ++++ .../DateFormat/QuarterTransformer.php | 64 ++ .../DateFormatter/DateFormat/SecondTransformer.php | 48 ++ .../DateFormat/TimeZoneTransformer.php | 99 +++ .../Intl/DateFormatter/DateFormat/Transformer.php | 64 ++ .../DateFormatter/DateFormat/YearTransformer.php | 50 ++ .../Intl/DateFormatter/IntlDateFormatter.php | 631 ++++++++++++++ .../Intl/Exception/BadMethodCallException.php | 21 + .../Intl/Exception/ExceptionInterface.php | 21 + .../Intl/Exception/InvalidArgumentException.php | 21 + .../MethodArgumentNotImplementedException.php | 32 + .../MethodArgumentValueNotImplementedException.php | 41 + .../Exception/MethodNotImplementedException.php | 28 + .../Intl/Exception/NotImplementedException.php | 32 + .../Intl/Exception/OutOfBoundsException.php | 21 + .../Component/Intl/Exception/RuntimeException.php | 21 + .../Symfony/Component/Intl/Globals/IntlGlobals.php | 137 +++ .../symfony/intl/Symfony/Component/Intl/Intl.php | 211 +++++ vendor/symfony/intl/Symfony/Component/Intl/LICENSE | 19 + .../intl/Symfony/Component/Intl/Locale/Locale.php | 317 +++++++ .../Intl/NumberFormatter/NumberFormatter.php | 891 ++++++++++++++++++++ .../symfony/intl/Symfony/Component/Intl/README.md | 25 + .../Intl/ResourceBundle/AbstractBundle.php | 71 ++ .../ResourceBundle/Compiler/BundleCompiler.php | 71 ++ .../Compiler/BundleCompilerInterface.php | 29 + .../Intl/ResourceBundle/CurrencyBundle.php | 94 +++ .../ResourceBundle/CurrencyBundleInterface.php | 74 ++ .../Intl/ResourceBundle/LanguageBundle.php | 115 +++ .../ResourceBundle/LanguageBundleInterface.php | 64 ++ .../Component/Intl/ResourceBundle/LocaleBundle.php | 52 ++ .../Intl/ResourceBundle/LocaleBundleInterface.php | 41 + .../ResourceBundle/Reader/AbstractBundleReader.php | 42 + .../ResourceBundle/Reader/BinaryBundleReader.php | 51 ++ .../ResourceBundle/Reader/BufferedBundleReader.php | 62 ++ .../Reader/BundleReaderInterface.php | 40 + .../Intl/ResourceBundle/Reader/PhpBundleReader.php | 61 ++ .../Reader/StructuredBundleReader.php | 113 +++ .../Reader/StructuredBundleReaderInterface.php | 50 ++ .../Component/Intl/ResourceBundle/RegionBundle.php | 52 ++ .../Intl/ResourceBundle/RegionBundleInterface.php | 41 + .../ResourceBundle/ResourceBundleInterface.php | 27 + .../Transformer/BundleTransformer.php | 96 +++ .../Transformer/CompilationContext.php | 97 +++ .../Transformer/CompilationContextInterface.php | 56 ++ .../Rule/CurrencyBundleTransformationRule.php | 94 +++ .../Rule/LanguageBundleTransformationRule.php | 71 ++ .../Rule/LocaleBundleTransformationRule.php | 251 ++++++ .../Rule/RegionBundleTransformationRule.php | 70 ++ .../Rule/TransformationRuleInterface.php | 70 ++ .../ResourceBundle/Transformer/StubbingContext.php | 80 ++ .../Transformer/StubbingContextInterface.php | 46 + .../Util/ArrayAccessibleResourceBundle.php | 79 ++ .../ResourceBundle/Util/RecursiveArrayAccess.php | 33 + .../Intl/ResourceBundle/Util/RingBuffer.php | 88 ++ .../Writer/BundleWriterInterface.php | 29 + .../Intl/ResourceBundle/Writer/PhpBundleWriter.php | 50 ++ .../ResourceBundle/Writer/TextBundleWriter.php | 202 +++++ .../Component/Intl/Resources/bin/autoload.php | 18 + .../Component/Intl/Resources/bin/common.php | 69 ++ .../Intl/Resources/bin/copy-stubs-to-component.php | 63 ++ .../Component/Intl/Resources/bin/create-stubs.php | 112 +++ .../Component/Intl/Resources/bin/icu-version.php | 18 + .../Symfony/Component/Intl/Resources/bin/icu.ini | 9 + .../Component/Intl/Resources/bin/test-compat.php | 56 ++ .../Intl/Resources/bin/update-icu-component.php | 212 +++++ .../Intl/Resources/bin/util/test-compat-helper.php | 23 + .../Component/Intl/Resources/stubs/Collator.php | 21 + .../Intl/Resources/stubs/IntlDateFormatter.php | 21 + .../Component/Intl/Resources/stubs/Locale.php | 21 + .../Intl/Resources/stubs/NumberFormatter.php | 21 + .../Component/Intl/Resources/stubs/functions.php | 80 ++ .../Intl/Tests/Collator/AbstractCollatorTest.php | 62 ++ .../Component/Intl/Tests/Collator/CollatorTest.php | 109 +++ .../Tests/Collator/Verification/CollatorTest.php | 37 + .../AbstractIntlDateFormatterTest.php | 932 +++++++++++++++++++++ .../Tests/DateFormatter/IntlDateFormatterTest.php | 220 +++++ .../Verification/IntlDateFormatterTest.php | 64 ++ .../Intl/Tests/Globals/AbstractIntlGlobalsTest.php | 41 + .../Intl/Tests/Globals/IntlGlobalsTest.php | 22 + .../Tests/Globals/Verification/IntlGlobalsTest.php | 36 + .../Intl/Tests/Locale/AbstractLocaleTest.php | 29 + .../Component/Intl/Tests/Locale/LocaleTest.php | 159 ++++ .../Intl/Tests/Locale/Verification/LocaleTest.php | 38 + .../AbstractNumberFormatterTest.php | 707 ++++++++++++++++ .../Tests/NumberFormatter/NumberFormatterTest.php | 239 ++++++ .../Verification/NumberFormatterTest.php | 54 ++ .../Tests/ResourceBundle/AbstractBundleTest.php | 55 ++ .../Tests/ResourceBundle/CurrencyBundleTest.php | 98 +++ .../Tests/ResourceBundle/LanguageBundleTest.php | 197 +++++ .../Intl/Tests/ResourceBundle/LocaleBundleTest.php | 64 ++ .../Reader/AbstractBundleReaderTest.php | 64 ++ .../Reader/BinaryBundleReaderTest.php | 58 ++ .../Reader/Fixtures/NotAFile/en.php/.gitkeep | 0 .../Tests/ResourceBundle/Reader/Fixtures/en.php | 14 + .../Tests/ResourceBundle/Reader/Fixtures/en.res | Bin 0 -> 84 bytes .../Tests/ResourceBundle/Reader/Fixtures/en.txt | 3 + .../ResourceBundle/Reader/PhpBundleReaderTest.php | 63 ++ .../Reader/StructuredBundleReaderTest.php | 223 +++++ .../Intl/Tests/ResourceBundle/RegionBundleTest.php | 63 ++ .../Tests/ResourceBundle/Util/RingBufferTest.php | 101 +++ .../Tests/ResourceBundle/Writer/Fixtures/en.php | 23 + .../Tests/ResourceBundle/Writer/Fixtures/en.res | Bin 0 -> 316 bytes .../Tests/ResourceBundle/Writer/Fixtures/en.txt | 23 + .../ResourceBundle/Writer/PhpBundleWriterTest.php | 62 ++ .../ResourceBundle/Writer/TextBundleWriterTest.php | 67 ++ .../Component/Intl/Tests/Util/IcuVersionTest.php | 111 +++ .../Component/Intl/Tests/Util/VersionTest.php | 87 ++ .../Symfony/Component/Intl/Util/IcuVersion.php | 105 +++ .../Symfony/Component/Intl/Util/IntlTestHelper.php | 128 +++ .../intl/Symfony/Component/Intl/Util/SvnCommit.php | 66 ++ .../Symfony/Component/Intl/Util/SvnRepository.php | 141 ++++ .../intl/Symfony/Component/Intl/Util/Version.php | 96 +++ .../intl/Symfony/Component/Intl/composer.json | 48 ++ .../intl/Symfony/Component/Intl/phpunit.xml.dist | 29 + 128 files changed, 12250 insertions(+) create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/.gitignore create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/CONTRIBUTING.md create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Collator/Collator.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/AmPmTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfWeekTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1200Transformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1201Transformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2400Transformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2401Transformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/HourTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MinuteTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MonthTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/SecondTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/TimeZoneTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Transformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/YearTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/BadMethodCallException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentNotImplementedException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentValueNotImplementedException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodNotImplementedException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/NotImplementedException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/OutOfBoundsException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Exception/RuntimeException.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Globals/IntlGlobals.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Intl.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/LICENSE create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Locale/Locale.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/README.md create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/AbstractBundle.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompiler.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompilerInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundle.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundleInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundle.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundleInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundle.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundleInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/AbstractBundleReader.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BinaryBundleReader.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BufferedBundleReader.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BundleReaderInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/PhpBundleReader.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReader.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReaderInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundle.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundleInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/ResourceBundleInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/BundleTransformer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContext.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContextInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/CurrencyBundleTransformationRule.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LanguageBundleTransformationRule.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LocaleBundleTransformationRule.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/RegionBundleTransformationRule.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/TransformationRuleInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContext.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContextInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/ArrayAccessibleResourceBundle.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RecursiveArrayAccess.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RingBuffer.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/BundleWriterInterface.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/PhpBundleWriter.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/TextBundleWriter.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/autoload.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/common.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/copy-stubs-to-component.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/create-stubs.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/icu-version.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/icu.ini create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/test-compat.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/update-icu-component.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/bin/util/test-compat-helper.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/stubs/Collator.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/stubs/IntlDateFormatter.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/stubs/Locale.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/stubs/NumberFormatter.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Resources/stubs/functions.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Collator/AbstractCollatorTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Collator/CollatorTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Collator/Verification/CollatorTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/DateFormatter/IntlDateFormatterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Globals/AbstractIntlGlobalsTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Globals/IntlGlobalsTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Globals/Verification/IntlGlobalsTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Locale/AbstractLocaleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Locale/LocaleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Locale/Verification/LocaleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/NumberFormatter/NumberFormatterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/NumberFormatter/Verification/NumberFormatterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/AbstractBundleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/CurrencyBundleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/LanguageBundleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/LocaleBundleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/AbstractBundleReaderTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/BinaryBundleReaderTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/Fixtures/NotAFile/en.php/.gitkeep create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/Fixtures/en.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/Fixtures/en.res create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/Fixtures/en.txt create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/PhpBundleReaderTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Reader/StructuredBundleReaderTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/RegionBundleTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Util/RingBufferTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Writer/Fixtures/en.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Writer/Fixtures/en.res create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Writer/Fixtures/en.txt create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Writer/PhpBundleWriterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/ResourceBundle/Writer/TextBundleWriterTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Util/IcuVersionTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Tests/Util/VersionTest.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Util/IcuVersion.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Util/IntlTestHelper.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Util/SvnCommit.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Util/SvnRepository.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/Util/Version.php create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/composer.json create mode 100644 vendor/symfony/intl/Symfony/Component/Intl/phpunit.xml.dist (limited to 'vendor/symfony/intl/Symfony/Component') diff --git a/vendor/symfony/intl/Symfony/Component/Intl/.gitignore b/vendor/symfony/intl/Symfony/Component/Intl/.gitignore new file mode 100644 index 00000000..c49a5d8d --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/intl/Symfony/Component/Intl/CONTRIBUTING.md b/vendor/symfony/intl/Symfony/Component/Intl/CONTRIBUTING.md new file mode 100644 index 00000000..315c28ab --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/CONTRIBUTING.md @@ -0,0 +1,91 @@ +Contributing to the Intl component +================================== + +A very good way of contributing to the Intl component is by updating the +included data for the ICU version you have installed on your system. + +Preparation +----------- + +To prepare, you need to install the development dependencies of the component. + + $ cd /path/to/Symfony/Component/Intl + $ composer.phar install --dev + +Determining your ICU version +--------------------------- + +The ICU version installed in your PHP environment can be found by running +icu-version.php: + + $ php Resources/bin/icu-version.php + +Updating the ICU data +--------------------- + +To update the data files, run the update-icu-component.php script: + + $ php Resources/bin/update-icu-component.php + +The script needs the binaries "svn" and "make" to be available on your system. +It will download the latest version of the ICU sources for the ICU version +installed in your PHP environment. The script will then compile the "genrb" +binary and use it to compile the ICU data files to binaries. The binaries are +copied to the Resources/ directory of the Icu component found in the +vendor/symfony/icu/ directory. + +Updating the stub data +---------------------- + +In the previous step you updated the Icu component for the ICU version +installed on your system. If you are using the latest ICU version, you should +also create the stub data files which will be used by people who don't have +the intl extension installed. + +To update the stub files, run the update-stubs.php script: + + $ php Resources/bin/update-stubs.php + +The script will fail if you don't have the latest ICU version. If you want to +upgrade the ICU version, adjust the return value of the +`Intl::getIcuStubVersion()` before you run the script. + +The script creates copies of the binary resource bundles in the Icu component +and stores them in the Resources/ directory of the Intl component. The copies +are made for the locale "en" only and are stored in .php files, so that they +can be read even if the intl extension is not available. + +Creating a pull request +----------------------- + +You need to create up to two pull requests: + +* If you updated the Icu component, you need to push that change and create a + pull request in the `symfony/Icu` repository. Make sure to submit the pull + request to the correct master branch. If you updated the ICU data for version + 4.8, your pull request goes to branch `48-master`, for version 49 to + `49-master` and so on. + +* If you updated the stub files of the Intl component, you need to push that + change and create a pull request in the `symfony/symfony` repository. The + pull request should be based on the `master` branch. + +Combining .res files to a .dat-package +-------------------------------------- + +The individual *.res files can be combined into a single .dat-file. +Unfortunately, PHP's `ResourceBundle` class is currently not able to handle +.dat-files. + +Once it is, the following steps have to be followed to build the .dat-file: + +1. Package the resource bundles into a single file + + $ find . -name *.res | sed -e "s/\.\///g" > packagelist.txt + $ pkgdata -p region -T build -d . packagelist.txt + +2. Clean up + + $ rm -rf build packagelist.txt + +3. You can now move region.dat to replace the version bundled with Symfony2. diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Collator/Collator.php b/vendor/symfony/intl/Symfony/Component/Intl/Collator/Collator.php new file mode 100644 index 00000000..8c0ffc33 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Collator/Collator.php @@ -0,0 +1,295 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Collator; + +use Symfony\Component\Intl\Exception\MethodNotImplementedException; +use Symfony\Component\Intl\Exception\MethodArgumentValueNotImplementedException; +use Symfony\Component\Intl\Globals\IntlGlobals; +use Symfony\Component\Intl\Locale\Locale; + +/** + * Replacement for PHP's native {@link \Collator} class. + * + * The only methods currently supported in this class are: + * + * - {@link \__construct} + * - {@link create} + * - {@link asort} + * - {@link getErrorCode} + * - {@link getErrorMessage} + * - {@link getLocale} + * + * @author Igor Wiedler + * @author Bernhard Schussek + */ +class Collator +{ + /* Attribute constants */ + const FRENCH_COLLATION = 0; + const ALTERNATE_HANDLING = 1; + const CASE_FIRST = 2; + const CASE_LEVEL = 3; + const NORMALIZATION_MODE = 4; + const STRENGTH = 5; + const HIRAGANA_QUATERNARY_MODE = 6; + const NUMERIC_COLLATION = 7; + + /* Attribute constants values */ + const DEFAULT_VALUE = -1; + + const PRIMARY = 0; + const SECONDARY = 1; + const TERTIARY = 2; + const DEFAULT_STRENGTH = 2; + const QUATERNARY = 3; + const IDENTICAL = 15; + + const OFF = 16; + const ON = 17; + + const SHIFTED = 20; + const NON_IGNORABLE = 21; + + const LOWER_FIRST = 24; + const UPPER_FIRST = 25; + + /* Sorting options */ + const SORT_REGULAR = 0; + const SORT_NUMERIC = 2; + const SORT_STRING = 1; + + /** + * Constructor + * + * @param string $locale The locale code. The only currently supported locale is "en". + * + * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed + */ + public function __construct($locale) + { + if ('en' != $locale) { + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'locale', $locale, 'Only the locale "en" is supported'); + } + } + + /** + * Static constructor + * + * @param string $locale The locale code. The only currently supported locale is "en". + * + * @return Collator + * + * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed + */ + public static function create($locale) + { + return new self($locale); + } + + /** + * Sort array maintaining index association + * + * @param array &$array Input array + * @param integer $sortFlag Flags for sorting, can be one of the following: + * Collator::SORT_REGULAR - compare items normally (don't change types) + * Collator::SORT_NUMERIC - compare items numerically + * Collator::SORT_STRING - compare items as strings + * + * @return Boolean True on success or false on failure + */ + public function asort(&$array, $sortFlag = self::SORT_REGULAR) + { + $intlToPlainFlagMap = array( + self::SORT_REGULAR => \SORT_REGULAR, + self::SORT_NUMERIC => \SORT_NUMERIC, + self::SORT_STRING => \SORT_STRING, + ); + + $plainSortFlag = isset($intlToPlainFlagMap[$sortFlag]) ? $intlToPlainFlagMap[$sortFlag] : self::SORT_REGULAR; + + return asort($array, $plainSortFlag); + } + + /** + * Not supported. Compare two Unicode strings + * + * @param string $str1 The first string to compare + * @param string $str2 The second string to compare + * + * @return Boolean|int Return the comparison result or false on failure: + * 1 if $str1 is greater than $str2 + * 0 if $str1 is equal than $str2 + * -1 if $str1 is less than $str2 + * + * @see http://www.php.net/manual/en/collator.compare.php + * + * @throws MethodNotImplementedException + */ + public function compare($str1, $str2) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Get a value of an integer collator attribute + * + * @param int $attr An attribute specifier, one of the attribute constants + * + * @return Boolean|int The attribute value on success or false on error + * + * @see http://www.php.net/manual/en/collator.getattribute.php + * + * @throws MethodNotImplementedException + */ + public function getAttribute($attr) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Returns collator's last error code. Always returns the U_ZERO_ERROR class constant value + * + * @return int The error code from last collator call + */ + public function getErrorCode() + { + return IntlGlobals::U_ZERO_ERROR; + } + + /** + * Returns collator's last error message. Always returns the U_ZERO_ERROR_MESSAGE class constant value + * + * @return string The error message from last collator call + */ + public function getErrorMessage() + { + return 'U_ZERO_ERROR'; + } + + /** + * Returns the collator's locale + * + * @param int $type Not supported. The locale name type to return (Locale::VALID_LOCALE or Locale::ACTUAL_LOCALE) + * + * @return string The locale used to create the collator. Currently always + * returns "en". + */ + public function getLocale($type = Locale::ACTUAL_LOCALE) + { + return 'en'; + } + + /** + * Not supported. Get sorting key for a string + * + * @param string $string The string to produce the key from + * + * @return string The collation key for $string + * + * @see http://www.php.net/manual/en/collator.getsortkey.php + * + * @throws MethodNotImplementedException + */ + public function getSortKey($string) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Get current collator's strength + * + * @return Boolean|int The current collator's strength or false on failure + * + * @see http://www.php.net/manual/en/collator.getstrength.php + * + * @throws MethodNotImplementedException + */ + public function getStrength() + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Set a collator's attribute + * + * @param int $attr An attribute specifier, one of the attribute constants + * @param int $val The attribute value, one of the attribute value constants + * + * @return Boolean True on success or false on failure + * + * @see http://www.php.net/manual/en/collator.setattribute.php + * + * @throws MethodNotImplementedException + */ + public function setAttribute($attr, $val) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Set the collator's strength + * + * @param int $strength Strength to set, possible values: + * Collator::PRIMARY + * Collator::SECONDARY + * Collator::TERTIARY + * Collator::QUATERNARY + * Collator::IDENTICAL + * Collator::DEFAULT + * + * @return Boolean True on success or false on failure + * + * @see http://www.php.net/manual/en/collator.setstrength.php + * + * @throws MethodNotImplementedException + */ + public function setStrength($strength) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Sort array using specified collator and sort keys + * + * @param array &$arr Array of strings to sort + * + * @return Boolean True on success or false on failure + * + * @see http://www.php.net/manual/en/collator.sortwithsortkeys.php + * + * @throws MethodNotImplementedException + */ + public function sortWithSortKeys(&$arr) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Sort array using specified collator + * + * @param array &$arr Array of string to sort + * @param int $sortFlag Optional sorting type, one of the following: + * Collator::SORT_REGULAR + * Collator::SORT_NUMERIC + * Collator::SORT_STRING + * + * @return Boolean True on success or false on failure + * + * @see http://www.php.net/manual/en/collator.sort.php + * + * @throws MethodNotImplementedException + */ + public function sort(&$arr, $sortFlag = self::SORT_REGULAR) + { + throw new MethodNotImplementedException(__METHOD__); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/AmPmTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/AmPmTransformer.php new file mode 100644 index 00000000..1a9601d8 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/AmPmTransformer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for AM/PM markers format + * + * @author Igor Wiedler + */ +class AmPmTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + return $dateTime->format('A'); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return 'AM|PM'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'marker' => $matched + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfWeekTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfWeekTransformer.php new file mode 100644 index 00000000..ee53a4e6 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfWeekTransformer.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for day of week format + * + * @author Igor Wiedler + */ +class DayOfWeekTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $dayOfWeek = $dateTime->format('l'); + switch ($length) { + case 4: + return $dayOfWeek; + case 5: + return $dayOfWeek[0]; + default: + return substr($dayOfWeek, 0, 3); + } + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + switch ($length) { + case 4: + return 'Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday'; + case 5: + return '[MTWFS]'; + default: + return 'Mon|Tue|Wed|Thu|Fri|Sat|Sun'; + } + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array(); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php new file mode 100644 index 00000000..2c33888c --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayOfYearTransformer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for day of year format + * + * @author Igor Wiedler + */ +class DayOfYearTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $dayOfYear = $dateTime->format('z') + 1; + + return $this->padLeft($dayOfYear, $length); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return '\d{'.$length.'}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array(); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayTransformer.php new file mode 100644 index 00000000..19d30e74 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/DayTransformer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for day format + * + * @author Igor Wiedler + */ +class DayTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + return $this->padLeft($dateTime->format('j'), $length); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'day' => (int) $matched, + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php new file mode 100644 index 00000000..b89db363 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php @@ -0,0 +1,356 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +use Symfony\Component\Intl\Exception\NotImplementedException; +use Symfony\Component\Intl\Globals\IntlGlobals; +use Symfony\Component\Intl\DateFormatter\DateFormat\MonthTransformer; + +/** + * Parser and formatter for date formats + * + * @author Igor Wiedler + */ +class FullTransformer +{ + private $quoteMatch = "'(?:[^']+|'')*'"; + private $implementedChars = 'MLydQqhDEaHkKmsz'; + private $notImplementedChars = 'GYuwWFgecSAZvVW'; + private $regExp; + + /** + * @var Transformer[] + */ + private $transformers; + + private $pattern; + private $timezone; + + /** + * Constructor + * + * @param string $pattern The pattern to be used to format and/or parse values + * @param string $timezone The timezone to perform the date/time calculations + */ + public function __construct($pattern, $timezone) + { + $this->pattern = $pattern; + $this->timezone = $timezone; + + $implementedCharsMatch = $this->buildCharsMatch($this->implementedChars); + $notImplementedCharsMatch = $this->buildCharsMatch($this->notImplementedChars); + $this->regExp = "/($this->quoteMatch|$implementedCharsMatch|$notImplementedCharsMatch)/"; + + $this->transformers = array( + 'M' => new MonthTransformer(), + 'L' => new MonthTransformer(), + 'y' => new YearTransformer(), + 'd' => new DayTransformer(), + 'q' => new QuarterTransformer(), + 'Q' => new QuarterTransformer(), + 'h' => new Hour1201Transformer(), + 'D' => new DayOfYearTransformer(), + 'E' => new DayOfWeekTransformer(), + 'a' => new AmPmTransformer(), + 'H' => new Hour2400Transformer(), + 'K' => new Hour1200Transformer(), + 'k' => new Hour2401Transformer(), + 'm' => new MinuteTransformer(), + 's' => new SecondTransformer(), + 'z' => new TimeZoneTransformer(), + ); + } + + /** + * Return the array of Transformer objects + * + * @return Transformer[] Associative array of Transformer objects (format char => Transformer) + */ + public function getTransformers() + { + return $this->transformers; + } + + /** + * Format a DateTime using ICU dateformat pattern + * + * @param \DateTime $dateTime A DateTime object to be used to generate the formatted value + * + * @return string The formatted value + */ + public function format(\DateTime $dateTime) + { + $that = $this; + + $formatted = preg_replace_callback($this->regExp, function($matches) use ($that, $dateTime) { + return $that->formatReplace($matches[0], $dateTime); + }, $this->pattern); + + return $formatted; + } + + /** + * Return the formatted ICU value for the matched date characters + * + * @param string $dateChars The date characters to be replaced with a formatted ICU value + * @param DateTime $dateTime A DateTime object to be used to generate the formatted value + * + * @return string The formatted value + * + * @throws NotImplementedException When it encounters a not implemented date character + */ + public function formatReplace($dateChars, $dateTime) + { + $length = strlen($dateChars); + + if ($this->isQuoteMatch($dateChars)) { + return $this->replaceQuoteMatch($dateChars); + } + + if (isset($this->transformers[$dateChars[0]])) { + $transformer = $this->transformers[$dateChars[0]]; + + return $transformer->format($dateTime, $length); + } + + // handle unimplemented characters + if (false !== strpos($this->notImplementedChars, $dateChars[0])) { + throw new NotImplementedException(sprintf("Unimplemented date character '%s' in format '%s'", $dateChars[0], $this->pattern)); + } + } + + /** + * Parse a pattern based string to a timestamp value + * + * @param \DateTime $dateTime A configured DateTime object to use to perform the date calculation + * @param string $value String to convert to a time value + * + * @return int The corresponding Unix timestamp + * + * @throws \InvalidArgumentException When the value can not be matched with pattern + */ + public function parse(\DateTime $dateTime, $value) + { + $reverseMatchingRegExp = $this->getReverseMatchingRegExp($this->pattern); + $reverseMatchingRegExp = '/^'.$reverseMatchingRegExp.'$/'; + + $options = array(); + + if (preg_match($reverseMatchingRegExp, $value, $matches)) { + $matches = $this->normalizeArray($matches); + + foreach ($this->transformers as $char => $transformer) { + if (isset($matches[$char])) { + $length = strlen($matches[$char]['pattern']); + $options = array_merge($options, $transformer->extractDateOptions($matches[$char]['value'], $length)); + } + } + + // reset error code and message + IntlGlobals::setError(IntlGlobals::U_ZERO_ERROR); + + return $this->calculateUnixTimestamp($dateTime, $options); + } + + // behave like the intl extension + IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Date parsing failed'); + + return false; + } + + /** + * Retrieve a regular expression to match with a formatted value. + * + * @param string $pattern The pattern to create the reverse matching regular expression + * + * @return string The reverse matching regular expression with named captures being formed by the + * transformer index in the $transformer array + */ + public function getReverseMatchingRegExp($pattern) + { + $that = $this; + + $escapedPattern = preg_quote($pattern, '/'); + + // ICU 4.8 recognizes slash ("/") in a value to be parsed as a dash ("-") and vice-versa + // when parsing a date/time value + $escapedPattern = preg_replace('/\\\[\-|\/]/', '[\/\-]', $escapedPattern); + + $reverseMatchingRegExp = preg_replace_callback($this->regExp, function($matches) use ($that) { + $length = strlen($matches[0]); + $transformerIndex = $matches[0][0]; + + $dateChars = $matches[0]; + if ($that->isQuoteMatch($dateChars)) { + return $that->replaceQuoteMatch($dateChars); + } + + $transformers = $that->getTransformers(); + if (isset($transformers[$transformerIndex])) { + $transformer = $transformers[$transformerIndex]; + $captureName = str_repeat($transformerIndex, $length); + + return "(?P<$captureName>".$transformer->getReverseMatchingRegExp($length).')'; + } + }, $escapedPattern); + + return $reverseMatchingRegExp; + } + + /** + * Check if the first char of a string is a single quote + * + * @param string $quoteMatch The string to check + * + * @return Boolean true if matches, false otherwise + */ + public function isQuoteMatch($quoteMatch) + { + return ("'" === $quoteMatch[0]); + } + + /** + * Replaces single quotes at the start or end of a string with two single quotes + * + * @param string $quoteMatch The string to replace the quotes + * + * @return string A string with the single quotes replaced + */ + public function replaceQuoteMatch($quoteMatch) + { + if (preg_match("/^'+$/", $quoteMatch)) { + return str_replace("''", "'", $quoteMatch); + } + + return str_replace("''", "'", substr($quoteMatch, 1, -1)); + } + + /** + * Builds a chars match regular expression + * + * @param string $specialChars A string of chars to build the regular expression + * + * @return string The chars match regular expression + */ + protected function buildCharsMatch($specialChars) + { + $specialCharsArray = str_split($specialChars); + + $specialCharsMatch = implode('|', array_map(function($char) { + return $char.'+'; + }, $specialCharsArray)); + + return $specialCharsMatch; + } + + /** + * Normalize a preg_replace match array, removing the numeric keys and returning an associative array + * with the value and pattern values for the matched Transformer + * + * @param array $data + * + * @return array + */ + protected function normalizeArray(array $data) + { + $ret = array(); + + foreach ($data as $key => $value) { + if (!is_string($key)) { + continue; + } + + $ret[$key[0]] = array( + 'value' => $value, + 'pattern' => $key + ); + } + + return $ret; + } + + /** + * Calculates the Unix timestamp based on the matched values by the reverse matching regular + * expression of parse() + * + * @param \DateTime $dateTime The DateTime object to be used to calculate the timestamp + * @param array $options An array with the matched values to be used to calculate the timestamp + * + * @return Boolean|int The calculated timestamp or false if matched date is invalid + */ + protected function calculateUnixTimestamp(\DateTime $dateTime, array $options) + { + $options = $this->getDefaultValueForOptions($options); + + $year = $options['year']; + $month = $options['month']; + $day = $options['day']; + $hour = $options['hour']; + $hourInstance = $options['hourInstance']; + $minute = $options['minute']; + $second = $options['second']; + $marker = $options['marker']; + $timezone = $options['timezone']; + + // If month is false, return immediately (intl behavior) + if (false === $month) { + IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Date parsing failed'); + + return false; + } + + // Normalize hour + if ($hourInstance instanceof HourTransformer) { + $hour = $hourInstance->normalizeHour($hour, $marker); + } + + // Set the timezone if different from the default one + if (null !== $timezone && $timezone !== $this->timezone) { + $dateTime->setTimezone(new \DateTimeZone($timezone)); + } + + // Normalize yy year + preg_match_all($this->regExp, $this->pattern, $matches); + if (in_array('yy', $matches[0])) { + $dateTime->setTimestamp(time()); + $year = $year > $dateTime->format('y') + 20 ? 1900 + $year : 2000 + $year; + } + + $dateTime->setDate($year, $month, $day); + $dateTime->setTime($hour, $minute, $second); + + return $dateTime->getTimestamp(); + } + + /** + * Add sensible default values for missing items in the extracted date/time options array. The values + * are base in the beginning of the Unix era + * + * @param array $options + * + * @return array + */ + private function getDefaultValueForOptions(array $options) + { + return array( + 'year' => isset($options['year']) ? $options['year'] : 1970, + 'month' => isset($options['month']) ? $options['month'] : 1, + 'day' => isset($options['day']) ? $options['day'] : 1, + 'hour' => isset($options['hour']) ? $options['hour'] : 0, + 'hourInstance' => isset($options['hourInstance']) ? $options['hourInstance'] : null, + 'minute' => isset($options['minute']) ? $options['minute'] : 0, + 'second' => isset($options['second']) ? $options['second'] : 0, + 'marker' => isset($options['marker']) ? $options['marker'] : null, + 'timezone' => isset($options['timezone']) ? $options['timezone'] : null, + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1200Transformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1200Transformer.php new file mode 100644 index 00000000..8c8f5ef4 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1200Transformer.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for 12 hour format (0-11) + * + * @author Igor Wiedler + */ +class Hour1200Transformer extends HourTransformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $hourOfDay = $dateTime->format('g'); + $hourOfDay = '12' == $hourOfDay ? '0' : $hourOfDay; + + return $this->padLeft($hourOfDay, $length); + } + + /** + * {@inheritDoc} + */ + public function normalizeHour($hour, $marker = null) + { + if ('PM' === $marker) { + $hour += 12; + } + + return $hour; + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return '\d{1,2}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'hour' => (int) $matched, + 'hourInstance' => $this + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1201Transformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1201Transformer.php new file mode 100644 index 00000000..a8c43702 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour1201Transformer.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for 12 hour format (1-12) + * + * @author Igor Wiedler + */ +class Hour1201Transformer extends HourTransformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + return $this->padLeft($dateTime->format('g'), $length); + } + + /** + * {@inheritDoc} + */ + public function normalizeHour($hour, $marker = null) + { + if ('PM' !== $marker && 12 === $hour) { + $hour = 0; + } elseif ('PM' === $marker && 12 !== $hour) { + // If PM and hour is not 12 (1-12), sum 12 hour + $hour += 12; + } + + return $hour; + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return '\d{1,2}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'hour' => (int) $matched, + 'hourInstance' => $this + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2400Transformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2400Transformer.php new file mode 100644 index 00000000..8f22da13 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2400Transformer.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for 24 hour format (0-23) + * + * @author Igor Wiedler + */ +class Hour2400Transformer extends HourTransformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + return $this->padLeft($dateTime->format('G'), $length); + } + + /** + * {@inheritDoc} + */ + public function normalizeHour($hour, $marker = null) + { + if ('AM' == $marker) { + $hour = 0; + } elseif ('PM' == $marker) { + $hour = 12; + } + + return $hour; + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return '\d{1,2}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'hour' => (int) $matched, + 'hourInstance' => $this + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2401Transformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2401Transformer.php new file mode 100644 index 00000000..b0f486b9 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Hour2401Transformer.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for 24 hour format (1-24) + * + * @author Igor Wiedler + */ +class Hour2401Transformer extends HourTransformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $hourOfDay = $dateTime->format('G'); + $hourOfDay = ('0' == $hourOfDay) ? '24' : $hourOfDay; + + return $this->padLeft($hourOfDay, $length); + } + + /** + * {@inheritDoc} + */ + public function normalizeHour($hour, $marker = null) + { + if ((null === $marker && 24 === $hour) || 'AM' == $marker) { + $hour = 0; + } elseif ('PM' == $marker) { + $hour = 12; + } + + return $hour; + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return '\d{1,2}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'hour' => (int) $matched, + 'hourInstance' => $this + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/HourTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/HourTransformer.php new file mode 100644 index 00000000..51097d92 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/HourTransformer.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Base class for hour transformers + * + * @author Eriksen Costa + */ +abstract class HourTransformer extends Transformer +{ + /** + * Returns a normalized hour value suitable for the hour transformer type + * + * @param int $hour The hour value + * @param string $marker An optional AM/PM marker + * + * @return int The normalized hour value + */ + abstract public function normalizeHour($hour, $marker = null); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MinuteTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MinuteTransformer.php new file mode 100644 index 00000000..b48de292 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MinuteTransformer.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for minute format + * + * @author Igor Wiedler + */ +class MinuteTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $minuteOfHour = (int) $dateTime->format('i'); + + return $this->padLeft($minuteOfHour, $length); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'minute' => (int) $matched, + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MonthTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MonthTransformer.php new file mode 100644 index 00000000..30c15af7 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/MonthTransformer.php @@ -0,0 +1,143 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for month format + * + * @author Igor Wiedler + */ +class MonthTransformer extends Transformer +{ + /** + * @var array + */ + protected static $months = array( + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ); + + /** + * Short months names (first 3 letters) + * @var array + */ + protected static $shortMonths = array(); + + /** + * Flipped $months array, $name => $index + * @var array + */ + protected static $flippedMonths = array(); + + /** + * Flipped $shortMonths array, $name => $index + * @var array + */ + protected static $flippedShortMonths = array(); + + /** + * Constructor + */ + public function __construct() + { + if (0 === count(self::$shortMonths)) { + self::$shortMonths = array_map(function($month) { + return substr($month, 0, 3); + }, self::$months); + + self::$flippedMonths = array_flip(self::$months); + self::$flippedShortMonths = array_flip(self::$shortMonths); + } + } + + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $matchLengthMap = array( + 1 => 'n', + 2 => 'm', + 3 => 'M', + 4 => 'F', + ); + + if (isset($matchLengthMap[$length])) { + return $dateTime->format($matchLengthMap[$length]); + } + + if (5 === $length) { + return substr($dateTime->format('M'), 0, 1); + } + + return $this->padLeft($dateTime->format('m'), $length); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + switch ($length) { + case 1: + $regExp = '\d{1,2}'; + break; + case 3: + $regExp = implode('|', self::$shortMonths); + break; + case 4: + $regExp = implode('|', self::$months); + break; + case 5: + $regExp = '[JFMASOND]'; + break; + default: + $regExp = '\d{'.$length.'}'; + break; + } + + return $regExp; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + if (!is_numeric($matched)) { + if (3 === $length) { + $matched = self::$flippedShortMonths[$matched] + 1; + } elseif (4 === $length) { + $matched = self::$flippedMonths[$matched] + 1; + } elseif (5 === $length) { + // IntlDateFormatter::parse() always returns false for MMMMM or LLLLL + $matched = false; + } + } else { + $matched = (int) $matched; + } + + return array( + 'month' => $matched, + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php new file mode 100644 index 00000000..8e83dc75 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for quarter format + * + * @author Igor Wiedler + */ +class QuarterTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $month = (int) $dateTime->format('n'); + $quarter = (int) floor(($month - 1) / 3) + 1; + switch ($length) { + case 1: + case 2: + return $this->padLeft($quarter, $length); + case 3: + return 'Q'.$quarter; + default: + $map = array(1 => '1st quarter', 2 => '2nd quarter', 3 => '3rd quarter', 4 => '4th quarter'); + + return $map[$quarter]; + } + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + switch ($length) { + case 1: + case 2: + return '\d{'.$length.'}'; + case 3: + return 'Q\d'; + default: + return '(?:1st|2nd|3rd|4th) quarter'; + } + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array(); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/SecondTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/SecondTransformer.php new file mode 100644 index 00000000..ccbcdb41 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/SecondTransformer.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for the second format + * + * @author Igor Wiedler + */ +class SecondTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + $secondOfMinute = (int) $dateTime->format('s'); + + return $this->padLeft($secondOfMinute, $length); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'second' => (int) $matched, + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/TimeZoneTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/TimeZoneTransformer.php new file mode 100644 index 00000000..7d74bd36 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/TimeZoneTransformer.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +use Symfony\Component\Intl\Exception\NotImplementedException; + +/** + * Parser and formatter for time zone format + * + * @author Igor Wiedler + */ +class TimeZoneTransformer extends Transformer +{ + /** + * {@inheritDoc} + * + * @throws NotImplementedException When time zone is different than UTC or GMT (Etc/GMT) + */ + public function format(\DateTime $dateTime, $length) + { + $timeZone = substr($dateTime->getTimezone()->getName(), 0, 3); + + if (!in_array($timeZone, array('Etc', 'UTC'))) { + throw new NotImplementedException('Time zone different than GMT or UTC is not supported as a formatting output.'); + } + + // From ICU >= 4.8, the zero offset is not more used, example: GMT instead of GMT+00:00 + $format = (0 !== (int) $dateTime->format('O')) ? '\G\M\TP' : '\G\M\T'; + + return $dateTime->format($format); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return 'GMT[+-]\d{2}:?\d{2}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'timezone' => self::getEtcTimeZoneId($matched) + ); + } + + /** + * Get an Etc/GMT timezone identifier for the specified timezone + * + * The PHP documentation for timezones states to not use the 'Other' time zones because them exists + * "for backwards compatibility". However all Etc/GMT time zones are in the tz database 'etcetera' file, + * which indicates they are not deprecated (neither are old names). + * + * Only GMT, Etc/Universal, Etc/Zulu, Etc/Greenwich, Etc/GMT-0, Etc/GMT+0 and Etc/GMT0 are old names and + * are linked to Etc/GMT or Etc/UTC. + * + * @param string $formattedTimeZone A GMT timezone string (GMT-03:00, e.g.) + * + * @return string A timezone identifier + * + * @see http://php.net/manual/en/timezones.others.php + * @see http://www.twinsun.com/tz/tz-link.htm + * + * @throws NotImplementedException When the GMT time zone have minutes offset different than zero + * @throws \InvalidArgumentException When the value can not be matched with pattern + */ + public static function getEtcTimeZoneId($formattedTimeZone) + { + if (preg_match('/GMT(?P[+-])(?P\d{2}):?(?P\d{2})/', $formattedTimeZone, $matches)) { + $hours = (int) $matches['hours']; + $minutes = (int) $matches['minutes']; + $signal = $matches['signal'] == '-' ? '+' : '-'; + + if (0 < $minutes) { + throw new NotImplementedException(sprintf( + 'It is not possible to use a GMT time zone with minutes offset different than zero (0). GMT time zone tried: %s.', + $formattedTimeZone + )); + } + + return 'Etc/GMT'.($hours !== 0 ? $signal.$hours : ''); + } + + throw new \InvalidArgumentException('The GMT time zone \'%s\' does not match with the supported formats GMT[+-]HH:MM or GMT[+-]HHMM.'); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Transformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Transformer.php new file mode 100644 index 00000000..0e67f8ae --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/Transformer.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for date formats + * + * @author Igor Wiedler + */ +abstract class Transformer +{ + /** + * Format a value using a configured DateTime as date/time source + * + * + * @param \DateTime $dateTime A DateTime object to be used to generate the formatted value + * @param int $length The formatted value string length + * + * @return string The formatted value + */ + abstract public function format(\DateTime $dateTime, $length); + + /** + * Returns a reverse matching regular expression of a string generated by format() + * + * @param int $length The length of the value to be reverse matched + * + * @return string The reverse matching regular expression + */ + abstract public function getReverseMatchingRegExp($length); + + /** + * Extract date options from a matched value returned by the processing of the reverse matching + * regular expression + * + * @param string $matched The matched value + * @param int $length The length of the Transformer pattern string + * + * @return array An associative array + */ + abstract public function extractDateOptions($matched, $length); + + /** + * Pad a string with zeros to the left + * + * @param string $value The string to be padded + * @param int $length The length to pad + * + * @return string The padded string + */ + protected function padLeft($value, $length) + { + return str_pad($value, $length, '0', STR_PAD_LEFT); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/YearTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/YearTransformer.php new file mode 100644 index 00000000..c3bd699d --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/DateFormat/YearTransformer.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter\DateFormat; + +/** + * Parser and formatter for year format + * + * @author Igor Wiedler + */ +class YearTransformer extends Transformer +{ + /** + * {@inheritDoc} + */ + public function format(\DateTime $dateTime, $length) + { + if (2 === $length) { + return $dateTime->format('y'); + } + + return $this->padLeft($dateTime->format('Y'), $length); + } + + /** + * {@inheritDoc} + */ + public function getReverseMatchingRegExp($length) + { + return 2 === $length ? '\d{2}' : '\d{4}'; + } + + /** + * {@inheritDoc} + */ + public function extractDateOptions($matched, $length) + { + return array( + 'year' => (int) $matched, + ); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php new file mode 100644 index 00000000..33a499a8 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php @@ -0,0 +1,631 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\DateFormatter; + +use Symfony\Component\Intl\Globals\IntlGlobals; +use Symfony\Component\Intl\DateFormatter\DateFormat\FullTransformer; +use Symfony\Component\Intl\Exception\MethodNotImplementedException; +use Symfony\Component\Intl\Exception\MethodArgumentNotImplementedException; +use Symfony\Component\Intl\Exception\MethodArgumentValueNotImplementedException; +use Symfony\Component\Intl\Locale\Locale; + +/** + * Replacement for PHP's native {@link \IntlDateFormatter} class. + * + * The only methods currently supported in this class are: + * + * - {@link __construct} + * - {@link create} + * - {@link format} + * - {@link getCalendar} + * - {@link getDateType} + * - {@link getErrorCode} + * - {@link getErrorMessage} + * - {@link getLocale} + * - {@link getPattern} + * - {@link getTimeType} + * - {@link getTimeZoneId} + * - {@link isLenient} + * - {@link parse} + * - {@link setLenient} + * - {@link setPattern} + * - {@link setTimeZoneId} + * - {@link setTimeZone} + * + * @author Igor Wiedler + * @author Bernhard Schussek + */ +class IntlDateFormatter +{ + /** + * The error code from the last operation + * + * @var integer + */ + protected $errorCode = IntlGlobals::U_ZERO_ERROR; + + /** + * The error message from the last operation + * + * @var string + */ + protected $errorMessage = 'U_ZERO_ERROR'; + + /* date/time format types */ + const NONE = -1; + const FULL = 0; + const LONG = 1; + const MEDIUM = 2; + const SHORT = 3; + + /* calendar formats */ + const TRADITIONAL = 0; + const GREGORIAN = 1; + + /** + * Patterns used to format the date when no pattern is provided + * + * @var array + */ + private $defaultDateFormats = array( + self::NONE => '', + self::FULL => 'EEEE, LLLL d, y', + self::LONG => 'LLLL d, y', + self::MEDIUM => 'LLL d, y', + self::SHORT => 'M/d/yy', + ); + + /** + * Patterns used to format the time when no pattern is provided + * + * @var array + */ + private $defaultTimeFormats = array( + self::FULL => 'h:mm:ss a zzzz', + self::LONG => 'h:mm:ss a z', + self::MEDIUM => 'h:mm:ss a', + self::SHORT => 'h:mm a', + ); + + /** + * @var int + */ + private $datetype; + + /** + * @var int + */ + private $timetype; + + /** + * @var string + */ + private $pattern; + + /** + * @var \DateTimeZone + */ + private $dateTimeZone; + + /** + * @var Boolean + */ + private $unitializedTimeZoneId = false; + + /** + * @var string + */ + private $timeZoneId; + + /** + * Constructor + * + * @param string $locale The locale code. The only currently supported locale is "en". + * @param int $datetype Type of date formatting, one of the format type constants + * @param int $timetype Type of time formatting, one of the format type constants + * @param string $timezone Timezone identifier + * @param int $calendar Calendar to use for formatting or parsing. The only currently + * supported value is IntlDateFormatter::GREGORIAN. + * @param string $pattern Optional pattern to use when formatting + * + * @see http://www.php.net/manual/en/intldateformatter.create.php + * @see http://userguide.icu-project.org/formatparse/datetime + * + * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed + * @throws MethodArgumentValueNotImplementedException When $calendar different than GREGORIAN is passed + */ + public function __construct($locale, $datetype, $timetype, $timezone = null, $calendar = self::GREGORIAN, $pattern = null) + { + if ('en' !== $locale) { + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'locale', $locale, 'Only the locale "en" is supported'); + } + + if (self::GREGORIAN !== $calendar) { + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'calendar', $calendar, 'Only the GREGORIAN calendar is supported'); + } + + $this->datetype = $datetype; + $this->timetype = $timetype; + + $this->setPattern($pattern); + $this->setTimeZoneId($timezone); + } + + /** + * Static constructor + * + * @param string $locale The locale code. The only currently supported locale is "en". + * @param int $datetype Type of date formatting, one of the format type constants + * @param int $timetype Type of time formatting, one of the format type constants + * @param string $timezone Timezone identifier + * @param int $calendar Calendar to use for formatting or parsing; default is Gregorian. + * One of the calendar constants. + * @param string $pattern Optional pattern to use when formatting + * + * @return IntlDateFormatter + * + * @see http://www.php.net/manual/en/intldateformatter.create.php + * @see http://userguide.icu-project.org/formatparse/datetime + * + * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed + * @throws MethodArgumentValueNotImplementedException When $calendar different than GREGORIAN is passed + */ + public static function create($locale, $datetype, $timetype, $timezone = null, $calendar = self::GREGORIAN, $pattern = null) + { + return new self($locale, $datetype, $timetype, $timezone, $calendar, $pattern); + } + + /** + * Format the date/time value (timestamp) as a string + * + * @param integer|\DateTime $timestamp The timestamp to format. \DateTime objects + * are supported as of PHP 5.3.4. + * + * @return string|Boolean The formatted value or false if formatting failed. + * + * @see http://www.php.net/manual/en/intldateformatter.format.php + * + * @throws MethodArgumentValueNotImplementedException If one of the formatting characters is not implemented + */ + public function format($timestamp) + { + // intl allows timestamps to be passed as arrays - we don't + if (is_array($timestamp)) { + $message = version_compare(PHP_VERSION, '5.3.4', '>=') ? + 'Only integer unix timestamps and DateTime objects are supported' : + 'Only integer unix timestamps are supported'; + + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'timestamp', $timestamp, $message); + } + + // behave like the intl extension + $argumentError = null; + if (version_compare(PHP_VERSION, '5.3.4', '<') && !is_int($timestamp)) { + $argumentError = 'datefmt_format: takes either an array or an integer timestamp value '; + } elseif (version_compare(PHP_VERSION, '5.3.4', '>=') && !is_int($timestamp) && !$timestamp instanceof \DateTime) { + $argumentError = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object'; + if (version_compare(PHP_VERSION, '5.5.0-dev', '>=') && !is_int($timestamp)) { + $argumentError = sprintf('datefmt_format: string \'%s\' is not numeric, which would be required for it to be a valid date', $timestamp); + } + } + + if (null !== $argumentError) { + IntlGlobals::setError(IntlGlobals::U_ILLEGAL_ARGUMENT_ERROR, $argumentError); + $this->errorCode = IntlGlobals::getErrorCode(); + $this->errorMessage = IntlGlobals::getErrorMessage(); + + return false; + } + + // As of PHP 5.3.4, IntlDateFormatter::format() accepts DateTime instances + if (version_compare(PHP_VERSION, '5.3.4', '>=') && $timestamp instanceof \DateTime) { + $timestamp = $timestamp->getTimestamp(); + } + + $transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId()); + $formatted = $transformer->format($this->createDateTime($timestamp)); + + // behave like the intl extension + IntlGlobals::setError(IntlGlobals::U_ZERO_ERROR); + $this->errorCode = IntlGlobals::getErrorCode(); + $this->errorMessage = IntlGlobals::getErrorMessage(); + + return $formatted; + } + + /** + * Not supported. Formats an object + * + * @param object $object + * @param mixed $format + * @param string $locale + * + * @return string The formatted value + * + * @see http://www.php.net/manual/en/intldateformatter.formatobject.php + * + * @throws MethodNotImplementedException + */ + public function formatObject($object, $format = null, $locale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Returns the formatter's calendar + * + * @return int The calendar being used by the formatter. Currently always returns + * IntlDateFormatter::GREGORIAN. + * + * @see http://www.php.net/manual/en/intldateformatter.getcalendar.php + */ + public function getCalendar() + { + return self::GREGORIAN; + } + + /** + * Not supported. Returns the formatter's calendar object + * + * @return object The calendar's object being used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.getcalendarobject.php + * + * @throws MethodNotImplementedException + */ + public function getCalendarObject() + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Returns the formatter's datetype + * + * @return int The current value of the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.getdatetype.php + */ + public function getDateType() + { + return $this->datetype; + } + + /** + * Returns formatter's last error code. Always returns the U_ZERO_ERROR class constant value + * + * @return int The error code from last formatter call + * + * @see http://www.php.net/manual/en/intldateformatter.geterrorcode.php + */ + public function getErrorCode() + { + return $this->errorCode; + } + + /** + * Returns formatter's last error message. Always returns the U_ZERO_ERROR_MESSAGE class constant value + * + * @return string The error message from last formatter call + * + * @see http://www.php.net/manual/en/intldateformatter.geterrormessage.php + */ + public function getErrorMessage() + { + return $this->errorMessage; + } + + /** + * Returns the formatter's locale + * + * @param int $type Not supported. The locale name type to return (Locale::VALID_LOCALE or Locale::ACTUAL_LOCALE) + * + * @return string The locale used to create the formatter. Currently always + * returns "en". + * + * @see http://www.php.net/manual/en/intldateformatter.getlocale.php + */ + public function getLocale($type = Locale::ACTUAL_LOCALE) + { + return 'en'; + } + + /** + * Returns the formatter's pattern + * + * @return string The pattern string used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.getpattern.php + */ + public function getPattern() + { + return $this->pattern; + } + + /** + * Returns the formatter's time type + * + * @return string The time type used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.gettimetype.php + */ + public function getTimeType() + { + return $this->timetype; + } + + /** + * Returns the formatter's timezone identifier + * + * @return string The timezone identifier used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.gettimezoneid.php + */ + public function getTimeZoneId() + { + if (!$this->unitializedTimeZoneId) { + return $this->timeZoneId; + } + + // In PHP 5.5 default timezone depends on `date_default_timezone_get()` method + if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) { + return date_default_timezone_get(); + } + + return null; + } + + /** + * Not supported. Returns the formatter's timezone + * + * @return mixed The timezone used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.gettimezone.php + * + * @throws MethodNotImplementedException + */ + public function getTimeZone() + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Returns whether the formatter is lenient + * + * @return Boolean Currently always returns false. + * + * @see http://www.php.net/manual/en/intldateformatter.islenient.php + * + * @throws MethodNotImplementedException + */ + public function isLenient() + { + return false; + } + + /** + * Not supported. Parse string to a field-based time value + * + * @param string $value String to convert to a time value + * @param int $position Position at which to start the parsing in $value (zero-based). + * If no error occurs before $value is consumed, $parse_pos will + * contain -1 otherwise it will contain the position at which parsing + * ended. If $parse_pos > strlen($value), the parse fails immediately. + * + * @return string Localtime compatible array of integers: contains 24 hour clock value in tm_hour field + * + * @see http://www.php.net/manual/en/intldateformatter.localtime.php + * + * @throws MethodNotImplementedException + */ + public function localtime($value, &$position = 0) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Parse string to a timestamp value + * + * @param string $value String to convert to a time value + * @param int $position Not supported. Position at which to start the parsing in $value (zero-based). + * If no error occurs before $value is consumed, $parse_pos will + * contain -1 otherwise it will contain the position at which parsing + * ended. If $parse_pos > strlen($value), the parse fails immediately. + * + * @return string Parsed value as a timestamp + * + * @see http://www.php.net/manual/en/intldateformatter.parse.php + * + * @throws MethodArgumentNotImplementedException When $position different than null, behavior not implemented + */ + public function parse($value, &$position = null) + { + // We don't calculate the position when parsing the value + if (null !== $position) { + throw new MethodArgumentNotImplementedException(__METHOD__, 'position'); + } + + $dateTime = $this->createDateTime(0); + $transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId()); + + $timestamp = $transformer->parse($dateTime, $value); + + // behave like the intl extension. FullTransformer::parse() set the proper error + $this->errorCode = IntlGlobals::getErrorCode(); + $this->errorMessage = IntlGlobals::getErrorMessage(); + + return $timestamp; + } + + /** + * Not supported. Set the formatter's calendar + * + * @param string $calendar The calendar to use. Default is IntlDateFormatter::GREGORIAN. + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/intldateformatter.setcalendar.php + * + * @throws MethodNotImplementedException + */ + public function setCalendar($calendar) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Set the leniency of the parser + * + * Define if the parser is strict or lenient in interpreting inputs that do not match the pattern + * exactly. Enabling lenient parsing allows the parser to accept otherwise flawed date or time + * patterns, parsing as much as possible to obtain a value. Extra space, unrecognized tokens, or + * invalid values ("February 30th") are not accepted. + * + * @param Boolean $lenient Sets whether the parser is lenient or not. Currently + * only false (strict) is supported. + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/intldateformatter.setlenient.php + * + * @throws MethodArgumentValueNotImplementedException When $lenient is true + */ + public function setLenient($lenient) + { + if ($lenient) { + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'lenient', $lenient, 'Only the strict parser is supported'); + } + + return true; + } + + /** + * Set the formatter's pattern + * + * @param string $pattern A pattern string in conformance with the ICU IntlDateFormatter documentation + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/intldateformatter.setpattern.php + * @see http://userguide.icu-project.org/formatparse/datetime + */ + public function setPattern($pattern) + { + if (null === $pattern) { + $pattern = $this->getDefaultPattern(); + } + + $this->pattern = $pattern; + + return true; + } + + /** + * Set the formatter's timezone identifier + * + * @param string $timeZoneId The time zone ID string of the time zone to use. + * If NULL or the empty string, the default time zone for the + * runtime is used. + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/intldateformatter.settimezoneid.php + */ + public function setTimeZoneId($timeZoneId) + { + if (null === $timeZoneId) { + // In PHP 5.5 if $timeZoneId is null it fallbacks to `date_default_timezone_get()` method + if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) { + $timeZoneId = date_default_timezone_get(); + } else { + // TODO: changes were made to ext/intl in PHP 5.4.4 release that need to be investigated since it will + // use ini's date.timezone when the time zone is not provided. As a not well tested workaround, uses UTC. + // See the first two items of the commit message for more information: + // https://github.com/php/php-src/commit/eb346ef0f419b90739aadfb6cc7b7436c5b521d9 + $timeZoneId = getenv('TZ') ?: 'UTC'; + } + + $this->unitializedTimeZoneId = true; + } + + // Backup original passed time zone + $timeZone = $timeZoneId; + + // Get an Etc/GMT time zone that is accepted for \DateTimeZone + if ('GMT' !== $timeZoneId && 0 === strpos($timeZoneId, 'GMT')) { + try { + $timeZoneId = DateFormat\TimeZoneTransformer::getEtcTimeZoneId($timeZoneId); + } catch (\InvalidArgumentException $e) { + // Does nothing, will fallback to UTC + } + } + + try { + $this->dateTimeZone = new \DateTimeZone($timeZoneId); + } catch (\Exception $e) { + $this->dateTimeZone = new \DateTimeZone('UTC'); + } + + $this->timeZoneId = $timeZone; + + return true; + } + + /** + * This method was added in PHP 5.5 as replacement for `setTimeZoneId()` + * + * @param mixed $timeZone + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/intldateformatter.settimezone.php + */ + public function setTimeZone($timeZone) + { + return $this->setTimeZoneId($timeZone); + } + + /** + * Create and returns a DateTime object with the specified timestamp and with the + * current time zone + * + * @param int $timestamp + * + * @return \DateTime + */ + protected function createDateTime($timestamp) + { + $dateTime = new \DateTime(); + $dateTime->setTimestamp($timestamp); + $dateTime->setTimezone($this->dateTimeZone); + + return $dateTime; + } + + /** + * Returns a pattern string based in the datetype and timetype values + * + * @return string + */ + protected function getDefaultPattern() + { + $patternParts = array(); + if (self::NONE !== $this->datetype) { + $patternParts[] = $this->defaultDateFormats[$this->datetype]; + } + if (self::NONE !== $this->timetype) { + $patternParts[] = $this->defaultTimeFormats[$this->timetype]; + } + $pattern = implode(' ', $patternParts); + + return $pattern; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/BadMethodCallException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/BadMethodCallException.php new file mode 100644 index 00000000..ca79729f --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/BadMethodCallException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * Base BadMethodCallException for the Intl component. + * + * @author Bernhard Schussek + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/ExceptionInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/ExceptionInterface.php new file mode 100644 index 00000000..4fc076ca --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * Base ExceptionInterface for the Intl component. + * + * @author Bernhard Schussek + */ +interface ExceptionInterface +{ +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/InvalidArgumentException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..10f69ee3 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * InvalidArgumentException for the Intl component. + * + * @author Bernhard Schussek + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentNotImplementedException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentNotImplementedException.php new file mode 100644 index 00000000..570609d0 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentNotImplementedException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +use Symfony\Component\Intl\Exception\NotImplementedException; + +/** + * @author Eriksen Costa + */ +class MethodArgumentNotImplementedException extends NotImplementedException +{ + /** + * Constructor + * + * @param string $methodName The method name that raised the exception + * @param string $argName The argument name that is not implemented + */ + public function __construct($methodName, $argName) + { + $message = sprintf('The %s() method\'s argument $%s behavior is not implemented.', $methodName, $argName); + parent::__construct($message); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentValueNotImplementedException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentValueNotImplementedException.php new file mode 100644 index 00000000..76e3f634 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodArgumentValueNotImplementedException.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +use Symfony\Component\Intl\Exception\NotImplementedException; + +/** + * @author Eriksen Costa + */ +class MethodArgumentValueNotImplementedException extends NotImplementedException +{ + /** + * Constructor + * + * @param string $methodName The method name that raised the exception + * @param string $argName The argument name + * @param string $argValue The argument value that is not implemented + * @param string $additionalMessage An optional additional message to append to the exception message + */ + public function __construct($methodName, $argName, $argValue, $additionalMessage = '') + { + $message = sprintf( + 'The %s() method\'s argument $%s value %s behavior is not implemented.%s', + $methodName, + $argName, + var_export($argValue, true), + $additionalMessage !== '' ? ' '.$additionalMessage.'. ' : '' + ); + + parent::__construct($message); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodNotImplementedException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodNotImplementedException.php new file mode 100644 index 00000000..d8a0e90f --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/MethodNotImplementedException.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * @author Eriksen Costa + */ +class MethodNotImplementedException extends NotImplementedException +{ + /** + * Constructor + * + * @param string $methodName The name of the method + */ + public function __construct($methodName) + { + parent::__construct(sprintf('The %s() is not implemented.', $methodName)); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/NotImplementedException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/NotImplementedException.php new file mode 100644 index 00000000..1f3ba46b --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/NotImplementedException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * Base exception class for not implemented behaviors of the intl extension in the Locale component. + * + * @author Eriksen Costa + */ +class NotImplementedException extends RuntimeException +{ + const INTL_INSTALL_MESSAGE = 'Please install the "intl" extension for full localization capabilities.'; + + /** + * Constructor + * + * @param string $message The exception message. A note to install the intl extension is appended to this string + */ + public function __construct($message) + { + parent::__construct($message.' '.self::INTL_INSTALL_MESSAGE); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/OutOfBoundsException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/OutOfBoundsException.php new file mode 100644 index 00000000..2727141d --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/OutOfBoundsException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * Base OutOfBoundsException for the Intl component. + * + * @author Bernhard Schussek + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Exception/RuntimeException.php b/vendor/symfony/intl/Symfony/Component/Intl/Exception/RuntimeException.php new file mode 100644 index 00000000..98937142 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Exception/RuntimeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Exception; + +/** + * RuntimeException for the Intl component. + * + * @author Bernhard Schussek + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Globals/IntlGlobals.php b/vendor/symfony/intl/Symfony/Component/Intl/Globals/IntlGlobals.php new file mode 100644 index 00000000..6da00011 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Globals/IntlGlobals.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Globals; + +/** + * Provides fake static versions of the global functions in the intl extension + * + * @author Bernhard Schussek + */ +abstract class IntlGlobals +{ + /** + * Indicates that no error occurred + * + * @var integer + */ + const U_ZERO_ERROR = 0; + + /** + * Indicates that an invalid argument was passed + * + * @var integer + */ + const U_ILLEGAL_ARGUMENT_ERROR = 1; + + /** + * Indicates that the parse() operation failed + * + * @var integer + */ + const U_PARSE_ERROR = 9; + + /** + * All known error codes + * + * @var array + */ + private static $errorCodes = array( + self::U_ZERO_ERROR => 'U_ZERO_ERROR', + self::U_ILLEGAL_ARGUMENT_ERROR => 'U_ILLEGAL_ARGUMENT_ERROR', + self::U_PARSE_ERROR => 'U_PARSE_ERROR', + ); + + /** + * The error code of the last operation + * + * @var integer + */ + private static $errorCode = self::U_ZERO_ERROR; + + /** + * The error code of the last operation + * + * @var integer + */ + private static $errorMessage = 'U_ZERO_ERROR'; + + /** + * Returns whether the error code indicates a failure + * + * @param integer $errorCode The error code returned by IntlGlobals::getErrorCode() + * + * @return Boolean + */ + public static function isFailure($errorCode) + { + return isset(self::$errorCodes[$errorCode]) + && $errorCode > self::U_ZERO_ERROR; + } + + /** + * Returns the error code of the last operation + * + * Returns IntlGlobals::U_ZERO_ERROR if no error occurred. + * + * @return integer + */ + public static function getErrorCode() + { + return self::$errorCode; + } + + /** + * Returns the error message of the last operation + * + * Returns "U_ZERO_ERROR" if no error occurred. + * + * @return string + */ + public static function getErrorMessage() + { + return self::$errorMessage; + } + + /** + * Returns the symbolic name for a given error code + * + * @param integer $code The error code returned by IntlGlobals::getErrorCode() + * + * @return string + */ + public static function getErrorName($code) + { + if (isset(self::$errorCodes[$code])) { + return self::$errorCodes[$code]; + } + + return '[BOGUS UErrorCode]'; + } + + /** + * Sets the current error + * + * @param integer $code One of the error constants in this class + * @param string $message The ICU class error message + * + * @throws \InvalidArgumentException If the code is not one of the error constants in this class + */ + public static function setError($code, $message = '') + { + if (!isset(self::$errorCodes[$code])) { + throw new \InvalidArgumentException(sprintf('No such error code: "%s"', $code)); + } + + self::$errorMessage = $message ? sprintf('%s: %s', $message, self::$errorCodes[$code]) : self::$errorCodes[$code]; + self::$errorCode = $code; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Intl.php b/vendor/symfony/intl/Symfony/Component/Intl/Intl.php new file mode 100644 index 00000000..c13899a4 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Intl.php @@ -0,0 +1,211 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl; + +use Symfony\Component\Icu\IcuCurrencyBundle; +use Symfony\Component\Icu\IcuData; +use Symfony\Component\Icu\IcuLanguageBundle; +use Symfony\Component\Icu\IcuLocaleBundle; +use Symfony\Component\Icu\IcuRegionBundle; +use Symfony\Component\Intl\ResourceBundle\Reader\BufferedBundleReader; +use Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReader; + +/** + * Gives access to internationalization data. + * + * @author Bernhard Schussek + */ +class Intl +{ + /** + * The number of resource bundles to buffer. Loading the same resource + * bundle for n locales takes up n spots in the buffer. + */ + const BUFFER_SIZE = 10; + + /** + * @var ResourceBundle\CurrencyBundleInterface + */ + private static $currencyBundle; + + /** + * @var ResourceBundle\LanguageBundleInterface + */ + private static $languageBundle; + + /** + * @var ResourceBundle\LocaleBundleInterface + */ + private static $localeBundle; + + /** + * @var ResourceBundle\RegionBundleInterface + */ + private static $regionBundle; + + /** + * @var string|Boolean|null + */ + private static $icuVersion = false; + + /** + * @var string + */ + private static $icuDataVersion = false; + + /** + * @var ResourceBundle\Reader\StructuredBundleReaderInterface + */ + private static $bundleReader; + + /** + * Returns whether the intl extension is installed. + * + * @return Boolean Returns true if the intl extension is installed, false otherwise. + */ + public static function isExtensionLoaded() + { + return class_exists('\ResourceBundle'); + } + + /** + * Returns the bundle containing currency information. + * + * @return ResourceBundle\CurrencyBundleInterface The currency resource bundle. + */ + public static function getCurrencyBundle() + { + if (null === self::$currencyBundle) { + self::$currencyBundle = new IcuCurrencyBundle(self::getBundleReader()); + } + + return self::$currencyBundle; + } + + /** + * Returns the bundle containing language information. + * + * @return ResourceBundle\LanguageBundleInterface The language resource bundle. + */ + public static function getLanguageBundle() + { + if (null === self::$languageBundle) { + self::$languageBundle = new IcuLanguageBundle(self::getBundleReader()); + } + + return self::$languageBundle; + } + + /** + * Returns the bundle containing locale information. + * + * @return ResourceBundle\LocaleBundleInterface The locale resource bundle. + */ + public static function getLocaleBundle() + { + if (null === self::$localeBundle) { + self::$localeBundle = new IcuLocaleBundle(self::getBundleReader()); + } + + return self::$localeBundle; + } + + /** + * Returns the bundle containing region information. + * + * @return ResourceBundle\RegionBundleInterface The region resource bundle. + */ + public static function getRegionBundle() + { + if (null === self::$regionBundle) { + self::$regionBundle = new IcuRegionBundle(self::getBundleReader()); + } + + return self::$regionBundle; + } + + /** + * Returns the version of the installed ICU library. + * + * @return null|string The ICU version or NULL if it could not be determined. + */ + public static function getIcuVersion() + { + if (false === self::$icuVersion) { + if (!self::isExtensionLoaded()) { + self::$icuVersion = self::getIcuStubVersion(); + } elseif (defined('INTL_ICU_VERSION')) { + self::$icuVersion = INTL_ICU_VERSION; + } else { + try { + $reflector = new \ReflectionExtension('intl'); + ob_start(); + $reflector->info(); + $output = strip_tags(ob_get_clean()); + preg_match('/^ICU version (?:=>)?(.*)$/m', $output, $matches); + + self::$icuVersion = trim($matches[1]); + } catch (\ReflectionException $e) { + self::$icuVersion = null; + } + } + } + + return self::$icuVersion; + } + + /** + * Returns the version of the installed ICU data. + * + * @return string The version of the installed ICU data. + */ + public static function getIcuDataVersion() + { + if (false === self::$icuDataVersion) { + self::$icuDataVersion = IcuData::getVersion(); + } + + return self::$icuDataVersion; + } + + /** + * Returns the ICU version that the stub classes mimic. + * + * @return string The ICU version of the stub classes. + */ + public static function getIcuStubVersion() + { + return '50.1.2'; + } + + /** + * Returns a resource bundle reader for .php resource bundle files. + * + * @return ResourceBundle\Reader\StructuredBundleReaderInterface The resource reader. + */ + private static function getBundleReader() + { + if (null === self::$bundleReader) { + self::$bundleReader = new StructuredBundleReader(new BufferedBundleReader( + IcuData::getBundleReader(), + self::BUFFER_SIZE + )); + } + + return self::$bundleReader; + } + + /** + * This class must not be instantiated. + */ + private function __construct() {} +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/LICENSE b/vendor/symfony/intl/Symfony/Component/Intl/LICENSE new file mode 100644 index 00000000..88a57f8d --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2013 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. diff --git a/vendor/symfony/intl/Symfony/Component/Intl/Locale/Locale.php b/vendor/symfony/intl/Symfony/Component/Intl/Locale/Locale.php new file mode 100644 index 00000000..cca4e9e4 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/Locale/Locale.php @@ -0,0 +1,317 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Locale; + +use Symfony\Component\Intl\Exception\MethodNotImplementedException; + +/** + * Replacement for PHP's native {@link \Locale} class. + * + * The only method supported in this class is {@link getDefault}. This method + * will always return "en". All other methods will throw an exception when used. + * + * @author Eriksen Costa + * @author Bernhard Schussek + */ +class Locale +{ + const DEFAULT_LOCALE = null; + + /* Locale method constants */ + const ACTUAL_LOCALE = 0; + const VALID_LOCALE = 1; + + /* Language tags constants */ + const LANG_TAG = 'language'; + const EXTLANG_TAG = 'extlang'; + const SCRIPT_TAG = 'script'; + const REGION_TAG = 'region'; + const VARIANT_TAG = 'variant'; + const GRANDFATHERED_LANG_TAG = 'grandfathered'; + const PRIVATE_TAG = 'private'; + + /** + * Not supported. Returns the best available locale based on HTTP "Accept-Language" header according to RFC 2616 + * + * @param string $header The string containing the "Accept-Language" header value + * + * @return string The corresponding locale code + * + * @see http://www.php.net/manual/en/locale.acceptfromhttp.php + * + * @throws MethodNotImplementedException + */ + public static function acceptFromHttp($header) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns a correctly ordered and delimited locale code + * + * @param array $subtags A keyed array where the keys identify the particular locale code subtag + * + * @return string The corresponding locale code + * + * @see http://www.php.net/manual/en/locale.composelocale.php + * + * @throws MethodNotImplementedException + */ + public static function composeLocale(array $subtags) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Checks if a language tag filter matches with locale + * + * @param string $langtag The language tag to check + * @param string $locale The language range to check against + * @param Boolean $canonicalize + * + * @return string The corresponding locale code + * + * @see http://www.php.net/manual/en/locale.filtermatches.php + * + * @throws MethodNotImplementedException + */ + public static function filterMatches($langtag, $locale, $canonicalize = false) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the variants for the input locale + * + * @param string $locale The locale to extract the variants from + * + * @return array The locale variants + * + * @see http://www.php.net/manual/en/locale.getallvariants.php + * + * @throws MethodNotImplementedException + */ + public static function getAllVariants($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Returns the default locale + * + * @return string The default locale code. Always returns 'en' + * + * @see http://www.php.net/manual/en/locale.getdefault.php + */ + public static function getDefault() + { + return 'en'; + } + + /** + * Not supported. Returns the localized display name for the locale language + * + * @param string $locale The locale code to return the display language from + * @param string $inLocale Optional format locale code to use to display the language name + * + * @return string The localized language display name + * + * @see http://www.php.net/manual/en/locale.getdisplaylanguage.php + * + * @throws MethodNotImplementedException + */ + public static function getDisplayLanguage($locale, $inLocale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the localized display name for the locale + * + * @param string $locale The locale code to return the display locale name from + * @param string $inLocale Optional format locale code to use to display the locale name + * + * @return string The localized locale display name + * + * @see http://www.php.net/manual/en/locale.getdisplayname.php + * + * @throws MethodNotImplementedException + */ + public static function getDisplayName($locale, $inLocale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the localized display name for the locale region + * + * @param string $locale The locale code to return the display region from + * @param string $inLocale Optional format locale code to use to display the region name + * + * @return string The localized region display name + * + * @see http://www.php.net/manual/en/locale.getdisplayregion.php + * + * @throws MethodNotImplementedException + */ + public static function getDisplayRegion($locale, $inLocale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the localized display name for the locale script + * + * @param string $locale The locale code to return the display script from + * @param string $inLocale Optional format locale code to use to display the script name + * + * @return string The localized script display name + * + * @see http://www.php.net/manual/en/locale.getdisplayscript.php + * + * @throws MethodNotImplementedException + */ + public static function getDisplayScript($locale, $inLocale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the localized display name for the locale variant + * + * @param string $locale The locale code to return the display variant from + * @param string $inLocale Optional format locale code to use to display the variant name + * + * @return string The localized variant display name + * + * @see http://www.php.net/manual/en/locale.getdisplayvariant.php + * + * @throws MethodNotImplementedException + */ + public static function getDisplayVariant($locale, $inLocale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the keywords for the locale + * + * @param string $locale The locale code to extract the keywords from + * + * @return array Associative array with the extracted variants + * + * @see http://www.php.net/manual/en/locale.getkeywords.php + * + * @throws MethodNotImplementedException + */ + public static function getKeywords($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the primary language for the locale + * + * @param string $locale The locale code to extract the language code from + * + * @return string|null The extracted language code or null in case of error + * + * @see http://www.php.net/manual/en/locale.getprimarylanguage.php + * + * @throws MethodNotImplementedException + */ + public static function getPrimaryLanguage($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the region for the locale + * + * @param string $locale The locale code to extract the region code from + * + * @return string|null The extracted region code or null if not present + * + * @see http://www.php.net/manual/en/locale.getregion.php + * + * @throws MethodNotImplementedException + */ + public static function getRegion($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the script for the locale + * + * @param string $locale The locale code to extract the script code from + * + * @return string|null The extracted script code or null if not present + * + * @see http://www.php.net/manual/en/locale.getscript.php + * + * @throws MethodNotImplementedException + */ + public static function getScript($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns the closest language tag for the locale + * + * @param array $langtag A list of the language tags to compare to locale + * @param string $locale The locale to use as the language range when matching + * @param Boolean $canonicalize If true, the arguments will be converted to canonical form before matching + * @param string $default The locale to use if no match is found + * + * @see http://www.php.net/manual/en/locale.lookup.php + * + * @throws MethodNotImplementedException + */ + public static function lookup(array $langtag, $locale, $canonicalize = false, $default = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns an associative array of locale identifier subtags + * + * @param string $locale The locale code to extract the subtag array from + * + * @return array Associative array with the extracted subtags + * + * @see http://www.php.net/manual/en/locale.parselocale.php + * + * @throws MethodNotImplementedException + */ + public static function parseLocale($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Sets the default runtime locale + * + * @param string $locale The locale code + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/locale.parselocale.php + * + * @throws MethodNotImplementedException + */ + public static function setDefault($locale) + { + throw new MethodNotImplementedException(__METHOD__); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php b/vendor/symfony/intl/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php new file mode 100644 index 00000000..0e5652e2 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php @@ -0,0 +1,891 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\NumberFormatter; + +use Symfony\Component\Intl\Exception\NotImplementedException; +use Symfony\Component\Intl\Exception\MethodNotImplementedException; +use Symfony\Component\Intl\Exception\MethodArgumentNotImplementedException; +use Symfony\Component\Intl\Exception\MethodArgumentValueNotImplementedException; +use Symfony\Component\Intl\Globals\IntlGlobals; +use Symfony\Component\Intl\Intl; +use Symfony\Component\Intl\Locale\Locale; + +/** + * Replacement for PHP's native {@link \NumberFormatter} class. + * + * The only methods currently supported in this class are: + * + * - {@link __construct} + * - {@link create} + * - {@link formatCurrency} + * - {@link format} + * - {@link getAttribute} + * - {@link getErrorCode} + * - {@link getErrorMessage} + * - {@link getLocale} + * - {@link parse} + * - {@link setAttribute} + * + * @author Eriksen Costa + * @author Bernhard Schussek + */ +class NumberFormatter +{ + /* Format style constants */ + const PATTERN_DECIMAL = 0; + const DECIMAL = 1; + const CURRENCY = 2; + const PERCENT = 3; + const SCIENTIFIC = 4; + const SPELLOUT = 5; + const ORDINAL = 6; + const DURATION = 7; + const PATTERN_RULEBASED = 9; + const IGNORE = 0; + const DEFAULT_STYLE = 1; + + /* Format type constants */ + const TYPE_DEFAULT = 0; + const TYPE_INT32 = 1; + const TYPE_INT64 = 2; + const TYPE_DOUBLE = 3; + const TYPE_CURRENCY = 4; + + /* Numeric attribute constants */ + const PARSE_INT_ONLY = 0; + const GROUPING_USED = 1; + const DECIMAL_ALWAYS_SHOWN = 2; + const MAX_INTEGER_DIGITS = 3; + const MIN_INTEGER_DIGITS = 4; + const INTEGER_DIGITS = 5; + const MAX_FRACTION_DIGITS = 6; + const MIN_FRACTION_DIGITS = 7; + const FRACTION_DIGITS = 8; + const MULTIPLIER = 9; + const GROUPING_SIZE = 10; + const ROUNDING_MODE = 11; + const ROUNDING_INCREMENT = 12; + const FORMAT_WIDTH = 13; + const PADDING_POSITION = 14; + const SECONDARY_GROUPING_SIZE = 15; + const SIGNIFICANT_DIGITS_USED = 16; + const MIN_SIGNIFICANT_DIGITS = 17; + const MAX_SIGNIFICANT_DIGITS = 18; + const LENIENT_PARSE = 19; + + /* Text attribute constants */ + const POSITIVE_PREFIX = 0; + const POSITIVE_SUFFIX = 1; + const NEGATIVE_PREFIX = 2; + const NEGATIVE_SUFFIX = 3; + const PADDING_CHARACTER = 4; + const CURRENCY_CODE = 5; + const DEFAULT_RULESET = 6; + const PUBLIC_RULESETS = 7; + + /* Format symbol constants */ + const DECIMAL_SEPARATOR_SYMBOL = 0; + const GROUPING_SEPARATOR_SYMBOL = 1; + const PATTERN_SEPARATOR_SYMBOL = 2; + const PERCENT_SYMBOL = 3; + const ZERO_DIGIT_SYMBOL = 4; + const DIGIT_SYMBOL = 5; + const MINUS_SIGN_SYMBOL = 6; + const PLUS_SIGN_SYMBOL = 7; + const CURRENCY_SYMBOL = 8; + const INTL_CURRENCY_SYMBOL = 9; + const MONETARY_SEPARATOR_SYMBOL = 10; + const EXPONENTIAL_SYMBOL = 11; + const PERMILL_SYMBOL = 12; + const PAD_ESCAPE_SYMBOL = 13; + const INFINITY_SYMBOL = 14; + const NAN_SYMBOL = 15; + const SIGNIFICANT_DIGIT_SYMBOL = 16; + const MONETARY_GROUPING_SEPARATOR_SYMBOL = 17; + + /* Rounding mode values used by NumberFormatter::setAttribute() with NumberFormatter::ROUNDING_MODE attribute */ + const ROUND_CEILING = 0; + const ROUND_FLOOR = 1; + const ROUND_DOWN = 2; + const ROUND_UP = 3; + const ROUND_HALFEVEN = 4; + const ROUND_HALFDOWN = 5; + const ROUND_HALFUP = 6; + + /* Pad position values used by NumberFormatter::setAttribute() with NumberFormatter::PADDING_POSITION attribute */ + const PAD_BEFORE_PREFIX = 0; + const PAD_AFTER_PREFIX = 1; + const PAD_BEFORE_SUFFIX = 2; + const PAD_AFTER_SUFFIX = 3; + + /** + * The error code from the last operation + * + * @var integer + */ + protected $errorCode = IntlGlobals::U_ZERO_ERROR; + + /** + * The error message from the last operation + * + * @var string + */ + protected $errorMessage = 'U_ZERO_ERROR'; + + /** + * @var int + */ + private $style; + + /** + * Default values for the en locale + * + * @var array + */ + private $attributes = array( + self::FRACTION_DIGITS => 0, + self::GROUPING_USED => 1, + self::ROUNDING_MODE => self::ROUND_HALFEVEN + ); + + /** + * Holds the initialized attributes code + * + * @var array + */ + private $initializedAttributes = array(); + + /** + * The supported styles to the constructor $styles argument + * + * @var array + */ + private static $supportedStyles = array( + 'CURRENCY' => self::CURRENCY, + 'DECIMAL' => self::DECIMAL + ); + + /** + * Supported attributes to the setAttribute() $attr argument + * + * @var array + */ + private static $supportedAttributes = array( + 'FRACTION_DIGITS' => self::FRACTION_DIGITS, + 'GROUPING_USED' => self::GROUPING_USED, + 'ROUNDING_MODE' => self::ROUNDING_MODE + ); + + /** + * The available rounding modes for setAttribute() usage with + * NumberFormatter::ROUNDING_MODE. NumberFormatter::ROUND_DOWN + * and NumberFormatter::ROUND_UP does not have a PHP only equivalent + * + * @var array + */ + private static $roundingModes = array( + 'ROUND_HALFEVEN' => self::ROUND_HALFEVEN, + 'ROUND_HALFDOWN' => self::ROUND_HALFDOWN, + 'ROUND_HALFUP' => self::ROUND_HALFUP + ); + + /** + * The mapping between NumberFormatter rounding modes to the available + * modes in PHP's round() function. + * + * @see http://www.php.net/manual/en/function.round.php + * + * @var array + */ + private static $phpRoundingMap = array( + self::ROUND_HALFDOWN => \PHP_ROUND_HALF_DOWN, + self::ROUND_HALFEVEN => \PHP_ROUND_HALF_EVEN, + self::ROUND_HALFUP => \PHP_ROUND_HALF_UP + ); + + /** + * The maximum values of the integer type in 32 bit platforms. + * + * @var array + */ + private static $int32Range = array( + 'positive' => 2147483647, + 'negative' => -2147483648 + ); + + /** + * The maximum values of the integer type in 64 bit platforms. + * + * @var array + */ + private static $int64Range = array( + 'positive' => 9223372036854775807, + 'negative' => -9223372036854775808 + ); + + /** + * Constructor. + * + * @param string $locale The locale code. The only currently supported locale is "en". + * @param int $style Style of the formatting, one of the format style constants. + * The only supported styles are NumberFormatter::DECIMAL + * and NumberFormatter::CURRENCY. + * @param string $pattern Not supported. A pattern string in case $style is NumberFormat::PATTERN_DECIMAL or + * NumberFormat::PATTERN_RULEBASED. It must conform to the syntax + * described in the ICU DecimalFormat or ICU RuleBasedNumberFormat documentation + * + * @see http://www.php.net/manual/en/numberformatter.create.php + * @see http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details + * @see http://www.icu-project.org/apiref/icu4c/classRuleBasedNumberFormat.html#_details + * + * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed + * @throws MethodArgumentValueNotImplementedException When the $style is not supported + * @throws MethodArgumentNotImplementedException When the pattern value is different than null + */ + public function __construct($locale = 'en', $style = null, $pattern = null) + { + if ('en' != $locale) { + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'locale', $locale, 'Only the locale "en" is supported'); + } + + if (!in_array($style, self::$supportedStyles)) { + $message = sprintf('The available styles are: %s.', implode(', ', array_keys(self::$supportedStyles))); + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'style', $style, $message); + } + + if (null !== $pattern) { + throw new MethodArgumentNotImplementedException(__METHOD__, 'pattern'); + } + + $this->style = $style; + } + + /** + * Static constructor. + * + * @param string $locale The locale code. The only supported locale is "en". + * @param int $style Style of the formatting, one of the format style constants. + * The only currently supported styles are NumberFormatter::DECIMAL + * and NumberFormatter::CURRENCY. + * @param string $pattern Not supported. A pattern string in case $style is NumberFormat::PATTERN_DECIMAL or + * NumberFormat::PATTERN_RULEBASED. It must conform to the syntax + * described in the ICU DecimalFormat or ICU RuleBasedNumberFormat documentation + * + * @return NumberFormatter + * + * @see http://www.php.net/manual/en/numberformatter.create.php + * @see http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details + * @see http://www.icu-project.org/apiref/icu4c/classRuleBasedNumberFormat.html#_details + * + * @throws MethodArgumentValueNotImplementedException When $locale different than "en" is passed + * @throws MethodArgumentValueNotImplementedException When the $style is not supported + * @throws MethodArgumentNotImplementedException When the pattern value is different than null + */ + public static function create($locale = 'en', $style = null, $pattern = null) + { + return new self($locale, $style, $pattern); + } + + /** + * Format a currency value + * + * @param float $value The numeric currency value + * @param string $currency The 3-letter ISO 4217 currency code indicating the currency to use + * + * @return string The formatted currency value + * + * @see http://www.php.net/manual/en/numberformatter.formatcurrency.php + * @see http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + */ + public function formatCurrency($value, $currency) + { + if ($this->style == self::DECIMAL) { + return $this->format($value); + } + + $symbol = Intl::getCurrencyBundle()->getCurrencySymbol($currency, 'en'); + $fractionDigits = Intl::getCurrencyBundle()->getFractionDigits($currency); + + $value = $this->roundCurrency($value, $currency); + + $negative = false; + if (0 > $value) { + $negative = true; + $value *= -1; + } + + $value = $this->formatNumber($value, $fractionDigits); + + $ret = $symbol.$value; + + return $negative ? '('.$ret.')' : $ret; + } + + /** + * Format a number + * + * @param number $value The value to format + * @param int $type Type of the formatting, one of the format type constants. + * Only type NumberFormatter::TYPE_DEFAULT is currently supported. + * + * @return Boolean|string The formatted value or false on error + * + * @see http://www.php.net/manual/en/numberformatter.format.php + * + * @throws NotImplementedException If the method is called with the class $style 'CURRENCY' + * @throws MethodArgumentValueNotImplementedException If the $type is different than TYPE_DEFAULT + */ + public function format($value, $type = self::TYPE_DEFAULT) + { + // The original NumberFormatter does not support this format type + if ($type == self::TYPE_CURRENCY) { + trigger_error(__METHOD__.'(): Unsupported format type '.$type, \E_USER_WARNING); + + return false; + } + + if ($this->style == self::CURRENCY) { + throw new NotImplementedException(sprintf( + '%s() method does not support the formatting of currencies (instance with CURRENCY style). %s', + __METHOD__, NotImplementedException::INTL_INSTALL_MESSAGE + )); + } + + // Only the default type is supported. + if ($type != self::TYPE_DEFAULT) { + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'type', $type, 'Only TYPE_DEFAULT is supported'); + } + + $fractionDigits = $this->getAttribute(self::FRACTION_DIGITS); + + $value = $this->round($value, $fractionDigits); + $value = $this->formatNumber($value, $fractionDigits); + + // behave like the intl extension + $this->resetError(); + + return $value; + } + + /** + * Returns an attribute value + * + * @param int $attr An attribute specifier, one of the numeric attribute constants + * + * @return Boolean|int The attribute value on success or false on error + * + * @see http://www.php.net/manual/en/numberformatter.getattribute.php + */ + public function getAttribute($attr) + { + return isset($this->attributes[$attr]) ? $this->attributes[$attr] : null; + } + + /** + * Returns formatter's last error code. Always returns the U_ZERO_ERROR class constant value + * + * @return int The error code from last formatter call + * + * @see http://www.php.net/manual/en/numberformatter.geterrorcode.php + */ + public function getErrorCode() + { + return $this->errorCode; + } + + /** + * Returns formatter's last error message. Always returns the U_ZERO_ERROR_MESSAGE class constant value + * + * @return string The error message from last formatter call + * + * @see http://www.php.net/manual/en/numberformatter.geterrormessage.php + */ + public function getErrorMessage() + { + return $this->errorMessage; + } + + /** + * Returns the formatter's locale + * + * The parameter $type is currently ignored. + * + * @param int $type Not supported. The locale name type to return (Locale::VALID_LOCALE or Locale::ACTUAL_LOCALE) + * + * @return string The locale used to create the formatter. Currently always + * returns "en". + * + * @see http://www.php.net/manual/en/numberformatter.getlocale.php + */ + public function getLocale($type = Locale::ACTUAL_LOCALE) + { + return 'en'; + } + + /** + * Not supported. Returns the formatter's pattern + * + * @return Boolean|string The pattern string used by the formatter or false on error + * + * @see http://www.php.net/manual/en/numberformatter.getpattern.php + * + * @throws MethodNotImplementedException + */ + public function getPattern() + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns a formatter symbol value + * + * @param int $attr A symbol specifier, one of the format symbol constants + * + * @return Boolean|string The symbol value or false on error + * + * @see http://www.php.net/manual/en/numberformatter.getsymbol.php + * + * @throws MethodNotImplementedException + */ + public function getSymbol($attr) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Returns a formatter text attribute value + * + * @param int $attr An attribute specifier, one of the text attribute constants + * + * @return Boolean|string The attribute value or false on error + * + * @see http://www.php.net/manual/en/numberformatter.gettextattribute.php + * + * @throws MethodNotImplementedException + */ + public function getTextAttribute($attr) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Parse a currency number + * + * @param string $value The value to parse + * @param string $currency Parameter to receive the currency name (reference) + * @param int $position Offset to begin the parsing on return this value will hold the offset at which the parsing ended + * + * @return Boolean|string The parsed numeric value of false on error + * + * @see http://www.php.net/manual/en/numberformatter.parsecurrency.php + * + * @throws MethodNotImplementedException + */ + public function parseCurrency($value, &$currency, &$position = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Parse a number + * + * @param string $value The value to parse + * @param int $type Type of the formatting, one of the format type constants. + * The only currently supported types are NumberFormatter::TYPE_DOUBLE, + * NumberFormatter::TYPE_INT32 and NumberFormatter::TYPE_INT64. + * @param int $position Not supported. Offset to begin the parsing on return this value will hold the offset at which the parsing ended + * + * @return Boolean|string The parsed value of false on error + * + * @see http://www.php.net/manual/en/numberformatter.parse.php + * + * @throws MethodArgumentNotImplementedException When $position different than null, behavior not implemented + */ + public function parse($value, $type = self::TYPE_DOUBLE, &$position = null) + { + if ($type == self::TYPE_DEFAULT || $type == self::TYPE_CURRENCY) { + trigger_error(__METHOD__.'(): Unsupported format type '.$type, \E_USER_WARNING); + + return false; + } + + // We don't calculate the position when parsing the value + if (null !== $position) { + throw new MethodArgumentNotImplementedException(__METHOD__, 'position'); + } + + preg_match('/^([^0-9\-]{0,})(.*)/', $value, $matches); + + // Any string before the numeric value causes error in the parsing + if (isset($matches[1]) && !empty($matches[1])) { + IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Number parsing failed'); + $this->errorCode = IntlGlobals::getErrorCode(); + $this->errorMessage = IntlGlobals::getErrorMessage(); + + return false; + } + + // Remove everything that is not number or dot (.) + $value = preg_replace('/[^0-9\.\-]/', '', $value); + $value = $this->convertValueDataType($value, $type); + + // behave like the intl extension + $this->resetError(); + + return $value; + } + + /** + * Set an attribute + * + * @param int $attr An attribute specifier, one of the numeric attribute constants. + * The only currently supported attributes are NumberFormatter::FRACTION_DIGITS, + * NumberFormatter::GROUPING_USED and NumberFormatter::ROUNDING_MODE. + * @param int $value The attribute value. The only currently supported rounding modes are + * NumberFormatter::ROUND_HALFEVEN, NumberFormatter::ROUND_HALFDOWN and + * NumberFormatter::ROUND_HALFUP. + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/numberformatter.setattribute.php + * + * @throws MethodArgumentValueNotImplementedException When the $attr is not supported + * @throws MethodArgumentValueNotImplementedException When the $value is not supported + */ + public function setAttribute($attr, $value) + { + if (!in_array($attr, self::$supportedAttributes)) { + $message = sprintf( + 'The available attributes are: %s', + implode(', ', array_keys(self::$supportedAttributes)) + ); + + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'attr', $value, $message); + } + + if (self::$supportedAttributes['ROUNDING_MODE'] == $attr && $this->isInvalidRoundingMode($value)) { + $message = sprintf( + 'The supported values for ROUNDING_MODE are: %s', + implode(', ', array_keys(self::$roundingModes)) + ); + + throw new MethodArgumentValueNotImplementedException(__METHOD__, 'attr', $value, $message); + } + + if (self::$supportedAttributes['GROUPING_USED'] == $attr) { + $value = $this->normalizeGroupingUsedValue($value); + } + + if (self::$supportedAttributes['FRACTION_DIGITS'] == $attr) { + $value = $this->normalizeFractionDigitsValue($value); + } + + $this->attributes[$attr] = $value; + $this->initializedAttributes[$attr] = true; + + return true; + } + + /** + * Not supported. Set the formatter's pattern + * + * @param string $pattern A pattern string in conformance with the ICU DecimalFormat documentation + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/numberformatter.setpattern.php + * @see http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details + * + * @throws MethodNotImplementedException + */ + public function setPattern($pattern) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Set the formatter's symbol + * + * @param int $attr A symbol specifier, one of the format symbol constants + * @param string $value The value for the symbol + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/numberformatter.setsymbol.php + * + * @throws MethodNotImplementedException + */ + public function setSymbol($attr, $value) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Not supported. Set a text attribute + * + * @param int $attr An attribute specifier, one of the text attribute constants + * @param int $value The attribute value + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/numberformatter.settextattribute.php + * + * @throws MethodNotImplementedException + */ + public function setTextAttribute($attr, $value) + { + throw new MethodNotImplementedException(__METHOD__); + } + + /** + * Set the error to the default U_ZERO_ERROR + */ + protected function resetError() + { + IntlGlobals::setError(IntlGlobals::U_ZERO_ERROR); + $this->errorCode = IntlGlobals::getErrorCode(); + $this->errorMessage = IntlGlobals::getErrorMessage(); + } + + /** + * Rounds a currency value, applying increment rounding if applicable + * + * When a currency have a rounding increment, an extra round is made after the first one. The rounding factor is + * determined in the ICU data and is explained as of: + * + * "the rounding increment is given in units of 10^(-fraction_digits)" + * + * The only actual rounding data as of this writing, is CHF. + * + * @param float $value The numeric currency value + * @param string $currency The 3-letter ISO 4217 currency code indicating the currency to use + * + * @return string The rounded numeric currency value + * + * @see http://en.wikipedia.org/wiki/Swedish_rounding + * @see http://www.docjar.com/html/api/com/ibm/icu/util/Currency.java.html#1007 + */ + private function roundCurrency($value, $currency) + { + $fractionDigits = Intl::getCurrencyBundle()->getFractionDigits($currency); + $roundingIncrement = Intl::getCurrencyBundle()->getRoundingIncrement($currency); + + // Round with the formatter rounding mode + $value = $this->round($value, $fractionDigits); + + // Swiss rounding + if (0 < $roundingIncrement && 0 < $fractionDigits) { + $roundingFactor = $roundingIncrement / pow(10, $fractionDigits); + $value = round($value / $roundingFactor) * $roundingFactor; + } + + return $value; + } + + /** + * Rounds a value. + * + * @param integer|float $value The value to round + * @param int $precision The number of decimal digits to round to + * + * @return integer|float The rounded value + */ + private function round($value, $precision) + { + $precision = $this->getUnitializedPrecision($value, $precision); + + $roundingMode = self::$phpRoundingMap[$this->getAttribute(self::ROUNDING_MODE)]; + $value = round($value, $precision, $roundingMode); + + return $value; + } + + /** + * Formats a number. + * + * @param integer|float $value The numeric value to format + * @param int $precision The number of decimal digits to use + * + * @return string The formatted number + */ + private function formatNumber($value, $precision) + { + $precision = $this->getUnitializedPrecision($value, $precision); + + return number_format($value, $precision, '.', $this->getAttribute(self::GROUPING_USED) ? ',' : ''); + } + + /** + * Returns the precision value if the DECIMAL style is being used and the FRACTION_DIGITS attribute is unitialized. + * + * @param integer|float $value The value to get the precision from if the FRACTION_DIGITS attribute is unitialized + * @param int $precision The precision value to returns if the FRACTION_DIGITS attribute is initialized + * + * @return int The precision value + */ + private function getUnitializedPrecision($value, $precision) + { + if ($this->style == self::CURRENCY) { + return $precision; + } + + if (!$this->isInitializedAttribute(self::FRACTION_DIGITS)) { + preg_match('/.*\.(.*)/', (string) $value, $digits); + if (isset($digits[1])) { + $precision = strlen($digits[1]); + } + } + + return $precision; + } + + /** + * Check if the attribute is initialized (value set by client code). + * + * @param string $attr The attribute name + * + * @return Boolean true if the value was set by client, false otherwise + */ + private function isInitializedAttribute($attr) + { + return isset($this->initializedAttributes[$attr]); + } + + /** + * Returns the numeric value using the $type to convert to the right data type. + * + * @param mixed $value The value to be converted + * @param int $type The type to convert. Can be TYPE_DOUBLE (float) or TYPE_INT32 (int) + * + * @return integer|float The converted value + */ + private function convertValueDataType($value, $type) + { + if ($type == self::TYPE_DOUBLE) { + $value = (float) $value; + } elseif ($type == self::TYPE_INT32) { + $value = $this->getInt32Value($value); + } elseif ($type == self::TYPE_INT64) { + $value = $this->getInt64Value($value); + } + + return $value; + } + + /** + * Convert the value data type to int or returns false if the value is out of the integer value range. + * + * @param mixed $value The value to be converted + * + * @return int The converted value + */ + private function getInt32Value($value) + { + if ($value > self::$int32Range['positive'] || $value < self::$int32Range['negative']) { + return false; + } + + return (int) $value; + } + + /** + * Convert the value data type to int or returns false if the value is out of the integer value range. + * + * @param mixed $value The value to be converted + * + * @return int|float The converted value + * + * @see https://bugs.php.net/bug.php?id=59597 Bug #59597 + */ + private function getInt64Value($value) + { + if ($value > self::$int64Range['positive'] || $value < self::$int64Range['negative']) { + return false; + } + + if (PHP_INT_SIZE !== 8 && ($value > self::$int32Range['positive'] || $value <= self::$int32Range['negative'])) { + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // The negative PHP_INT_MAX was being converted to float + if ( + $value == self::$int32Range['negative'] && + ( + (version_compare(PHP_VERSION, '5.4.0', '<') && version_compare(PHP_VERSION, '5.3.14', '>=')) || + version_compare(PHP_VERSION, '5.4.4', '>=') + ) + ) { + return (int) $value; + } + + return (float) $value; + } + + if (PHP_INT_SIZE === 8) { + // Bug #59597 was fixed on PHP 5.3.14 and 5.4.4 + // A 32 bit integer was being generated instead of a 64 bit integer + if ( + ($value > self::$int32Range['positive'] || $value < self::$int32Range['negative']) && + ( + (version_compare(PHP_VERSION, '5.3.14', '<')) || + (version_compare(PHP_VERSION, '5.4.0', '>=') && version_compare(PHP_VERSION, '5.4.4', '<')) + ) + ) { + $value = (-2147483648 - ($value % -2147483648)) * ($value / abs($value)); + } + } + + return (int) $value; + } + + /** + * Check if the rounding mode is invalid. + * + * @param int $value The rounding mode value to check + * + * @return Boolean true if the rounding mode is invalid, false otherwise + */ + private function isInvalidRoundingMode($value) + { + if (in_array($value, self::$roundingModes, true)) { + return false; + } + + return true; + } + + /** + * Returns the normalized value for the GROUPING_USED attribute. Any value that can be converted to int will be + * cast to Boolean and then to int again. This way, negative values are converted to 1 and string values to 0. + * + * @param mixed $value The value to be normalized + * + * @return int The normalized value for the attribute (0 or 1) + */ + private function normalizeGroupingUsedValue($value) + { + return (int) (Boolean) (int) $value; + } + + /** + * Returns the normalized value for the FRACTION_DIGITS attribute. The value is converted to int and if negative, + * the returned value will be 0. + * + * @param mixed $value The value to be normalized + * + * @return int The normalized value for the attribute + */ + private function normalizeFractionDigitsValue($value) + { + $value = (int) $value; + + return (0 > $value) ? 0 : $value; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/README.md b/vendor/symfony/intl/Symfony/Component/Intl/README.md new file mode 100644 index 00000000..ef4ba505 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/README.md @@ -0,0 +1,25 @@ +Intl Component +============= + +A PHP replacement layer for the C intl extension that includes additional data +from the ICU library. + +The replacement layer is limited to the locale "en". If you want to use other +locales, you should [install the intl extension] [1] instead. + +Documentation +------------- + +The documentation for the component can be found [online] [2]. + +Resources +--------- + +You can run the unit tests with the following command: + + $ cd path/to/Symfony/Component/Intl/ + $ composer.phar install --dev + $ phpunit + +[0]: http://www.php.net/manual/en/intl.setup.php +[1]: http://symfony.com/doc/2.3/components/intl.html diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/AbstractBundle.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/AbstractBundle.php new file mode 100644 index 00000000..d1d523c4 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/AbstractBundle.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +use Symfony\Component\Intl\Intl; +use Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReaderInterface; + +/** + * Base class for {@link ResourceBundleInterface} implementations. + * + * @author Bernhard Schussek + */ +abstract class AbstractBundle implements ResourceBundleInterface +{ + /** + * @var string + */ + private $path; + + /** + * @var StructuredBundleReaderInterface + */ + private $reader; + + /** + * Creates a bundle at the given path using the given reader for reading + * bundle entries. + * + * @param string $path The path to the bundle. + * @param StructuredBundleReaderInterface $reader The reader for reading + * the bundle. + */ + public function __construct($path, StructuredBundleReaderInterface $reader) + { + $this->path = $path; + $this->reader = $reader; + } + + /** + * {@inheritdoc} + */ + public function getLocales() + { + return $this->reader->getLocales($this->path); + } + + /** + * Proxy method for {@link StructuredBundleReaderInterface#read}. + */ + protected function read($locale) + { + return $this->reader->read($this->path, $locale); + } + + /** + * Proxy method for {@link StructuredBundleReaderInterface#readEntry}. + */ + protected function readEntry($locale, array $indices, $mergeFallback = false) + { + return $this->reader->readEntry($this->path, $locale, $indices, $mergeFallback); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompiler.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompiler.php new file mode 100644 index 00000000..174aa179 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompiler.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Compiler; + +use Symfony\Component\Intl\Exception\RuntimeException; + +/** + * Compiles .txt resource bundles to binary .res files. + * + * @author Bernhard Schussek + */ +class BundleCompiler implements BundleCompilerInterface +{ + /** + * @var string The path to the "genrb" executable. + */ + private $genrb; + + /** + * Creates a new compiler based on the "genrb" executable. + * + * @param string $genrb Optional. The path to the "genrb" executable. + * @param string $envVars Optional. Environment variables to be loaded when + * running "genrb". + * + * @throws RuntimeException If the "genrb" cannot be found. + */ + public function __construct($genrb = 'genrb', $envVars = '') + { + exec('which ' . $genrb, $output, $status); + + if (0 !== $status) { + throw new RuntimeException(sprintf( + 'The command "%s" is not installed', + $genrb + )); + } + + $this->genrb = ($envVars ? $envVars . ' ' : '') . $genrb; + } + + /** + * {@inheritdoc} + */ + public function compile($sourcePath, $targetDir) + { + if (is_dir($sourcePath)) { + $sourcePath .= '/*.txt'; + } + + exec($this->genrb.' --quiet -e UTF-8 -d '.$targetDir.' '.$sourcePath, $output, $status); + + if ($status !== 0) { + throw new RuntimeException(sprintf( + 'genrb failed with status %d while compiling %s to %s.', + $status, + $sourcePath, + $targetDir + )); + } + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompilerInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompilerInterface.php new file mode 100644 index 00000000..6184ea3e --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Compiler/BundleCompilerInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Compiler; + +/** + * Compiles a resource bundle. + * + * @author Bernhard Schussek + */ +interface BundleCompilerInterface +{ + /** + * Compiles a resource bundle at the given source to the given target + * directory. + * + * @param string $sourcePath + * @param string $targetDir + */ + public function compile($sourcePath, $targetDir); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundle.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundle.php new file mode 100644 index 00000000..6f2a0ed3 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundle.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Default implementation of {@link CurrencyBundleInterface}. + * + * @author Bernhard Schussek + */ +class CurrencyBundle extends AbstractBundle implements CurrencyBundleInterface +{ + const INDEX_NAME = 0; + + const INDEX_SYMBOL = 1; + + const INDEX_FRACTION_DIGITS = 2; + + const INDEX_ROUNDING_INCREMENT = 3; + + /** + * {@inheritdoc} + */ + public function getCurrencySymbol($currency, $locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + return $this->readEntry($locale, array('Currencies', $currency, static::INDEX_SYMBOL)); + } + + /** + * {@inheritdoc} + */ + public function getCurrencyName($currency, $locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + return $this->readEntry($locale, array('Currencies', $currency, static::INDEX_NAME)); + } + + /** + * {@inheritdoc} + */ + public function getCurrencyNames($locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + if (null === ($currencies = $this->readEntry($locale, array('Currencies')))) { + return array(); + } + + if ($currencies instanceof \Traversable) { + $currencies = iterator_to_array($currencies); + } + + $index = static::INDEX_NAME; + + array_walk($currencies, function (&$value) use ($index) { + $value = $value[$index]; + }); + + return $currencies; + } + + /** + * {@inheritdoc} + */ + public function getFractionDigits($currency) + { + return $this->readEntry('en', array('Currencies', $currency, static::INDEX_FRACTION_DIGITS)); + } + + /** + * {@inheritdoc} + */ + public function getRoundingIncrement($currency) + { + return $this->readEntry('en', array('Currencies', $currency, static::INDEX_ROUNDING_INCREMENT)); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundleInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundleInterface.php new file mode 100644 index 00000000..1a88e937 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/CurrencyBundleInterface.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Gives access to currency-related ICU data. + * + * @author Bernhard Schussek + */ +interface CurrencyBundleInterface extends ResourceBundleInterface +{ + /** + * Returns the symbol used for a currency. + * + * @param string $currency A currency code (e.g. "EUR"). + * @param string $locale Optional. The locale to return the result in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string|null The currency symbol or NULL if not found. + */ + public function getCurrencySymbol($currency, $locale = null); + + /** + * Returns the name of a currency. + * + * @param string $currency A currency code (e.g. "EUR"). + * @param string $locale Optional. The locale to return the name in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string|null The name of the currency or NULL if not found. + */ + public function getCurrencyName($currency, $locale = null); + + /** + * Returns the names of all known currencies. + * + * @param string $locale Optional. The locale to return the names in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string[] A list of currency names indexed by currency codes. + */ + public function getCurrencyNames($locale = null); + + /** + * Returns the number of digits after the comma of a currency. + * + * @param string $currency A currency code (e.g. "EUR"). + * + * @return integer|null The number of digits after the comma or NULL if not found. + */ + public function getFractionDigits($currency); + + /** + * Returns the rounding increment of a currency. + * + * The rounding increment indicates to which number a currency is rounded. + * For example, 1230 rounded to the nearest 50 is 1250. 1.234 rounded to the + * nearest 0.65 is 1.3. + * + * @param string $currency A currency code (e.g. "EUR"). + * + * @return float|integer|null The rounding increment or NULL if not found. + */ + public function getRoundingIncrement($currency); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundle.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundle.php new file mode 100644 index 00000000..c449f9c1 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundle.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Default implementation of {@link LanguageBundleInterface}. + * + * @author Bernhard Schussek + */ +class LanguageBundle extends AbstractBundle implements LanguageBundleInterface +{ + /** + * {@inheritdoc} + */ + public function getLanguageName($lang, $region = null, $locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + if (null === ($languages = $this->readEntry($locale, array('Languages')))) { + return null; + } + + // Some languages are translated together with their region, + // i.e. "en_GB" is translated as "British English" + if (null !== $region && isset($languages[$lang.'_'.$region])) { + return $languages[$lang.'_'.$region]; + } + + return $languages[$lang]; + } + + /** + * {@inheritdoc} + */ + public function getLanguageNames($locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + if (null === ($languages = $this->readEntry($locale, array('Languages')))) { + return array(); + } + + if ($languages instanceof \Traversable) { + $languages = iterator_to_array($languages); + } + + return $languages; + } + + /** + * {@inheritdoc} + */ + public function getScriptName($script, $lang = null, $locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + $data = $this->read($locale); + + // Some languages are translated together with their script, + // e.g. "zh_Hans" is translated as "Simplified Chinese" + if (null !== $lang && isset($data['Languages'][$lang.'_'.$script])) { + $langName = $data['Languages'][$lang.'_'.$script]; + + // If the script is appended in braces, extract it, e.g. "zh_Hans" + // is translated as "Chinesisch (vereinfacht)" in locale "de" + if (strpos($langName, '(') !== false) { + list($langName, $scriptName) = preg_split('/[\s()]/', $langName, null, PREG_SPLIT_NO_EMPTY); + + return $scriptName; + } + } + + // "af" (Afrikaans) has no "Scripts" block + if (!isset($data['Scripts'][$script])) { + return null; + } + + return $data['Scripts'][$script]; + } + + /** + * {@inheritdoc} + */ + public function getScriptNames($locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + if (null === ($scripts = $this->readEntry($locale, array('Scripts')))) { + return array(); + } + + if ($scripts instanceof \Traversable) { + $scripts = iterator_to_array($scripts); + } + + return $scripts; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundleInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundleInterface.php new file mode 100644 index 00000000..de50bda0 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LanguageBundleInterface.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Gives access to language-related ICU data. + * + * @author Bernhard Schussek + */ +interface LanguageBundleInterface extends ResourceBundleInterface +{ + /** + * Returns the name of a language. + * + * @param string $lang A language code (e.g. "en"). + * @param string|null $region Optional. A region code (e.g. "US"). + * @param string $locale Optional. The locale to return the name in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string|null The name of the language or NULL if not found. + */ + public function getLanguageName($lang, $region = null, $locale = null); + + /** + * Returns the names of all known languages. + * + * @param string $locale Optional. The locale to return the names in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string[] A list of language names indexed by language codes. + */ + public function getLanguageNames($locale = null); + + /** + * Returns the name of a script. + * + * @param string $script A script code (e.g. "Hans"). + * @param string $lang Optional. A language code (e.g. "zh"). + * @param string $locale Optional. The locale to return the name in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string|null The name of the script or NULL if not found. + */ + public function getScriptName($script, $lang = null, $locale = null); + + /** + * Returns the names of all known scripts. + * + * @param string $locale Optional. The locale to return the names in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string[] A list of script names indexed by script codes. + */ + public function getScriptNames($locale = null); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundle.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundle.php new file mode 100644 index 00000000..6f6cdfcb --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundle.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Default implementation of {@link LocaleBundleInterface}. + * + * @author Bernhard Schussek + */ +class LocaleBundle extends AbstractBundle implements LocaleBundleInterface +{ + /** + * {@inheritdoc} + */ + public function getLocaleName($ofLocale, $locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + return $this->readEntry($locale, array('Locales', $ofLocale)); + } + + /** + * {@inheritdoc} + */ + public function getLocaleNames($locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + if (null === ($locales = $this->readEntry($locale, array('Locales')))) { + return array(); + } + + if ($locales instanceof \Traversable) { + $locales = iterator_to_array($locales); + } + + return $locales; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundleInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundleInterface.php new file mode 100644 index 00000000..daf5be68 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/LocaleBundleInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Gives access to locale-related ICU data. + * + * @author Bernhard Schussek + */ +interface LocaleBundleInterface extends ResourceBundleInterface +{ + /** + * Returns the name of a locale. + * + * @param string $ofLocale The locale to return the name of (e.g. "de_AT"). + * @param string $locale Optional. The locale to return the name in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string|null The name of the locale or NULL if not found. + */ + public function getLocaleName($ofLocale, $locale = null); + + /** + * Returns the names of all known locales. + * + * @param string $locale Optional. The locale to return the names in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string[] A list of locale names indexed by locale codes. + */ + public function getLocaleNames($locale = null); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/AbstractBundleReader.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/AbstractBundleReader.php new file mode 100644 index 00000000..c30693ac --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/AbstractBundleReader.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +/** + * Base class for {@link BundleReaderInterface} implementations. + * + * @author Bernhard Schussek + */ +abstract class AbstractBundleReader implements BundleReaderInterface +{ + /** + * {@inheritdoc} + */ + public function getLocales($path) + { + $extension = '.' . $this->getFileExtension(); + $locales = glob($path . '/*' . $extension); + + // Remove file extension and sort + array_walk($locales, function (&$locale) use ($extension) { $locale = basename($locale, $extension); }); + sort($locales); + + return $locales; + } + + /** + * Returns the extension of locale files in this bundle. + * + * @return string The file extension (without leading dot). + */ + abstract protected function getFileExtension(); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BinaryBundleReader.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BinaryBundleReader.php new file mode 100644 index 00000000..56cef806 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BinaryBundleReader.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +use Symfony\Component\Intl\Exception\RuntimeException; +use Symfony\Component\Intl\ResourceBundle\Util\ArrayAccessibleResourceBundle; + +/** + * Reads binary .res resource bundles. + * + * @author Bernhard Schussek + */ +class BinaryBundleReader extends AbstractBundleReader implements BundleReaderInterface +{ + /** + * {@inheritdoc} + */ + public function read($path, $locale) + { + // Point for future extension: Modify this class so that it works also + // if the \ResourceBundle class is not available. + $bundle = new \ResourceBundle($locale, $path); + + if (null === $bundle) { + throw new RuntimeException(sprintf( + 'Could not load the resource bundle "%s/%s.res".', + $path, + $locale + )); + } + + return new ArrayAccessibleResourceBundle($bundle); + } + + /** + * {@inheritdoc} + */ + protected function getFileExtension() + { + return 'res'; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BufferedBundleReader.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BufferedBundleReader.php new file mode 100644 index 00000000..e44074b1 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BufferedBundleReader.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +use Symfony\Component\Intl\ResourceBundle\Util\RingBuffer; + +/** + * @author Bernhard Schussek + */ +class BufferedBundleReader implements BundleReaderInterface +{ + /** + * @var BundleReaderInterface + */ + private $reader; + + private $buffer; + + /** + * Buffers a given reader. + * + * @param BundleReaderInterface $reader The reader to buffer. + * @param integer $bufferSize The number of entries to store + * in the buffer. + */ + public function __construct(BundleReaderInterface $reader, $bufferSize) + { + $this->reader = $reader; + $this->buffer = new RingBuffer($bufferSize); + } + + /** + * {@inheritdoc} + */ + public function read($path, $locale) + { + $hash = $path . '//' . $locale; + + if (!isset($this->buffer[$hash])) { + $this->buffer[$hash] = $this->reader->read($path, $locale); + } + + return $this->buffer[$hash]; + } + + /** + * {@inheritdoc} + */ + public function getLocales($path) + { + return $this->reader->getLocales($path); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BundleReaderInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BundleReaderInterface.php new file mode 100644 index 00000000..bc485cd5 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/BundleReaderInterface.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +/** + * Reads resource bundle files. + * + * @author Bernhard Schussek + */ +interface BundleReaderInterface +{ + /** + * Reads a resource bundle. + * + * @param string $path The path to the resource bundle. + * @param string $locale The locale to read. + * + * @return mixed Returns an array or {@link \ArrayAccess} instance for + * complex data, a scalar value otherwise. + */ + public function read($path, $locale); + + /** + * Reads the available locales of a resource bundle. + * + * @param string $path The path to the resource bundle. + * + * @return string[] A list of supported locale codes. + */ + public function getLocales($path); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/PhpBundleReader.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/PhpBundleReader.php new file mode 100644 index 00000000..663bcc9d --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/PhpBundleReader.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +use Symfony\Component\Intl\Exception\InvalidArgumentException; +use Symfony\Component\Intl\Exception\RuntimeException; + +/** + * Reads .php resource bundles. + * + * @author Bernhard Schussek + */ +class PhpBundleReader extends AbstractBundleReader implements BundleReaderInterface +{ + /** + * {@inheritdoc} + */ + public function read($path, $locale) + { + if ('en' !== $locale) { + throw new InvalidArgumentException('Only the locale "en" is supported.'); + } + + $fileName = $path . '/' . $locale . '.php'; + + if (!file_exists($fileName)) { + throw new RuntimeException(sprintf( + 'The resource bundle "%s/%s.php" does not exist.', + $path, + $locale + )); + } + + if (!is_file($fileName)) { + throw new RuntimeException(sprintf( + 'The resource bundle "%s/%s.php" is not a file.', + $path, + $locale + )); + } + + return include $fileName; + } + + /** + * {@inheritdoc} + */ + protected function getFileExtension() + { + return 'php'; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReader.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReader.php new file mode 100644 index 00000000..e3656fe2 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReader.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +use Symfony\Component\Intl\ResourceBundle\Util\RecursiveArrayAccess; + +/** + * A structured reader wrapping an existing resource bundle reader. + * + * @author Bernhard Schussek + * + * @see StructuredResourceBundleBundleReaderInterface + */ +class StructuredBundleReader implements StructuredBundleReaderInterface +{ + /** + * @var BundleReaderInterface + */ + private $reader; + + /** + * Creates an entry reader based on the given resource bundle reader. + * + * @param BundleReaderInterface $reader A resource bundle reader to use. + */ + public function __construct(BundleReaderInterface $reader) + { + $this->reader = $reader; + } + + /** + * {@inheritdoc} + */ + public function read($path, $locale) + { + return $this->reader->read($path, $locale); + } + + /** + * {@inheritdoc} + */ + public function getLocales($path) + { + return $this->reader->getLocales($path); + } + + /** + * {@inheritdoc} + */ + public function readEntry($path, $locale, array $indices, $fallback = true) + { + $data = $this->reader->read($path, $locale); + + $entry = RecursiveArrayAccess::get($data, $indices); + $multivalued = is_array($entry) || $entry instanceof \Traversable; + + if (!($fallback && (null === $entry || $multivalued))) { + return $entry; + } + + if (null !== ($fallbackLocale = $this->getFallbackLocale($locale))) { + $parentEntry = $this->readEntry($path, $fallbackLocale, $indices, true); + + if ($entry || $parentEntry) { + $multivalued = $multivalued || is_array($parentEntry) || $parentEntry instanceof \Traversable; + + if ($multivalued) { + if ($entry instanceof \Traversable) { + $entry = iterator_to_array($entry); + } + + if ($parentEntry instanceof \Traversable) { + $parentEntry = iterator_to_array($parentEntry); + } + + $entry = array_merge( + $parentEntry ?: array(), + $entry ?: array() + ); + } else { + $entry = null === $entry ? $parentEntry : $entry; + } + } + } + + return $entry; + } + + /** + * Returns the fallback locale for a given locale, if any + * + * @param string $locale The locale to find the fallback for. + * + * @return string|null The fallback locale, or null if no parent exists + */ + private function getFallbackLocale($locale) + { + if (false === $pos = strrpos($locale, '_')) { + return null; + } + + return substr($locale, 0, $pos); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReaderInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReaderInterface.php new file mode 100644 index 00000000..c22ad93b --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Reader/StructuredBundleReaderInterface.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Reader; + +/** + * Reads individual entries of a resource file. + * + * @author Bernhard Schussek + */ +interface StructuredBundleReaderInterface extends BundleReaderInterface +{ + /** + * Reads an entry from a resource bundle. + * + * An entry can be selected from the resource bundle by passing the path + * to that entry in the bundle. For example, if the bundle is structured + * like this: + * + * TopLevel + * NestedLevel + * Entry: Value + * + * Then the value can be read by calling: + * + * $reader->readEntry('...', 'en', array('TopLevel', 'NestedLevel', 'Entry')); + * + * @param string $path The path to the resource bundle. + * @param string $locale The locale to read. + * @param string[] $indices The indices to read from the bundle. + * @param Boolean $fallback Whether to merge the value with the value from + * the fallback locale (e.g. "en" for "en_GB"). + * Only applicable if the result is multivalued + * (i.e. array or \ArrayAccess) or cannot be found + * in the requested locale. + * + * @return mixed Returns an array or {@link \ArrayAccess} instance for + * complex data, a scalar value for simple data and NULL + * if the given path could not be accessed. + */ + public function readEntry($path, $locale, array $indices, $fallback = true); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundle.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundle.php new file mode 100644 index 00000000..a3cd9bd3 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundle.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Default implementation of {@link RegionBundleInterface}. + * + * @author Bernhard Schussek + */ +class RegionBundle extends AbstractBundle implements RegionBundleInterface +{ + /** + * {@inheritdoc} + */ + public function getCountryName($country, $locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + return $this->readEntry($locale, array('Countries', $country)); + } + + /** + * {@inheritdoc} + */ + public function getCountryNames($locale = null) + { + if (null === $locale) { + $locale = \Locale::getDefault(); + } + + if (null === ($countries = $this->readEntry($locale, array('Countries')))) { + return array(); + } + + if ($countries instanceof \Traversable) { + $countries = iterator_to_array($countries); + } + + return $countries; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundleInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundleInterface.php new file mode 100644 index 00000000..4e55f2dc --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/RegionBundleInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Gives access to region-related ICU data. + * + * @author Bernhard Schussek + */ +interface RegionBundleInterface extends ResourceBundleInterface +{ + /** + * Returns the name of a country. + * + * @param string $country A country code (e.g. "US"). + * @param string $locale Optional. The locale to return the name in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string|null The name of the country or NULL if not found. + */ + public function getCountryName($country, $locale = null); + + /** + * Returns the names of all known countries. + * + * @param string $locale Optional. The locale to return the names in. + * Defaults to {@link \Locale::getDefault()}. + * + * @return string[] A list of country names indexed by country codes. + */ + public function getCountryNames($locale = null); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/ResourceBundleInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/ResourceBundleInterface.php new file mode 100644 index 00000000..497a66a3 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/ResourceBundleInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle; + +/** + * Gives access to ICU data. + * + * @author Bernhard Schussek + */ +interface ResourceBundleInterface +{ + /** + * Returns the list of locales that this bundle supports. + * + * @return string[] A list of locale codes. + */ + public function getLocales(); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/BundleTransformer.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/BundleTransformer.php new file mode 100644 index 00000000..0692d6fe --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/BundleTransformer.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer; + +use Symfony\Component\Intl\Exception\RuntimeException; +use Symfony\Component\Intl\ResourceBundle\Transformer\Rule\TransformationRuleInterface; +use Symfony\Component\Intl\ResourceBundle\Writer\PhpBundleWriter; + +/** + * Compiles a number of resource bundles based on predefined compilation rules. + * + * @author Bernhard Schussek + */ +class BundleTransformer +{ + /** + * @var TransformationRuleInterface[] + */ + private $rules = array(); + + /** + * Adds a new compilation rule. + * + * @param TransformationRuleInterface $rule The compilation rule. + */ + public function addRule(TransformationRuleInterface $rule) + { + $this->rules[] = $rule; + } + + /** + * Runs the compilation with the given compilation context. + * + * @param CompilationContextInterface $context The context storing information + * needed to run the compilation. + * + * @throws RuntimeException If any of the files to be compiled by the loaded + * compilation rules does not exist. + */ + public function compileBundles(CompilationContextInterface $context) + { + $filesystem = $context->getFilesystem(); + $compiler = $context->getCompiler(); + + $filesystem->remove($context->getBinaryDir()); + $filesystem->mkdir($context->getBinaryDir()); + + foreach ($this->rules as $rule) { + $filesystem->mkdir($context->getBinaryDir() . '/' . $rule->getBundleName()); + + $resources = (array) $rule->beforeCompile($context); + + foreach ($resources as $resource) { + if (!file_exists($resource)) { + throw new RuntimeException(sprintf( + 'The file "%s" to be compiled by %s does not exist.', + $resource, + get_class($rule) + )); + } + + $compiler->compile($resource, $context->getBinaryDir() . '/' . $rule->getBundleName()); + } + + $rule->afterCompile($context); + } + } + + public function createStubs(StubbingContextInterface $context) + { + $filesystem = $context->getFilesystem(); + $phpWriter = new PhpBundleWriter(); + + $filesystem->remove($context->getStubDir()); + $filesystem->mkdir($context->getStubDir()); + + foreach ($this->rules as $rule) { + $filesystem->mkdir($context->getStubDir() . '/' . $rule->getBundleName()); + + $data = $rule->beforeCreateStub($context); + + $phpWriter->write($context->getStubDir() . '/' . $rule->getBundleName(), 'en', $data); + + $rule->afterCreateStub($context); + } + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContext.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContext.php new file mode 100644 index 00000000..cdc1951b --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContext.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface; + +/** + * Default implementation of {@link CompilationContextInterface}. + * + * @author Bernhard Schussek + */ +class CompilationContext implements CompilationContextInterface +{ + /** + * @var string + */ + private $sourceDir; + + /** + * @var string + */ + private $binaryDir; + + /** + * @var FileSystem + */ + private $filesystem; + + /** + * @var BundleCompilerInterface + */ + private $compiler; + + /** + * @var string + */ + private $icuVersion; + + public function __construct($sourceDir, $binaryDir, Filesystem $filesystem, BundleCompilerInterface $compiler, $icuVersion) + { + $this->sourceDir = $sourceDir; + $this->binaryDir = $binaryDir; + $this->filesystem = $filesystem; + $this->compiler = $compiler; + $this->icuVersion = $icuVersion; + } + + /** + * {@inheritdoc} + */ + public function getSourceDir() + { + return $this->sourceDir; + } + + /** + * {@inheritdoc} + */ + public function getBinaryDir() + { + return $this->binaryDir; + } + + /** + * {@inheritdoc} + */ + public function getFilesystem() + { + return $this->filesystem; + } + + /** + * {@inheritdoc} + */ + public function getCompiler() + { + return $this->compiler; + } + + /** + * {@inheritdoc} + */ + public function getIcuVersion() + { + return $this->icuVersion; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContextInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContextInterface.php new file mode 100644 index 00000000..f05c2807 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/CompilationContextInterface.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer; + +/** + * Stores contextual information for resource bundle compilation. + * + * @author Bernhard Schussek + */ +interface CompilationContextInterface +{ + /** + * Returns the directory where the source versions of the resource bundles + * are stored. + * + * @return string An absolute path to a directory. + */ + public function getSourceDir(); + + /** + * Returns the directory where the binary resource bundles are stored. + * + * @return string An absolute path to a directory. + */ + public function getBinaryDir(); + + /** + * Returns a tool for manipulating the filesystem. + * + * @return \Symfony\Component\Filesystem\Filesystem The filesystem manipulator. + */ + public function getFilesystem(); + + /** + * Returns a resource bundle compiler. + * + * @return \Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface The loaded resource bundle compiler. + */ + public function getCompiler(); + + /** + * Returns the ICU version of the bundles being converted. + * + * @return string The ICU version string. + */ + public function getIcuVersion(); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/CurrencyBundleTransformationRule.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/CurrencyBundleTransformationRule.php new file mode 100644 index 00000000..95783b3b --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/CurrencyBundleTransformationRule.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer\Rule; + +use Symfony\Component\Intl\Intl; +use Symfony\Component\Intl\ResourceBundle\CurrencyBundle; +use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface; +use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface; +use Symfony\Component\Intl\Util\IcuVersion; + +/** + * The rule for compiling the currency bundle. + * + * @author Bernhard Schussek + */ +class CurrencyBundleTransformationRule implements TransformationRuleInterface +{ + /** + * {@inheritdoc} + */ + public function getBundleName() + { + return 'curr'; + } + + /** + * {@inheritdoc} + */ + public function beforeCompile(CompilationContextInterface $context) + { + // The currency data is contained in the locales and misc bundles + // in ICU <= 4.2 + if (IcuVersion::compare($context->getIcuVersion(), '4.2', '<=', 1)) { + return array( + $context->getSourceDir() . '/misc/supplementalData.txt', + $context->getSourceDir() . '/locales' + ); + } + + return $context->getSourceDir() . '/curr'; + } + + /** + * {@inheritdoc} + */ + public function afterCompile(CompilationContextInterface $context) + { + // \ResourceBundle does not like locale names with uppercase chars, so rename + // the resource file + // See: http://bugs.php.net/bug.php?id=54025 + $fileName = $context->getBinaryDir() . '/curr/supplementalData.res'; + $fileNameLower = $context->getBinaryDir() . '/curr/supplementaldata.res'; + + $context->getFilesystem()->rename($fileName, $fileNameLower); + } + + /** + * {@inheritdoc} + */ + public function beforeCreateStub(StubbingContextInterface $context) + { + $currencies = array(); + $currencyBundle = Intl::getCurrencyBundle(); + + foreach ($currencyBundle->getCurrencyNames('en') as $code => $name) { + $currencies[$code] = array( + CurrencyBundle::INDEX_NAME => $name, + CurrencyBundle::INDEX_SYMBOL => $currencyBundle->getCurrencySymbol($code, 'en'), + CurrencyBundle::INDEX_FRACTION_DIGITS => $currencyBundle->getFractionDigits($code), + CurrencyBundle::INDEX_ROUNDING_INCREMENT => $currencyBundle->getRoundingIncrement($code), + ); + } + + return array( + 'Currencies' => $currencies, + ); + } + + /** + * {@inheritdoc} + */ + public function afterCreateStub(StubbingContextInterface $context) + { + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LanguageBundleTransformationRule.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LanguageBundleTransformationRule.php new file mode 100644 index 00000000..5e6f9018 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LanguageBundleTransformationRule.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer\Rule; + +use Symfony\Component\Intl\Intl; +use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface; +use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface; +use Symfony\Component\Intl\Util\IcuVersion; + +/** + * The rule for compiling the language bundle. + * + * @author Bernhard Schussek + */ +class LanguageBundleTransformationRule implements TransformationRuleInterface +{ + /** + * {@inheritdoc} + */ + public function getBundleName() + { + return 'lang'; + } + + /** + * {@inheritdoc} + */ + public function beforeCompile(CompilationContextInterface $context) + { + // The language data is contained in the locales bundle in ICU <= 4.2 + if (IcuVersion::compare($context->getIcuVersion(), '4.2', '<=', 1)) { + return $context->getSourceDir() . '/locales'; + } + + return $context->getSourceDir() . '/lang'; + } + + /** + * {@inheritdoc} + */ + public function afterCompile(CompilationContextInterface $context) + { + } + + /** + * {@inheritdoc} + */ + public function beforeCreateStub(StubbingContextInterface $context) + { + return array( + 'Languages' => Intl::getLanguageBundle()->getLanguageNames('en'), + 'Scripts' => Intl::getLanguageBundle()->getScriptNames('en'), + ); + } + + /** + * {@inheritdoc} + */ + public function afterCreateStub(StubbingContextInterface $context) + { + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LocaleBundleTransformationRule.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LocaleBundleTransformationRule.php new file mode 100644 index 00000000..b2576d6e --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LocaleBundleTransformationRule.php @@ -0,0 +1,251 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer\Rule; + +use Symfony\Component\Intl\Exception\RuntimeException; +use Symfony\Component\Intl\Intl; +use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface; +use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface; +use Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter; + +/** + * The rule for compiling the locale bundle. + * + * @author Bernhard Schussek + */ +class LocaleBundleTransformationRule implements TransformationRuleInterface +{ + /** + * @var \Symfony\Component\Intl\ResourceBundle\LanguageBundleInterface + */ + private $languageBundle; + + /** + * @var \Symfony\Component\Intl\ResourceBundle\RegionBundleInterface + */ + private $regionBundle; + + public function __construct() + { + $this->languageBundle = Intl::getLanguageBundle(); + $this->regionBundle = Intl::getRegionBundle(); + } + + /** + * {@inheritdoc} + */ + public function getBundleName() + { + return 'locales'; + } + + /** + * {@inheritdoc} + */ + public function beforeCompile(CompilationContextInterface $context) + { + $tempDir = sys_get_temp_dir() . '/icu-data-locales'; + + $context->getFilesystem()->remove($tempDir); + $context->getFilesystem()->mkdir($tempDir); + + $this->generateTextFiles($tempDir, $this->scanLocales($context)); + + return $tempDir; + } + + /** + * {@inheritdoc} + */ + public function afterCompile(CompilationContextInterface $context) + { + $context->getFilesystem()->remove(sys_get_temp_dir() . '/icu-data-locales'); + } + + /** + * {@inheritdoc} + */ + public function beforeCreateStub(StubbingContextInterface $context) + { + return array( + 'Locales' => Intl::getLocaleBundle()->getLocaleNames('en'), + ); + } + + /** + * {@inheritdoc} + */ + public function afterCreateStub(StubbingContextInterface $context) + { + } + + private function scanLocales(CompilationContextInterface $context) + { + $tempDir = sys_get_temp_dir() . '/icu-data-locales-source'; + + $context->getFilesystem()->remove($tempDir); + $context->getFilesystem()->mkdir($tempDir); + + // Temporarily generate the resource bundles + $context->getCompiler()->compile($context->getSourceDir() . '/locales', $tempDir); + + // Discover the list of supported locales, which are the names of the resource + // bundles in the "locales" directory + $locales = glob($tempDir . '/*.res'); + + // Remove file extension and sort + array_walk($locales, function (&$locale) { $locale = basename($locale, '.res'); }); + sort($locales); + + // Delete unneeded locales + foreach ($locales as $key => $locale) { + // Delete all aliases from the list + // i.e., "az_AZ" is an alias for "az_Latn_AZ" + $content = file_get_contents($context->getSourceDir() . '/locales/' . $locale . '.txt'); + + // The key "%%ALIAS" is not accessible through the \ResourceBundle class, + // so look in the original .txt file instead + if (strpos($content, '%%ALIAS') !== false) { + unset($locales[$key]); + } + + // Delete locales that have no content (i.e. only "Version" key) + $bundle = new \ResourceBundle($locale, $tempDir); + + if (null === $bundle) { + throw new RuntimeException('The resource bundle for locale ' . $locale . ' could not be loaded from directory ' . $tempDir); + } + + // There seems to be no other way for identifying all keys in this specific + // resource bundle + if (array_keys(iterator_to_array($bundle)) === array('Version')) { + unset($locales[$key]); + } + } + + $context->getFilesystem()->remove($tempDir); + + return $locales; + } + + private function generateTextFiles($targetDirectory, array $locales) + { + $displayLocales = array_unique(array_merge( + $this->languageBundle->getLocales(), + $this->regionBundle->getLocales() + )); + + $txtWriter = new TextBundleWriter(); + + // Generate a list of locale names in the language of each display locale + // Each locale name has the form: "Language (Script, Region, Variant1, ...) + // Script, Region and Variants are optional. If none of them is available, + // the braces are not printed. + foreach ($displayLocales as $displayLocale) { + // Don't include ICU's root resource bundle + if ('root' === $displayLocale) { + continue; + } + + $names = array(); + + foreach ($locales as $locale) { + // Don't include ICU's root resource bundle + if ($locale === 'root') { + continue; + } + + if (null !== ($name = $this->generateLocaleName($locale, $displayLocale))) { + $names[$locale] = $name; + } + } + + // If no names could be generated for the current locale, skip it + if (0 === count($names)) { + continue; + } + + $txtWriter->write($targetDirectory, $displayLocale, array('Locales' => $names)); + } + } + + private function generateLocaleName($locale, $displayLocale) + { + $name = null; + + $lang = \Locale::getPrimaryLanguage($locale); + $script = \Locale::getScript($locale); + $region = \Locale::getRegion($locale); + $variants = \Locale::getAllVariants($locale); + + // Currently the only available variant is POSIX, which we don't want + // to include in the list + if (count($variants) > 0) { + return null; + } + + // Some languages are translated together with their region, + // i.e. "en_GB" is translated as "British English" + // we don't include these languages though because they mess up + // the name sorting + // $name = $this->langBundle->getLanguageName($displayLocale, $lang, $region); + + // Some languages are simply not translated + // Example: "az" (Azerbaijani) has no translation in "af" (Afrikaans) + if (null === ($name = $this->languageBundle->getLanguageName($lang, null, $displayLocale))) { + return null; + } + + // "as" (Assamese) has no "Variants" block + //if (!$langBundle->get('Variants')) { + // continue; + //} + + $extras = array(); + + // Discover the name of the script part of the locale + // i.e. in zh_Hans_MO, "Hans" is the script + if ($script) { + // Some scripts are not translated into every language + if (null === ($scriptName = $this->languageBundle->getScriptName($script, $lang, $displayLocale))) { + return null; + } + + $extras[] = $scriptName; + } + + // Discover the name of the region part of the locale + // i.e. in de_AT, "AT" is the region + if ($region) { + // Some regions are not translated into every language + if (null === ($regionName = $this->regionBundle->getCountryName($region, $displayLocale))) { + return null; + } + + $extras[] = $regionName; + } + + if (count($extras) > 0) { + // Remove any existing extras + // For example, in German, zh_Hans is "Chinesisch (vereinfacht)". + // The latter is the script part which is already included in the + // extras and will be appended again with the other extras. + if (preg_match('/^(.+)\s+\([^\)]+\)$/', $name, $matches)) { + $name = $matches[1]; + } + + $name .= ' ('.implode(', ', $extras).')'; + } + + return $name; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/RegionBundleTransformationRule.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/RegionBundleTransformationRule.php new file mode 100644 index 00000000..52fdbed8 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/RegionBundleTransformationRule.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer\Rule; + +use Symfony\Component\Intl\Intl; +use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface; +use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface; +use Symfony\Component\Intl\Util\IcuVersion; + +/** + * The rule for compiling the region bundle. + * + * @author Bernhard Schussek + */ +class RegionBundleTransformationRule implements TransformationRuleInterface +{ + /** + * {@inheritdoc} + */ + public function getBundleName() + { + return 'region'; + } + + /** + * {@inheritdoc} + */ + public function beforeCompile(CompilationContextInterface $context) + { + // The region data is contained in the locales bundle in ICU <= 4.2 + if (IcuVersion::compare($context->getIcuVersion(), '4.2', '<=', 1)) { + return $context->getSourceDir() . '/locales'; + } + + return $context->getSourceDir() . '/region'; + } + + /** + * {@inheritdoc} + */ + public function afterCompile(CompilationContextInterface $context) + { + } + + /** + * {@inheritdoc} + */ + public function beforeCreateStub(StubbingContextInterface $context) + { + return array( + 'Countries' => Intl::getRegionBundle()->getCountryNames('en'), + ); + } + + /** + * {@inheritdoc} + */ + public function afterCreateStub(StubbingContextInterface $context) + { + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/TransformationRuleInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/TransformationRuleInterface.php new file mode 100644 index 00000000..3965e0d2 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/TransformationRuleInterface.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer\Rule; + +use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface; +use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface; + +/** + * Contains instruction for compiling a resource bundle. + * + * @author Bernhard Schussek + */ +interface TransformationRuleInterface +{ + /** + * Returns the name of the compiled resource bundle. + * + * @return string The name of the bundle. + */ + public function getBundleName(); + + /** + * Runs instructions to be executed before compiling the sources of the + * resource bundle. + * + * @param CompilationContextInterface $context The contextual information of + * the compilation. + * + * @return string[] The source directories/files of the bundle. + */ + public function beforeCompile(CompilationContextInterface $context); + + /** + * Runs instructions to be executed after compiling the sources of the + * resource bundle. + * + * @param CompilationContextInterface $context The contextual information of + * the compilation. + */ + public function afterCompile(CompilationContextInterface $context); + + /** + * Runs instructions to be executed before creating the stub version of the + * resource bundle. + * + * @param StubbingContextInterface $context The contextual information of + * the compilation. + * + * @return mixed The data to include in the stub version. + */ + public function beforeCreateStub(StubbingContextInterface $context); + + /** + * Runs instructions to be executed after creating the stub version of the + * resource bundle. + * + * @param StubbingContextInterface $context The contextual information of + * the compilation. + */ + public function afterCreateStub(StubbingContextInterface $context); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContext.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContext.php new file mode 100644 index 00000000..25ab68db --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContext.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer; + +use Symfony\Component\Filesystem\Filesystem; + +/** + * @author Bernhard Schussek + */ +class StubbingContext implements StubbingContextInterface +{ + /** + * @var string + */ + private $binaryDir; + + /** + * @var string + */ + private $stubDir; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var string + */ + private $icuVersion; + + public function __construct($binaryDir, $stubDir, Filesystem $filesystem, $icuVersion) + { + $this->binaryDir = $binaryDir; + $this->stubDir = $stubDir; + $this->filesystem = $filesystem; + $this->icuVersion = $icuVersion; + } + + /** + * {@inheritdoc} + */ + public function getBinaryDir() + { + return $this->binaryDir; + } + + /** + * {@inheritdoc} + */ + public function getStubDir() + { + return $this->stubDir; + } + + /** + * {@inheritdoc} + */ + public function getFilesystem() + { + return $this->filesystem; + } + + /** + * {@inheritdoc} + */ + public function getIcuVersion() + { + return $this->icuVersion; + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContextInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContextInterface.php new file mode 100644 index 00000000..dc492556 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Transformer/StubbingContextInterface.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Transformer; + +/** + * @author Bernhard Schussek + */ +interface StubbingContextInterface +{ + /** + * Returns the directory where the binary resource bundles are stored. + * + * @return string An absolute path to a directory. + */ + public function getBinaryDir(); + + /** + * Returns the directory where the stub resource bundles are stored. + * + * @return string An absolute path to a directory. + */ + public function getStubDir(); + + /** + * Returns a tool for manipulating the filesystem. + * + * @return \Symfony\Component\Filesystem\Filesystem The filesystem manipulator. + */ + public function getFilesystem(); + + /** + * Returns the ICU version of the bundles being converted. + * + * @return string The ICU version string. + */ + public function getIcuVersion(); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/ArrayAccessibleResourceBundle.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/ArrayAccessibleResourceBundle.php new file mode 100644 index 00000000..9a4cccb4 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/ArrayAccessibleResourceBundle.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Util; + +use Symfony\Component\Intl\Exception\BadMethodCallException; + +/** + * Work-around for a bug in PHP's \ResourceBundle implementation. + * + * More information can be found on https://bugs.php.net/bug.php?id=64356. + * This class can be removed once that bug is fixed. + * + * @author Bernhard Schussek + */ +class ArrayAccessibleResourceBundle implements \ArrayAccess, \IteratorAggregate, \Countable +{ + private $bundleImpl; + + public function __construct(\ResourceBundle $bundleImpl) + { + $this->bundleImpl = $bundleImpl; + } + + public function get($offset, $fallback = null) + { + $value = $this->bundleImpl->get($offset, $fallback); + + return $value instanceof \ResourceBundle ? new static($value) : $value; + } + + public function offsetExists($offset) + { + return null !== $this->bundleImpl[$offset]; + } + + public function offsetGet($offset) + { + return $this->get($offset); + } + + public function offsetSet($offset, $value) + { + throw new BadMethodCallException('Resource bundles cannot be modified.'); + } + + public function offsetUnset($offset) + { + throw new BadMethodCallException('Resource bundles cannot be modified.'); + } + + public function getIterator() + { + return $this->bundleImpl; + } + + public function count() + { + return $this->bundleImpl->count(); + } + + public function getErrorCode() + { + return $this->bundleImpl->getErrorCode(); + } + + public function getErrorMessage() + { + return $this->bundleImpl->getErrorMessage(); + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RecursiveArrayAccess.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RecursiveArrayAccess.php new file mode 100644 index 00000000..e1feaa2c --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RecursiveArrayAccess.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Util; + +/** + * @author Bernhard Schussek + */ +class RecursiveArrayAccess +{ + public static function get($array, array $indices) + { + foreach ($indices as $index) { + if (!$array instanceof \ArrayAccess && !is_array($array)) { + return null; + } + + $array = $array[$index]; + } + + return $array; + } + + private function __construct() {} +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RingBuffer.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RingBuffer.php new file mode 100644 index 00000000..7ccbd1e7 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Util/RingBuffer.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Util; + +use Symfony\Component\Intl\Exception\OutOfBoundsException; + +/** + * Implements a ring buffer. + * + * A ring buffer is an array-like structure with a fixed size. If the buffer + * is full, the next written element overwrites the first bucket in the buffer, + * then the second and so on. + * + * @author Bernhard Schussek + */ +class RingBuffer implements \ArrayAccess +{ + private $values = array(); + + private $indices = array(); + + private $cursor = 0; + + private $size; + + public function __construct($size) + { + $this->size = $size; + } + + /** + * {@inheritdoc} + */ + public function offsetExists($key) + { + return isset($this->indices[$key]); + } + + /** + * {@inheritdoc} + */ + public function offsetGet($key) + { + if (!isset($this->indices[$key])) { + throw new OutOfBoundsException(sprintf( + 'The index "%s" does not exist.', + $key + )); + } + + return $this->values[$this->indices[$key]]; + } + + /** + * {@inheritdoc} + */ + public function offsetSet($key, $value) + { + if (false !== ($keyToRemove = array_search($this->cursor, $this->indices))) { + unset($this->indices[$keyToRemove]); + } + + $this->values[$this->cursor] = $value; + $this->indices[$key] = $this->cursor; + + $this->cursor = ($this->cursor + 1) % $this->size; + } + + /** + * {@inheritdoc} + */ + public function offsetUnset($key) + { + if (isset($this->indices[$key])) { + $this->values[$this->indices[$key]] = null; + unset($this->indices[$key]); + } + } +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/BundleWriterInterface.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/BundleWriterInterface.php new file mode 100644 index 00000000..cc3b9586 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/BundleWriterInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Writer; + +/** + * Writes resource bundle files. + * + * @author Bernhard Schussek + */ +interface BundleWriterInterface +{ + /** + * Writes data to a resource bundle. + * + * @param string $path The path to the resource bundle. + * @param string $locale The locale to (over-)write. + * @param mixed $data The data to write. + */ + public function write($path, $locale, $data); +} diff --git a/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/PhpBundleWriter.php b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/PhpBundleWriter.php new file mode 100644 index 00000000..d2688b49 --- /dev/null +++ b/vendor/symfony/intl/Symfony/Component/Intl/ResourceBundle/Writer/PhpBundleWriter.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\ResourceBundle\Writer; + +/** + * Writes .php resource bundles. + * + * @author Bernhard Schussek + */ +class PhpBundleWriter implements BundleWriterInterface +{ + /** + * {@inheritdoc} + */ + public function write($path, $locale, $data) + { + $template = <<