HEX
Server: nginx/1.30.4
System: Linux d-twindigital-web-1.host-ed.eu 4.18.0-553.141.2.el8_10.x86_64 #1 SMP Wed Jul 8 10:28:18 EDT 2026 x86_64
User: u_twindigital_html (1009)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: //usr/bin/sw-cli-tools
#!/usr/bin/env php
<?php
/**
 * Generated by Box.
 *
 * @link https://github.com/herrera-io/php-box/
 */
if (class_exists('Phar')) {
Phar::mapPhar('sw.phar');
Phar::interceptFileFuncs();
require 'phar://' . __FILE__ . '/bin/sw';
}
__HALT_COMPILER(); ?>
�z9"vendor/piwik/ini/src/IniWriter.php��!�\�E�,vendor/piwik/ini/src/IniReadingException.phpW�!�\Wʸ��"vendor/piwik/ini/src/IniReader.php�!�\�=Bq�,vendor/piwik/ini/src/IniWritingException.phpW�!�\WqT��,vendor/psr/http-message/src/UriInterface.php|�!�\|���k�5vendor/psr/http-message/src/UploadedFileInterface.phpz�!�\z�9�b�/vendor/psr/http-message/src/StreamInterface.php��!�\�h�\l�6vendor/psr/http-message/src/ServerRequestInterface.phpo�!�\o
�$h�1vendor/psr/http-message/src/ResponseInterface.php�!�\��0vendor/psr/http-message/src/MessageInterface.php��!�\��)t�0vendor/psr/http-message/src/RequestInterface.php��!�\��V���%vendor/psr/log/Psr/Log/NullLogger.php��!�\����*vendor/psr/log/Psr/Log/LoggerInterface.php��!�\��sg�3vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php��!�\�iq0ض)vendor/psr/log/Psr/Log/AbstractLogger.php;�!�\;�>3[�&vendor/psr/log/Psr/Log/LoggerTrait.phpi�!�\i35�޶+vendor/psr/log/Psr/Log/LoggerAwareTrait.php��!�\�T��B�3vendor/psr/log/Psr/Log/InvalidArgumentException.php`�!�\` �X1�/vendor/psr/log/Psr/Log/LoggerAwareInterface.php|�!�\|$���#vendor/psr/log/Psr/Log/LogLevel.php��!�\�j��8�,vendor/guzzlehttp/promises/src/TaskQueue.php��!�\�C��]�5vendor/guzzlehttp/promises/src/TaskQueueInterface.php��!�\�j��{�2vendor/guzzlehttp/promises/src/RejectedPromise.php�!�\��]��,vendor/guzzlehttp/promises/src/functions.php��!�\��+ �4vendor/guzzlehttp/promises/src/PromisorInterface.phph�!�\h��i�8vendor/guzzlehttp/promises/src/CancellationException.phpc�!�\c��!0�5vendor/guzzlehttp/promises/src/AggregateException.php��!�\�O�]��5vendor/guzzlehttp/promises/src/RejectionException.php��!�\�3��*vendor/guzzlehttp/promises/src/Promise.php��!�\��ڻS�.vendor/guzzlehttp/promises/src/EachPromise.php��!�\�-��3vendor/guzzlehttp/promises/src/PromiseInterface.php�!�\�sö,vendor/guzzlehttp/promises/src/Coroutine.php��!�\��r3&�3vendor/guzzlehttp/promises/src/FulfilledPromise.php�!�\��D�4vendor/guzzlehttp/promises/src/functions_include.phph�!�\h��ʏ�.vendor/guzzlehttp/guzzle/build/Burgomaster.php�!�\/��+vendor/guzzlehttp/guzzle/build/packager.php0�!�\0P�Dz�1vendor/guzzlehttp/guzzle/src/MessageFormatter.php��!�\��Zy�.vendor/guzzlehttp/guzzle/src/TransferStats.php��!�\��/c��0vendor/guzzlehttp/guzzle/src/ClientInterface.php��!�\�:�Oֶ%vendor/guzzlehttp/guzzle/src/Pool.phpw�!�\w���4vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php��!�\�Ԙ�ܶ6vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php+(�!�\+(G��4vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php�,�!�\�,)�^�.vendor/guzzlehttp/guzzle/src/Handler/Proxy.php��!�\���˶3vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php9�!�\9�:\��9vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php��!�\�����=vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php��!�\���u�4vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.phpv�!�\v�9f��*vendor/guzzlehttp/guzzle/src/functions.php�!�\�R��1vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php��!�\�o�$�:vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.phpH�!�\H?I��5vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php��!�\����ζ1vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.phpA�!�\A�ɶ8vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php��!�\�ms��'vendor/guzzlehttp/guzzle/src/Client.phpP�!�\P��H�6vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.phpN�!�\N�Q��+vendor/guzzlehttp/guzzle/src/Middleware.php��!�\��cö3vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php}�!�\}ǿ�,vendor/guzzlehttp/guzzle/src/UriTemplate.phpa�!�\a.���-vendor/guzzlehttp/guzzle/src/HandlerStack.php�
�!�\�
�a�/vendor/guzzlehttp/guzzle/src/RequestOptions.php�!�\�g�y�2vendor/guzzlehttp/guzzle/src/functions_include.phpa�!�\a��j�0vendor/guzzlehttp/guzzle/src/RetryMiddleware.php��!�\��)�_�8vendor/guzzlehttp/guzzle/src/Exception/SeekException.php��!�\�ZM%]�;vendor/guzzlehttp/guzzle/src/Exception/RequestException.php�
�!�\�
[��k�<vendor/guzzlehttp/guzzle/src/Exception/TransferException.phpw�!�\w�
Q�?vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.phpa�!�\a��]I�:vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.phpD�!�\DD&��:vendor/guzzlehttp/guzzle/src/Exception/ClientException.php`�!�\`��p�:vendor/guzzlehttp/guzzle/src/Exception/ServerException.php`�!�\`� �Dvendor/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.phpc�!�\c�߶;vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php��!�\��հ�-vendor/guzzlehttp/psr7/src/DroppingStream.php/�!�\/FE;��'vendor/guzzlehttp/psr7/src/Response.php�
�!�\�
�g�|�(vendor/guzzlehttp/psr7/src/functions.php'5�!�\'5��Aw�+vendor/guzzlehttp/psr7/src/AppendStream.php��!�\����ƶ+vendor/guzzlehttp/psr7/src/UploadedFile.php��!�\��>#��'vendor/guzzlehttp/psr7/src/FnStream.phpn�!�\no�"vendor/guzzlehttp/psr7/src/Uri.php�%�!�\�%���M�.vendor/guzzlehttp/psr7/src/MultipartStream.phpH
�!�\H
����,vendor/guzzlehttp/psr7/src/CachingStream.phpx�!�\xà�3vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php8�!�\8b����,vendor/guzzlehttp/psr7/src/StreamWrapper.php��!�\���z��*vendor/guzzlehttp/psr7/src/LimitStream.php��!�\��0���*vendor/guzzlehttp/psr7/src/UriResolver.php��!�\��2Ŷ&vendor/guzzlehttp/psr7/src/Request.php.�!�\.����,vendor/guzzlehttp/psr7/src/InflateStream.phpb�!�\bL('��,vendor/guzzlehttp/psr7/src/UriNormalizer.php�
�!�\�
���2�,vendor/guzzlehttp/psr7/src/ServerRequest.php�!�\�[	�%vendor/guzzlehttp/psr7/src/Stream.php��!�\�!�5&�+vendor/guzzlehttp/psr7/src/NoSeekStream.php:�!�\:��R!�-vendor/guzzlehttp/psr7/src/LazyOpenStream.php��!�\�b�E�)vendor/guzzlehttp/psr7/src/PumpStream.php_�!�\_�!IU�+vendor/guzzlehttp/psr7/src/MessageTrait.phpk�!�\ki�~�0vendor/guzzlehttp/psr7/src/functions_include.php]�!�\]���ɶ+vendor/guzzlehttp/psr7/src/BufferStream.php)�!�\)�1��"vendor/composer/autoload_files.php��!�\���34�#vendor/composer/autoload_static.php��!�\�#
�m�!vendor/composer/autoload_real.php��!�\������!vendor/composer/autoload_psr4.php[�!�\[�qͶvendor/composer/ClassLoader.php��!�\�x��`�%vendor/composer/autoload_classmap.phpd�!�\dZ��H�'vendor/composer/autoload_namespaces.phpd�!�\dZ��H�%vendor/fzaninotto/faker/test/test.php��!�\��N�ζ+vendor/fzaninotto/faker/test/documentor.php��!�\��ɶ;vendor/fzaninotto/faker/test/Faker/Provider/PaymentTest.php��!�\��K�Avendor/fzaninotto/faker/test/Faker/Provider/nl_BE/PaymentTest.php��!�\�T��g�@vendor/fzaninotto/faker/test/Faker/Provider/id_ID/PersonTest.phpW�!�\W���_�Bvendor/fzaninotto/faker/test/Faker/Provider/ar_JO/InternetTest.phpN�!�\N0���Bvendor/fzaninotto/faker/test/Faker/Provider/ar_SA/InternetTest.phpN�!�\N�� �Bvendor/fzaninotto/faker/test/Faker/Provider/da_DK/InternetTest.phpN�!�\N�?�]�Bvendor/fzaninotto/faker/test/Faker/Provider/de_AT/InternetTest.phpN�!�\NZ�<�Evendor/fzaninotto/faker/test/Faker/Provider/de_AT/PhoneNumberTest.php��!�\��,s�Avendor/fzaninotto/faker/test/Faker/Provider/at_AT/PaymentTest.php��!�\���\��8vendor/fzaninotto/faker/test/Faker/Provider/UuidTest.php��!�\����Avendor/fzaninotto/faker/test/Faker/Provider/fr_BE/PaymentTest.php��!�\�o��Y�@vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/PersonTest.php��!�\����Avendor/fzaninotto/faker/test/Faker/Provider/pt_BR/CompanyTest.php��!�\�Ш���Evendor/fzaninotto/faker/test/Faker/Provider/en_NZ/PhoneNumberTest.phpz�!�\z�^��<vendor/fzaninotto/faker/test/Faker/Provider/InternetTest.php��!�\�'�͜�:vendor/fzaninotto/faker/test/Faker/Provider/PersonTest.php��!�\�'�v�Bvendor/fzaninotto/faker/test/Faker/Provider/de_CH/InternetTest.phpM�!�\Mm�oȶEvendor/fzaninotto/faker/test/Faker/Provider/de_CH/PhoneNumberTest.php]�!�\]��ݙ�Avendor/fzaninotto/faker/test/Faker/Provider/de_CH/AddressTest.php��!�\��~�Bvendor/fzaninotto/faker/test/Faker/Provider/en_ZA/InternetTest.phpN�!�\N�Z�a�@vendor/fzaninotto/faker/test/Faker/Provider/en_ZA/PersonTest.php
�!�\
�_�J�Avendor/fzaninotto/faker/test/Faker/Provider/en_ZA/CompanyTest.php��!�\�<�/�Evendor/fzaninotto/faker/test/Faker/Provider/en_ZA/PhoneNumberTest.php��!�\�a1aڶ=vendor/fzaninotto/faker/test/Faker/Provider/HtmlLoremTest.php��!�\� ��6�;vendor/fzaninotto/faker/test/Faker/Provider/CompanyTest.php��!�\�O�9�Bvendor/fzaninotto/faker/test/Faker/Provider/fi_FI/InternetTest.phpN�!�\N�`tD�@vendor/fzaninotto/faker/test/Faker/Provider/fi_FI/PersonTest.php5�!�\5�˲O�Bvendor/fzaninotto/faker/test/Faker/Provider/ja_JP/InternetTest.php�!�\m����@vendor/fzaninotto/faker/test/Faker/Provider/ja_JP/PersonTest.php��!�\�~*^��Evendor/fzaninotto/faker/test/Faker/Provider/ja_JP/PhoneNumberTest.php��!�\�8z��@vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/PersonTest.php��!�\��.f۶Evendor/fzaninotto/faker/test/Faker/Provider/uk_UA/PhoneNumberTest.phpO�!�\O�FE�Avendor/fzaninotto/faker/test/Faker/Provider/uk_UA/AddressTest.php,�!�\,r7�Avendor/fzaninotto/faker/test/Faker/Provider/en_US/PaymentTest.php=�!�\=[��Ӷ@vendor/fzaninotto/faker/test/Faker/Provider/en_US/PersonTest.php	�!�\	���M�Evendor/fzaninotto/faker/test/Faker/Provider/en_US/PhoneNumberTest.php��!�\�`q���Avendor/fzaninotto/faker/test/Faker/Provider/en_UG/AddressTest.php��!�\��[읶@vendor/fzaninotto/faker/test/Faker/Provider/sv_SE/PersonTest.php_�!�\_�8/�@vendor/fzaninotto/faker/test/Faker/Provider/kk_KZ/PersonTest.php��!�\�c[�U�Avendor/fzaninotto/faker/test/Faker/Provider/kk_KZ/CompanyTest.php��!�\��C�j�Avendor/fzaninotto/faker/test/Faker/Provider/MiscellaneousTest.php��!�\���kж8vendor/fzaninotto/faker/test/Faker/Provider/TextTest.php��!�\�p��x�@vendor/fzaninotto/faker/test/Faker/Provider/it_IT/PersonTest.php��!�\���=��Avendor/fzaninotto/faker/test/Faker/Provider/it_IT/CompanyTest.php��!�\�
ŠC�@vendor/fzaninotto/faker/test/Faker/Provider/fr_FR/PersonTest.php�!�\�܋7�Avendor/fzaninotto/faker/test/Faker/Provider/fr_FR/CompanyTest.phpZ�!�\Z� ζ@vendor/fzaninotto/faker/test/Faker/Provider/LocalizationTest.phpx�!�\x�q涶<vendor/fzaninotto/faker/test/Faker/Provider/DateTimeTest.php��!�\�@�ٶAvendor/fzaninotto/faker/test/Faker/Provider/en_GB/AddressTest.php@�!�\@�1�9vendor/fzaninotto/faker/test/Faker/Provider/ImageTest.php��!�\��*�
�Evendor/fzaninotto/faker/test/Faker/Provider/en_SG/PhoneNumberTest.php��!�\��բ�Avendor/fzaninotto/faker/test/Faker/Provider/en_SG/AddressTest.php��!�\�Nu��Bvendor/fzaninotto/faker/test/Faker/Provider/fr_CH/InternetTest.phpM�!�\M@�S�Evendor/fzaninotto/faker/test/Faker/Provider/fr_CH/PhoneNumberTest.php]�!�\]j”"�Avendor/fzaninotto/faker/test/Faker/Provider/fr_CH/AddressTest.php��!�\��7��@vendor/fzaninotto/faker/test/Faker/Provider/zh_TW/PersonTest.php��!�\��-�Avendor/fzaninotto/faker/test/Faker/Provider/zh_TW/CompanyTest.php��!�\�����>vendor/fzaninotto/faker/test/Faker/Provider/zh_TW/TextTest.php�!�\�r�;vendor/fzaninotto/faker/test/Faker/Provider/BarcodeTest.php��!�\��2��Avendor/fzaninotto/faker/test/Faker/Provider/es_ES/PaymentTest.php5�!�\5&<Z�@vendor/fzaninotto/faker/test/Faker/Provider/es_ES/PersonTest.php��!�\�ulFض>vendor/fzaninotto/faker/test/Faker/Provider/es_ES/TextTest.php{�!�\{�`)��@vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PersonTest.php��!�\�g��Evendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PhoneNumberTest.php��!�\�u����Avendor/fzaninotto/faker/test/Faker/Provider/pt_PT/AddressTest.php��!�\�!
 ��Avendor/fzaninotto/faker/test/Faker/Provider/en_PH/AddressTest.phpy�!�\y����@vendor/fzaninotto/faker/test/Faker/Provider/cs_CZ/PersonTest.phpu�!�\uN�w��Bvendor/fzaninotto/faker/test/Faker/Provider/it_CH/InternetTest.phpM�!�\M�/z�Evendor/fzaninotto/faker/test/Faker/Provider/it_CH/PhoneNumberTest.php]�!�\]K�]��Avendor/fzaninotto/faker/test/Faker/Provider/it_CH/AddressTest.php��!�\�ݼ}��Bvendor/fzaninotto/faker/test/Faker/Provider/en_NG/InternetTest.phpN�!�\N��]7�@vendor/fzaninotto/faker/test/Faker/Provider/en_NG/PersonTest.php��!�\�Bf7�Evendor/fzaninotto/faker/test/Faker/Provider/en_NG/PhoneNumberTest.phpM�!�\M��IA�Avendor/fzaninotto/faker/test/Faker/Provider/en_NG/AddressTest.php�!�\��E�?vendor/fzaninotto/faker/test/Faker/Provider/PhoneNumberTest.phpI�!�\I��)��@vendor/fzaninotto/faker/test/Faker/Provider/es_PE/PersonTest.php��!�\��.�@vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PersonTest.php��!�\����Evendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PhoneNumberTest.php��!�\�^�D�Avendor/fzaninotto/faker/test/Faker/Provider/ru_RU/CompanyTest.php�!�\�RL�Avendor/fzaninotto/faker/test/Faker/Provider/en_CA/AddressTest.php��!�\����(�Avendor/fzaninotto/faker/test/Faker/Provider/pl_PL/AddressTest.php��!�\�CNA��8vendor/fzaninotto/faker/test/Faker/Provider/BaseTest.php�;�!�\�;�"㓶Bvendor/fzaninotto/faker/test/Faker/Provider/de_DE/InternetTest.phpN�!�\N~Q0*�9vendor/fzaninotto/faker/test/Faker/Provider/ColorTest.php��!�\�N�Ѷ=vendor/fzaninotto/faker/test/Faker/Provider/UserAgentTest.php�!�\��ɶAvendor/fzaninotto/faker/test/Faker/Provider/bg_BG/PaymentTest.php��!�\�F��"�:vendor/fzaninotto/faker/test/Faker/Provider/BiasedTest.phpu�!�\u�Wm�Dvendor/fzaninotto/faker/test/Faker/Provider/ProviderOverrideTest.php��!�\��l��Avendor/fzaninotto/faker/test/Faker/Provider/nl_NL/CompanyTest.php��!�\�^����Avendor/fzaninotto/faker/test/Faker/Provider/en_IN/AddressTest.phpd�!�\d�r���@vendor/fzaninotto/faker/test/Faker/Provider/bn_BD/PersonTest.php<�!�\<,�m�@vendor/fzaninotto/faker/test/Faker/Provider/mn_MN/PersonTest.php�!�\0VSq�Avendor/fzaninotto/faker/test/Faker/Provider/en_AU/AddressTest.php��!�\�����;vendor/fzaninotto/faker/test/Faker/Provider/AddressTest.php��!�\�Jr,��9vendor/fzaninotto/faker/test/Faker/Provider/LoremTest.phpJ
�!�\J
�0�]�4vendor/fzaninotto/faker/test/Faker/GeneratorTest.phpK�!�\K=A�t�;vendor/fzaninotto/faker/test/Faker/DefaultGeneratorTest.phpj�!�\j89�}�:vendor/fzaninotto/faker/test/Faker/Calculator/LuhnTest.php@�!�\@ʵ��9vendor/fzaninotto/faker/test/Faker/Calculator/InnTest.php�!�\�#�N�:vendor/fzaninotto/faker/test/Faker/Calculator/IbanTest.php�%�!�\�%/{���7vendor/fzaninotto/faker/src/Faker/Provider/DateTime.php��!�\�[
�Q�<vendor/fzaninotto/faker/src/Faker/Provider/Miscellaneous.php�&�!�\�&c.���5vendor/fzaninotto/faker/src/Faker/Provider/Person.php��!�\�W�n��8vendor/fzaninotto/faker/src/Faker/Provider/UserAgent.php��!�\�c1n�5vendor/fzaninotto/faker/src/Faker/Provider/Biased.php�!�\W�Xڶ6vendor/fzaninotto/faker/src/Faker/Provider/Company.php_�!�\_]?�;vendor/fzaninotto/faker/src/Faker/Provider/en_US/Person.php��!�\��y	��<vendor/fzaninotto/faker/src/Faker/Provider/en_US/Company.php���!�\��1�-�9vendor/fzaninotto/faker/src/Faker/Provider/en_US/Text.php�5�!�\�5�]X��<vendor/fzaninotto/faker/src/Faker/Provider/en_US/Payment.php��!�\�E�ck�<vendor/fzaninotto/faker/src/Faker/Provider/en_US/Address.php� �!�\� mz8�@vendor/fzaninotto/faker/src/Faker/Provider/en_US/PhoneNumber.php��!�\�5�ƻ�4vendor/fzaninotto/faker/src/Faker/Provider/Color.php �!�\ �w���3vendor/fzaninotto/faker/src/Faker/Provider/Text.phpQ
�!�\Q
X~��6vendor/fzaninotto/faker/src/Faker/Provider/Barcode.php��!�\���)��3vendor/fzaninotto/faker/src/Faker/Provider/Base.php` �!�\` /mԶ4vendor/fzaninotto/faker/src/Faker/Provider/Lorem.php��!�\�ǽ7��3vendor/fzaninotto/faker/src/Faker/Provider/File.phpJP�!�\JP�%��3vendor/fzaninotto/faker/src/Faker/Provider/Uuid.php��!�\��b`<�7vendor/fzaninotto/faker/src/Faker/Provider/Internet.php:.�!�\:.KW((�4vendor/fzaninotto/faker/src/Faker/Provider/Image.php��!�\�)}�Q�6vendor/fzaninotto/faker/src/Faker/Provider/Payment.php�!�\�V���6vendor/fzaninotto/faker/src/Faker/Provider/Address.php�!�\�w��:vendor/fzaninotto/faker/src/Faker/Provider/PhoneNumber.phpF�!�\F��9�8vendor/fzaninotto/faker/src/Faker/Provider/HtmlLorem.php��!�\�ɹB�2vendor/fzaninotto/faker/src/Faker/Guesser/Name.php;�!�\;���]�Bvendor/fzaninotto/faker/src/Faker/ORM/Mandango/EntityPopulator.php��!�\���ɓ�Dvendor/fzaninotto/faker/src/Faker/ORM/Mandango/ColumnTypeGuesser.php��!�\��ͦ��<vendor/fzaninotto/faker/src/Faker/ORM/Mandango/Populator.php��!�\��"5϶>vendor/fzaninotto/faker/src/Faker/ORM/Spot/EntityPopulator.php��!�\�����@vendor/fzaninotto/faker/src/Faker/ORM/Spot/ColumnTypeGuesser.php��!�\��*���8vendor/fzaninotto/faker/src/Faker/ORM/Spot/Populator.php��!�\�����@vendor/fzaninotto/faker/src/Faker/ORM/Propel/EntityPopulator.php��!�\��'�ȶBvendor/fzaninotto/faker/src/Faker/ORM/Propel/ColumnTypeGuesser.php		�!�\		P���:vendor/fzaninotto/faker/src/Faker/ORM/Propel/Populator.php��!�\����Avendor/fzaninotto/faker/src/Faker/ORM/Propel2/EntityPopulator.php#�!�\#��{�Cvendor/fzaninotto/faker/src/Faker/ORM/Propel2/ColumnTypeGuesser.php��!�\����;vendor/fzaninotto/faker/src/Faker/ORM/Propel2/Populator.php<�!�\<��նAvendor/fzaninotto/faker/src/Faker/ORM/CakePHP/EntityPopulator.php{�!�\{ ���Cvendor/fzaninotto/faker/src/Faker/ORM/CakePHP/ColumnTypeGuesser.php��!�\�_|�h�;vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/Populator.php��!�\��-�ҶBvendor/fzaninotto/faker/src/Faker/ORM/Doctrine/EntityPopulator.php(�!�\(�#{�Dvendor/fzaninotto/faker/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php��!�\�v�)��<vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/Populator.php��!�\��c��5vendor/fzaninotto/faker/src/Faker/UniqueGenerator.php\�!�\\��]�5vendor/fzaninotto/faker/src/Faker/Calculator/Iban.php^�!�\^e���5vendor/fzaninotto/faker/src/Faker/Calculator/Luhn.php��!�\�Vp�ö4vendor/fzaninotto/faker/src/Faker/Calculator/Inn.php��!�\�YlBU�0vendor/fzaninotto/faker/src/Faker/Documentor.php��!�\�A���6vendor/fzaninotto/faker/src/Faker/DefaultGenerator.php+�!�\+ApP�-vendor/fzaninotto/faker/src/Faker/Factory.phps�!�\s�^��4vendor/fzaninotto/faker/src/Faker/ValidGenerator.php��!�\��e@��/vendor/fzaninotto/faker/src/Faker/Generator.php8�!�\8�s�(vendor/fzaninotto/faker/src/autoload.php��!�\��4x�!vendor/symfony/yaml/Unescaper.phpB�!�\Be��C�vendor/symfony/yaml/Inline.php*�!�\*H�6�vendor/symfony/yaml/Parser.php7D�!�\7D~�>�vendor/symfony/yaml/Dumper.phpS�!�\S���vendor/symfony/yaml/Escaper.phpR�!�\R����(vendor/symfony/yaml/Tests/DumperTest.php�!�\���۶(vendor/symfony/yaml/Tests/ParserTest.phpkI�!�\kI%p�&vendor/symfony/yaml/Tests/YamlTest.phpp�!�\p�Pu�0vendor/symfony/yaml/Tests/ParseExceptionTest.php��!�\���(vendor/symfony/yaml/Tests/InlineTest.php};�!�\};G��4�vendor/symfony/yaml/Yaml.php�!�\>�
��4vendor/symfony/yaml/Exception/ExceptionInterface.phpc�!�\c��۶0vendor/symfony/yaml/Exception/ParseException.php��!�\�d<	�/vendor/symfony/yaml/Exception/DumpException.phps�!�\s�ƶ2vendor/symfony/yaml/Exception/RuntimeException.php��!�\���$�%vendor/symfony/debug/ErrorHandler.phpqB�!�\qB�\/r�)vendor/symfony/debug/DebugClassLoader.php��!�\���3\�)vendor/symfony/debug/ExceptionHandler.php
3�!�\
3��ȣ�(vendor/symfony/debug/BufferingLogger.phpt�!�\t=hܶvendor/symfony/debug/Debug.php��!�\��xa?�/vendor/symfony/debug/Tests/ErrorHandlerTest.phpV9�!�\V9��k�3vendor/symfony/debug/Tests/ExceptionHandlerTest.php
�!�\
����)vendor/symfony/debug/Tests/HeaderMock.php��!�\��zW�3vendor/symfony/debug/Tests/MockExceptionHandler.php��!�\�b��5vendor/symfony/debug/Tests/Fixtures/reallyNotPsr0.phpL�!�\LV�7��=vendor/symfony/debug/Tests/Fixtures/psr4/Psr4CaseMismatch.phpU�!�\U)6:�7vendor/symfony/debug/Tests/Fixtures/DeprecatedClass.phpY�!�\Y	m�f�;vendor/symfony/debug/Tests/Fixtures/DeprecatedInterface.phpa�!�\a7��Ѷ4vendor/symfony/debug/Tests/Fixtures/casemismatch.phpQ�!�\Qiܶ1vendor/symfony/debug/Tests/Fixtures/PEARClass.phpB�!�\B�[���2vendor/symfony/debug/Tests/Fixtures/ClassAlias.php~�!�\~c��	�>vendor/symfony/debug/Tests/Fixtures/NonDeprecatedInterface.php{�!�\{;��t�7vendor/symfony/debug/Tests/Fixtures/ToStringThrower.php4�!�\4�f�[�2vendor/symfony/debug/Tests/Fixtures/notPsr0Bis.phpO�!�\O�����3vendor/symfony/debug/Tests/DebugClassLoaderTest.php7 �!�\7 ��K�6vendor/symfony/debug/Tests/Fixtures2/RequiredTwice.phpS�!�\S�HжWvendor/symfony/debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php=�!�\= a���Svendor/symfony/debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php}�!�\}��`�Uvendor/symfony/debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php��!�\�۪���=vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.phpk!�!�\k!e�냶Mvendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.phpu�!�\u�j�Ivendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php7�!�\7�j/=�Evendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php�!�\ĹBV�Kvendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.phpN�!�\N�o-�3vendor/symfony/debug/Exception/FlattenException.php��!�\�H���6vendor/symfony/debug/Exception/FatalErrorException.php��!�\��fz�6vendor/symfony/debug/Exception/FatalThrowableError.phpD�!�\D���;vendor/symfony/debug/Exception/UndefinedMethodException.php��!�\��L�:�7vendor/symfony/debug/Exception/OutOfMemoryException.php~�!�\~�o�8vendor/symfony/debug/Exception/ContextErrorException.php��!�\�-
d2�=vendor/symfony/debug/Exception/UndefinedFunctionException.php��!�\��G�n�9vendor/symfony/debug/Exception/ClassNotFoundException.php��!�\�n����1vendor/symfony/debug/Exception/DummyException.php�!�\-"�d�5vendor/symfony/config/ConfigCacheFactoryInterface.php��!�\�3j-c�,vendor/symfony/config/ConfigCacheFactory.php2�!�\2�!�R�4vendor/symfony/config/Definition/ReferenceDumper.php��!�\�����;vendor/symfony/config/Definition/ConfigurationInterface.php��!�\�<@P�1vendor/symfony/config/Definition/VariableNode.php��!�\�K짚�2vendor/symfony/config/Definition/NodeInterface.php��!�\�`�P�0vendor/symfony/config/Definition/BooleanNode.php.�!�\.Vp��;vendor/symfony/config/Definition/Builder/NodeDefinition.php��!�\����=�@vendor/symfony/config/Definition/Builder/NodeParentInterface.phpo�!�\o�vr�@vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php��!�\�~]�Bvendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php|�!�\|FVn��Bvendor/symfony/config/Definition/Builder/NumericNodeDefinition.phph�!�\h�p��>vendor/symfony/config/Definition/Builder/ValidationBuilder.php��!�\�v�8vendor/symfony/config/Definition/Builder/ExprBuilder.php:	�!�\:	���+�8vendor/symfony/config/Definition/Builder/TreeBuilder.php��!�\�`1��9vendor/symfony/config/Definition/Builder/MergeBuilder.php��!�\�u��l�Bvendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php;�!�\;�1�R�Avendor/symfony/config/Definition/Builder/NormalizationBuilder.phpS�!�\S��8vendor/symfony/config/Definition/Builder/NodeBuilder.php	�!�\	܄ݶ?vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php��!�\�uU�4�@vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php5�!�\5,�O��Avendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php!�!�\!z�ƶCvendor/symfony/config/Definition/Builder/VariableNodeDefinition.php��!�\��;��Jvendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php��!�\�>�#?�.vendor/symfony/config/Definition/ArrayNode.phpu�!�\u#=��.vendor/symfony/config/Definition/Processor.php��!�\����v�>vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php�!�\�1�J�?vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php[�!�\[���E�.vendor/symfony/config/Definition/FloatNode.php�!�\QT���-vendor/symfony/config/Definition/EnumNode.php��!�\���%D�8vendor/symfony/config/Definition/PrototypedArrayNode.php$�!�\$��,B�0vendor/symfony/config/Definition/IntegerNode.php��!�\�T�0vendor/symfony/config/Definition/NumericNode.php9�!�\9}ض/vendor/symfony/config/Definition/ScalarNode.phpc�!�\c(
G�-vendor/symfony/config/Definition/BaseNode.phpK�!�\KI&p�Jvendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php��!�\��ۙZ�Ivendor/symfony/config/Definition/Exception/InvalidDefinitionException.php��!�\��1�Dvendor/symfony/config/Definition/Exception/DuplicateKeyException.php��!�\����a�Lvendor/symfony/config/Definition/Exception/InvalidConfigurationException.php��!�\�kƶCvendor/symfony/config/Definition/Exception/InvalidTypeException.php��!�\����8vendor/symfony/config/Definition/Exception/Exception.php}�!�\}����@vendor/symfony/config/Definition/Exception/UnsetKeyException.php~�!�\~���_�;vendor/symfony/config/Definition/PrototypeNodeInterface.php��!�\��*/׶;vendor/symfony/config/ResourceCheckerConfigCacheFactory.php��!�\�rc���@vendor/symfony/config/Resource/SelfCheckingResourceInterface.php��!�\����[�>vendor/symfony/config/Resource/SelfCheckingResourceChecker.php��!�\��Ռg�8vendor/symfony/config/Resource/FileExistenceResource.php��!�\�'���/vendor/symfony/config/Resource/FileResource.php�!�\E�_�=vendor/symfony/config/Resource/BCResourceInterfaceChecker.php"�!�\"��ȶ4vendor/symfony/config/Resource/DirectoryResource.phpW�!�\Wh�4vendor/symfony/config/Resource/ResourceInterface.php��!�\�	�(ö%vendor/symfony/config/FileLocator.php"�!�\"���ȶ.vendor/symfony/config/FileLocatorInterface.php��!�\�3�5>�/vendor/symfony/config/Loader/LoaderResolver.php}�!�\}�pݶ+vendor/symfony/config/Loader/FileLoader.php�!�\0j��8vendor/symfony/config/Loader/LoaderResolverInterface.php��!�\��Kj�1vendor/symfony/config/Loader/DelegatingLoader.php`�!�\` �޶0vendor/symfony/config/Loader/LoaderInterface.php=�!�\=�n+��'vendor/symfony/config/Loader/Loader.php�!�\��(�'vendor/symfony/config/Util/XmlUtils.php2�!�\2�ݚ�2vendor/symfony/config/ResourceCheckerInterface.php+�!�\+���d�>vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php�
�!�\�
�k�4vendor/symfony/config/Tests/Definition/MergeTest.php�
�!�\�
!&y�:vendor/symfony/config/Tests/Definition/BooleanNodeTest.php��!�\��4]��Jvendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php(�!�\(�rG��Ivendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php��!�\�׀��Bvendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.phpE
�!�\E
Wg���Bvendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php�!�\Y9�7�Bvendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.phpo�!�\o�Aȉ�Lvendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php��!�\����
�8vendor/symfony/config/Tests/Definition/ArrayNodeTest.php��!�\�š�r�9vendor/symfony/config/Tests/Definition/ScalarNodeTest.php�	�!�\�	�X��;vendor/symfony/config/Tests/Definition/FinalizationTest.php��!�\��c)ѶIvendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php��!�\��=жHvendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.phps�!�\s���
�8vendor/symfony/config/Tests/Definition/FloatNodeTest.php��!�\�o��]�<vendor/symfony/config/Tests/Definition/NormalizationTest.php��!�\���Mz�:vendor/symfony/config/Tests/Definition/IntegerNodeTest.php��!�\�2x��Bvendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php��!�\�$�K��7vendor/symfony/config/Tests/Definition/EnumNodeTest.phpw�!�\w�Z�ݶ9vendor/symfony/config/Tests/Resource/FileResourceTest.php�!�\e�}߶5vendor/symfony/config/Tests/Resource/ResourceStub.php��!�\���ѐ�>vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php,�!�\,ҢZ�Bvendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php��!�\����6vendor/symfony/config/Tests/ConfigCacheFactoryTest.phpS�!�\S
��1vendor/symfony/config/Tests/Loader/LoaderTest.phpl�!�\lrN�Ҷ;vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php	�!�\	>C�G�9vendor/symfony/config/Tests/Loader/LoaderResolverTest.php��!�\�̶4�5vendor/symfony/config/Tests/Loader/FileLoaderTest.php�
�!�\�
��A<�1vendor/symfony/config/Tests/Util/XmlUtilsTest.php��!�\���*�/vendor/symfony/config/Tests/ConfigCacheTest.php��!�\��xz�Kvendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php��!�\��]��Bvendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php��!�\���aZ�<vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php�!�\��i�Gvendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php��!�\�1W��/vendor/symfony/config/Tests/FileLocatorTest.php�!�\��LնEvendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php?	�!�\?	
�(�%vendor/symfony/config/ConfigCache.php4�!�\4+�OI�4vendor/symfony/config/ResourceCheckerConfigCache.php	�!�\	T��ȶ;vendor/symfony/config/Exception/FileLoaderLoadException.php��!�\���I�Nvendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php��!�\�i~�|�.vendor/symfony/config/ConfigCacheInterface.php�!�\r,�C�(vendor/symfony/filesystem/Filesystem.php�.�!�\�.�L{�)vendor/symfony/filesystem/LockHandler.php��!�\���Ŷ3vendor/symfony/filesystem/Tests/LockHandlerTest.php��!�\�� :��6vendor/symfony/filesystem/Tests/FilesystemTestCase.phpx
�!�\x
�7,�Bvendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php�!�\.��l�2vendor/symfony/filesystem/Tests/FilesystemTest.php�t�!�\�t�H�1vendor/symfony/filesystem/Tests/ExceptionTest.php�!�\����<vendor/symfony/filesystem/Exception/IOExceptionInterface.php��!�\�j�wM�:vendor/symfony/filesystem/Exception/ExceptionInterface.phpi�!�\i$ ���3vendor/symfony/filesystem/Exception/IOException.php��!�\���#Ѷ=vendor/symfony/filesystem/Exception/FileNotFoundException.php��!�\�p�\��-vendor/symfony/polyfill-mbstring/Mbstring.php�4�!�\�4^iS�@vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php�A�!�\�A�	Ͷ@vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php2A�!�\2A�=��.vendor/symfony/polyfill-mbstring/bootstrap.php��!�\�|��Ҷ8vendor/symfony/dependency-injection/SimpleXMLElement.phpo�!�\o!��Vvendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php��!�\���E��Tvendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.phpt�!�\t#"j�Fvendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php��!�\��+��Kvendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.phpz�!�\z,�eǶ;vendor/symfony/dependency-injection/DefinitionDecorator.php�
�!�\�
ׁ"��@vendor/symfony/dependency-injection/TaggedContainerInterface.php��!�\�
ض-vendor/symfony/dependency-injection/Scope.php��!�\��5[�1vendor/symfony/dependency-injection/Container.php�&�!�\�&4�,�6vendor/symfony/dependency-injection/ScopeInterface.php��!�\��h(s�8vendor/symfony/dependency-injection/ContainerBuilder.php�I�!�\�Iv��:vendor/symfony/dependency-injection/ExpressionLanguage.php��!�\���2۶1vendor/symfony/dependency-injection/Reference.php��!�\��'�X�Hvendor/symfony/dependency-injection/IntrospectableContainerInterface.php��!�\���i�:vendor/symfony/dependency-injection/ContainerInterface.phpj�!�\j3�dž�8vendor/symfony/dependency-injection/Dumper/PhpDumper.php=��!�\=��#�~�8vendor/symfony/dependency-injection/Dumper/XmlDumper.phpo#�!�\o#@��ٶ5vendor/symfony/dependency-injection/Dumper/Dumper.php6�!�\6�բ�9vendor/symfony/dependency-injection/Dumper/YamlDumper.php�!�\{��=vendor/symfony/dependency-injection/Dumper/GraphvizDumper.phpP�!�\P��a�>vendor/symfony/dependency-injection/Dumper/DumperInterface.php��!�\����0vendor/symfony/dependency-injection/Variable.php��!�\���@��<vendor/symfony/dependency-injection/Loader/PhpFileLoader.php>�!�\>�K�e�<vendor/symfony/dependency-injection/Loader/XmlFileLoader.php�8�!�\�8^�c�9vendor/symfony/dependency-injection/Loader/FileLoader.php��!�\��Ų��>vendor/symfony/dependency-injection/Loader/DirectoryLoader.php��!�\���a��<vendor/symfony/dependency-injection/Loader/IniFileLoader.php��!�\�|E
�<vendor/symfony/dependency-injection/Loader/ClosureLoader.php�!�\x��¶=vendor/symfony/dependency-injection/Loader/YamlFileLoader.php
1�!�\
1���ضGvendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php.�!�\.���Avendor/symfony/dependency-injection/ParameterBag/ParameterBag.php��!�\�;�ֶJvendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php��!�\��C�<�Hvendor/symfony/dependency-injection/Tests/LegacyContainerBuilderTest.php��!�\�ޕ�V�;vendor/symfony/dependency-injection/Tests/ContainerTest.php8X�!�\8X����`vendor/symfony/dependency-injection/Tests/LazyProxy/Instantiator/RealServiceInstantiatorTest.php��!�\�V.kt�Pvendor/symfony/dependency-injection/Tests/LazyProxy/PhpDumper/NullDumperTest.phpX�!�\X��Evendor/symfony/dependency-injection/Tests/DefinitionDecoratorTest.phpM
�!�\M
�|K�<vendor/symfony/dependency-injection/Tests/DefinitionTest.php�0�!�\�0(߽�Bvendor/symfony/dependency-injection/Tests/ContainerBuilderTest.php��!�\�˴���;vendor/symfony/dependency-injection/Tests/ReferenceTest.phpD�!�\D��\�Cvendor/symfony/dependency-injection/Tests/Dumper/YamlDumperTest.php�
�!�\�
��3�Bvendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php/�!�\/�jnڶGvendor/symfony/dependency-injection/Tests/Dumper/GraphvizDumperTest.php�!�\���Bvendor/symfony/dependency-injection/Tests/Dumper/PhpDumperTest.php3-�!�\3-{�EɶHvendor/symfony/dependency-injection/Tests/Loader/DirectoryLoaderTest.php�	�!�\�	�Q�Gvendor/symfony/dependency-injection/Tests/Loader/YamlFileLoaderTest.php>=�!�\>=`q���Fvendor/symfony/dependency-injection/Tests/Loader/IniFileLoaderTest.php��!�\�X�M�Fvendor/symfony/dependency-injection/Tests/Loader/ClosureLoaderTest.phpo�!�\or�vٶFvendor/symfony/dependency-injection/Tests/Loader/PhpFileLoaderTest.php��!�\�+V��Fvendor/symfony/dependency-injection/Tests/Loader/XmlFileLoaderTest.php�k�!�\�k��9m�<vendor/symfony/dependency-injection/Tests/CrossCheckTest.php
�!�\
vG~�Kvendor/symfony/dependency-injection/Tests/ParameterBag/ParameterBagTest.php�-�!�\�-�'ܡ�Qvendor/symfony/dependency-injection/Tests/ParameterBag/FrozenParameterBagTest.php|�!�\|����;vendor/symfony/dependency-injection/Tests/ParameterTest.php��!�\�i�B?�Gvendor/symfony/dependency-injection/Tests/Fixtures/directory/simple.php/�!�\/�v���Evendor/symfony/dependency-injection/Tests/Fixtures/php/services19.php��!�\�ZG�{�Evendor/symfony/dependency-injection/Tests/Fixtures/php/services24.php!�!�\!Я`��Evendor/symfony/dependency-injection/Tests/Fixtures/php/services13.phpx�!�\x�FB�Evendor/symfony/dependency-injection/Tests/Fixtures/php/services10.php�	�!�\�	�:'�Evendor/symfony/dependency-injection/Tests/Fixtures/php/services12.php��!�\�3�b�Fvendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php��!�\�g�	�Avendor/symfony/dependency-injection/Tests/Fixtures/php/simple.php/�!�\/��ɶMvendor/symfony/dependency-injection/Tests/Fixtures/php/services9_compiled.php��!�\��H�Dvendor/symfony/dependency-injection/Tests/Fixtures/php/services8.php��!�\�9���Dvendor/symfony/dependency-injection/Tests/Fixtures/php/services9.php��!�\�XtQ��Evendor/symfony/dependency-injection/Tests/Fixtures/php/services20.php<�!�\<UF�Dvendor/symfony/dependency-injection/Tests/Fixtures/php/services1.php��!�\����Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container21.php�!�\�k5<�Tvendor/symfony/dependency-injection/Tests/Fixtures/containers/legacy-container18.php2�!�\2�ξ5�Lvendor/symfony/dependency-injection/Tests/Fixtures/containers/container8.php~�!�\~��-u�Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container15.php��!�\�)�呶Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php�!�\�i|�Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container16.php��!�\�a���Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container17.php��!�\�t.R�Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container19.php��!�\���!��Lvendor/symfony/dependency-injection/Tests/Fixtures/containers/container9.php��!�\��Mb)�Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container13.phpC�!�\CT��3�Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container20.php�!�\O�}+�Svendor/symfony/dependency-injection/Tests/Fixtures/containers/legacy-container9.phpM�!�\M���ŶMvendor/symfony/dependency-injection/Tests/Fixtures/containers/container11.php+�!�\+Zrlz�Mvendor/symfony/dependency-injection/Tests/Fixtures/containers/container12.php�!�\u��ĶMvendor/symfony/dependency-injection/Tests/Fixtures/containers/container10.php3�!�\3�!XȶMvendor/symfony/dependency-injection/Tests/Fixtures/containers/container24.php!�!�\!g��g�Gvendor/symfony/dependency-injection/Tests/Fixtures/CustomDefinition.php��!�\��R���Cvendor/symfony/dependency-injection/Tests/Fixtures/includes/foo.phpS�!�\S�zB�Wvendor/symfony/dependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtension.php�!�\���Jvendor/symfony/dependency-injection/Tests/Fixtures/includes/createphar.php�!�\U��@�Pvendor/symfony/dependency-injection/Tests/Fixtures/includes/ProjectExtension.php&�!�\&�u��Gvendor/symfony/dependency-injection/Tests/Fixtures/includes/classes.phpU�!�\UP��s�Evendor/symfony/dependency-injection/Tests/Extension/ExtensionTest.php��!�\��[y(�]vendor/symfony/dependency-injection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php	�!�\	+��Pvendor/symfony/dependency-injection/Tests/Compiler/ExtensionCompilerPassTest.php��!�\�y0v�gvendor/symfony/dependency-injection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php	�!�\	��E�Yvendor/symfony/dependency-injection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php:
�!�\:
'1��Vvendor/symfony/dependency-injection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php
�!�\
�xd�Wvendor/symfony/dependency-injection/Tests/Compiler/InlineServiceDefinitionsPassTest.php��!�\�yC���Wvendor/symfony/dependency-injection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php��!�\�#��Ovendor/symfony/dependency-injection/Tests/Compiler/DecoratorServicePassTest.php�!�\�\��Zvendor/symfony/dependency-injection/Tests/Compiler/MergeExtensionConfigurationPassTest.php[
�!�\[
3'��[vendor/symfony/dependency-injection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php�
�!�\�
T���avendor/symfony/dependency-injection/Tests/Compiler/LegacyResolveParameterPlaceHoldersPassTest.phpA�!�\Ah��w�Vvendor/symfony/dependency-injection/Tests/Compiler/CheckCircularReferencesPassTest.php�!�\�4"�Uvendor/symfony/dependency-injection/Tests/Compiler/CheckReferenceValidityPassTest.php	�!�\	v�2w�Ovendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php��!�\��;�϶Fvendor/symfony/dependency-injection/Tests/Compiler/IntegrationTest.php��!�\�M
F,�Vvendor/symfony/dependency-injection/Tests/Compiler/CheckDefinitionValidityPassTest.php�	�!�\�	��08�Wvendor/symfony/dependency-injection/Tests/Compiler/ResolveInvalidReferencesPassTest.php��!�\�i�$�Kvendor/symfony/dependency-injection/Tests/Compiler/OptionalServiceClass.php��!�\�9�5��Yvendor/symfony/dependency-injection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.phpc#�!�\c#5=���Gvendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php;�!�\;����Bvendor/symfony/dependency-injection/Tests/LegacyDefinitionTest.php�!�\7����2vendor/symfony/dependency-injection/Definition.php{'�!�\{'_�(��Kvendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php��!�\�a��E�Dvendor/symfony/dependency-injection/Extension/ExtensionInterface.phpv�!�\vtC��;vendor/symfony/dependency-injection/Extension/Extension.php�!�\��Ӵ�Qvendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.phpR�!�\Rh3U9�;vendor/symfony/dependency-injection/ContainerAwareTrait.php��!�\�H]���1vendor/symfony/dependency-injection/Parameter.php��!�\��@F<�Bvendor/symfony/dependency-injection/ExpressionLanguageProvider.php��!�\�?�`ٶFvendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php��!�\�� ��Evendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php�!�\��(��Mvendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php��!�\�sb3�Qvendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.phpg�!�\gV�Q�Jvendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php��!�\�����Mvendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php��!�\��~β�;vendor/symfony/dependency-injection/Compiler/PassConfig.php�!�\�&�Fvendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php��!�\��+�)�Lvendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php��!�\��n�Pvendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php��!�\�mPw�Nvendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.phpC�!�\C�[���Kvendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php
�!�\
jJn�Ivendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php=�!�\=4q s�Ovendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php�	�!�\�	G��D�Ovendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.phpc�!�\cROU��Jvendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.phpB�!�\BndB��]vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php��!�\���Avendor/symfony/dependency-injection/Compiler/LoggingFormatter.php�!�\�Tܶ9vendor/symfony/dependency-injection/Compiler/Compiler.phpU�!�\U!��4�=vendor/symfony/dependency-injection/Compiler/AutowirePass.php_�!�\_��DR�=vendor/symfony/dependency-injection/Compiler/RepeatedPass.php��!�\�����Svendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php��!�\���*#�Hvendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php��!�\��I�j�Mvendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php��!�\�BMH�Lvendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.phpy	�!�\y	y�W�Lvendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php��!�\��W�Fvendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php��!�\�je1t�Evendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php^�!�\^���-vendor/symfony/dependency-injection/Alias.php��!�\�
��Uvendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php�!�\���@vendor/symfony/dependency-injection/Exception/LogicException.php��!�\�O��Y�Jvendor/symfony/dependency-injection/Exception/ServiceNotFoundException.phpy�!�\y]Ln�Dvendor/symfony/dependency-injection/Exception/ExceptionInterface.phps�!�\s-l�I�Qvendor/symfony/dependency-injection/Exception/ScopeWideningInjectionException.phpQ�!�\QBR�t�Hvendor/symfony/dependency-injection/Exception/BadMethodCallException.php��!�\��hڀ�Hvendor/symfony/dependency-injection/Exception/InactiveScopeException.php-�!�\-2߫�Qvendor/symfony/dependency-injection/Exception/ScopeCrossingInjectionException.php>�!�\>o,b]�Fvendor/symfony/dependency-injection/Exception/OutOfBoundsException.php��!�\�T~셶Lvendor/symfony/dependency-injection/Exception/ParameterNotFoundException.phpH�!�\H:]n�Jvendor/symfony/dependency-injection/Exception/InvalidArgumentException.php��!�\���K�Svendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.phpB�!�\B�A'ɶBvendor/symfony/dependency-injection/Exception/RuntimeException.php��!�\�C�ן�?vendor/symfony/dependency-injection/ContainerAwareInterface.php��!�\�c%��Dvendor/symfony/dependency-injection/ResettableContainerInterface.php��!�\�����6vendor/symfony/dependency-injection/ContainerAware.php�!�\Qz���.vendor/symfony/process/PhpExecutableFinder.phpg�!�\g���+vendor/symfony/process/ExecutableFinder.php��!�\���m��Dvendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php��!�\��cu��3vendor/symfony/process/Tests/ProcessBuilderTest.phpr�!�\r��G�8vendor/symfony/process/Tests/PhpExecutableFinderTest.php%
�!�\%
��~�5vendor/symfony/process/Tests/ExecutableFinderTest.php�
�!�\�
��f�/vendor/symfony/process/Tests/SignalListener.php��!�\��"���1vendor/symfony/process/Tests/ProcessUtilsTest.php��!�\�ţ�ܶ,vendor/symfony/process/Tests/ProcessTest.php�n�!�\�n�(�+�;vendor/symfony/process/Tests/ProcessFailedExceptionTest.php�
�!�\�
�{�/vendor/symfony/process/Tests/PhpProcessTest.php�!�\L�+�3vendor/symfony/process/Tests/NonStopableProcess.php��!�\����%vendor/symfony/process/PhpProcess.php��!�\�_�9�)vendor/symfony/process/ProcessBuilder.php�
�!�\�
ʧ���"vendor/symfony/process/Process.php�R�!�\�R+���-vendor/symfony/process/Pipes/WindowsPipes.php��!�\���h�.vendor/symfony/process/Pipes/AbstractPipes.php^�!�\^%s��*vendor/symfony/process/Pipes/UnixPipes.php��!�\�ȥ�/vendor/symfony/process/Pipes/PipesInterface.phpD�!�\Dv�'vendor/symfony/process/ProcessUtils.phpK�!�\K��~�3vendor/symfony/process/Exception/LogicException.php��!�\� ���=vendor/symfony/process/Exception/ProcessTimedOutException.php�!�\.	��7vendor/symfony/process/Exception/ExceptionInterface.phpf�!�\f]�>T�=vendor/symfony/process/Exception/InvalidArgumentException.php��!�\��+_�;vendor/symfony/process/Exception/ProcessFailedException.phpx�!�\x��zy�5vendor/symfony/process/Exception/RuntimeException.php��!�\���:�/vendor/symfony/console/Logger/ConsoleLogger.php<	�!�\<	:��l�,vendor/symfony/console/Style/OutputStyle.php_�!�\_���-vendor/symfony/console/Style/SymfonyStyle.php��!�\���Pg�/vendor/symfony/console/Style/StyleInterface.php��!�\����j�(vendor/symfony/console/ConsoleEvents.php��!�\�
�H��<vendor/symfony/console/Descriptor/ApplicationDescription.php��!�\����7�4vendor/symfony/console/Descriptor/TextDescriptor.phpi�!�\i���4vendor/symfony/console/Descriptor/JsonDescriptor.php�
�!�\�
l��9vendor/symfony/console/Descriptor/DescriptorInterface.php��!�\��Q��8vendor/symfony/console/Descriptor/MarkdownDescriptor.php��!�\�k�.a�3vendor/symfony/console/Descriptor/XmlDescriptor.php�!�\�P$�0vendor/symfony/console/Descriptor/Descriptor.php��!�\�;~Ķ vendor/symfony/console/Shell.php��!�\��f���,vendor/symfony/console/Question/Question.php#
�!�\#
e� �8vendor/symfony/console/Question/ConfirmationQuestion.php��!�\��Q@�2vendor/symfony/console/Question/ChoiceQuestion.php"
�!�\"
_ΰ��/vendor/symfony/console/Tester/CommandTester.php��!�\�Eٚ|�3vendor/symfony/console/Tester/ApplicationTester.php��!�\���d�&vendor/symfony/console/Application.php.W�!�\.W�'��9vendor/symfony/console/Formatter/OutputFormatterStyle.phpL�!�\L��8<�>vendor/symfony/console/Formatter/OutputFormatterStyleStack.phpL�!�\L.=b�4vendor/symfony/console/Formatter/OutputFormatter.php!�!�\!��wx�Bvendor/symfony/console/Formatter/OutputFormatterStyleInterface.php��!�\��Rڭ�=vendor/symfony/console/Formatter/OutputFormatterInterface.php��!�\�:��6vendor/symfony/console/Helper/DebugFormatterHelper.phpx�!�\xN�ؼ�2vendor/symfony/console/Helper/DescriptorHelper.phpz�!�\zf���1vendor/symfony/console/Helper/HelperInterface.php��!�\����2vendor/symfony/console/Helper/InputAwareHelper.phpc�!�\c�|�+vendor/symfony/console/Helper/HelperSet.php��!�\�a�~
�0vendor/symfony/console/Helper/ProgressHelper.php\�!�\\?��-vendor/symfony/console/Helper/TableHelper.php�!�\�pm��/vendor/symfony/console/Helper/ProcessHelper.php�	�!�\�	@�ぶ0vendor/symfony/console/Helper/TableSeparator.php��!�\�Q�a��0vendor/symfony/console/Helper/QuestionHelper.php��!�\��b��'vendor/symfony/console/Helper/Table.php*�!�\*��}�1vendor/symfony/console/Helper/FormatterHelper.phpc�!�\c���N�.vendor/symfony/console/Helper/DialogHelper.php��!�\�hX�ö7vendor/symfony/console/Helper/SymfonyQuestionHelper.phpl
�!�\l
��L�-vendor/symfony/console/Helper/ProgressBar.phps%�!�\s%鯦��(vendor/symfony/console/Helper/Helper.php�!�\��<��3vendor/symfony/console/Helper/ProgressIndicator.phpK�!�\K�Ͱ�,vendor/symfony/console/Helper/TableStyle.php
�!�\
P޵��+vendor/symfony/console/Helper/TableCell.php��!�\��*��8vendor/symfony/console/Output/ConsoleOutputInterface.php��!�\�rN��/vendor/symfony/console/Output/ConsoleOutput.php��!�\�
�S\�,vendor/symfony/console/Output/NullOutput.php��!�\����Z�.vendor/symfony/console/Output/StreamOutput.php��!�\��핶(vendor/symfony/console/Output/Output.php�	�!�\�	01 ��0vendor/symfony/console/Output/BufferedOutput.php_�!�\_�Bͷ�1vendor/symfony/console/Output/OutputInterface.php�!�\��>�4vendor/symfony/console/Event/ConsoleCommandEvent.php��!�\�Zk�2�6vendor/symfony/console/Event/ConsoleTerminateEvent.phpz�!�\z�,�L�-vendor/symfony/console/Event/ConsoleEvent.php��!�\��x�\�6vendor/symfony/console/Event/ConsoleExceptionEvent.php�!�\�2�9vendor/symfony/console/Tests/Logger/ConsoleLoggerTest.phpX�!�\X���7vendor/symfony/console/Tests/Style/SymfonyStyleTest.php��!�\�˝�A�>vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.phpa�!�\aq���=vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php0�!�\0���l�Bvendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.phpl�!�\l4��ضBvendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php�
�!�\�
�n�S�>vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php��!�\�[��ʶ;vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php�!�\Y�B�0vendor/symfony/console/Tests/ApplicationTest.phpL��!�\L�VPnO�9vendor/symfony/console/Tests/Tester/CommandTesterTest.php	�!�\	1��W�=vendor/symfony/console/Tests/Tester/ApplicationTesterTest.php��!�\�	1%�Hvendor/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.phpq�!�\q�6�!�Cvendor/symfony/console/Tests/Formatter/OutputFormatterStyleTest.phpO
�!�\O
pа¶>vendor/symfony/console/Tests/Formatter/OutputFormatterTest.php\�!�\\��p�2vendor/symfony/console/Tests/Helper/HelperTest.php-�!�\-w��>�:vendor/symfony/console/Tests/Helper/QuestionHelperTest.php(;�!�\(;EKڶ1vendor/symfony/console/Tests/Helper/TableTest.phpEN�!�\EN�Ɣ��Avendor/symfony/console/Tests/Helper/SymfonyQuestionHelperTest.php��!�\��x�>�5vendor/symfony/console/Tests/Helper/HelperSetTest.php2�!�\2�N�;vendor/symfony/console/Tests/Helper/FormatterHelperTest.php	�!�\	��ᡶ=vendor/symfony/console/Tests/Helper/LegacyTableHelperTest.phpd"�!�\d"�;绶9vendor/symfony/console/Tests/Helper/ProcessHelperTest.phps�!�\sPޫB�=vendor/symfony/console/Tests/Helper/ProgressIndicatorTest.php{�!�\{v!nö6vendor/symfony/console/Tests/Helper/TableStyleTest.php.�!�\.���ʶ>vendor/symfony/console/Tests/Helper/LegacyDialogHelperTest.php�%�!�\�%����@vendor/symfony/console/Tests/Helper/LegacyProgressHelperTest.phpL�!�\L��>Ͷ7vendor/symfony/console/Tests/Helper/ProgressBarTest.php'D�!�\'DG�1W�6vendor/symfony/console/Tests/Output/NullOutputTest.php��!�\�TW�~�9vendor/symfony/console/Tests/Output/ConsoleOutputTest.php?�!�\?tl�k�8vendor/symfony/console/Tests/Output/StreamOutputTest.php��!�\��&�ݶ2vendor/symfony/console/Tests/Output/OutputTest.php��!�\�K�l��<vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.phpV�!�\V��1�Bvendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php�!�\��ZY�Bvendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php�!�\tq�7vendor/symfony/console/Tests/Fixtures/FoobarCommand.php��!�\��g��Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php�!�\q��Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php!�!�\!/�Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.phpi�!�\i0�ֲ�Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php|�!�\|7��Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_17.php��!�\��!�ڶOvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php@�!�\@9̣F�Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php�!�\�zذ�Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php��!�\���(��Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php��!�\��|���Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.phpD�!�\D��u�Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php��!�\�b���Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php��!�\����Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php1�!�\1}���Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.phpv�!�\v�I8��Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php��!�\���9�Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php��!�\��<�k�Nvendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.phpi�!�\iT+z�Ovendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.phpN�!�\N2�&�5vendor/symfony/console/Tests/Fixtures/Foo3Command.php��!�\�����5vendor/symfony/console/Tests/Fixtures/Foo4Command.php��!�\���{_�<vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php\�!�\\4q�
�5vendor/symfony/console/Tests/Fixtures/Foo6Command.php��!�\��Y�@vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.phpK�!�\K9��4vendor/symfony/console/Tests/Fixtures/FooCommand.php��!�\�s�o�5vendor/symfony/console/Tests/Fixtures/DummyOutput.php��!�\�mq	��@vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php��!�\���K��5vendor/symfony/console/Tests/Fixtures/TestCommand.phpF�!�\Fq:[M�Gvendor/symfony/console/Tests/Fixtures/DescriptorApplicationMbString.php,�!�\,�Uڶ�7vendor/symfony/console/Tests/Fixtures/BarBucCommand.php��!�\�����5vendor/symfony/console/Tests/Fixtures/Foo1Command.php��!�\�]!�6�Cvendor/symfony/console/Tests/Fixtures/DescriptorCommandMbString.phpi�!�\i�)�5vendor/symfony/console/Tests/Fixtures/Foo5Command.php�!�\�+��5vendor/symfony/console/Tests/Fixtures/Foo2Command.php��!�\��a#4�4vendor/symfony/console/Tests/Input/ArgvInputTest.php�:�!�\�:�6�:vendor/symfony/console/Tests/Input/InputDefinitionTest.php�:�!�\�:�"���6vendor/symfony/console/Tests/Input/StringInputTest.php�!�\��v�5vendor/symfony/console/Tests/Input/ArrayInputTest.php��!�\�h�N��6vendor/symfony/console/Tests/Input/InputOptionTest.php��!�\�|�e*�0vendor/symfony/console/Tests/Input/InputTest.php��!�\�KV��8vendor/symfony/console/Tests/Input/InputArgumentTest.php�
�!�\�
��ZP�8vendor/symfony/console/Tests/Command/ListCommandTest.php�
�!�\�
2��4vendor/symfony/console/Tests/Command/CommandTest.php�;�!�\�;�,�Ƕ8vendor/symfony/console/Tests/Command/HelpCommandTest.php8�!�\8M�"Ķ4vendor/symfony/console/Input/InputAwareInterface.php��!�\��jT��0vendor/symfony/console/Input/InputDefinition.php��!�\�0Oly�&vendor/symfony/console/Input/Input.php��!�\���.vendor/symfony/console/Input/InputArgument.php�!�\����+vendor/symfony/console/Input/ArrayInput.php_
�!�\_
[��ɶ,vendor/symfony/console/Input/StringInput.php��!�\� ڤ�,vendor/symfony/console/Input/InputOption.php�!�\����*vendor/symfony/console/Input/ArgvInput.php�!�\����/vendor/symfony/console/Input/InputInterface.php��!�\��R6۶.vendor/symfony/console/Command/ListCommand.phpZ�!�\Zɣ��.vendor/symfony/console/Command/HelpCommand.php��!�\�.ؙu�*vendor/symfony/console/Command/Command.php�#�!�\�#��+!�3vendor/symfony/console/Exception/LogicException.php��!�\��O\e�;vendor/symfony/console/Exception/InvalidOptionException.php��!�\���H�7vendor/symfony/console/Exception/ExceptionInterface.phpf�!�\f�AB��=vendor/symfony/console/Exception/CommandNotFoundException.php��!�\�� L�=vendor/symfony/console/Exception/InvalidArgumentException.php��!�\��̽Z�5vendor/symfony/console/Exception/RuntimeException.php��!�\���,6�1vendor/padraic/phar-updater/src/VersionParser.php&
�!�\&
'p�+vendor/padraic/phar-updater/src/Updater.php( �!�\( SK�"�Bvendor/padraic/phar-updater/src/Exception/NoSignatureException.phpo�!�\o"}<�@vendor/padraic/phar-updater/src/Exception/ExceptionInterface.phpX�!�\Xcu�,�Bvendor/padraic/phar-updater/src/Exception/HttpRequestException.phpo�!�\oD��Bvendor/padraic/phar-updater/src/Exception/JsonParsingException.phpo�!�\oZ�?�Fvendor/padraic/phar-updater/src/Exception/InvalidArgumentException.php��!�\�b"1�Avendor/padraic/phar-updater/src/Exception/FilesystemException.phpn�!�\n����>vendor/padraic/phar-updater/src/Exception/RuntimeException.php��!�\���Ћ�>vendor/padraic/phar-updater/src/Strategy/StrategyInterface.php.�!�\. c:�;vendor/padraic/phar-updater/src/Strategy/GithubStrategy.php��!�\��1$�8vendor/padraic/phar-updater/src/Strategy/ShaStrategy.phpc�!�\c�����Avendor/padraic/humbug_get_contents/src/Humbug/FileGetContents.php��!�\�H�"��3vendor/padraic/humbug_get_contents/src/function.php0�!�\0p*N�5vendor/php-http/promise/spec/FulfilledPromiseSpec.php��!�\��)�ն4vendor/php-http/promise/spec/RejectedPromiseSpec.php�!�\���J�/vendor/php-http/promise/src/RejectedPromise.phpT�!�\T$'6�'vendor/php-http/promise/src/Promise.phpX�!�\X��MW�0vendor/php-http/promise/src/FulfilledPromise.php;�!�\;���.vendor/php-http/guzzle6-adapter/src/Client.php��!�\�%$B	�/vendor/php-http/guzzle6-adapter/src/Promise.php)
�!�\)
ʸ��Avendor/php-http/httplug/spec/Promise/HttpFulfilledPromiseSpec.phpA�!�\A�S�^�@vendor/php-http/httplug/spec/Promise/HttpRejectedPromiseSpec.php��!�\���q�@vendor/php-http/httplug/spec/Exception/TransferExceptionSpec.php*�!�\*�٤��?vendor/php-http/httplug/spec/Exception/RequestExceptionSpec.phph�!�\hg�5�?vendor/php-http/httplug/spec/Exception/NetworkExceptionSpec.php��!�\���i�<vendor/php-http/httplug/spec/Exception/HttpExceptionSpec.php|�!�\|���/vendor/php-http/httplug/src/HttpAsyncClient.php��!�\�f�Ρ�<vendor/php-http/httplug/src/Promise/HttpFulfilledPromise.php��!�\���[#�;vendor/php-http/httplug/src/Promise/HttpRejectedPromise.php��!�\��΂��)vendor/php-http/httplug/src/Exception.php<�!�\<`d	�*vendor/php-http/httplug/src/HttpClient.php��!�\����:vendor/php-http/httplug/src/Exception/RequestException.php��!�\�.veζ7vendor/php-http/httplug/src/Exception/HttpException.php��!�\�ynyz�;vendor/php-http/httplug/src/Exception/TransferException.php��!�\�M��l�:vendor/php-http/httplug/src/Exception/NetworkException.phpd�!�\d'�ƶvendor/autoload.php��!�\��R�+vendor/dnoegel/php-xdg-base-dir/src/Xdg.php��!�\�P���/vendor/ramsey/array_column/src/array_column.php��!�\�Lb��Xvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php��!�\�CO�Rvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.phpb�!�\bW���Tvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php��!�\�]j�Rvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php*�!�\*-3��Gvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.phpt�!�\tI���Dvendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.phpa�!�\a�,Η�Cvendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.phpR	�!�\R	p�i1�?vendor/justinrainbow/json-schema/src/JsonSchema/RefResolver.php�
�!�\�
K$��Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php �!�\ ����Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.phpQ�!�\Qx���Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php��!�\�rق�Svendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php��!�\�^�gӶJvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php��!�\���(c�Nvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.phpx�!�\x�ّ�Svendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.phpr�!�\r�{s6�Tvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php�	�!�\�	�&�ضNvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php��!�\���ڊ�Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php��!�\��A�r�Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.phpY
�!�\Y
��Gvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php��!�\�C9S�=vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php��!�\�zD4�Wvendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.phpo�!�\o�$"ŶRvendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.phpj�!�\jS�dz�Wvendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.phpw�!�\wN-�[�Vvendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.phpv�!�\v� �"�]vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.phpv�!�\v�CӶSvendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php��!�\������2vendor/shopwarelabs/plugin-info/src/PluginInfo.php$�!�\$���I�:vendor/shopwarelabs/plugin-info/src/PluginInfoHydrator.php>�!�\>&�>�Evendor/shopwarelabs/plugin-info/src/Exceptions/ValidatorException.phpg�!�\g`��)�Fvendor/shopwarelabs/plugin-info/src/Exceptions/ConstraintException.phph�!�\h�+�ƶ3vendor/shopwarelabs/plugin-info/src/Struct/Info.php��!�\�����5vendor/shopwarelabs/plugin-info/src/InfoDecorator.php�	�!�\�	�	���:vendor/shopwarelabs/plugin-info/src/Backend/AutoDetect.php��!�\��d+�=vendor/shopwarelabs/plugin-info/src/Backend/ArrayTestCase.php��!�\�Ŋn�@vendor/shopwarelabs/plugin-info/src/Backend/BackendInterface.phpz�!�\zIJ�p�3vendor/shopwarelabs/plugin-info/src/Backend/Zip.php �!�\ �|��9vendor/shopwarelabs/plugin-info/src/Backend/Directory.php��!�\��|�k�src/DirectoryFilterIterator.phpL�!�\L����)src/Application/ConsoleAwareExtension.php��!�\��A_�+src/Application/ContainerAwareExtension.php��!�\��g�-�$src/Application/ExtensionManager.php*	�!�\*	s��[�"src/Application/CommandManager.phpe�!�\etu�W�'src/Application/DependencyInjection.php�
�!�\�
(v[�0src/Extensions/Shopware/AutoUpdate/Bootstrap.php=�!�\=����>src/Extensions/Shopware/AutoUpdate/Command/RollbackCommand.php��!�\�|q�8�@src/Extensions/Shopware/AutoUpdate/Command/SelfUpdateCommand.php$�!�\$�}��,src/Extensions/Shopware/RunCli/Bootstrap.php�!�\�X1a�8src/Extensions/Shopware/RunCli/Command/RunCliCommand.php��!�\�sE��?src/Extensions/Shopware/DataGenerator/Writer/DatabaseWriter.phpT�!�\Td��Csrc/Extensions/Shopware/DataGenerator/Writer/BufferedFileWriter.php?�!�\?X�J�@src/Extensions/Shopware/DataGenerator/Writer/WriterInterface.php��!�\�<*���>src/Extensions/Shopware/DataGenerator/Writer/WriterManager.phpM�!�\M����<src/Extensions/Shopware/DataGenerator/RandomDataProvider.php2�!�\2L�4�7src/Extensions/Shopware/DataGenerator/Struct/Config.php��!�\��X��7src/Extensions/Shopware/DataGenerator/DataGenerator.php��!�\�����3src/Extensions/Shopware/DataGenerator/Bootstrap.php�!�\0}@�8src/Extensions/Shopware/DataGenerator/ResourceLoader.php��!�\��bԖ�Asrc/Extensions/Shopware/DataGenerator/Services/LoadDataInfile.phpu�!�\uw5yٶ@src/Extensions/Shopware/DataGenerator/Resources/BaseResource.php�	�!�\�	�|��:src/Extensions/Shopware/DataGenerator/Resources/Orders.php��!�\�}��>src/Extensions/Shopware/DataGenerator/Resources/Categories.php_�!�\_��{�<src/Extensions/Shopware/DataGenerator/Resources/Articles.php�5�!�\�5���M�<src/Extensions/Shopware/DataGenerator/Resources/Vouchers.php2�!�\2J�K�>src/Extensions/Shopware/DataGenerator/Resources/Newsletter.php�	�!�\�	`׶�=src/Extensions/Shopware/DataGenerator/Resources/Customers.php��!�\�ĕ�̶Csrc/Extensions/Shopware/DataGenerator/Command/CreateDataCommand.php�!�!�\�!2!ж;src/Extensions/Shopware/Plugin/RepositoryAwareExtension.phpm�!�\m^�8�9src/Extensions/Shopware/Plugin/Struct/PluginBootstrap.php��!�\�tZ}ܶ0src/Extensions/Shopware/Plugin/Struct/Plugin.php��!�\���[m�7src/Extensions/Shopware/Plugin/Struct/DisplayPlugin.php��!�\����,src/Extensions/Shopware/Plugin/Bootstrap.phph
�!�\h
�[��4src/Extensions/Shopware/Plugin/Services/Checkout.php��!�\�8r�T�9src/Extensions/Shopware/Plugin/Services/PluginFactory.php��!�\�X/�
�:src/Extensions/Shopware/Plugin/Services/PluginProvider.php��!�\��Ͻ�Gsrc/Extensions/Shopware/Plugin/Services/Repositories/Standard/Stash.php��!�\�����Hsrc/Extensions/Shopware/Plugin/Services/Repositories/Standard/GitHub.php��!�\��uu�Lsrc/Extensions/Shopware/Plugin/Services/Repositories/Standard/SimpleList.phpc�!�\c�F@0�Ksrc/Extensions/Shopware/Plugin/Services/Repositories/Standard/BitBucket.php��!�\���b2�Gsrc/Extensions/Shopware/Plugin/Services/Repositories/BaseRepository.php�!�\>KU�Lsrc/Extensions/Shopware/Plugin/Services/Repositories/RepositoryInterface.php��!�\�;"
d�Qsrc/Extensions/Shopware/Plugin/Services/Repositories/DefaultRepositoryFactory.php��!�\����Ѷ9src/Extensions/Shopware/Plugin/Services/BootstrapInfo.php��!�\���/src/Extensions/Shopware/Plugin/Services/Zip.php+�!�\+� �H�3src/Extensions/Shopware/Plugin/Services/Install.php�	�!�\�	��哶=src/Extensions/Shopware/Plugin/Services/RepositoryManager.php?�!�\?��d�Usrc/Extensions/Shopware/Plugin/Services/ConsoleInteraction/PluginInputVerificator.php��!�\�h�ĶUsrc/Extensions/Shopware/Plugin/Services/ConsoleInteraction/PluginOperationManager.phpL	�!�\L	{�A�Ssrc/Extensions/Shopware/Plugin/Services/ConsoleInteraction/PluginColumnRenderer.php=�!�\=+r}2�5src/Extensions/Shopware/Plugin/Command/ZipCommand.php		�!�\		���0�:src/Extensions/Shopware/Plugin/Command/ZipLocalCommand.php��!�\��6�*�9src/Extensions/Shopware/Plugin/Command/InstallCommand.php�!�\һ#Ŷ>src/Extensions/Shopware/Install/Struct/InstallationRequest.phpZ	�!�\Z	��ض-src/Extensions/Shopware/Install/Bootstrap.php'�!�\'�[n��5src/Extensions/Shopware/Install/Services/Checkout.php��!�\���5src/Extensions/Shopware/Install/Services/Demodata.phpF�!�\F2=ze�8src/Extensions/Shopware/Install/Services/PostInstall.phpT
�!�\T
�[d$�>src/Extensions/Shopware/Install/Services/ReleaseDownloader.php��!�\���+�2src/Extensions/Shopware/Install/Services/Owner.php��!�\��[݊�9src/Extensions/Shopware/Install/Services/VcsGenerator.php(�!�\(6b�W�5src/Extensions/Shopware/Install/Services/Database.phpg�!�\gKM��8src/Extensions/Shopware/Install/Services/Install/Vcs.php��!�\�Q9۶<src/Extensions/Shopware/Install/Services/Install/Release.php��!�\��]�w�9src/Extensions/Shopware/Install/Services/ConfigWriter.php#�!�\#�c˶Isrc/Extensions/Shopware/Install/Command/ShopwareInstallReleaseCommand.php�!�!�\�!��A��Esrc/Extensions/Shopware/Install/Command/ShopwareClearCacheCommand.php��!�\��q��Esrc/Extensions/Shopware/Install/Command/ShopwareInstallVcsCommand.phpr�!�\r��	�>src/Extensions/Shopware/PluginCreator/Struct/Configuration.php�!�\�k�Ͷ3src/Extensions/Shopware/PluginCreator/Bootstrap.php�!�\ܢ.:�fsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/LegacyOptionFileProviderLoader.php_�!�\_�.8�^src/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/ApiFileProvider.php��!�\�����lsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/BackendControllerFileProvider.php��!�\���#��dsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/ElasticSearchProvider.phpu�!�\u���isrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/ControllerPathFileProvider.php��!�\�o̷)�bsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/CommandFileProvider.php>�!�\>��z�asrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/WidgetFileProvider.php��!�\�?�bsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/BackendFileProvider.php�!�\��;�asrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/FilterFileProvider.php/�!�\/{R`��bsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/DefaultFileProvider.phpD�!�\D�s�ƶ`src/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/ModelFileProvider.php��!�\����csrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Legacy/FrontendFileProvider.php��!�\���P��csrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/FileProviderLoaderInterface.php��!�\�.PzW�]src/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/FileProviderInterface.phpz�!�\z!_�_src/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/ApiFileProvider.php�!�\��r1�msrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/BackendControllerFileProvider.php��!�\�8�;3�esrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/ElasticSearchProvider.php|�!�\|�N���jsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/ControllerPathFileProvider.php��!�\��5�X�csrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/CommandFileProvider.php@�!�\@M9�bsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/WidgetFileProvider.php��!�\�-���csrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/BackendFileProvider.php��!�\�.�<u�bsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/FilterFileProvider.php��!�\����M�csrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/DefaultFileProvider.phpa�!�\axR(\�asrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/ModelFileProvider.php~�!�\~�hj�dsrc/Extensions/Shopware/PluginCreator/Services/TemplateFileProvider/Current/FrontendFileProvider.php��!�\�1m��Fsrc/Extensions/Shopware/PluginCreator/Services/IoAdapter/IoAdapter.php��!�\�f�5�Bsrc/Extensions/Shopware/PluginCreator/Services/IoAdapter/Dummy.phpu�!�\u�g�q�Fsrc/Extensions/Shopware/PluginCreator/Services/IoAdapter/HardDrive.php��!�\��3[_�lsrc/Extensions/Shopware/PluginCreator/Services/WorkingDirectoryProvider/OutputDirectoryProviderInterface.php��!�\�v��;�msrc/Extensions/Shopware/PluginCreator/Services/WorkingDirectoryProvider/RootDetector/ShopwareRootDetector.php�!�\�Nf?�nsrc/Extensions/Shopware/PluginCreator/Services/WorkingDirectoryProvider/RootDetector/RootDetectorInterface.php��!�\��p��jsrc/Extensions/Shopware/PluginCreator/Services/WorkingDirectoryProvider/CurrentOutputDirectoryProvider.php��!�\�G�ҙ�isrc/Extensions/Shopware/PluginCreator/Services/WorkingDirectoryProvider/LegacyOutputDirectoryProvider.php�!�\Y��Ͷ@src/Extensions/Shopware/PluginCreator/Services/NameGenerator.php_�!�\_�[w.�;src/Extensions/Shopware/PluginCreator/Services/Template.php��!�\�aӲ��Csrc/Extensions/Shopware/PluginCreator/Services/GeneratorFactory.phpE�!�\E`t�<src/Extensions/Shopware/PluginCreator/Services/Generator.phpf�!�\fò�g�Esrc/Extensions/Shopware/PluginCreator/Command/CreatePluginCommand.php�!�\�ڇ��src/ConfigFileCollector.php��!�\��/��src/Application.php��!�\��ڂ��src/Utilities.php�!�\�F��src/Cache/File.php��!�\��g��src/Cache/CacheInterface.php�!�\��pҶsrc/Struct.phpF�!�\F��1Ͷ src/Services/ProcessExecutor.phpM�!�\M��<f�%src/Services/Rest/Curl/RestClient.php��!�\�d^��#src/Services/Rest/Curl/Response.php6�!�\67�LU�'src/Services/Rest/ResponseInterface.php��!�\��}Զ(src/Services/Rest/RestServiceFactory.php�!�\�[�~�#src/Services/Rest/RestInterface.phpf�!�\f����$src/Services/Rest/CacheDecorator.php��!�\���m��%src/Services/StreamFileDownloader.php2�!�\2U��K�'src/Services/GitIdentityEnvironment.php��!�\������ src/Services/ZipUtil/Adapter.php��!�\�E:�src/Services/ZipUtil/Zip.php6�!�\6��<��"src/Services/ZipUtil/Entry/Zip.php��!�\�����src/Services/ShopwareInfo.php}�!�\}\��Զsrc/Services/IoService.php��!�\�KU���*src/Services/PathProvider/PathProvider.php�!�\=U�϶Hsrc/Services/PathProvider/DirectoryGateway/DirectoryGatewayInterface.php$�!�\$����=src/Services/PathProvider/DirectoryGateway/CliToolGateway.php��!�\����]�9src/Services/PathProvider/DirectoryGateway/XdgGateway.php��!�\��a�src/Services/GitUtil.php��!�\��P]��src/Services/FileDownloader.php��!�\�U�H� src/Services/OpenSSLVerifier.php$�!�\$o��|�src/Command/CacheGetCommand.phpV�!�\V���src/Command/BaseCommand.php��!�\��NVI�src/Command/CacheCommand.php��!�\���c��src/Config.php�!�\�Gy�/src/Extensions/Shopware/PluginCreator/README.md��!�\�i"n�Jsrc/Extensions/Shopware/PluginCreator/template/legacy/Commands/Command.tplO�!�\OE}��hsrc/Extensions/Shopware/PluginCreator/template/legacy/Components/SearchBundleDBAL/Facet/FacetHandler.tplw�!�\w��g�asrc/Extensions/Shopware/PluginCreator/template/legacy/Components/SearchBundleDBAL/Facet/Facet.tpl��!�\�w�'ɶlsrc/Extensions/Shopware/PluginCreator/template/legacy/Components/SearchBundleDBAL/CriteriaRequestHandler.tpl��!�\��2l5�isrc/Extensions/Shopware/PluginCreator/template/legacy/Components/SearchBundleDBAL/Condition/Condition.tpl��!�\�L�`0�psrc/Extensions/Shopware/PluginCreator/template/legacy/Components/SearchBundleDBAL/Condition/ConditionHandler.tpl��!�\�>V��Zsrc/Extensions/Shopware/PluginCreator/template/legacy/Components/SearchBundleES/Search.tpl��!�\��n��]src/Extensions/Shopware/PluginCreator/template/legacy/Components/ESIndexingBundle/Mapping.tpl[�!�\[(�($�asrc/Extensions/Shopware/PluginCreator/template/legacy/Components/ESIndexingBundle/DataIndexer.tpl@�!�\@<�Eöbsrc/Extensions/Shopware/PluginCreator/template/legacy/Components/ESIndexingBundle/Synchronizer.tplO�!�\O7l��^src/Extensions/Shopware/PluginCreator/template/legacy/Components/ESIndexingBundle/Provider.tpl4�!�\4_��^src/Extensions/Shopware/PluginCreator/template/legacy/Components/ESIndexingBundle/Settings.tpl��!�\�Cc'��Zsrc/Extensions/Shopware/PluginCreator/template/legacy/Components/Api/Resource/Resource.tpl��!�\��Χ�Isrc/Extensions/Shopware/PluginCreator/template/legacy/licenses/mit_sw.txt1�!�\1�h��Csrc/Extensions/Shopware/PluginCreator/template/legacy/Bootstrap.tpl&'�!�\&'�ڶQsrc/Extensions/Shopware/PluginCreator/template/legacy/Subscriber/SearchBundle.tpl=�!�\=��ضSsrc/Extensions/Shopware/PluginCreator/template/legacy/Subscriber/ControllerPath.tplo�!�\o�z*�Msrc/Extensions/Shopware/PluginCreator/template/legacy/Subscriber/Frontend.tpl-�!�\-Y8#ܶ=src/Extensions/Shopware/PluginCreator/template/legacy/LICENSE*�!�\*Ε��Nsrc/Extensions/Shopware/PluginCreator/template/legacy/Controllers/Frontend.tpln�!�\n)Ul>�Isrc/Extensions/Shopware/PluginCreator/template/legacy/Controllers/Api.tplp�!�\p>��M�Msrc/Extensions/Shopware/PluginCreator/template/legacy/Controllers/Backend.tpl�!�\��P:�@src/Extensions/Shopware/PluginCreator/template/legacy/Readme.tpl��!�\�v1zA�Psrc/Extensions/Shopware/PluginCreator/template/legacy/tests/LegacyPluginTest.tpl��!�\��D�Jsrc/Extensions/Shopware/PluginCreator/template/legacy/phpunit.xml.dist.tpl}�!�\}�AhH�Ssrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/widget/main.tpl��!�\�1�:��^src/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/model/main.tpl��!�\�\�,m�^src/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/store/main.tplO�!�\O:S�p�fsrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/view/detail/window.tplA�!�\A�ra�isrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/view/detail/container.tpl*�!�\*ӑ>V�dsrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/view/list/window.tpl�!�\\mǪ�bsrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/view/list/list.tpl��!�\��E��csrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/controller/main.tpl�!�\� �8�Wsrc/Extensions/Shopware/PluginCreator/template/legacy/Views/backend/application/app.tpl�!�\�5s5�Zsrc/Extensions/Shopware/PluginCreator/template/legacy/Views/frontend/plugin_name/index.tpl��!�\��31�Xsrc/Extensions/Shopware/PluginCreator/template/legacy/Snippets/backend/widget/labels.tpl��!�\�X~U�Fsrc/Extensions/Shopware/PluginCreator/template/legacy/Models/Model.tpl��!�\��r�Ksrc/Extensions/Shopware/PluginCreator/template/legacy/Models/Repository.tpl]�!�\]v/��@src/Extensions/Shopware/PluginCreator/template/legacy/plugin.tpl��!�\��D��Ksrc/Extensions/Shopware/PluginCreator/template/current/Commands/Command.tpl��!�\�@�	{�fsrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleDBAL/Sorting/Sorting.tpl��!�\�t#�msrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleDBAL/Sorting/SortingHandler.tpl��!�\�2�jQ�isrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleDBAL/Facet/FacetHandler.tpl��!�\��B?;�bsrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleDBAL/Facet/Facet.tpl�!�\����jsrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleDBAL/Condition/Condition.tpl�!�\:o�qsrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleDBAL/Condition/ConditionHandler.tpl$�!�\$[O���[src/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundleES/Search.tpl��!�\�뱿`�isrc/Extensions/Shopware/PluginCreator/template/current/Components/SearchBundle/CriteriaRequestHandler.tpl)�!�\)��g&�^src/Extensions/Shopware/PluginCreator/template/current/Components/ESIndexingBundle/Mapping.tpl3�!�\3�x�S�bsrc/Extensions/Shopware/PluginCreator/template/current/Components/ESIndexingBundle/DataIndexer.tplJ�!�\J\�U�csrc/Extensions/Shopware/PluginCreator/template/current/Components/ESIndexingBundle/Synchronizer.tpl'�!�\'t���_src/Extensions/Shopware/PluginCreator/template/current/Components/ESIndexingBundle/Provider.tpl�!�\���_src/Extensions/Shopware/PluginCreator/template/current/Components/ESIndexingBundle/Settings.tpl��!�\��l�L�[src/Extensions/Shopware/PluginCreator/template/current/Components/Api/Resource/Resource.tpl��!�\���ܒ�Jsrc/Extensions/Shopware/PluginCreator/template/current/licenses/mit_sw.txt1�!�\1�h��Rsrc/Extensions/Shopware/PluginCreator/template/current/Subscriber/SearchBundle.tpl�	�!�\�	�]AJ�Tsrc/Extensions/Shopware/PluginCreator/template/current/Subscriber/ControllerPath.tpl(
�!�\(
��xݶNsrc/Extensions/Shopware/PluginCreator/template/current/Subscriber/Frontend.tpl|�!�\|����Ssrc/Extensions/Shopware/PluginCreator/template/current/Subscriber/ApiSubscriber.tplG�!�\G&�2��Ssrc/Extensions/Shopware/PluginCreator/template/current/Subscriber/BackendWidget.tpl��!�\�w�)��>src/Extensions/Shopware/PluginCreator/template/current/LICENSE*�!�\*Ε��Osrc/Extensions/Shopware/PluginCreator/template/current/Controllers/Frontend.tpln�!�\n)Ul>�Tsrc/Extensions/Shopware/PluginCreator/template/current/Controllers/BackendWidget.tpl*�!�\*�+�Jsrc/Extensions/Shopware/PluginCreator/template/current/Controllers/Api.tplp�!�\p>��M�Nsrc/Extensions/Shopware/PluginCreator/template/current/Controllers/Backend.tpl�!�\����Esrc/Extensions/Shopware/PluginCreator/template/current/plugin.xml.tpl[�!�\[
�C��Asrc/Extensions/Shopware/PluginCreator/template/current/Readme.tpl��!�\�v1zA�Ksrc/Extensions/Shopware/PluginCreator/template/current/tests/PluginTest.tplT�!�\T�ldY�Ksrc/Extensions/Shopware/PluginCreator/template/current/phpunit.xml.dist.tpl��!�\�ɠ�M�Fsrc/Extensions/Shopware/PluginCreator/template/current/PluginClass.tpl��!�\��E�ƶMsrc/Extensions/Shopware/PluginCreator/template/current/Resources/menu.xml.tpl��!�\�uHӻ�Qsrc/Extensions/Shopware/PluginCreator/template/current/Resources/services.xml.tpl��!�\��o��^src/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/widget/main.tpl��!�\�UǠȶisrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/model/main.tpl��!�\�\�,m�isrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/store/main.tplO�!�\O:S�p�qsrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/view/detail/window.tplA�!�\A�ra�tsrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/view/detail/container.tpl*�!�\*ӑ>V�osrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/view/list/window.tpl�!�\\mǪ�msrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/view/list/list.tpl��!�\��E��nsrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/controller/main.tpl�!�\� �8�bsrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/backend/application/app.tpl�!�\�5s5�esrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/frontend/plugin_name/index.tpl��!�\��31�rsrc/Extensions/Shopware/PluginCreator/template/current/Resources/views/frontend/listing/actions/action-sorting.tplO�!�\O/B�5�csrc/Extensions/Shopware/PluginCreator/template/current/Resources/snippets/backend/widget/labels.tpl��!�\�X~U�Osrc/Extensions/Shopware/PluginCreator/template/current/Resources/config.xml.tpl��!�\�?�K۶Gsrc/Extensions/Shopware/PluginCreator/template/current/Models/Model.tpl8�!�\8��"��Lsrc/Extensions/Shopware/PluginCreator/template/current/Models/Repository.tpl��!�\��W�+�assets/README.mdH�!�\Har'�LICENSE6�!�\6|E��	README.mdB,�!�\B,IS���config.yaml.dist�!�\82���Resources/public.key �!�\ =�2�;vendor/shopwarelabs/plugin-info/res/plugin-info-schema.json��!�\�H���bin/swL�!�\L�U��<?php







namespace Piwik\Ini;




class IniWriter
{






















public function writeToFile($filename, array $config, $header = '')
{
$ini = $this->writeToString($config, $header);

if (!file_put_contents($filename, $ini)) {
throw new IniWritingException(sprintf('Impossible to write to file %s', $filename));
}
}























public function writeToString(array $config, $header = '')
{
$ini = $header;

$sectionNames = array_keys($config);

foreach ($sectionNames as $sectionName) {
$section = $config[$sectionName];


 if (empty($section)) {
continue;
}

if (! is_array($section)) {
throw new IniWritingException(sprintf("Section \"%s\" doesn't contain an array of values", $sectionName));
}

$ini .= "[$sectionName]\n";

foreach ($section as $option => $value) {
if (is_numeric($option)) {
$option = $sectionName;
$value = array($value);
}

if (is_array($value)) {
foreach ($value as $currentValue) {
$ini .= $option . '[] = ' . $this->encodeValue($currentValue) . "\n";
}
} else {
$ini .= $option . ' = ' . $this->encodeValue($value) . "\n";
}
}

$ini .= "\n";
}

return $ini;
}

private function encodeValue($value)
{
if (is_bool($value)) {
return (int) $value;
}
if (is_string($value)) {
return "\"$value\"";
}
return $value;
}
}
<?php







namespace Piwik\Ini;




class IniReadingException extends \Exception
{
}
<?php







namespace Piwik\Ini;




class IniReader
{



private $useNativeFunction;

public function __construct()
{
$this->useNativeFunction = function_exists('parse_ini_string');
}






















public function readFile($filename)
{
$ini = $this->getContentOfIniFile($filename);

return $this->readString($ini);
}






















public function readString($ini)
{

 
 $ini .= "\n";

if ($this->useNativeFunction) {
$array = $this->readWithNativeFunction($ini);
} else {
$array = $this->readWithAlternativeImplementation($ini);
}

return $array;
}






private function readWithNativeFunction($ini)
{
$array = @parse_ini_string($ini, true);

if ($array === false) {
$e = error_get_last();
throw new IniReadingException('Syntax error in INI configuration: ' . $e['message']);
}


 
 $rawValues = @parse_ini_string($ini, true, INI_SCANNER_RAW);
$array = $this->decode($array, $rawValues);

return $array;
}

private function getContentOfIniFile($filename)
{
if (!file_exists($filename) || !is_readable($filename)) {
throw new IniReadingException(sprintf("The file %s doesn't exist or is not readable", $filename));
}

$content = $this->getFileContent($filename);

if ($content === false) {
throw new IniReadingException(sprintf('Impossible to read the file %s', $filename));
}

return $content;
}






















public function readComments($filename)
{
$ini = $this->getContentOfIniFile($filename);
$ini = $this->splitIniContentIntoLines($ini);

$descriptions = array();

$section = '';
$lastComment = '';

foreach ($ini as $line) {
$line = trim($line);

if (strpos($line, '[') === 0) {
$tmp = explode(']', $line);
$section = trim(substr($tmp[0], 1));
$descriptions[$section] = array();
$lastComment = '';
continue;
}

if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {
if (strpos($line, ';') === 0) {
$line = trim(substr($line, 1));
}

 $lastComment .= $line . "\n";
continue;
}

list($key, $value) = explode('=', $line, 2);

$key = trim($key);
if (strpos($key, '[]') === strlen($key) - 2) {
$key = substr($key, 0, -2);
}

if (empty($descriptions[$section][$key])) {
$descriptions[$section][$key] = $lastComment;
}

$lastComment = '';
}

return $descriptions;
}

private function splitIniContentIntoLines($ini)
{
if (is_string($ini)) {
$ini = explode("\n", str_replace("\r", "\n", $ini));
}

return $ini;
}










private function readWithAlternativeImplementation($ini)
{
$ini = $this->splitIniContentIntoLines($ini);

if (count($ini) == 0) {
return array();
}

$sections = array();
$values = array();
$result = array();
$globals = array();
$i = 0;
foreach ($ini as $line) {
$line = trim($line);
$line = str_replace("\t", " ", $line);


 if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {
continue;
}


 if ($line{0} == '[') {
$tmp = explode(']', $line);
$sections[] = trim(substr($tmp[0], 1));
$i++;
continue;
}


 list($key, $value) = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
if (strstr($value, ";")) {
$tmp = explode(';', $value);
if (count($tmp) == 2) {
if ((($value{0} != '"') && ($value{0} != "'")) ||
preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) ||
preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value)
) {
$value = $tmp[0];
}
} else {
if ($value{0} == '"') {
$value = preg_replace('/^"(.*)".*/', '$1', $value);
} elseif ($value{0} == "'") {
$value = preg_replace("/^'(.*)'.*/", '$1', $value);
} else {
$value = $tmp[0];
}
}
}

$value = trim($value);


 if ($value === 'true' || $value === 'yes' || $value === 'on') {
$value = true;
} elseif ($value === 'false' || $value === 'no' || $value === 'off') {
$value = false;
} elseif ($value === '' || $value === 'null') {
$value = null;
}

if (is_string($value)) {
$value = trim($value, "'\"");
}

if ($i == 0) {
if (substr($key, -2) == '[]') {
$globals[substr($key, 0, -2)][] = $value;
} else {
$globals[$key] = $value;
}
} else {
if (substr($key, -2) == '[]') {
$values[$i - 1][substr($key, 0, -2)][] = $value;
} else {
$values[$i - 1][$key] = $value;
}
}
}

for ($j = 0; $j < $i; $j++) {
if (isset($values[$j])) {
$result[$sections[$j]] = $values[$j];
} else {
$result[$sections[$j]] = array();
}
}

$finalResult = $result + $globals;

return $this->decode($finalResult, $finalResult);
}





private function getFileContent($filename)
{
if (function_exists('file_get_contents')) {
return file_get_contents($filename);
} elseif (function_exists('file')) {
$ini = file($filename);
if ($ini !== false) {
return implode("\n", $ini);
}
} elseif (function_exists('fopen') && function_exists('fread')) {
$handle = fopen($filename, 'r');
if (!$handle) {
return false;
}
$ini = fread($handle, filesize($filename));
fclose($handle);
return $ini;
}

return false;
}









private function decode($value, $rawValue)
{
if (is_array($value)) {
foreach ($value as $i => &$subValue) {
$subValue = $this->decode($subValue, $rawValue[$i]);
}
return $value;
}

if (! is_string($value)) {
return $value;
}

$value = $this->decodeBoolean($value, $rawValue);
$value = $this->decodeNull($value, $rawValue);

if (is_numeric($value) && $this->noLossWhenCastToInt($value)) {
return $value + 0;
}

return $value;
}

private function decodeBoolean($value, $rawValue)
{
if ($value === '1' && ($rawValue === 'true' || $rawValue === 'yes' || $rawValue === 'on')) {
return true;
}
if ($value === '' && ($rawValue === 'false' || $rawValue === 'no' || $rawValue === 'off')) {
return false;
}
return $value;
}

private function decodeNull($value, $rawValue)
{
if ($value === '' && $rawValue === 'null') {
return null;
}
return $value;
}

private function noLossWhenCastToInt($value)
{
return (string) ($value + 0) === $value;
}
}
<?php







namespace Piwik\Ini;




class IniWritingException extends \Exception
{
}
<?php
namespace Psr\Http\Message;





















interface UriInterface
{














public function getScheme();



















public function getAuthority();
















public function getUserInfo();












public function getHost();
















public function getPort();


























public function getPath();





















public function getQuery();

















public function getFragment();
















public function withScheme($scheme);















public function withUserInfo($user, $password = null);













public function withHost($host);


















public function withPort($port);























public function withPath($path);
















public function withQuery($query);















public function withFragment($fragment);
























public function __toString();
}
<?php

namespace Psr\Http\Message;









interface UploadedFileInterface
{
















public function getStream();

































public function moveTo($targetPath);










public function getSize();















public function getError();














public function getClientFilename();














public function getClientMediaType();
}
<?php

namespace Psr\Http\Message;








interface StreamInterface
{














public function __toString();






public function close();








public function detach();






public function getSize();







public function tell();






public function eof();






public function isSeekable();













public function seek($offset, $whence = SEEK_SET);











public function rewind();






public function isWritable();








public function write($string);






public function isReadable();











public function read($length);








public function getContents();













public function getMetadata($key = null);
}
<?php

namespace Psr\Http\Message;







































interface ServerRequestInterface extends RequestInterface
{









public function getServerParams();











public function getCookieParams();


















public function withCookieParams(array $cookies);













public function getQueryParams();























public function withQueryParams(array $query);













public function getUploadedFiles();












public function withUploadedFiles(array $uploadedFiles);
















public function getParsedBody();





























public function withParsedBody($data);












public function getAttributes();
















public function getAttribute($name, $default = null);
















public function withAttribute($name, $value);















public function withoutAttribute($name);
}
<?php

namespace Psr\Http\Message;
















interface ResponseInterface extends MessageInterface
{








public function getStatusCode();





















public function withStatus($code, $reasonPhrase = '');














public function getReasonPhrase();
}
<?php

namespace Psr\Http\Message;













interface MessageInterface
{







public function getProtocolVersion();














public function withProtocolVersion($version);


























public function getHeaders();









public function hasHeader($name);















public function getHeader($name);




















public function getHeaderLine($name);
















public function withHeader($name, $value);

















public function withAddedHeader($name, $value);













public function withoutHeader($name);






public function getBody();














public function withBody(StreamInterface $body);
}
<?php

namespace Psr\Http\Message;




















interface RequestInterface extends MessageInterface
{
















public function getRequestTarget();


















public function withRequestTarget($requestTarget);






public function getMethod();
















public function withMethod($method);










public function getUri();































public function withUri(UriInterface $uri, $preserveHost = false);
}
<?php

namespace Psr\Log;









class NullLogger extends AbstractLogger
{









public function log($level, $message, array $context = array())
{

 }
}
<?php

namespace Psr\Log;
















interface LoggerInterface
{








public function emergency($message, array $context = array());












public function alert($message, array $context = array());











public function critical($message, array $context = array());










public function error($message, array $context = array());












public function warning($message, array $context = array());









public function notice($message, array $context = array());











public function info($message, array $context = array());









public function debug($message, array $context = array());










public function log($level, $message, array $context = array());
}
<?php

namespace Psr\Log\Test;

use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;







abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
{



abstract public function getLogger();










abstract public function getLogs();

public function testImplements()
{
$this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
}




public function testLogsAtAllLevels($level, $message)
{
$logger = $this->getLogger();
$logger->{$level}($message, array('user' => 'Bob'));
$logger->log($level, $message, array('user' => 'Bob'));

$expected = array(
$level.' message of level '.$level.' with context: Bob',
$level.' message of level '.$level.' with context: Bob',
);
$this->assertEquals($expected, $this->getLogs());
}

public function provideLevelsAndMessages()
{
return array(
LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
);
}




public function testThrowsOnInvalidLevel()
{
$logger = $this->getLogger();
$logger->log('invalid level', 'Foo');
}

public function testContextReplacement()
{
$logger = $this->getLogger();
$logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));

$expected = array('info {Message {nothing} Bob Bar a}');
$this->assertEquals($expected, $this->getLogs());
}

public function testObjectCastToString()
{
if (method_exists($this, 'createPartialMock')) {
$dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString'));
} else {
$dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
}
$dummy->expects($this->once())
->method('__toString')
->will($this->returnValue('DUMMY'));

$this->getLogger()->warning($dummy);

$expected = array('warning DUMMY');
$this->assertEquals($expected, $this->getLogs());
}

public function testContextCanContainAnything()
{
$context = array(
'bool' => true,
'null' => null,
'string' => 'Foo',
'int' => 0,
'float' => 0.5,
'nested' => array('with object' => new DummyTest),
'object' => new \DateTime,
'resource' => fopen('php://memory', 'r'),
);

$this->getLogger()->warning('Crazy context data', $context);

$expected = array('warning Crazy context data');
$this->assertEquals($expected, $this->getLogs());
}

public function testContextExceptionKeyCanBeExceptionOrOtherValues()
{
$logger = $this->getLogger();
$logger->warning('Random message', array('exception' => 'oops'));
$logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));

$expected = array(
'warning Random message',
'critical Uncaught Exception!'
);
$this->assertEquals($expected, $this->getLogs());
}
}

class DummyTest
{
public function __toString()
{
}
}
<?php

namespace Psr\Log;








abstract class AbstractLogger implements LoggerInterface
{








public function emergency($message, array $context = array())
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}












public function alert($message, array $context = array())
{
$this->log(LogLevel::ALERT, $message, $context);
}











public function critical($message, array $context = array())
{
$this->log(LogLevel::CRITICAL, $message, $context);
}










public function error($message, array $context = array())
{
$this->log(LogLevel::ERROR, $message, $context);
}












public function warning($message, array $context = array())
{
$this->log(LogLevel::WARNING, $message, $context);
}









public function notice($message, array $context = array())
{
$this->log(LogLevel::NOTICE, $message, $context);
}











public function info($message, array $context = array())
{
$this->log(LogLevel::INFO, $message, $context);
}









public function debug($message, array $context = array())
{
$this->log(LogLevel::DEBUG, $message, $context);
}
}
<?php

namespace Psr\Log;









trait LoggerTrait
{








public function emergency($message, array $context = array())
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}












public function alert($message, array $context = array())
{
$this->log(LogLevel::ALERT, $message, $context);
}











public function critical($message, array $context = array())
{
$this->log(LogLevel::CRITICAL, $message, $context);
}










public function error($message, array $context = array())
{
$this->log(LogLevel::ERROR, $message, $context);
}












public function warning($message, array $context = array())
{
$this->log(LogLevel::WARNING, $message, $context);
}









public function notice($message, array $context = array())
{
$this->log(LogLevel::NOTICE, $message, $context);
}











public function info($message, array $context = array())
{
$this->log(LogLevel::INFO, $message, $context);
}









public function debug($message, array $context = array())
{
$this->log(LogLevel::DEBUG, $message, $context);
}










abstract public function log($level, $message, array $context = array());
}
<?php

namespace Psr\Log;




trait LoggerAwareTrait
{





protected $logger;






public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
<?php

namespace Psr\Log;

class InvalidArgumentException extends \InvalidArgumentException
{
}
<?php

namespace Psr\Log;




interface LoggerAwareInterface
{







public function setLogger(LoggerInterface $logger);
}
<?php

namespace Psr\Log;




class LogLevel
{
const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
}
<?php
namespace GuzzleHttp\Promise;










class TaskQueue implements TaskQueueInterface
{
private $enableShutdown = true;
private $queue = [];

public function __construct($withShutdown = true)
{
if ($withShutdown) {
register_shutdown_function(function () {
if ($this->enableShutdown) {

 $err = error_get_last();
if (!$err || ($err['type'] ^ E_ERROR)) {
$this->run();
}
}
});
}
}

public function isEmpty()
{
return !$this->queue;
}

public function add(callable $task)
{
$this->queue[] = $task;
}

public function run()
{

while ($task = array_shift($this->queue)) {
$task();
}
}












public function disableShutdown()
{
$this->enableShutdown = false;
}
}
<?php
namespace GuzzleHttp\Promise;

interface TaskQueueInterface
{





public function isEmpty();







public function add(callable $task);




public function run();
}
<?php
namespace GuzzleHttp\Promise;







class RejectedPromise implements PromiseInterface
{
private $reason;

public function __construct($reason)
{
if (method_exists($reason, 'then')) {
throw new \InvalidArgumentException(
'You cannot create a RejectedPromise with a promise.');
}

$this->reason = $reason;
}

public function then(
callable $onFulfilled = null,
callable $onRejected = null
) {

 if (!$onRejected) {
return $this;
}

$queue = queue();
$reason = $this->reason;
$p = new Promise([$queue, 'run']);
$queue->add(static function () use ($p, $reason, $onRejected) {
if ($p->getState() === self::PENDING) {
try {

 $p->resolve($onRejected($reason));
} catch (\Throwable $e) {

 $p->reject($e);
} catch (\Exception $e) {

 $p->reject($e);
}
}
});

return $p;
}

public function otherwise(callable $onRejected)
{
return $this->then(null, $onRejected);
}

public function wait($unwrap = true, $defaultDelivery = null)
{
if ($unwrap) {
throw exception_for($this->reason);
}
}

public function getState()
{
return self::REJECTED;
}

public function resolve($value)
{
throw new \LogicException("Cannot resolve a rejected promise");
}

public function reject($reason)
{
if ($reason !== $this->reason) {
throw new \LogicException("Cannot reject a rejected promise");
}
}

public function cancel()
{

 }
}
<?php
namespace GuzzleHttp\Promise;


















function queue(TaskQueueInterface $assign = null)
{
static $queue;

if ($assign) {
$queue = $assign;
} elseif (!$queue) {
$queue = new TaskQueue();
}

return $queue;
}









function task(callable $task)
{
$queue = queue();
$promise = new Promise([$queue, 'run']);
$queue->add(function () use ($task, $promise) {
try {
$promise->resolve($task());
} catch (\Throwable $e) {
$promise->reject($e);
} catch (\Exception $e) {
$promise->reject($e);
}
});

return $promise;
}








function promise_for($value)
{
if ($value instanceof PromiseInterface) {
return $value;
}


 if (method_exists($value, 'then')) {
$wfn = method_exists($value, 'wait') ? [$value, 'wait'] : null;
$cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null;
$promise = new Promise($wfn, $cfn);
$value->then([$promise, 'resolve'], [$promise, 'reject']);
return $promise;
}

return new FulfilledPromise($value);
}









function rejection_for($reason)
{
if ($reason instanceof PromiseInterface) {
return $reason;
}

return new RejectedPromise($reason);
}








function exception_for($reason)
{
return $reason instanceof \Exception || $reason instanceof \Throwable
? $reason
: new RejectionException($reason);
}








function iter_for($value)
{
if ($value instanceof \Iterator) {
return $value;
} elseif (is_array($value)) {
return new \ArrayIterator($value);
} else {
return new \ArrayIterator([$value]);
}
}















function inspect(PromiseInterface $promise)
{
try {
return [
'state' => PromiseInterface::FULFILLED,
'value' => $promise->wait()
];
} catch (RejectionException $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
} catch (\Throwable $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
} catch (\Exception $e) {
return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
}
}












function inspect_all($promises)
{
$results = [];
foreach ($promises as $key => $promise) {
$results[$key] = inspect($promise);
}

return $results;
}














function unwrap($promises)
{
$results = [];
foreach ($promises as $key => $promise) {
$results[$key] = $promise->wait();
}

return $results;
}













function all($promises)
{
$results = [];
return each(
$promises,
function ($value, $idx) use (&$results) {
$results[$idx] = $value;
},
function ($reason, $idx, Promise $aggregate) {
$aggregate->reject($reason);
}
)->then(function () use (&$results) {
ksort($results);
return $results;
});
}

















function some($count, $promises)
{
$results = [];
$rejections = [];

return each(
$promises,
function ($value, $idx, PromiseInterface $p) use (&$results, $count) {
if ($p->getState() !== PromiseInterface::PENDING) {
return;
}
$results[$idx] = $value;
if (count($results) >= $count) {
$p->resolve(null);
}
},
function ($reason) use (&$rejections) {
$rejections[] = $reason;
}
)->then(
function () use (&$results, &$rejections, $count) {
if (count($results) !== $count) {
throw new AggregateException(
'Not enough promises to fulfill count',
$rejections
);
}
ksort($results);
return array_values($results);
}
);
}









function any($promises)
{
return some(1, $promises)->then(function ($values) { return $values[0]; });
}












function settle($promises)
{
$results = [];

return each(
$promises,
function ($value, $idx) use (&$results) {
$results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
},
function ($reason, $idx) use (&$results) {
$results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
}
)->then(function () use (&$results) {
ksort($results);
return $results;
});
}




















function each(
$iterable,
callable $onFulfilled = null,
callable $onRejected = null
) {
return (new EachPromise($iterable, [
'fulfilled' => $onFulfilled,
'rejected' => $onRejected
]))->promise();
}
















function each_limit(
$iterable,
$concurrency,
callable $onFulfilled = null,
callable $onRejected = null
) {
return (new EachPromise($iterable, [
'fulfilled' => $onFulfilled,
'rejected' => $onRejected,
'concurrency' => $concurrency
]))->promise();
}












function each_limit_all(
$iterable,
$concurrency,
callable $onFulfilled = null
) {
return each_limit(
$iterable,
$concurrency,
$onFulfilled,
function ($reason, $idx, PromiseInterface $aggregate) {
$aggregate->reject($reason);
}
);
}








function is_fulfilled(PromiseInterface $promise)
{
return $promise->getState() === PromiseInterface::FULFILLED;
}








function is_rejected(PromiseInterface $promise)
{
return $promise->getState() === PromiseInterface::REJECTED;
}








function is_settled(PromiseInterface $promise)
{
return $promise->getState() !== PromiseInterface::PENDING;
}








function coroutine(callable $generatorFn)
{
return new Coroutine($generatorFn);
}
<?php
namespace GuzzleHttp\Promise;




interface PromisorInterface
{





public function promise();
}
<?php
namespace GuzzleHttp\Promise;




class CancellationException extends RejectionException
{
}
<?php
namespace GuzzleHttp\Promise;




class AggregateException extends RejectionException
{
public function __construct($msg, array $reasons)
{
parent::__construct(
$reasons,
sprintf('%s; %d rejected promises', $msg, count($reasons))
);
}
}
<?php
namespace GuzzleHttp\Promise;






class RejectionException extends \RuntimeException
{

private $reason;





public function __construct($reason, $description = null)
{
$this->reason = $reason;

$message = 'The promise was rejected';

if ($description) {
$message .= ' with reason: ' . $description;
} elseif (is_string($reason)
|| (is_object($reason) && method_exists($reason, '__toString'))
) {
$message .= ' with reason: ' . $this->reason;
} elseif ($reason instanceof \JsonSerializable) {
$message .= ' with reason: '
. json_encode($this->reason, JSON_PRETTY_PRINT);
}

parent::__construct($message);
}






public function getReason()
{
return $this->reason;
}
}
<?php
namespace GuzzleHttp\Promise;






class Promise implements PromiseInterface
{
private $state = self::PENDING;
private $result;
private $cancelFn;
private $waitFn;
private $waitList;
private $handlers = [];





public function __construct(
callable $waitFn = null,
callable $cancelFn = null
) {
$this->waitFn = $waitFn;
$this->cancelFn = $cancelFn;
}

public function then(
callable $onFulfilled = null,
callable $onRejected = null
) {
if ($this->state === self::PENDING) {
$p = new Promise(null, [$this, 'cancel']);
$this->handlers[] = [$p, $onFulfilled, $onRejected];
$p->waitList = $this->waitList;
$p->waitList[] = $this;
return $p;
}


 if ($this->state === self::FULFILLED) {
return $onFulfilled
? promise_for($this->result)->then($onFulfilled)
: promise_for($this->result);
}


 
 $rejection = rejection_for($this->result);
return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
}

public function otherwise(callable $onRejected)
{
return $this->then(null, $onRejected);
}

public function wait($unwrap = true)
{
$this->waitIfPending();

$inner = $this->result instanceof PromiseInterface
? $this->result->wait($unwrap)
: $this->result;

if ($unwrap) {
if ($this->result instanceof PromiseInterface
|| $this->state === self::FULFILLED
) {
return $inner;
} else {

 throw exception_for($inner);
}
}
}

public function getState()
{
return $this->state;
}

public function cancel()
{
if ($this->state !== self::PENDING) {
return;
}

$this->waitFn = $this->waitList = null;

if ($this->cancelFn) {
$fn = $this->cancelFn;
$this->cancelFn = null;
try {
$fn();
} catch (\Throwable $e) {
$this->reject($e);
} catch (\Exception $e) {
$this->reject($e);
}
}


 if ($this->state === self::PENDING) {
$this->reject(new CancellationException('Promise has been cancelled'));
}
}

public function resolve($value)
{
$this->settle(self::FULFILLED, $value);
}

public function reject($reason)
{
$this->settle(self::REJECTED, $reason);
}

private function settle($state, $value)
{
if ($this->state !== self::PENDING) {

 if ($state === $this->state && $value === $this->result) {
return;
}
throw $this->state === $state
? new \LogicException("The promise is already {$state}.")
: new \LogicException("Cannot change a {$this->state} promise to {$state}");
}

if ($value === $this) {
throw new \LogicException('Cannot fulfill or reject a promise with itself');
}


 $this->state = $state;
$this->result = $value;
$handlers = $this->handlers;
$this->handlers = null;
$this->waitList = $this->waitFn = null;
$this->cancelFn = null;

if (!$handlers) {
return;
}


 
 if (!method_exists($value, 'then')) {
$id = $state === self::FULFILLED ? 1 : 2;

 queue()->add(static function () use ($id, $value, $handlers) {
foreach ($handlers as $handler) {
self::callHandler($id, $value, $handler);
}
});
} elseif ($value instanceof Promise
&& $value->getState() === self::PENDING
) {

 $value->handlers = array_merge($value->handlers, $handlers);
} else {

 $value->then(
static function ($value) use ($handlers) {
foreach ($handlers as $handler) {
self::callHandler(1, $value, $handler);
}
},
static function ($reason) use ($handlers) {
foreach ($handlers as $handler) {
self::callHandler(2, $reason, $handler);
}
}
);
}
}










private static function callHandler($index, $value, array $handler)
{

$promise = $handler[0];


 
 if ($promise->getState() !== self::PENDING) {
return;
}

try {
if (isset($handler[$index])) {
$promise->resolve($handler[$index]($value));
} elseif ($index === 1) {

 $promise->resolve($value);
} else {

 $promise->reject($value);
}
} catch (\Throwable $reason) {
$promise->reject($reason);
} catch (\Exception $reason) {
$promise->reject($reason);
}
}

private function waitIfPending()
{
if ($this->state !== self::PENDING) {
return;
} elseif ($this->waitFn) {
$this->invokeWaitFn();
} elseif ($this->waitList) {
$this->invokeWaitList();
} else {

 $this->reject('Cannot wait on a promise that has '
. 'no internal wait function. You must provide a wait '
. 'function when constructing the promise to be able to '
. 'wait on a promise.');
}

queue()->run();

if ($this->state === self::PENDING) {
$this->reject('Invoking the wait callback did not resolve the promise');
}
}

private function invokeWaitFn()
{
try {
$wfn = $this->waitFn;
$this->waitFn = null;
$wfn(true);
} catch (\Exception $reason) {
if ($this->state === self::PENDING) {

 
 $this->reject($reason);
} else {

 
 throw $reason;
}
}
}

private function invokeWaitList()
{
$waitList = $this->waitList;
$this->waitList = null;

foreach ($waitList as $result) {
while (true) {
$result->waitIfPending();

if ($result->result instanceof Promise) {
$result = $result->result;
} else {
if ($result->result instanceof PromiseInterface) {
$result->result->wait(false);
}
break;
}
}
}
}
}
<?php
namespace GuzzleHttp\Promise;





class EachPromise implements PromisorInterface
{
private $pending = [];


private $iterable;


private $concurrency;


private $onFulfilled;


private $onRejected;


private $aggregate;


private $mutex;






















public function __construct($iterable, array $config = [])
{
$this->iterable = iter_for($iterable);

if (isset($config['concurrency'])) {
$this->concurrency = $config['concurrency'];
}

if (isset($config['fulfilled'])) {
$this->onFulfilled = $config['fulfilled'];
}

if (isset($config['rejected'])) {
$this->onRejected = $config['rejected'];
}
}

public function promise()
{
if ($this->aggregate) {
return $this->aggregate;
}

try {
$this->createPromise();
$this->iterable->rewind();
$this->refillPending();
} catch (\Throwable $e) {
$this->aggregate->reject($e);
} catch (\Exception $e) {
$this->aggregate->reject($e);
}

return $this->aggregate;
}

private function createPromise()
{
$this->mutex = false;
$this->aggregate = new Promise(function () {
reset($this->pending);
if (empty($this->pending) && !$this->iterable->valid()) {
$this->aggregate->resolve(null);
return;
}


 
 while ($promise = current($this->pending)) {
next($this->pending);
$promise->wait();
if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
return;
}
}
});


 $clearFn = function () {
$this->iterable = $this->concurrency = $this->pending = null;
$this->onFulfilled = $this->onRejected = null;
};

$this->aggregate->then($clearFn, $clearFn);
}

private function refillPending()
{
if (!$this->concurrency) {

 while ($this->addPending() && $this->advanceIterator());
return;
}


 $concurrency = is_callable($this->concurrency)
? call_user_func($this->concurrency, count($this->pending))
: $this->concurrency;
$concurrency = max($concurrency - count($this->pending), 0);

 if (!$concurrency) {
return;
}

 $this->addPending();

 
 
 
 while (--$concurrency
&& $this->advanceIterator()
&& $this->addPending());
}

private function addPending()
{
if (!$this->iterable || !$this->iterable->valid()) {
return false;
}

$promise = promise_for($this->iterable->current());
$idx = $this->iterable->key();

$this->pending[$idx] = $promise->then(
function ($value) use ($idx) {
if ($this->onFulfilled) {
call_user_func(
$this->onFulfilled, $value, $idx, $this->aggregate
);
}
$this->step($idx);
},
function ($reason) use ($idx) {
if ($this->onRejected) {
call_user_func(
$this->onRejected, $reason, $idx, $this->aggregate
);
}
$this->step($idx);
}
);

return true;
}

private function advanceIterator()
{

 
 if ($this->mutex) {
return false;
}

$this->mutex = true;

try {
$this->iterable->next();
$this->mutex = false;
return true;
} catch (\Throwable $e) {
$this->aggregate->reject($e);
$this->mutex = false;
return false;
} catch (\Exception $e) {
$this->aggregate->reject($e);
$this->mutex = false;
return false;
}
}

private function step($idx)
{

 if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
return;
}

unset($this->pending[$idx]);


 
 
 if ($this->advanceIterator() && !$this->checkIfFinished()) {

 $this->refillPending();
}
}

private function checkIfFinished()
{
if (!$this->pending && !$this->iterable->valid()) {

 $this->aggregate->resolve(null);
return true;
}

return false;
}
}
<?php
namespace GuzzleHttp\Promise;










interface PromiseInterface
{
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';










public function then(
callable $onFulfilled = null,
callable $onRejected = null
);











public function otherwise(callable $onRejected);









public function getState();







public function resolve($value);







public function reject($reason);






public function cancel();















public function wait($unwrap = true);
}
<?php
namespace GuzzleHttp\Promise;

use Exception;
use Generator;
use Throwable;




































final class Coroutine implements PromiseInterface
{



private $currentPromise;




private $generator;




private $result;

public function __construct(callable $generatorFn)
{
$this->generator = $generatorFn();
$this->result = new Promise(function () {
while (isset($this->currentPromise)) {
$this->currentPromise->wait();
}
});
$this->nextCoroutine($this->generator->current());
}

public function then(
callable $onFulfilled = null,
callable $onRejected = null
) {
return $this->result->then($onFulfilled, $onRejected);
}

public function otherwise(callable $onRejected)
{
return $this->result->otherwise($onRejected);
}

public function wait($unwrap = true)
{
return $this->result->wait($unwrap);
}

public function getState()
{
return $this->result->getState();
}

public function resolve($value)
{
$this->result->resolve($value);
}

public function reject($reason)
{
$this->result->reject($reason);
}

public function cancel()
{
$this->currentPromise->cancel();
$this->result->cancel();
}

private function nextCoroutine($yielded)
{
$this->currentPromise = promise_for($yielded)
->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
}




public function _handleSuccess($value)
{
unset($this->currentPromise);
try {
$next = $this->generator->send($value);
if ($this->generator->valid()) {
$this->nextCoroutine($next);
} else {
$this->result->resolve($value);
}
} catch (Exception $exception) {
$this->result->reject($exception);
} catch (Throwable $throwable) {
$this->result->reject($throwable);
}
}




public function _handleFailure($reason)
{
unset($this->currentPromise);
try {
$nextYield = $this->generator->throw(exception_for($reason));

 $this->nextCoroutine($nextYield);
} catch (Exception $exception) {
$this->result->reject($exception);
} catch (Throwable $throwable) {
$this->result->reject($throwable);
}
}
}
<?php
namespace GuzzleHttp\Promise;







class FulfilledPromise implements PromiseInterface
{
private $value;

public function __construct($value)
{
if (method_exists($value, 'then')) {
throw new \InvalidArgumentException(
'You cannot create a FulfilledPromise with a promise.');
}

$this->value = $value;
}

public function then(
callable $onFulfilled = null,
callable $onRejected = null
) {

 if (!$onFulfilled) {
return $this;
}

$queue = queue();
$p = new Promise([$queue, 'run']);
$value = $this->value;
$queue->add(static function () use ($p, $value, $onFulfilled) {
if ($p->getState() === self::PENDING) {
try {
$p->resolve($onFulfilled($value));
} catch (\Throwable $e) {
$p->reject($e);
} catch (\Exception $e) {
$p->reject($e);
}
}
});

return $p;
}

public function otherwise(callable $onRejected)
{
return $this->then(null, $onRejected);
}

public function wait($unwrap = true, $defaultDelivery = null)
{
return $unwrap ? $this->value : null;
}

public function getState()
{
return self::FULFILLED;
}

public function resolve($value)
{
if ($value !== $this->value) {
throw new \LogicException("Cannot resolve a fulfilled promise");
}
}

public function reject($reason)
{
throw new \LogicException("Cannot reject a fulfilled promise");
}

public function cancel()
{

 }
}
<?php


if (!function_exists('GuzzleHttp\Promise\promise_for')) {
require __DIR__ . '/functions.php';
}
<?php







class Burgomaster
{

public $stageDir;


public $projectRoot;


private $sections = array();











public function __construct($stageDir, $projectRoot = null)
{
$this->startSection('setting_up');
$this->stageDir = $stageDir;
$this->projectRoot = $projectRoot;

if (!$this->stageDir || $this->stageDir == '/') {
throw new \InvalidArgumentException('Invalid base directory');
}

if (is_dir($this->stageDir)) {
$this->debug("Removing existing directory: $this->stageDir");
echo $this->exec("rm -rf $this->stageDir");
}

$this->debug("Creating staging directory: $this->stageDir");

if (!mkdir($this->stageDir, 0777, true)) {
throw new \RuntimeException("Could not create {$this->stageDir}");
}

$this->stageDir = realpath($this->stageDir);
$this->debug("Creating staging directory at: {$this->stageDir}");

if (!is_dir($this->projectRoot)) {
throw new \InvalidArgumentException(
"Project root not found: $this->projectRoot"
);
}

$this->endSection();
$this->startSection('staging');

chdir($this->projectRoot);
}




public function __destruct()
{
if ($this->sections) {
$this->endSection();
}
}










public function startSection($section)
{
$this->sections[] = $section;
$this->debug('Starting');
}




public function endSection()
{
if ($this->sections) {
$this->debug('Completed');
array_pop($this->sections);
}
}






public function debug($message)
{
$prefix = date('c') . ': ';

if ($this->sections) {
$prefix .= '[' . end($this->sections) . '] ';
}

fwrite(STDERR, $prefix . $message . "\n");
}











public function deepCopy($from, $to)
{
if (!is_file($from)) {
throw new \InvalidArgumentException("File not found: {$from}");
}

$to = str_replace('//', '/', $this->stageDir . '/' . $to);
$dir = dirname($to);

if (!is_dir($dir)) {
if (!mkdir($dir, 0777, true)) {
throw new \RuntimeException("Unable to create directory: $dir");
}
}

if (!copy($from, $to)) {
throw new \RuntimeException("Unable to copy $from to $to");
}
}













function recursiveCopy(
$sourceDir,
$destDir,
$extensions = array('php')
) {
if (!realpath($sourceDir)) {
throw new \InvalidArgumentException("$sourceDir not found");
}

if (!$extensions) {
throw new \InvalidArgumentException('$extensions is empty!');
}

$sourceDir = realpath($sourceDir);
$exts = array_fill_keys($extensions, true);
$iter = new \RecursiveDirectoryIterator($sourceDir);
$iter = new \RecursiveIteratorIterator($iter);
$total = 0;

$this->startSection('copy');
$this->debug("Starting to copy files from $sourceDir");

foreach ($iter as $file) {
if (isset($exts[$file->getExtension()])
|| $file->getBaseName() == 'LICENSE'
) {

 $toPath = str_replace($sourceDir, '', (string) $file);
$toPath = $destDir . '/' . $toPath;
$toPath = str_replace('//', '/', $toPath);
$this->deepCopy((string) $file, $toPath);
$total++;
}
}

$this->debug("Copied $total files from $sourceDir");
$this->endSection();
}









public function exec($command)
{
$this->debug("Executing: $command");
$output = $returnValue = null;
exec($command, $output, $returnValue);

if ($returnValue != 0) {
throw new \RuntimeException('Error executing command: '
. $command . ' : ' . implode("\n", $output));
}

return implode("\n", $output);
}










function createAutoloader($files = array(), $filename = 'autoloader.php') {
$sourceDir = realpath($this->stageDir);
$iter = new \RecursiveDirectoryIterator($sourceDir);
$iter = new \RecursiveIteratorIterator($iter);

$this->startSection('autoloader');
$this->debug('Creating classmap autoloader');
$this->debug("Collecting valid PHP files from {$this->stageDir}");

$classMap = array();
foreach ($iter as $file) {
if ($file->getExtension() == 'php') {
$location = str_replace($this->stageDir . '/', '', (string) $file);
$className = str_replace('/', '\\', $location);
$className = substr($className, 0, -4);


 if (strpos($className, 'src\\') === 0
|| strpos($className, 'lib\\') === 0
) {
$className = substr($className, 4);
}

$classMap[$className] = "__DIR__ . '/$location'";
$this->debug("Found $className");
}
}

$destFile = $this->stageDir . '/' . $filename;
$this->debug("Writing autoloader to {$destFile}");

if (!($h = fopen($destFile, 'w'))) {
throw new \RuntimeException('Unable to open file for writing');
}

$this->debug('Writing classmap files');
fwrite($h, "<?php\n\n");
fwrite($h, "\$mapping = array(\n");
foreach ($classMap as $c => $f) {
fwrite($h, "    '$c' => $f,\n");
}
fwrite($h, ");\n\n");
fwrite($h, <<<EOT
spl_autoload_register(function (\$class) use (\$mapping) {
    if (isset(\$mapping[\$class])) {
        require \$mapping[\$class];
    }
}, true);

EOT
);

fwrite($h, "\n");

$this->debug('Writing automatically included files');
foreach ($files as $file) {
fwrite($h, "require __DIR__ . '/$file';\n");
}

fclose($h);

$this->endSection();
}















private function createStub($dest, $autoloaderFilename = 'autoloader.php')
{
$this->startSection('stub');
$this->debug("Creating phar stub at $dest");

$alias = basename($dest);
$constName = str_replace('.phar', '', strtoupper($alias)) . '_PHAR';
$stub = "<?php\n";
$stub .= "define('$constName', true);\n";
$stub .= "require 'phar://$alias/{$autoloaderFilename}';\n";
$stub .= "__HALT_COMPILER();\n";
$this->endSection();

return $stub;
}














public function createPhar(
$dest,
$stub = null,
$autoloaderFilename = 'autoloader.php'
) {
$this->startSection('phar');
$this->debug("Creating phar file at $dest");
$this->createDirIfNeeded(dirname($dest));
$phar = new \Phar($dest, 0, basename($dest));
$phar->buildFromDirectory($this->stageDir);

if ($stub !== false) {
if (!$stub) {
$stub = $this->createStub($dest, $autoloaderFilename);
}
$phar->setStub($stub);
}

$this->debug("Created phar at $dest");
$this->endSection();
}








public function createZip($dest)
{
$this->startSection('zip');
$this->debug("Creating a zip file at $dest");
$this->createDirIfNeeded(dirname($dest));
chdir($this->stageDir);
$this->exec("zip -r $dest ./");
$this->debug("  > Created at $dest");
chdir(__DIR__);
$this->endSection();
}

private function createDirIfNeeded($dir)
{
if (!is_dir($dir) && !mkdir($dir, 0755, true)) {
throw new \RuntimeException("Could not create dir: $dir");
}
}
}
<?php
require __DIR__ . '/Burgomaster.php';

$stageDirectory = __DIR__ . '/artifacts/staging';
$projectRoot = __DIR__ . '/../';
$packager = new \Burgomaster($stageDirectory, $projectRoot);



foreach (['README.md', 'LICENSE'] as $file) {
$packager->deepCopy($file, $file);
}


$packager->recursiveCopy('src', 'GuzzleHttp', ['php']);
$packager->recursiveCopy('vendor/guzzlehttp/promises/src', 'GuzzleHttp/Promise');
$packager->recursiveCopy('vendor/guzzlehttp/psr7/src', 'GuzzleHttp/Psr7');
$packager->recursiveCopy('vendor/psr/http-message/src', 'Psr/Http/Message');

$packager->createAutoloader([
'GuzzleHttp/functions.php',
'GuzzleHttp/Psr7/functions.php',
'GuzzleHttp/Promise/functions.php',
]);

$packager->createPhar(__DIR__ . '/artifacts/guzzle.phar');
$packager->createZip(__DIR__ . '/artifacts/guzzle.zip');
<?php
namespace GuzzleHttp;

use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;





























class MessageFormatter
{





const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';


private $template;




public function __construct($template = self::CLF)
{
$this->template = $template ?: self::CLF;
}










public function format(
RequestInterface $request,
ResponseInterface $response = null,
\Exception $error = null
) {
$cache = [];

return preg_replace_callback(
'/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
function (array $matches) use ($request, $response, $error, &$cache) {

if (isset($cache[$matches[1]])) {
return $cache[$matches[1]];
}

$result = '';
switch ($matches[1]) {
case 'request':
$result = Psr7\str($request);
break;
case 'response':
$result = $response ? Psr7\str($response) : '';
break;
case 'req_headers':
$result = trim($request->getMethod()
. ' ' . $request->getRequestTarget())
. ' HTTP/' . $request->getProtocolVersion() . "\r\n"
. $this->headers($request);
break;
case 'res_headers':
$result = $response ?
sprintf(
'HTTP/%s %d %s',
$response->getProtocolVersion(),
$response->getStatusCode(),
$response->getReasonPhrase()
) . "\r\n" . $this->headers($response)
: 'NULL';
break;
case 'req_body':
$result = $request->getBody();
break;
case 'res_body':
$result = $response ? $response->getBody() : 'NULL';
break;
case 'ts':
case 'date_iso_8601':
$result = gmdate('c');
break;
case 'date_common_log':
$result = date('d/M/Y:H:i:s O');
break;
case 'method':
$result = $request->getMethod();
break;
case 'version':
$result = $request->getProtocolVersion();
break;
case 'uri':
case 'url':
$result = $request->getUri();
break;
case 'target':
$result = $request->getRequestTarget();
break;
case 'req_version':
$result = $request->getProtocolVersion();
break;
case 'res_version':
$result = $response
? $response->getProtocolVersion()
: 'NULL';
break;
case 'host':
$result = $request->getHeaderLine('Host');
break;
case 'hostname':
$result = gethostname();
break;
case 'code':
$result = $response ? $response->getStatusCode() : 'NULL';
break;
case 'phrase':
$result = $response ? $response->getReasonPhrase() : 'NULL';
break;
case 'error':
$result = $error ? $error->getMessage() : 'NULL';
break;
default:

 if (strpos($matches[1], 'req_header_') === 0) {
$result = $request->getHeaderLine(substr($matches[1], 11));
} elseif (strpos($matches[1], 'res_header_') === 0) {
$result = $response
? $response->getHeaderLine(substr($matches[1], 11))
: 'NULL';
}
}

$cache[$matches[1]] = $result;
return $result;
},
$this->template
);
}

private function headers(MessageInterface $message)
{
$result = '';
foreach ($message->getHeaders() as $name => $values) {
$result .= $name . ': ' . implode(', ', $values) . "\r\n";
}

return trim($result);
}
}
<?php
namespace GuzzleHttp;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;





final class TransferStats
{
private $request;
private $response;
private $transferTime;
private $handlerStats;
private $handlerErrorData;








public function __construct(
RequestInterface $request,
ResponseInterface $response = null,
$transferTime = null,
$handlerErrorData = null,
$handlerStats = []
) {
$this->request = $request;
$this->response = $response;
$this->transferTime = $transferTime;
$this->handlerErrorData = $handlerErrorData;
$this->handlerStats = $handlerStats;
}




public function getRequest()
{
return $this->request;
}






public function getResponse()
{
return $this->response;
}






public function hasResponse()
{
return $this->response !== null;
}










public function getHandlerErrorData()
{
return $this->handlerErrorData;
}






public function getEffectiveUri()
{
return $this->request->getUri();
}






public function getTransferTime()
{
return $this->transferTime;
}






public function getHandlerStats()
{
return $this->handlerStats;
}








public function getHandlerStat($stat)
{
return isset($this->handlerStats[$stat])
? $this->handlerStats[$stat]
: null;
}
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;




interface ClientInterface
{
const VERSION = '6.2.1';











public function send(RequestInterface $request, array $options = []);










public function sendAsync(RequestInterface $request, array $options = []);















public function request($method, $uri, array $options = []);















public function requestAsync($method, $uri, array $options = []);












public function getConfig($option = null);
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Promise\PromisorInterface;
use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Promise\EachPromise;












class Pool implements PromisorInterface
{

private $each;











public function __construct(
ClientInterface $client,
$requests,
array $config = []
) {

 if (isset($config['pool_size'])) {
$config['concurrency'] = $config['pool_size'];
} elseif (!isset($config['concurrency'])) {
$config['concurrency'] = 25;
}

if (isset($config['options'])) {
$opts = $config['options'];
unset($config['options']);
} else {
$opts = [];
}

$iterable = \GuzzleHttp\Promise\iter_for($requests);
$requests = function () use ($iterable, $client, $opts) {
foreach ($iterable as $key => $rfn) {
if ($rfn instanceof RequestInterface) {
yield $key => $client->sendAsync($rfn, $opts);
} elseif (is_callable($rfn)) {
yield $key => $rfn($opts);
} else {
throw new \InvalidArgumentException('Each value yielded by '
. 'the iterator must be a Psr7\Http\Message\RequestInterface '
. 'or a callable that returns a promise that fulfills '
. 'with a Psr7\Message\Http\ResponseInterface object.');
}
}
};

$this->each = new EachPromise($requests(), $config);
}

public function promise()
{
return $this->each->promise();
}


















public static function batch(
ClientInterface $client,
$requests,
array $options = []
) {
$res = [];
self::cmpCallback($options, 'fulfilled', $res);
self::cmpCallback($options, 'rejected', $res);
$pool = new static($client, $requests, $options);
$pool->promise()->wait();
ksort($res);

return $res;
}

private static function cmpCallback(array &$options, $name, array &$results)
{
if (!isset($options[$name])) {
$options[$name] = function ($v, $k) use (&$results) {
$results[$k] = $v;
};
} else {
$currentFn = $options[$name];
$options[$name] = function ($v, $k) use (&$results, $currentFn) {
$currentFn($v, $k);
$results[$k] = $v;
};
}
}
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\HandlerStack;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\TransferStats;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;




class MockHandler implements \Countable
{
private $queue;
private $lastRequest;
private $lastOptions;
private $onFulfilled;
private $onRejected;











public static function createWithMiddleware(
array $queue = null,
callable $onFulfilled = null,
callable $onRejected = null
) {
return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
}










public function __construct(
array $queue = null,
callable $onFulfilled = null,
callable $onRejected = null
) {
$this->onFulfilled = $onFulfilled;
$this->onRejected = $onRejected;

if ($queue) {
call_user_func_array([$this, 'append'], $queue);
}
}

public function __invoke(RequestInterface $request, array $options)
{
if (!$this->queue) {
throw new \OutOfBoundsException('Mock queue is empty');
}

if (isset($options['delay'])) {
usleep($options['delay'] * 1000);
}

$this->lastRequest = $request;
$this->lastOptions = $options;
$response = array_shift($this->queue);

if (is_callable($response)) {
$response = call_user_func($response, $request, $options);
}

$response = $response instanceof \Exception
? new RejectedPromise($response)
: \GuzzleHttp\Promise\promise_for($response);

return $response->then(
function ($value) use ($request, $options) {
$this->invokeStats($request, $options, $value);
if ($this->onFulfilled) {
call_user_func($this->onFulfilled, $value);
}
if (isset($options['sink'])) {
$contents = (string) $value->getBody();
$sink = $options['sink'];

if (is_resource($sink)) {
fwrite($sink, $contents);
} elseif (is_string($sink)) {
file_put_contents($sink, $contents);
} elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
$sink->write($contents);
}
}

return $value;
},
function ($reason) use ($request, $options) {
$this->invokeStats($request, $options, null, $reason);
if ($this->onRejected) {
call_user_func($this->onRejected, $reason);
}
return new RejectedPromise($reason);
}
);
}





public function append()
{
foreach (func_get_args() as $value) {
if ($value instanceof ResponseInterface
|| $value instanceof \Exception
|| $value instanceof PromiseInterface
|| is_callable($value)
) {
$this->queue[] = $value;
} else {
throw new \InvalidArgumentException('Expected a response or '
. 'exception. Found ' . \GuzzleHttp\describe_type($value));
}
}
}






public function getLastRequest()
{
return $this->lastRequest;
}






public function getLastOptions()
{
return $this->lastOptions;
}






public function count()
{
return count($this->queue);
}

private function invokeStats(
RequestInterface $request,
array $options,
ResponseInterface $response = null,
$reason = null
) {
if (isset($options['on_stats'])) {
$stats = new TransferStats($request, $response, 0, $reason);
call_user_func($options['on_stats'], $stats);
}
}
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7;
use GuzzleHttp\TransferStats;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;




class StreamHandler
{
private $lastHeaders = [];









public function __invoke(RequestInterface $request, array $options)
{

 if (isset($options['delay'])) {
usleep($options['delay'] * 1000);
}

$startTime = isset($options['on_stats']) ? microtime(true) : null;

try {

 $request = $request->withoutHeader('Expect');


 
 if (0 === $request->getBody()->getSize()) {
$request = $request->withHeader('Content-Length', 0);
}

return $this->createResponse(
$request,
$options,
$this->createStream($request, $options),
$startTime
);
} catch (\InvalidArgumentException $e) {
throw $e;
} catch (\Exception $e) {

 $message = $e->getMessage();

 if (strpos($message, 'getaddrinfo') 
 || strpos($message, 'Connection refused')
|| strpos($message, "couldn't connect to host") 
 ) {
$e = new ConnectException($e->getMessage(), $request, $e);
}
$e = RequestException::wrapException($request, $e);
$this->invokeStats($options, $request, $startTime, null, $e);

return new RejectedPromise($e);
}
}

private function invokeStats(
array $options,
RequestInterface $request,
$startTime,
ResponseInterface $response = null,
$error = null
) {
if (isset($options['on_stats'])) {
$stats = new TransferStats(
$request,
$response,
microtime(true) - $startTime,
$error,
[]
);
call_user_func($options['on_stats'], $stats);
}
}

private function createResponse(
RequestInterface $request,
array $options,
$stream,
$startTime
) {
$hdrs = $this->lastHeaders;
$this->lastHeaders = [];
$parts = explode(' ', array_shift($hdrs), 3);
$ver = explode('/', $parts[0])[1];
$status = $parts[1];
$reason = isset($parts[2]) ? $parts[2] : null;
$headers = \GuzzleHttp\headers_from_lines($hdrs);
list ($stream, $headers) = $this->checkDecode($options, $headers, $stream);
$stream = Psr7\stream_for($stream);
$sink = $stream;

if (strcasecmp('HEAD', $request->getMethod())) {
$sink = $this->createSink($stream, $options);
}

$response = new Psr7\Response($status, $headers, $sink, $ver, $reason);

if (isset($options['on_headers'])) {
try {
$options['on_headers']($response);
} catch (\Exception $e) {
$msg = 'An error was encountered during the on_headers event';
$ex = new RequestException($msg, $request, $response, $e);
return new RejectedPromise($ex);
}
}


 
 if ($sink !== $stream) {
$this->drain(
$stream,
$sink,
$response->getHeaderLine('Content-Length')
);
}

$this->invokeStats($options, $request, $startTime, $response, null);

return new FulfilledPromise($response);
}

private function createSink(StreamInterface $stream, array $options)
{
if (!empty($options['stream'])) {
return $stream;
}

$sink = isset($options['sink'])
? $options['sink']
: fopen('php://temp', 'r+');

return is_string($sink)
? new Psr7\LazyOpenStream($sink, 'w+')
: Psr7\stream_for($sink);
}

private function checkDecode(array $options, array $headers, $stream)
{

 if (!empty($options['decode_content'])) {
$normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
if (isset($normalizedKeys['content-encoding'])) {
$encoding = $headers[$normalizedKeys['content-encoding']];
if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
$stream = new Psr7\InflateStream(
Psr7\stream_for($stream)
);
$headers['x-encoded-content-encoding']
= $headers[$normalizedKeys['content-encoding']];

 unset($headers[$normalizedKeys['content-encoding']]);

 if (isset($normalizedKeys['content-length'])) {
$headers['x-encoded-content-length']
= $headers[$normalizedKeys['content-length']];

$length = (int) $stream->getSize();
if ($length === 0) {
unset($headers[$normalizedKeys['content-length']]);
} else {
$headers[$normalizedKeys['content-length']] = [$length];
}
}
}
}
}

return [$stream, $headers];
}












private function drain(
StreamInterface $source,
StreamInterface $sink,
$contentLength
) {

 
 
 
 Psr7\copy_to_stream(
$source,
$sink,
(strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1
);

$sink->seek(0);
$source->close();

return $sink;
}









private function createResource(callable $callback)
{
$errors = null;
set_error_handler(function ($_, $msg, $file, $line) use (&$errors) {
$errors[] = [
'message' => $msg,
'file' => $file,
'line' => $line
];
return true;
});

$resource = $callback();
restore_error_handler();

if (!$resource) {
$message = 'Error creating resource: ';
foreach ($errors as $err) {
foreach ($err as $key => $value) {
$message .= "[$key] $value" . PHP_EOL;
}
}
throw new \RuntimeException(trim($message));
}

return $resource;
}

private function createStream(RequestInterface $request, array $options)
{
static $methods;
if (!$methods) {
$methods = array_flip(get_class_methods(__CLASS__));
}


 
 if ($request->getProtocolVersion() == '1.1'
&& !$request->hasHeader('Connection')
) {
$request = $request->withHeader('Connection', 'close');
}


 if (!isset($options['verify'])) {
$options['verify'] = true;
}

$params = [];
$context = $this->getDefaultContext($request, $options);

if (isset($options['on_headers']) && !is_callable($options['on_headers'])) {
throw new \InvalidArgumentException('on_headers must be callable');
}

if (!empty($options)) {
foreach ($options as $key => $value) {
$method = "add_{$key}";
if (isset($methods[$method])) {
$this->{$method}($request, $context, $value, $params);
}
}
}

if (isset($options['stream_context'])) {
if (!is_array($options['stream_context'])) {
throw new \InvalidArgumentException('stream_context must be an array');
}
$context = array_replace_recursive(
$context,
$options['stream_context']
);
}

$context = $this->createResource(
function () use ($context, $params) {
return stream_context_create($context, $params);
}
);

return $this->createResource(
function () use ($request, &$http_response_header, $context) {
$resource = fopen((string) $request->getUri()->withFragment(''), 'r', null, $context);
$this->lastHeaders = $http_response_header;
return $resource;
}
);
}

private function getDefaultContext(RequestInterface $request)
{
$headers = '';
foreach ($request->getHeaders() as $name => $value) {
foreach ($value as $val) {
$headers .= "$name: $val\r\n";
}
}

$context = [
'http' => [
'method' => $request->getMethod(),
'header' => $headers,
'protocol_version' => $request->getProtocolVersion(),
'ignore_errors' => true,
'follow_location' => 0,
],
];

$body = (string) $request->getBody();

if (!empty($body)) {
$context['http']['content'] = $body;

 if (!$request->hasHeader('Content-Type')) {
$context['http']['header'] .= "Content-Type:\r\n";
}
}

$context['http']['header'] = rtrim($context['http']['header']);

return $context;
}

private function add_proxy(RequestInterface $request, &$options, $value, &$params)
{
if (!is_array($value)) {
$options['http']['proxy'] = $value;
} else {
$scheme = $request->getUri()->getScheme();
if (isset($value[$scheme])) {
if (!isset($value['no'])
|| !\GuzzleHttp\is_host_in_noproxy(
$request->getUri()->getHost(),
$value['no']
)
) {
$options['http']['proxy'] = $value[$scheme];
}
}
}
}

private function add_timeout(RequestInterface $request, &$options, $value, &$params)
{
if ($value > 0) {
$options['http']['timeout'] = $value;
}
}

private function add_verify(RequestInterface $request, &$options, $value, &$params)
{
if ($value === true) {

 
 if (PHP_VERSION_ID < 50600) {
$options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle();
}
} elseif (is_string($value)) {
$options['ssl']['cafile'] = $value;
if (!file_exists($value)) {
throw new \RuntimeException("SSL CA bundle not found: $value");
}
} elseif ($value === false) {
$options['ssl']['verify_peer'] = false;
$options['ssl']['verify_peer_name'] = false;
return;
} else {
throw new \InvalidArgumentException('Invalid verify request option');
}

$options['ssl']['verify_peer'] = true;
$options['ssl']['verify_peer_name'] = true;
$options['ssl']['allow_self_signed'] = false;
}

private function add_cert(RequestInterface $request, &$options, $value, &$params)
{
if (is_array($value)) {
$options['ssl']['passphrase'] = $value[1];
$value = $value[0];
}

if (!file_exists($value)) {
throw new \RuntimeException("SSL certificate not found: {$value}");
}

$options['ssl']['local_cert'] = $value;
}

private function add_progress(RequestInterface $request, &$options, $value, &$params)
{
$this->addNotification(
$params,
function ($code, $a, $b, $c, $transferred, $total) use ($value) {
if ($code == STREAM_NOTIFY_PROGRESS) {
$value($total, $transferred, null, null);
}
}
);
}

private function add_debug(RequestInterface $request, &$options, $value, &$params)
{
if ($value === false) {
return;
}

static $map = [
STREAM_NOTIFY_CONNECT => 'CONNECT',
STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
STREAM_NOTIFY_PROGRESS => 'PROGRESS',
STREAM_NOTIFY_FAILURE => 'FAILURE',
STREAM_NOTIFY_COMPLETED => 'COMPLETED',
STREAM_NOTIFY_RESOLVE => 'RESOLVE',
];
static $args = ['severity', 'message', 'message_code',
'bytes_transferred', 'bytes_max'];

$value = \GuzzleHttp\debug_resource($value);
$ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
$this->addNotification(
$params,
function () use ($ident, $value, $map, $args) {
$passed = func_get_args();
$code = array_shift($passed);
fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
foreach (array_filter($passed) as $i => $v) {
fwrite($value, $args[$i] . ': "' . $v . '" ');
}
fwrite($value, "\n");
}
);
}

private function addNotification(array &$params, callable $notify)
{

 if (!isset($params['notification'])) {
$params['notification'] = $notify;
} else {
$params['notification'] = $this->callArray([
$params['notification'],
$notify
]);
}
}

private function callArray(array $functions)
{
return function () use ($functions) {
$args = func_get_args();
foreach ($functions as $fn) {
call_user_func_array($fn, $args);
}
};
}
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\LazyOpenStream;
use GuzzleHttp\TransferStats;
use Psr\Http\Message\RequestInterface;




class CurlFactory implements CurlFactoryInterface
{

private $handles;


private $maxHandles;




public function __construct($maxHandles)
{
$this->maxHandles = $maxHandles;
}

public function create(RequestInterface $request, array $options)
{
if (isset($options['curl']['body_as_string'])) {
$options['_body_as_string'] = $options['curl']['body_as_string'];
unset($options['curl']['body_as_string']);
}

$easy = new EasyHandle;
$easy->request = $request;
$easy->options = $options;
$conf = $this->getDefaultConf($easy);
$this->applyMethod($easy, $conf);
$this->applyHandlerOptions($easy, $conf);
$this->applyHeaders($easy, $conf);
unset($conf['_headers']);


 if (isset($options['curl'])) {
$conf = array_replace($conf, $options['curl']);
}

$conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
$easy->handle = $this->handles
? array_pop($this->handles)
: curl_init();
curl_setopt_array($easy->handle, $conf);

return $easy;
}

public function release(EasyHandle $easy)
{
$resource = $easy->handle;
unset($easy->handle);

if (count($this->handles) >= $this->maxHandles) {
curl_close($resource);
} else {

 
 
 
 curl_setopt($resource, CURLOPT_HEADERFUNCTION, null);
curl_setopt($resource, CURLOPT_READFUNCTION, null);
curl_setopt($resource, CURLOPT_WRITEFUNCTION, null);
curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null);
curl_reset($resource);
$this->handles[] = $resource;
}
}











public static function finish(
callable $handler,
EasyHandle $easy,
CurlFactoryInterface $factory
) {
if (isset($easy->options['on_stats'])) {
self::invokeStats($easy);
}

if (!$easy->response || $easy->errno) {
return self::finishError($handler, $easy, $factory);
}


 $factory->release($easy);


 $body = $easy->response->getBody();
if ($body->isSeekable()) {
$body->rewind();
}

return new FulfilledPromise($easy->response);
}

private static function invokeStats(EasyHandle $easy)
{
$curlStats = curl_getinfo($easy->handle);
$stats = new TransferStats(
$easy->request,
$easy->response,
$curlStats['total_time'],
$easy->errno,
$curlStats
);
call_user_func($easy->options['on_stats'], $stats);
}

private static function finishError(
callable $handler,
EasyHandle $easy,
CurlFactoryInterface $factory
) {

 $ctx = [
'errno' => $easy->errno,
'error' => curl_error($easy->handle),
] + curl_getinfo($easy->handle);
$factory->release($easy);


 if (empty($easy->options['_err_message'])
&& (!$easy->errno || $easy->errno == 65)
) {
return self::retryFailedRewind($handler, $easy, $ctx);
}

return self::createRejection($easy, $ctx);
}

private static function createRejection(EasyHandle $easy, array $ctx)
{
static $connectionErrors = [
CURLE_OPERATION_TIMEOUTED => true,
CURLE_COULDNT_RESOLVE_HOST => true,
CURLE_COULDNT_CONNECT => true,
CURLE_SSL_CONNECT_ERROR => true,
CURLE_GOT_NOTHING => true,
];


 
 if ($easy->onHeadersException) {
return new RejectedPromise(
new RequestException(
'An error was encountered during the on_headers event',
$easy->request,
$easy->response,
$easy->onHeadersException,
$ctx
)
);
}

$message = sprintf(
'cURL error %s: %s (%s)',
$ctx['errno'],
$ctx['error'],
'see http://curl.haxx.se/libcurl/c/libcurl-errors.html'
);


 $error = isset($connectionErrors[$easy->errno])
? new ConnectException($message, $easy->request, null, $ctx)
: new RequestException($message, $easy->request, $easy->response, null, $ctx);

return new RejectedPromise($error);
}

private function getDefaultConf(EasyHandle $easy)
{
$conf = [
'_headers' => $easy->request->getHeaders(),
CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HEADER => false,
CURLOPT_CONNECTTIMEOUT => 150,
];

if (defined('CURLOPT_PROTOCOLS')) {
$conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS;
}

$version = $easy->request->getProtocolVersion();
if ($version == 1.1) {
$conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
} elseif ($version == 2.0) {
$conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
} else {
$conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
}

return $conf;
}

private function applyMethod(EasyHandle $easy, array &$conf)
{
$body = $easy->request->getBody();
$size = $body->getSize();

if ($size === null || $size > 0) {
$this->applyBody($easy->request, $easy->options, $conf);
return;
}

$method = $easy->request->getMethod();
if ($method === 'PUT' || $method === 'POST') {

 if (!$easy->request->hasHeader('Content-Length')) {
$conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
}
} elseif ($method === 'HEAD') {
$conf[CURLOPT_NOBODY] = true;
unset(
$conf[CURLOPT_WRITEFUNCTION],
$conf[CURLOPT_READFUNCTION],
$conf[CURLOPT_FILE],
$conf[CURLOPT_INFILE]
);
}
}

private function applyBody(RequestInterface $request, array $options, array &$conf)
{
$size = $request->hasHeader('Content-Length')
? (int) $request->getHeaderLine('Content-Length')
: null;


 
 if (($size !== null && $size < 1000000) ||
!empty($options['_body_as_string'])
) {
$conf[CURLOPT_POSTFIELDS] = (string) $request->getBody();

 $this->removeHeader('Content-Length', $conf);
$this->removeHeader('Transfer-Encoding', $conf);
} else {
$conf[CURLOPT_UPLOAD] = true;
if ($size !== null) {
$conf[CURLOPT_INFILESIZE] = $size;
$this->removeHeader('Content-Length', $conf);
}
$body = $request->getBody();
if ($body->isSeekable()) {
$body->rewind();
}
$conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) {
return $body->read($length);
};
}


 if (!$request->hasHeader('Expect')) {
$conf[CURLOPT_HTTPHEADER][] = 'Expect:';
}


 if (!$request->hasHeader('Content-Type')) {
$conf[CURLOPT_HTTPHEADER][] = 'Content-Type:';
}
}

private function applyHeaders(EasyHandle $easy, array &$conf)
{
foreach ($conf['_headers'] as $name => $values) {
foreach ($values as $value) {
$conf[CURLOPT_HTTPHEADER][] = "$name: $value";
}
}


 if (!$easy->request->hasHeader('Accept')) {
$conf[CURLOPT_HTTPHEADER][] = 'Accept:';
}
}







private function removeHeader($name, array &$options)
{
foreach (array_keys($options['_headers']) as $key) {
if (!strcasecmp($key, $name)) {
unset($options['_headers'][$key]);
return;
}
}
}

private function applyHandlerOptions(EasyHandle $easy, array &$conf)
{
$options = $easy->options;
if (isset($options['verify'])) {
if ($options['verify'] === false) {
unset($conf[CURLOPT_CAINFO]);
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = false;
} else {
$conf[CURLOPT_SSL_VERIFYHOST] = 2;
$conf[CURLOPT_SSL_VERIFYPEER] = true;
if (is_string($options['verify'])) {
$conf[CURLOPT_CAINFO] = $options['verify'];
if (!file_exists($options['verify'])) {
throw new \InvalidArgumentException(
"SSL CA bundle not found: {$options['verify']}"
);
}
}
}
}

if (!empty($options['decode_content'])) {
$accept = $easy->request->getHeaderLine('Accept-Encoding');
if ($accept) {
$conf[CURLOPT_ENCODING] = $accept;
} else {
$conf[CURLOPT_ENCODING] = '';

 $conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
}
}

if (isset($options['sink'])) {
$sink = $options['sink'];
if (!is_string($sink)) {
$sink = \GuzzleHttp\Psr7\stream_for($sink);
} elseif (!is_dir(dirname($sink))) {

 throw new \RuntimeException(sprintf(
'Directory %s does not exist for sink value of %s',
dirname($sink),
$sink
));
} else {
$sink = new LazyOpenStream($sink, 'w+');
}
$easy->sink = $sink;
$conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) {
return $sink->write($write);
};
} else {

 $conf[CURLOPT_FILE] = fopen('php://temp', 'w+');
$easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]);
}

if (isset($options['timeout'])) {
$conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
}

if (isset($options['connect_timeout'])) {
$conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
}

if (isset($options['proxy'])) {
if (!is_array($options['proxy'])) {
$conf[CURLOPT_PROXY] = $options['proxy'];
} else {
$scheme = $easy->request->getUri()->getScheme();
if (isset($options['proxy'][$scheme])) {
$host = $easy->request->getUri()->getHost();
if (!isset($options['proxy']['no']) ||
!\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no'])
) {
$conf[CURLOPT_PROXY] = $options['proxy'][$scheme];
}
}
}
}

if (isset($options['cert'])) {
$cert = $options['cert'];
if (is_array($cert)) {
$conf[CURLOPT_SSLCERTPASSWD] = $cert[1];
$cert = $cert[0];
}
if (!file_exists($cert)) {
throw new \InvalidArgumentException(
"SSL certificate not found: {$cert}"
);
}
$conf[CURLOPT_SSLCERT] = $cert;
}

if (isset($options['ssl_key'])) {
$sslKey = $options['ssl_key'];
if (is_array($sslKey)) {
$conf[CURLOPT_SSLKEYPASSWD] = $sslKey[1];
$sslKey = $sslKey[0];
}
if (!file_exists($sslKey)) {
throw new \InvalidArgumentException(
"SSL private key not found: {$sslKey}"
);
}
$conf[CURLOPT_SSLKEY] = $sslKey;
}

if (isset($options['progress'])) {
$progress = $options['progress'];
if (!is_callable($progress)) {
throw new \InvalidArgumentException(
'progress client option must be callable'
);
}
$conf[CURLOPT_NOPROGRESS] = false;
$conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) {
$args = func_get_args();

 if (is_resource($args[0])) {
array_shift($args);
}
call_user_func_array($progress, $args);
};
}

if (!empty($options['debug'])) {
$conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']);
$conf[CURLOPT_VERBOSE] = true;
}
}










private static function retryFailedRewind(
callable $handler,
EasyHandle $easy,
array $ctx
) {
try {

 $body = $easy->request->getBody();
if ($body->tell() > 0) {
$body->rewind();
}
} catch (\RuntimeException $e) {
$ctx['error'] = 'The connection unexpectedly failed without '
. 'providing an error. The request would have been retried, '
. 'but attempting to rewind the request body failed. '
. 'Exception: ' . $e;
return self::createRejection($easy, $ctx);
}


 if (!isset($easy->options['_curl_retries'])) {
$easy->options['_curl_retries'] = 1;
} elseif ($easy->options['_curl_retries'] == 2) {
$ctx['error'] = 'The cURL request was retried 3 times '
. 'and did not succeed. The most likely reason for the failure '
. 'is that cURL was unable to rewind the body of the request '
. 'and subsequent retries resulted in the same error. Turn on '
. 'the debug option to see what went wrong. See '
. 'https://bugs.php.net/bug.php?id=47204 for more information.';
return self::createRejection($easy, $ctx);
} else {
$easy->options['_curl_retries']++;
}

return $handler($easy->request, $easy->options);
}

private function createHeaderFn(EasyHandle $easy)
{
if (isset($easy->options['on_headers'])) {
$onHeaders = $easy->options['on_headers'];

if (!is_callable($onHeaders)) {
throw new \InvalidArgumentException('on_headers must be callable');
}
} else {
$onHeaders = null;
}

return function ($ch, $h) use (
$onHeaders,
$easy,
&$startingResponse
) {
$value = trim($h);
if ($value === '') {
$startingResponse = true;
$easy->createResponse();
if ($onHeaders !== null) {
try {
$onHeaders($easy->response);
} catch (\Exception $e) {

 
 $easy->onHeadersException = $e;
return -1;
}
}
} elseif ($startingResponse) {
$startingResponse = false;
$easy->headers = [$value];
} else {
$easy->headers[] = $value;
}
return strlen($h);
};
}
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;




class Proxy
{









public static function wrapSync(
callable $default,
callable $sync
) {
return function (RequestInterface $request, array $options) use ($default, $sync) {
return empty($options[RequestOptions::SYNCHRONOUS])
? $default($request, $options)
: $sync($request, $options);
};
}














public static function wrapStreaming(
callable $default,
callable $streaming
) {
return function (RequestInterface $request, array $options) use ($default, $streaming) {
return empty($options['stream'])
? $default($request, $options)
: $streaming($request, $options);
};
}
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;






final class EasyHandle
{

public $handle;


public $sink;


public $headers = [];


public $response;


public $request;


public $options = [];


public $errno = 0;


public $onHeadersException;






public function createResponse()
{
if (empty($this->headers)) {
throw new \RuntimeException('No headers have been received');
}


 $startLine = explode(' ', array_shift($this->headers), 3);
$headers = \GuzzleHttp\headers_from_lines($this->headers);
$normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);

if (!empty($this->options['decode_content'])
&& isset($normalizedKeys['content-encoding'])
) {
$headers['x-encoded-content-encoding']
= $headers[$normalizedKeys['content-encoding']];
unset($headers[$normalizedKeys['content-encoding']]);
if (isset($normalizedKeys['content-length'])) {
$headers['x-encoded-content-length']
= $headers[$normalizedKeys['content-length']];

$bodyLength = (int) $this->sink->getSize();
if ($bodyLength) {
$headers[$normalizedKeys['content-length']] = $bodyLength;
} else {
unset($headers[$normalizedKeys['content-length']]);
}
}
}


 $this->response = new Response(
$startLine[1],
$headers,
$this->sink,
substr($startLine[0], 5),
isset($startLine[2]) ? (string) $startLine[2] : null
);
}

public function __get($name)
{
$msg = $name === 'handle'
? 'The EasyHandle has been released'
: 'Invalid property: ' . $name;
throw new \BadMethodCallException($msg);
}
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;










class CurlMultiHandler
{

private $factory;
private $selectTimeout;
private $active;
private $handles = [];
private $delays = [];










public function __construct(array $options = [])
{
$this->factory = isset($options['handle_factory'])
? $options['handle_factory'] : new CurlFactory(50);
$this->selectTimeout = isset($options['select_timeout'])
? $options['select_timeout'] : 1;
}

public function __get($name)
{
if ($name === '_mh') {
return $this->_mh = curl_multi_init();
}

throw new \BadMethodCallException();
}

public function __destruct()
{
if (isset($this->_mh)) {
curl_multi_close($this->_mh);
unset($this->_mh);
}
}

public function __invoke(RequestInterface $request, array $options)
{
$easy = $this->factory->create($request, $options);
$id = (int) $easy->handle;

$promise = new Promise(
[$this, 'execute'],
function () use ($id) { return $this->cancel($id); }
);

$this->addRequest(['easy' => $easy, 'deferred' => $promise]);

return $promise;
}




public function tick()
{

 if ($this->delays) {
$currentTime = microtime(true);
foreach ($this->delays as $id => $delay) {
if ($currentTime >= $delay) {
unset($this->delays[$id]);
curl_multi_add_handle(
$this->_mh,
$this->handles[$id]['easy']->handle
);
}
}
}


 P\queue()->run();

if ($this->active &&
curl_multi_select($this->_mh, $this->selectTimeout) === -1
) {

 
 usleep(250);
}

while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM);

$this->processMessages();
}




public function execute()
{
$queue = P\queue();

while ($this->handles || !$queue->isEmpty()) {

 if (!$this->active && $this->delays) {
usleep($this->timeToNext());
}
$this->tick();
}
}

private function addRequest(array $entry)
{
$easy = $entry['easy'];
$id = (int) $easy->handle;
$this->handles[$id] = $entry;
if (empty($easy->options['delay'])) {
curl_multi_add_handle($this->_mh, $easy->handle);
} else {
$this->delays[$id] = microtime(true) + ($easy->options['delay'] / 1000);
}
}








private function cancel($id)
{

 if (!isset($this->handles[$id])) {
return false;
}

$handle = $this->handles[$id]['easy']->handle;
unset($this->delays[$id], $this->handles[$id]);
curl_multi_remove_handle($this->_mh, $handle);
curl_close($handle);

return true;
}

private function processMessages()
{
while ($done = curl_multi_info_read($this->_mh)) {
$id = (int) $done['handle'];
curl_multi_remove_handle($this->_mh, $done['handle']);

if (!isset($this->handles[$id])) {

 continue;
}

$entry = $this->handles[$id];
unset($this->handles[$id], $this->delays[$id]);
$entry['easy']->errno = $done['result'];
$entry['deferred']->resolve(
CurlFactory::finish(
$this,
$entry['easy'],
$this->factory
)
);
}
}

private function timeToNext()
{
$currentTime = microtime(true);
$nextTime = PHP_INT_MAX;
foreach ($this->delays as $time) {
if ($time < $nextTime) {
$nextTime = $time;
}
}

return max(0, $nextTime - $currentTime) * 1000000;
}
}
<?php
namespace GuzzleHttp\Handler;

use Psr\Http\Message\RequestInterface;

interface CurlFactoryInterface
{









public function create(RequestInterface $request, array $options);








public function release(EasyHandle $easy);
}
<?php
namespace GuzzleHttp\Handler;

use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;








class CurlHandler
{

private $factory;








public function __construct(array $options = [])
{
$this->factory = isset($options['handle_factory'])
? $options['handle_factory']
: new CurlFactory(3);
}

public function __invoke(RequestInterface $request, array $options)
{
if (isset($options['delay'])) {
usleep($options['delay'] * 1000);
}

$easy = $this->factory->create($request, $options);
curl_exec($easy->handle);
$easy->errno = curl_errno($easy->handle);

return CurlFactory::finish($this, $easy, $this->factory);
}
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Handler\CurlMultiHandler;
use GuzzleHttp\Handler\Proxy;
use GuzzleHttp\Handler\StreamHandler;









function uri_template($template, array $variables)
{
if (extension_loaded('uri_template')) {

 return \uri_template($template, $variables);

 }

static $uriTemplate;
if (!$uriTemplate) {
$uriTemplate = new UriTemplate();
}

return $uriTemplate->expand($template, $variables);
}









function describe_type($input)
{
switch (gettype($input)) {
case 'object':
return 'object(' . get_class($input) . ')';
case 'array':
return 'array(' . count($input) . ')';
default:
ob_start();
var_dump($input);

 return str_replace('double(', 'float(', rtrim(ob_get_clean()));
}
}








function headers_from_lines($lines)
{
$headers = [];

foreach ($lines as $line) {
$parts = explode(':', $line, 2);
$headers[trim($parts[0])][] = isset($parts[1])
? trim($parts[1])
: null;
}

return $headers;
}








function debug_resource($value = null)
{
if (is_resource($value)) {
return $value;
} elseif (defined('STDOUT')) {
return STDOUT;
}

return fopen('php://output', 'w');
}









function choose_handler()
{
$handler = null;
if (function_exists('curl_multi_exec') && function_exists('curl_exec')) {
$handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
} elseif (function_exists('curl_exec')) {
$handler = new CurlHandler();
} elseif (function_exists('curl_multi_exec')) {
$handler = new CurlMultiHandler();
}

if (ini_get('allow_url_fopen')) {
$handler = $handler
? Proxy::wrapStreaming($handler, new StreamHandler())
: new StreamHandler();
} elseif (!$handler) {
throw new \RuntimeException('GuzzleHttp requires cURL, the '
. 'allow_url_fopen ini setting, or a custom HTTP handler.');
}

return $handler;
}






function default_user_agent()
{
static $defaultAgent = '';

if (!$defaultAgent) {
$defaultAgent = 'GuzzleHttp/' . Client::VERSION;
if (extension_loaded('curl') && function_exists('curl_version')) {
$defaultAgent .= ' curl/' . \curl_version()['version'];
}
$defaultAgent .= ' PHP/' . PHP_VERSION;
}

return $defaultAgent;
}















function default_ca_bundle()
{
static $cached = null;
static $cafiles = [

 '/etc/pki/tls/certs/ca-bundle.crt',

 '/etc/ssl/certs/ca-certificates.crt',

 '/usr/local/share/certs/ca-root-nss.crt',

 '/usr/local/etc/openssl/cert.pem',

 '/etc/ca-certificates.crt',

 'C:\\windows\\system32\\curl-ca-bundle.crt',
'C:\\windows\\curl-ca-bundle.crt',
];

if ($cached) {
return $cached;
}

if ($ca = ini_get('openssl.cafile')) {
return $cached = $ca;
}

if ($ca = ini_get('curl.cainfo')) {
return $cached = $ca;
}

foreach ($cafiles as $filename) {
if (file_exists($filename)) {
return $cached = $filename;
}
}

throw new \RuntimeException(<<< EOT
No system CA bundle could be found in any of the the common system locations.
PHP versions earlier than 5.6 are not properly configured to use the system's
CA bundle by default. In order to verify peer certificates, you will need to
supply the path on disk to a certificate bundle to the 'verify' request
option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not
need a specific certificate bundle, then Mozilla provides a commonly used CA
bundle which can be downloaded here (provided by the maintainer of cURL):
https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once
you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP
ini setting to point to the path to the file, allowing you to omit the 'verify'
request option. See http://curl.haxx.se/docs/sslcerts.html for more
information.
EOT
);
}









function normalize_header_keys(array $headers)
{
$result = [];
foreach (array_keys($headers) as $key) {
$result[strtolower($key)] = $key;
}

return $result;
}




















function is_host_in_noproxy($host, array $noProxyArray)
{
if (strlen($host) === 0) {
throw new \InvalidArgumentException('Empty host provided');
}


 if (strpos($host, ':')) {
$host = explode($host, ':', 2)[0];
}

foreach ($noProxyArray as $area) {

 if ($area === '*') {
return true;
} elseif (empty($area)) {

 continue;
} elseif ($area === $host) {

 return true;
} else {

 
 $area = '.' . ltrim($area, '.');
if (substr($host, -(strlen($area))) === $area) {
return true;
}
}
}

return false;
}














function json_decode($json, $assoc = false, $depth = 512, $options = 0)
{
$data = \json_decode($json, $assoc, $depth, $options);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException(
'json_decode error: ' . json_last_error_msg());
}

return $data;
}












function json_encode($value, $options = 0, $depth = 512)
{
$json = \json_encode($value, $options, $depth);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException(
'json_encode error: ' . json_last_error_msg());
}

return $json;
}
<?php
namespace GuzzleHttp\Cookie;




class SetCookie
{

private static $defaults = [
'Name' => null,
'Value' => null,
'Domain' => null,
'Path' => '/',
'Max-Age' => null,
'Expires' => null,
'Secure' => false,
'Discard' => false,
'HttpOnly' => false
];


private $data;








public static function fromString($cookie)
{

 $data = self::$defaults;

 $pieces = array_filter(array_map('trim', explode(';', $cookie)));

 if (empty($pieces) || !strpos($pieces[0], '=')) {
return new self($data);
}


 foreach ($pieces as $part) {

$cookieParts = explode('=', $part, 2);
$key = trim($cookieParts[0]);
$value = isset($cookieParts[1])
? trim($cookieParts[1], " \n\r\t\0\x0B")
: true;


 if (empty($data['Name'])) {
$data['Name'] = $key;
$data['Value'] = $value;
} else {
foreach (array_keys(self::$defaults) as $search) {
if (!strcasecmp($search, $key)) {
$data[$search] = $value;
continue 2;
}
}
$data[$key] = $value;
}
}

return new self($data);
}




public function __construct(array $data = [])
{
$this->data = array_replace(self::$defaults, $data);

 if (!$this->getExpires() && $this->getMaxAge()) {

 $this->setExpires(time() + $this->getMaxAge());
} elseif ($this->getExpires() && !is_numeric($this->getExpires())) {
$this->setExpires($this->getExpires());
}
}

public function __toString()
{
$str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
foreach ($this->data as $k => $v) {
if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
if ($k === 'Expires') {
$str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
} else {
$str .= ($v === true ? $k : "{$k}={$v}") . '; ';
}
}
}

return rtrim($str, '; ');
}

public function toArray()
{
return $this->data;
}






public function getName()
{
return $this->data['Name'];
}






public function setName($name)
{
$this->data['Name'] = $name;
}






public function getValue()
{
return $this->data['Value'];
}






public function setValue($value)
{
$this->data['Value'] = $value;
}






public function getDomain()
{
return $this->data['Domain'];
}






public function setDomain($domain)
{
$this->data['Domain'] = $domain;
}






public function getPath()
{
return $this->data['Path'];
}






public function setPath($path)
{
$this->data['Path'] = $path;
}






public function getMaxAge()
{
return $this->data['Max-Age'];
}






public function setMaxAge($maxAge)
{
$this->data['Max-Age'] = $maxAge;
}






public function getExpires()
{
return $this->data['Expires'];
}






public function setExpires($timestamp)
{
$this->data['Expires'] = is_numeric($timestamp)
? (int) $timestamp
: strtotime($timestamp);
}






public function getSecure()
{
return $this->data['Secure'];
}






public function setSecure($secure)
{
$this->data['Secure'] = $secure;
}






public function getDiscard()
{
return $this->data['Discard'];
}






public function setDiscard($discard)
{
$this->data['Discard'] = $discard;
}






public function getHttpOnly()
{
return $this->data['HttpOnly'];
}






public function setHttpOnly($httpOnly)
{
$this->data['HttpOnly'] = $httpOnly;
}


















public function matchesPath($requestPath)
{
$cookiePath = $this->getPath();


 if ($cookiePath === '/' || $cookiePath == $requestPath) {
return true;
}


 if (0 !== strpos($requestPath, $cookiePath)) {
return false;
}


 if (substr($cookiePath, -1, 1) === '/') {
return true;
}


 return substr($requestPath, strlen($cookiePath), 1) === '/';
}








public function matchesDomain($domain)
{

 
 $cookieDomain = ltrim($this->getDomain(), '.');


 if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) {
return true;
}


 
 if (filter_var($domain, FILTER_VALIDATE_IP)) {
return false;
}

return (bool) preg_match('/\.' . preg_quote($cookieDomain) . '$/', $domain);
}






public function isExpired()
{
return $this->getExpires() && time() > $this->getExpires();
}






public function validate()
{

 $name = $this->getName();
if (empty($name) && !is_numeric($name)) {
return 'The cookie name must not be empty';
}


 if (preg_match(
'/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/',
$name)
) {
return 'Cookie name must not contain invalid characters: ASCII '
. 'Control characters (0-31;127), space, tab and the '
. 'following characters: ()<>@,;:\"/?={}';
}


 $value = $this->getValue();
if (empty($value) && !is_numeric($value)) {
return 'The cookie value must not be empty';
}


 
 
 $domain = $this->getDomain();
if (empty($domain) && !is_numeric($domain)) {
return 'The cookie domain must not be empty';
}

return true;
}
}
<?php
namespace GuzzleHttp\Cookie;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;











interface CookieJarInterface extends \Countable, \IteratorAggregate
{










public function withCookieHeader(RequestInterface $request);







public function extractCookies(
RequestInterface $request,
ResponseInterface $response
);








public function setCookie(SetCookie $cookie);

















public function clear($domain = null, $path = null, $name = null);








public function clearSessionCookies();






public function toArray();
}
<?php
namespace GuzzleHttp\Cookie;




class FileCookieJar extends CookieJar
{

private $filename;


private $storeSessionCookies;










public function __construct($cookieFile, $storeSessionCookies = false)
{
$this->filename = $cookieFile;
$this->storeSessionCookies = $storeSessionCookies;

if (file_exists($cookieFile)) {
$this->load($cookieFile);
}
}




public function __destruct()
{
$this->save($this->filename);
}







public function save($filename)
{
$json = [];
foreach ($this as $cookie) {

if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
$json[] = $cookie->toArray();
}
}

$jsonStr = \GuzzleHttp\json_encode($json);
if (false === file_put_contents($filename, $jsonStr)) {
throw new \RuntimeException("Unable to save file {$filename}");
}
}









public function load($filename)
{
$json = file_get_contents($filename);
if (false === $json) {
throw new \RuntimeException("Unable to load file {$filename}");
} elseif ($json === '') {
return;
}

$data = \GuzzleHttp\json_decode($json, true);
if (is_array($data)) {
foreach (json_decode($json, true) as $cookie) {
$this->setCookie(new SetCookie($cookie));
}
} elseif (strlen($data)) {
throw new \RuntimeException("Invalid cookie file: {$filename}");
}
}
}
<?php
namespace GuzzleHttp\Cookie;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;




class CookieJar implements CookieJarInterface
{

private $cookies = [];


private $strictMode;








public function __construct($strictMode = false, $cookieArray = [])
{
$this->strictMode = $strictMode;

foreach ($cookieArray as $cookie) {
if (!($cookie instanceof SetCookie)) {
$cookie = new SetCookie($cookie);
}
$this->setCookie($cookie);
}
}









public static function fromArray(array $cookies, $domain)
{
$cookieJar = new self();
foreach ($cookies as $name => $value) {
$cookieJar->setCookie(new SetCookie([
'Domain' => $domain,
'Name' => $name,
'Value' => $value,
'Discard' => true
]));
}

return $cookieJar;
}




public static function getCookieValue($value)
{
return $value;
}









public static function shouldPersist(
SetCookie $cookie,
$allowSessionCookies = false
) {
if ($cookie->getExpires() || $allowSessionCookies) {
if (!$cookie->getDiscard()) {
return true;
}
}

return false;
}

public function toArray()
{
return array_map(function (SetCookie $cookie) {
return $cookie->toArray();
}, $this->getIterator()->getArrayCopy());
}

public function clear($domain = null, $path = null, $name = null)
{
if (!$domain) {
$this->cookies = [];
return;
} elseif (!$path) {
$this->cookies = array_filter(
$this->cookies,
function (SetCookie $cookie) use ($path, $domain) {
return !$cookie->matchesDomain($domain);
}
);
} elseif (!$name) {
$this->cookies = array_filter(
$this->cookies,
function (SetCookie $cookie) use ($path, $domain) {
return !($cookie->matchesPath($path) &&
$cookie->matchesDomain($domain));
}
);
} else {
$this->cookies = array_filter(
$this->cookies,
function (SetCookie $cookie) use ($path, $domain, $name) {
return !($cookie->getName() == $name &&
$cookie->matchesPath($path) &&
$cookie->matchesDomain($domain));
}
);
}
}

public function clearSessionCookies()
{
$this->cookies = array_filter(
$this->cookies,
function (SetCookie $cookie) {
return !$cookie->getDiscard() && $cookie->getExpires();
}
);
}

public function setCookie(SetCookie $cookie)
{

 
 $name = $cookie->getName();
if (!$name && $name !== '0') {
return false;
}


 $result = $cookie->validate();
if ($result !== true) {
if ($this->strictMode) {
throw new \RuntimeException('Invalid cookie: ' . $result);
} else {
$this->removeCookieIfEmpty($cookie);
return false;
}
}


 foreach ($this->cookies as $i => $c) {


 
 if ($c->getPath() != $cookie->getPath() ||
$c->getDomain() != $cookie->getDomain() ||
$c->getName() != $cookie->getName()
) {
continue;
}


 
 if (!$cookie->getDiscard() && $c->getDiscard()) {
unset($this->cookies[$i]);
continue;
}


 
 if ($cookie->getExpires() > $c->getExpires()) {
unset($this->cookies[$i]);
continue;
}


 if ($cookie->getValue() !== $c->getValue()) {
unset($this->cookies[$i]);
continue;
}


 return false;
}

$this->cookies[] = $cookie;

return true;
}

public function count()
{
return count($this->cookies);
}

public function getIterator()
{
return new \ArrayIterator(array_values($this->cookies));
}

public function extractCookies(
RequestInterface $request,
ResponseInterface $response
) {
if ($cookieHeader = $response->getHeader('Set-Cookie')) {
foreach ($cookieHeader as $cookie) {
$sc = SetCookie::fromString($cookie);
if (!$sc->getDomain()) {
$sc->setDomain($request->getUri()->getHost());
}
$this->setCookie($sc);
}
}
}

public function withCookieHeader(RequestInterface $request)
{
$values = [];
$uri = $request->getUri();
$scheme = $uri->getScheme();
$host = $uri->getHost();
$path = $uri->getPath() ?: '/';

foreach ($this->cookies as $cookie) {
if ($cookie->matchesPath($path) &&
$cookie->matchesDomain($host) &&
!$cookie->isExpired() &&
(!$cookie->getSecure() || $scheme === 'https')
) {
$values[] = $cookie->getName() . '='
. $cookie->getValue();
}
}

return $values
? $request->withHeader('Cookie', implode('; ', $values))
: $request;
}







private function removeCookieIfEmpty(SetCookie $cookie)
{
$cookieValue = $cookie->getValue();
if ($cookieValue === null || $cookieValue === '') {
$this->clear(
$cookie->getDomain(),
$cookie->getPath(),
$cookie->getName()
);
}
}
}
<?php
namespace GuzzleHttp\Cookie;




class SessionCookieJar extends CookieJar
{

private $sessionKey;


private $storeSessionCookies;









public function __construct($sessionKey, $storeSessionCookies = false)
{
$this->sessionKey = $sessionKey;
$this->storeSessionCookies = $storeSessionCookies;
$this->load();
}




public function __destruct()
{
$this->save();
}




public function save()
{
$json = [];
foreach ($this as $cookie) {

if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
$json[] = $cookie->toArray();
}
}

$_SESSION[$this->sessionKey] = json_encode($json);
}




protected function load()
{
if (!isset($_SESSION[$this->sessionKey])) {
return;
}
$data = json_decode($_SESSION[$this->sessionKey], true);
if (is_array($data)) {
foreach ($data as $cookie) {
$this->setCookie(new SetCookie($cookie));
}
} elseif (strlen($data)) {
throw new \RuntimeException("Invalid cookie data");
}
}
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Promise;
use GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;















class Client implements ClientInterface
{

private $config;

































public function __construct(array $config = [])
{
if (!isset($config['handler'])) {
$config['handler'] = HandlerStack::create();
}


 if (isset($config['base_uri'])) {
$config['base_uri'] = Psr7\uri_for($config['base_uri']);
}

$this->configureDefaults($config);
}

public function __call($method, $args)
{
if (count($args) < 1) {
throw new \InvalidArgumentException('Magic request methods require a URI and optional options array');
}

$uri = $args[0];
$opts = isset($args[1]) ? $args[1] : [];

return substr($method, -5) === 'Async'
? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
: $this->request($method, $uri, $opts);
}

public function sendAsync(RequestInterface $request, array $options = [])
{

 $options = $this->prepareDefaults($options);

return $this->transfer(
$request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
$options
);
}

public function send(RequestInterface $request, array $options = [])
{
$options[RequestOptions::SYNCHRONOUS] = true;
return $this->sendAsync($request, $options)->wait();
}

public function requestAsync($method, $uri = '', array $options = [])
{
$options = $this->prepareDefaults($options);

 $headers = isset($options['headers']) ? $options['headers'] : [];
$body = isset($options['body']) ? $options['body'] : null;
$version = isset($options['version']) ? $options['version'] : '1.1';

 $uri = $this->buildUri($uri, $options);
if (is_array($body)) {
$this->invalidBody();
}
$request = new Psr7\Request($method, $uri, $headers, $body, $version);

 unset($options['headers'], $options['body'], $options['version']);

return $this->transfer($request, $options);
}

public function request($method, $uri = '', array $options = [])
{
$options[RequestOptions::SYNCHRONOUS] = true;
return $this->requestAsync($method, $uri, $options)->wait();
}

public function getConfig($option = null)
{
return $option === null
? $this->config
: (isset($this->config[$option]) ? $this->config[$option] : null);
}

private function buildUri($uri, array $config)
{

 $uri = Psr7\uri_for($uri === null ? '' : $uri);

if (isset($config['base_uri'])) {
$uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
}

return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
}






private function configureDefaults(array $config)
{
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];




 
 
 if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
$defaults['proxy']['http'] = getenv('HTTP_PROXY');
}

if ($proxy = getenv('HTTPS_PROXY')) {
$defaults['proxy']['https'] = $proxy;
}

if ($noProxy = getenv('NO_PROXY')) {
$cleanedNoProxy = str_replace(' ', '', $noProxy);
$defaults['proxy']['no'] = explode(',', $cleanedNoProxy);
}

$this->config = $config + $defaults;

if (!empty($config['cookies']) && $config['cookies'] === true) {
$this->config['cookies'] = new CookieJar();
}


 if (!isset($this->config['headers'])) {
$this->config['headers'] = ['User-Agent' => default_user_agent()];
} else {

 foreach (array_keys($this->config['headers']) as $name) {
if (strtolower($name) === 'user-agent') {
return;
}
}
$this->config['headers']['User-Agent'] = default_user_agent();
}
}








private function prepareDefaults($options)
{
$defaults = $this->config;

if (!empty($defaults['headers'])) {

 $defaults['_conditional'] = $defaults['headers'];
unset($defaults['headers']);
}


 
 if (array_key_exists('headers', $options)) {

 if ($options['headers'] === null) {
$defaults['_conditional'] = null;
unset($options['headers']);
} elseif (!is_array($options['headers'])) {
throw new \InvalidArgumentException('headers must be an array');
}
}


 $result = $options + $defaults;


 foreach ($result as $k => $v) {
if ($v === null) {
unset($result[$k]);
}
}

return $result;
}












private function transfer(RequestInterface $request, array $options)
{

 if (isset($options['save_to'])) {
$options['sink'] = $options['save_to'];
unset($options['save_to']);
}


 if (isset($options['exceptions'])) {
$options['http_errors'] = $options['exceptions'];
unset($options['exceptions']);
}

$request = $this->applyOptions($request, $options);
$handler = $options['handler'];

try {
return Promise\promise_for($handler($request, $options));
} catch (\Exception $e) {
return Promise\rejection_for($e);
}
}









private function applyOptions(RequestInterface $request, array &$options)
{
$modify = [];

if (isset($options['form_params'])) {
if (isset($options['multipart'])) {
throw new \InvalidArgumentException('You cannot use '
. 'form_params and multipart at the same time. Use the '
. 'form_params option if you want to send application/'
. 'x-www-form-urlencoded requests, and the multipart '
. 'option to send multipart/form-data requests.');
}
$options['body'] = http_build_query($options['form_params'], '', '&');
unset($options['form_params']);
$options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
}

if (isset($options['multipart'])) {
$options['body'] = new Psr7\MultipartStream($options['multipart']);
unset($options['multipart']);
}

if (isset($options['json'])) {
$options['body'] = \GuzzleHttp\json_encode($options['json']);
unset($options['json']);
$options['_conditional']['Content-Type'] = 'application/json';
}

if (!empty($options['decode_content'])
&& $options['decode_content'] !== true
) {
$modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
}

if (isset($options['headers'])) {
if (isset($modify['set_headers'])) {
$modify['set_headers'] = $options['headers'] + $modify['set_headers'];
} else {
$modify['set_headers'] = $options['headers'];
}
unset($options['headers']);
}

if (isset($options['body'])) {
if (is_array($options['body'])) {
$this->invalidBody();
}
$modify['body'] = Psr7\stream_for($options['body']);
unset($options['body']);
}

if (!empty($options['auth']) && is_array($options['auth'])) {
$value = $options['auth'];
$type = isset($value[2]) ? strtolower($value[2]) : 'basic';
switch ($type) {
case 'basic':
$modify['set_headers']['Authorization'] = 'Basic '
. base64_encode("$value[0]:$value[1]");
break;
case 'digest':

 $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
$options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
break;
}
}

if (isset($options['query'])) {
$value = $options['query'];
if (is_array($value)) {
$value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
}
if (!is_string($value)) {
throw new \InvalidArgumentException('query must be a string or array');
}
$modify['query'] = $value;
unset($options['query']);
}


 if (isset($options['sink'])) {

 if (is_bool($options['sink'])) {
throw new \InvalidArgumentException('sink must not be a boolean');
}
}

$request = Psr7\modify_request($request, $modify);
if ($request->getBody() instanceof Psr7\MultipartStream) {

 $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
. $request->getBody()->getBoundary();
}


 if (isset($options['_conditional'])) {

 $modify = [];
foreach ($options['_conditional'] as $k => $v) {
if (!$request->hasHeader($k)) {
$modify['set_headers'][$k] = $v;
}
}
$request = Psr7\modify_request($request, $modify);

 unset($options['_conditional']);
}

return $request;
}

private function invalidBody()
{
throw new \InvalidArgumentException('Passing in the "body" request '
. 'option as an array to send a POST request has been deprecated. '
. 'Please use the "form_params" request option to send a '
. 'application/x-www-form-urlencoded request, or a the "multipart" '
. 'request option to send a multipart/form-data request.');
}
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;





class PrepareBodyMiddleware
{

private $nextHandler;


private static $skipMethods = ['GET' => true, 'HEAD' => true];




public function __construct(callable $nextHandler)
{
$this->nextHandler = $nextHandler;
}







public function __invoke(RequestInterface $request, array $options)
{
$fn = $this->nextHandler;


 if (isset(self::$skipMethods[$request->getMethod()])
|| $request->getBody()->getSize() === 0
) {
return $fn($request, $options);
}

$modify = [];


 if (!$request->hasHeader('Content-Type')) {
if ($uri = $request->getBody()->getMetadata('uri')) {
if ($type = Psr7\mimetype_from_filename($uri)) {
$modify['set_headers']['Content-Type'] = $type;
}
}
}


 if (!isset(self::$skipMethods[$request->getMethod()])
&& !$request->hasHeader('Content-Length')
&& !$request->hasHeader('Transfer-Encoding')
) {
$size = $request->getBody()->getSize();
if ($size !== null) {
$modify['set_headers']['Content-Length'] = $size;
} else {
$modify['set_headers']['Transfer-Encoding'] = 'chunked';
}
}


 $this->addExpectHeader($request, $options, $modify);

return $fn(Psr7\modify_request($request, $modify), $options);
}

private function addExpectHeader(
RequestInterface $request,
array $options,
array &$modify
) {

 if ($request->hasHeader('Expect')) {
return;
}

$expect = isset($options['expect']) ? $options['expect'] : null;


 if ($expect === false || $request->getProtocolVersion() < 1.1) {
return;
}


 if ($expect === true) {
$modify['set_headers']['Expect'] = '100-Continue';
return;
}


 if ($expect === null) {
$expect = 1048576;
}


 
 $body = $request->getBody();
$size = $body->getSize();

if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
$modify['set_headers']['Expect'] = '100-Continue';
}
}
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Cookie\CookieJarInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Psr7;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;




final class Middleware
{








public static function cookies()
{
return function (callable $handler) {
return function ($request, array $options) use ($handler) {
if (empty($options['cookies'])) {
return $handler($request, $options);
} elseif (!($options['cookies'] instanceof CookieJarInterface)) {
throw new \InvalidArgumentException('cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface');
}
$cookieJar = $options['cookies'];
$request = $cookieJar->withCookieHeader($request);
return $handler($request, $options)
->then(function ($response) use ($cookieJar, $request) {
$cookieJar->extractCookies($request, $response);
return $response;
}
);
};
};
}







public static function httpErrors()
{
return function (callable $handler) {
return function ($request, array $options) use ($handler) {
if (empty($options['http_errors'])) {
return $handler($request, $options);
}
return $handler($request, $options)->then(
function (ResponseInterface $response) use ($request, $handler) {
$code = $response->getStatusCode();
if ($code < 400) {
return $response;
}
throw RequestException::create($request, $response);
}
);
};
};
}









public static function history(&$container)
{
if (!is_array($container) && !$container instanceof \ArrayAccess) {
throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
}

return function (callable $handler) use (&$container) {
return function ($request, array $options) use ($handler, &$container) {
return $handler($request, $options)->then(
function ($value) use ($request, &$container, $options) {
$container[] = [
'request' => $request,
'response' => $value,
'error' => null,
'options' => $options
];
return $value;
},
function ($reason) use ($request, &$container, $options) {
$container[] = [
'request' => $request,
'response' => null,
'error' => $reason,
'options' => $options
];
return new RejectedPromise($reason);
}
);
};
};
}














public static function tap(callable $before = null, callable $after = null)
{
return function (callable $handler) use ($before, $after) {
return function ($request, array $options) use ($handler, $before, $after) {
if ($before) {
$before($request, $options);
}
$response = $handler($request, $options);
if ($after) {
$after($request, $options, $response);
}
return $response;
};
};
}






public static function redirect()
{
return function (callable $handler) {
return new RedirectMiddleware($handler);
};
}
















public static function retry(callable $decider, callable $delay = null)
{
return function (callable $handler) use ($decider, $delay) {
return new RetryMiddleware($decider, $handler, $delay);
};
}











public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
{
return function (callable $handler) use ($logger, $formatter, $logLevel) {
return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
return $handler($request, $options)->then(
function ($response) use ($logger, $request, $formatter, $logLevel) {
$message = $formatter->format($request, $response);
$logger->log($logLevel, $message);
return $response;
},
function ($reason) use ($logger, $request, $formatter) {
$response = $reason instanceof RequestException
? $reason->getResponse()
: null;
$message = $formatter->format($request, $response, $reason);
$logger->notice($message);
return \GuzzleHttp\Promise\rejection_for($reason);
}
);
};
};
}







public static function prepareBody()
{
return function (callable $handler) {
return new PrepareBodyMiddleware($handler);
};
}









public static function mapRequest(callable $fn)
{
return function (callable $handler) use ($fn) {
return function ($request, array $options) use ($handler, $fn) {
return $handler($fn($request), $options);
};
};
}









public static function mapResponse(callable $fn)
{
return function (callable $handler) use ($fn) {
return function ($request, array $options) use ($handler, $fn) {
return $handler($request, $options)->then($fn);
};
};
}
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\TooManyRedirectsException;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;







class RedirectMiddleware
{
const HISTORY_HEADER = 'X-Guzzle-Redirect-History';

public static $defaultSettings = [
'max' => 5,
'protocols' => ['http', 'https'],
'strict' => false,
'referer' => false,
'track_redirects' => false,
];


private $nextHandler;




public function __construct(callable $nextHandler)
{
$this->nextHandler = $nextHandler;
}







public function __invoke(RequestInterface $request, array $options)
{
$fn = $this->nextHandler;

if (empty($options['allow_redirects'])) {
return $fn($request, $options);
}

if ($options['allow_redirects'] === true) {
$options['allow_redirects'] = self::$defaultSettings;
} elseif (!is_array($options['allow_redirects'])) {
throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
} else {

 $options['allow_redirects'] += self::$defaultSettings;
}

if (empty($options['allow_redirects']['max'])) {
return $fn($request, $options);
}

return $fn($request, $options)
->then(function (ResponseInterface $response) use ($request, $options) {
return $this->checkRedirect($request, $options, $response);
});
}








public function checkRedirect(
RequestInterface $request,
array $options,
ResponseInterface $response
) {
if (substr($response->getStatusCode(), 0, 1) != '3'
|| !$response->hasHeader('Location')
) {
return $response;
}

$this->guardMax($request, $options);
$nextRequest = $this->modifyRequest($request, $options, $response);

if (isset($options['allow_redirects']['on_redirect'])) {
call_user_func(
$options['allow_redirects']['on_redirect'],
$request,
$response,
$nextRequest->getUri()
);
}


$promise = $this($nextRequest, $options);


 if (!empty($options['allow_redirects']['track_redirects'])) {
return $this->withTracking(
$promise,
(string) $nextRequest->getUri()
);
}

return $promise;
}

private function withTracking(PromiseInterface $promise, $uri)
{
return $promise->then(
function (ResponseInterface $response) use ($uri) {

 
 
 $header = $response->getHeader(self::HISTORY_HEADER);
array_unshift($header, $uri);
return $response->withHeader(self::HISTORY_HEADER, $header);
}
);
}

private function guardMax(RequestInterface $request, array &$options)
{
$current = isset($options['__redirect_count'])
? $options['__redirect_count']
: 0;
$options['__redirect_count'] = $current + 1;
$max = $options['allow_redirects']['max'];

if ($options['__redirect_count'] > $max) {
throw new TooManyRedirectsException(
"Will not follow more than {$max} redirects",
$request
);
}
}








public function modifyRequest(
RequestInterface $request,
array $options,
ResponseInterface $response
) {

 $modify = [];
$protocols = $options['allow_redirects']['protocols'];


 
 
 $statusCode = $response->getStatusCode();
if ($statusCode == 303 ||
($statusCode <= 302 && $request->getBody() && !$options['allow_redirects']['strict'])
) {
$modify['method'] = 'GET';
$modify['body'] = '';
}

$modify['uri'] = $this->redirectUri($request, $response, $protocols);
Psr7\rewind_body($request);


 
 if ($options['allow_redirects']['referer']
&& $modify['uri']->getScheme() === $request->getUri()->getScheme()
) {
$uri = $request->getUri()->withUserInfo('', '');
$modify['set_headers']['Referer'] = (string) $uri;
} else {
$modify['remove_headers'][] = 'Referer';
}


 if ($request->getUri()->getHost() !== $modify['uri']->getHost()) {
$modify['remove_headers'][] = 'Authorization';
}

return Psr7\modify_request($request, $modify);
}










private function redirectUri(
RequestInterface $request,
ResponseInterface $response,
array $protocols
) {
$location = Psr7\UriResolver::resolve(
$request->getUri(),
new Psr7\Uri($response->getHeaderLine('Location'))
);


 if (!in_array($location->getScheme(), $protocols)) {
throw new BadResponseException(
sprintf(
'Redirect URI, %s, does not use one of the allowed redirect protocols: %s',
$location,
implode(', ', $protocols)
),
$request,
$response
);
}

return $location;
}
}
<?php
namespace GuzzleHttp;






class UriTemplate
{

private $template;


private $variables;


private static $operatorHash = [
'' => ['prefix' => '', 'joiner' => ',', 'query' => false],
'+' => ['prefix' => '', 'joiner' => ',', 'query' => false],
'#' => ['prefix' => '#', 'joiner' => ',', 'query' => false],
'.' => ['prefix' => '.', 'joiner' => '.', 'query' => false],
'/' => ['prefix' => '/', 'joiner' => '/', 'query' => false],
';' => ['prefix' => ';', 'joiner' => ';', 'query' => true],
'?' => ['prefix' => '?', 'joiner' => '&', 'query' => true],
'&' => ['prefix' => '&', 'joiner' => '&', 'query' => true]
];


private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$',
'&', '\'', '(', ')', '*', '+', ',', ';', '='];


private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D',
'%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C',
'%3B', '%3D'];

public function expand($template, array $variables)
{
if (false === strpos($template, '{')) {
return $template;
}

$this->template = $template;
$this->variables = $variables;

return preg_replace_callback(
'/\{([^\}]+)\}/',
[$this, 'expandMatch'],
$this->template
);
}








private function parseExpression($expression)
{
$result = [];

if (isset(self::$operatorHash[$expression[0]])) {
$result['operator'] = $expression[0];
$expression = substr($expression, 1);
} else {
$result['operator'] = '';
}

foreach (explode(',', $expression) as $value) {
$value = trim($value);
$varspec = [];
if ($colonPos = strpos($value, ':')) {
$varspec['value'] = substr($value, 0, $colonPos);
$varspec['modifier'] = ':';
$varspec['position'] = (int) substr($value, $colonPos + 1);
} elseif (substr($value, -1) === '*') {
$varspec['modifier'] = '*';
$varspec['value'] = substr($value, 0, -1);
} else {
$varspec['value'] = (string) $value;
$varspec['modifier'] = '';
}
$result['values'][] = $varspec;
}

return $result;
}








private function expandMatch(array $matches)
{
static $rfc1738to3986 = ['+' => '%20', '%7e' => '~'];

$replacements = [];
$parsed = self::parseExpression($matches[1]);
$prefix = self::$operatorHash[$parsed['operator']]['prefix'];
$joiner = self::$operatorHash[$parsed['operator']]['joiner'];
$useQuery = self::$operatorHash[$parsed['operator']]['query'];

foreach ($parsed['values'] as $value) {

if (!isset($this->variables[$value['value']])) {
continue;
}

$variable = $this->variables[$value['value']];
$actuallyUseQuery = $useQuery;
$expanded = '';

if (is_array($variable)) {

$isAssoc = $this->isAssoc($variable);
$kvp = [];
foreach ($variable as $key => $var) {

if ($isAssoc) {
$key = rawurlencode($key);
$isNestedArray = is_array($var);
} else {
$isNestedArray = false;
}

if (!$isNestedArray) {
$var = rawurlencode($var);
if ($parsed['operator'] === '+' ||
$parsed['operator'] === '#'
) {
$var = $this->decodeReserved($var);
}
}

if ($value['modifier'] === '*') {
if ($isAssoc) {
if ($isNestedArray) {

 
 $var = strtr(
http_build_query([$key => $var]),
$rfc1738to3986
);
} else {
$var = $key . '=' . $var;
}
} elseif ($key > 0 && $actuallyUseQuery) {
$var = $value['value'] . '=' . $var;
}
}

$kvp[$key] = $var;
}

if (empty($variable)) {
$actuallyUseQuery = false;
} elseif ($value['modifier'] === '*') {
$expanded = implode($joiner, $kvp);
if ($isAssoc) {

 
 $actuallyUseQuery = false;
}
} else {
if ($isAssoc) {

 
 
 
 foreach ($kvp as $k => &$v) {
$v = $k . ',' . $v;
}
}
$expanded = implode(',', $kvp);
}

} else {
if ($value['modifier'] === ':') {
$variable = substr($variable, 0, $value['position']);
}
$expanded = rawurlencode($variable);
if ($parsed['operator'] === '+' || $parsed['operator'] === '#') {
$expanded = $this->decodeReserved($expanded);
}
}

if ($actuallyUseQuery) {
if (!$expanded && $joiner !== '&') {
$expanded = $value['value'];
} else {
$expanded = $value['value'] . '=' . $expanded;
}
}

$replacements[] = $expanded;
}

$ret = implode($joiner, $replacements);
if ($ret && $prefix) {
return $prefix . $ret;
}

return $ret;
}













private function isAssoc(array $array)
{
return $array && array_keys($array)[0] !== 0;
}









private function decodeReserved($string)
{
return str_replace(self::$delimsPct, self::$delims, $string);
}
}
<?php
namespace GuzzleHttp;

use Psr\Http\Message\RequestInterface;





class HandlerStack
{

private $handler;


private $stack = [];


private $cached;


















public static function create(callable $handler = null)
{
$stack = new self($handler ?: choose_handler());
$stack->push(Middleware::httpErrors(), 'http_errors');
$stack->push(Middleware::redirect(), 'allow_redirects');
$stack->push(Middleware::cookies(), 'cookies');
$stack->push(Middleware::prepareBody(), 'prepare_body');

return $stack;
}




public function __construct(callable $handler = null)
{
$this->handler = $handler;
}







public function __invoke(RequestInterface $request, array $options)
{
$handler = $this->resolve();

return $handler($request, $options);
}






public function __toString()
{
$depth = 0;
$stack = [];
if ($this->handler) {
$stack[] = "0) Handler: " . $this->debugCallable($this->handler);
}

$result = '';
foreach (array_reverse($this->stack) as $tuple) {
$depth++;
$str = "{$depth}) Name: '{$tuple[1]}', ";
$str .= "Function: " . $this->debugCallable($tuple[0]);
$result = "> {$str}\n{$result}";
$stack[] = $str;
}

foreach (array_keys($stack) as $k) {
$result .= "< {$stack[$k]}\n";
}

return $result;
}







public function setHandler(callable $handler)
{
$this->handler = $handler;
$this->cached = null;
}






public function hasHandler()
{
return (bool) $this->handler;
}







public function unshift(callable $middleware, $name = null)
{
array_unshift($this->stack, [$middleware, $name]);
$this->cached = null;
}







public function push(callable $middleware, $name = '')
{
$this->stack[] = [$middleware, $name];
$this->cached = null;
}








public function before($findName, callable $middleware, $withName = '')
{
$this->splice($findName, $withName, $middleware, true);
}








public function after($findName, callable $middleware, $withName = '')
{
$this->splice($findName, $withName, $middleware, false);
}






public function remove($remove)
{
$this->cached = null;
$idx = is_callable($remove) ? 0 : 1;
$this->stack = array_values(array_filter(
$this->stack,
function ($tuple) use ($idx, $remove) {
return $tuple[$idx] !== $remove;
}
));
}






public function resolve()
{
if (!$this->cached) {
if (!($prev = $this->handler)) {
throw new \LogicException('No handler has been specified');
}

foreach (array_reverse($this->stack) as $fn) {
$prev = $fn[0]($prev);
}

$this->cached = $prev;
}

return $this->cached;
}





private function findByName($name)
{
foreach ($this->stack as $k => $v) {
if ($v[1] === $name) {
return $k;
}
}

throw new \InvalidArgumentException("Middleware not found: $name");
}









private function splice($findName, $withName, callable $middleware, $before)
{
$this->cached = null;
$idx = $this->findByName($findName);
$tuple = [$middleware, $withName];

if ($before) {
if ($idx === 0) {
array_unshift($this->stack, $tuple);
} else {
$replacement = [$tuple, $this->stack[$idx]];
array_splice($this->stack, $idx, 1, $replacement);
}
} elseif ($idx === count($this->stack) - 1) {
$this->stack[] = $tuple;
} else {
$replacement = [$this->stack[$idx], $tuple];
array_splice($this->stack, $idx, 1, $replacement);
}
}








private function debugCallable($fn)
{
if (is_string($fn)) {
return "callable({$fn})";
}

if (is_array($fn)) {
return is_string($fn[0])
? "callable({$fn[0]}::{$fn[1]})"
: "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])";
}

return 'callable(' . spl_object_hash($fn) . ')';
}
}
<?php
namespace GuzzleHttp;








final class RequestOptions
{





















const ALLOW_REDIRECTS = 'allow_redirects';








const AUTH = 'auth';





const BODY = 'body';








const CERT = 'cert';








const COOKIES = 'cookies';






const CONNECT_TIMEOUT = 'connect_timeout';






const DEBUG = 'debug';






const DECODE_CONTENT = 'decode_content';




const DELAY = 'delay';

















const EXPECT = 'expect';







const FORM_PARAMS = 'form_params';





const HEADERS = 'headers';







const HTTP_ERRORS = 'http_errors';






const JSON = 'json';










const MULTIPART = 'multipart';






const ON_HEADERS = 'on_headers';










const ON_STATS = 'on_stats';








const PROGRESS = 'progress';






const PROXY = 'proxy';







const QUERY = 'query';






const SINK = 'sink';







const SYNCHRONOUS = 'synchronous';







const SSL_KEY = 'ssl_key';





const STREAM = 'stream';









const VERIFY = 'verify';





const TIMEOUT = 'timeout';




const VERSION = 'version';
}
<?php


if (!function_exists('GuzzleHttp\uri_template')) {
require __DIR__ . '/functions.php';
}
<?php
namespace GuzzleHttp;

use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\RejectedPromise;
use GuzzleHttp\Psr7;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;





class RetryMiddleware
{

private $nextHandler;


private $decider;











public function __construct(
callable $decider,
callable $nextHandler,
callable $delay = null
) {
$this->decider = $decider;
$this->nextHandler = $nextHandler;
$this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
}








public static function exponentialDelay($retries)
{
return (int) pow(2, $retries - 1);
}







public function __invoke(RequestInterface $request, array $options)
{
if (!isset($options['retries'])) {
$options['retries'] = 0;
}

$fn = $this->nextHandler;
return $fn($request, $options)
->then(
$this->onFulfilled($request, $options),
$this->onRejected($request, $options)
);
}

private function onFulfilled(RequestInterface $req, array $options)
{
return function ($value) use ($req, $options) {
if (!call_user_func(
$this->decider,
$options['retries'],
$req,
$value,
null
)) {
return $value;
}
return $this->doRetry($req, $options, $value);
};
}

private function onRejected(RequestInterface $req, array $options)
{
return function ($reason) use ($req, $options) {
if (!call_user_func(
$this->decider,
$options['retries'],
$req,
null,
$reason
)) {
return new RejectedPromise($reason);
}
return $this->doRetry($req, $options);
};
}

private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
{
$options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);

return $this($request, $options);
}
}
<?php
namespace GuzzleHttp\Exception;

use Psr\Http\Message\StreamInterface;




class SeekException extends \RuntimeException implements GuzzleException
{
private $stream;

public function __construct(StreamInterface $stream, $pos = 0, $msg = '')
{
$this->stream = $stream;
$msg = $msg ?: 'Could not seek the stream to position ' . $pos;
parent::__construct($msg);
}




public function getStream()
{
return $this->stream;
}
}
<?php
namespace GuzzleHttp\Exception;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\UriInterface;




class RequestException extends TransferException
{

private $request;


private $response;


private $handlerContext;

public function __construct(
$message,
RequestInterface $request,
ResponseInterface $response = null,
\Exception $previous = null,
array $handlerContext = []
) {

 $code = $response && !($response instanceof PromiseInterface)
? $response->getStatusCode()
: 0;
parent::__construct($message, $code, $previous);
$this->request = $request;
$this->response = $response;
$this->handlerContext = $handlerContext;
}









public static function wrapException(RequestInterface $request, \Exception $e)
{
return $e instanceof RequestException
? $e
: new RequestException($e->getMessage(), $request, null, $e);
}











public static function create(
RequestInterface $request,
ResponseInterface $response = null,
\Exception $previous = null,
array $ctx = []
) {
if (!$response) {
return new self(
'Error completing request',
$request,
null,
$previous,
$ctx
);
}

$level = (int) floor($response->getStatusCode() / 100);
if ($level === 4) {
$label = 'Client error';
$className = __NAMESPACE__ . '\\ClientException';
} elseif ($level === 5) {
$label = 'Server error';
$className = __NAMESPACE__ . '\\ServerException';
} else {
$label = 'Unsuccessful request';
$className = __CLASS__;
}

$uri = $request->getUri();
$uri = static::obfuscateUri($uri);


 
 $message = sprintf(
'%s: `%s` resulted in a `%s` response',
$label,
$request->getMethod() . ' ' . $uri,
$response->getStatusCode() . ' ' . $response->getReasonPhrase()
);

$summary = static::getResponseBodySummary($response);

if ($summary !== null) {
$message .= ":\n{$summary}\n";
}

return new $className($message, $request, $response, $previous, $ctx);
}










public static function getResponseBodySummary(ResponseInterface $response)
{
$body = $response->getBody();

if (!$body->isSeekable()) {
return null;
}

$size = $body->getSize();
$summary = $body->read(120);
$body->rewind();

if ($size > 120) {
$summary .= ' (truncated...)';
}


 
 if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
return null;
}

return $summary;
}








private static function obfuscateUri($uri)
{
$userInfo = $uri->getUserInfo();

if (false !== ($pos = strpos($userInfo, ':'))) {
return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
}

return $uri;
}






public function getRequest()
{
return $this->request;
}






public function getResponse()
{
return $this->response;
}






public function hasResponse()
{
return $this->response !== null;
}











public function getHandlerContext()
{
return $this->handlerContext;
}
}
<?php
namespace GuzzleHttp\Exception;

class TransferException extends \RuntimeException implements GuzzleException {}
<?php
namespace GuzzleHttp\Exception;




class BadResponseException extends RequestException {}
<?php
namespace GuzzleHttp\Exception;

interface GuzzleException {}
<?php
namespace GuzzleHttp\Exception;




class ClientException extends BadResponseException {}
<?php
namespace GuzzleHttp\Exception;




class ServerException extends BadResponseException {}
<?php
namespace GuzzleHttp\Exception;

class TooManyRedirectsException extends RequestException {}
<?php
namespace GuzzleHttp\Exception;

use Psr\Http\Message\RequestInterface;






class ConnectException extends RequestException
{
public function __construct(
$message,
RequestInterface $request,
\Exception $previous = null,
array $handlerContext = []
) {
parent::__construct($message, $request, null, $previous, $handlerContext);
}




public function getResponse()
{
return null;
}




public function hasResponse()
{
return false;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;





class DroppingStream implements StreamInterface
{
use StreamDecoratorTrait;

private $maxLength;





public function __construct(StreamInterface $stream, $maxLength)
{
$this->stream = $stream;
$this->maxLength = $maxLength;
}

public function write($string)
{
$diff = $this->maxLength - $this->stream->getSize();


 if ($diff <= 0) {
return 0;
}


 if (strlen($string) < $diff) {
return $this->stream->write($string);
}

return $this->stream->write(substr($string, 0, $diff));
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;




class Response implements ResponseInterface
{
use MessageTrait;


private static $phrases = [
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
207 => 'Multi-status',
208 => 'Already Reported',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
306 => 'Switch Proxy',
307 => 'Temporary Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
407 => 'Proxy Authentication Required',
408 => 'Request Time-out',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Request Entity Too Large',
414 => 'Request-URI Too Large',
415 => 'Unsupported Media Type',
416 => 'Requested range not satisfiable',
417 => 'Expectation Failed',
418 => 'I\'m a teapot',
422 => 'Unprocessable Entity',
423 => 'Locked',
424 => 'Failed Dependency',
425 => 'Unordered Collection',
426 => 'Upgrade Required',
428 => 'Precondition Required',
429 => 'Too Many Requests',
431 => 'Request Header Fields Too Large',
451 => 'Unavailable For Legal Reasons',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Time-out',
505 => 'HTTP Version not supported',
506 => 'Variant Also Negotiates',
507 => 'Insufficient Storage',
508 => 'Loop Detected',
511 => 'Network Authentication Required',
];


private $reasonPhrase = '';


private $statusCode = 200;








public function __construct(
$status = 200,
array $headers = [],
$body = null,
$version = '1.1',
$reason = null
) {
$this->statusCode = (int) $status;

if ($body !== '' && $body !== null) {
$this->stream = stream_for($body);
}

$this->setHeaders($headers);
if ($reason == '' && isset(self::$phrases[$this->statusCode])) {
$this->reasonPhrase = self::$phrases[$this->statusCode];
} else {
$this->reasonPhrase = (string) $reason;
}

$this->protocol = $version;
}

public function getStatusCode()
{
return $this->statusCode;
}

public function getReasonPhrase()
{
return $this->reasonPhrase;
}

public function withStatus($code, $reasonPhrase = '')
{
$new = clone $this;
$new->statusCode = (int) $code;
if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) {
$reasonPhrase = self::$phrases[$new->statusCode];
}
$new->reasonPhrase = $reasonPhrase;
return $new;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;








function str(MessageInterface $message)
{
if ($message instanceof RequestInterface) {
$msg = trim($message->getMethod() . ' '
. $message->getRequestTarget())
. ' HTTP/' . $message->getProtocolVersion();
if (!$message->hasHeader('host')) {
$msg .= "\r\nHost: " . $message->getUri()->getHost();
}
} elseif ($message instanceof ResponseInterface) {
$msg = 'HTTP/' . $message->getProtocolVersion() . ' '
. $message->getStatusCode() . ' '
. $message->getReasonPhrase();
} else {
throw new \InvalidArgumentException('Unknown message type');
}

foreach ($message->getHeaders() as $name => $values) {
$msg .= "\r\n{$name}: " . implode(', ', $values);
}

return "{$msg}\r\n\r\n" . $message->getBody();
}













function uri_for($uri)
{
if ($uri instanceof UriInterface) {
return $uri;
} elseif (is_string($uri)) {
return new Uri($uri);
}

throw new \InvalidArgumentException('URI must be a string or UriInterface');
}














function stream_for($resource = '', array $options = [])
{
if (is_scalar($resource)) {
$stream = fopen('php://temp', 'r+');
if ($resource !== '') {
fwrite($stream, $resource);
fseek($stream, 0);
}
return new Stream($stream, $options);
}

switch (gettype($resource)) {
case 'resource':
return new Stream($resource, $options);
case 'object':
if ($resource instanceof StreamInterface) {
return $resource;
} elseif ($resource instanceof \Iterator) {
return new PumpStream(function () use ($resource) {
if (!$resource->valid()) {
return false;
}
$result = $resource->current();
$resource->next();
return $result;
}, $options);
} elseif (method_exists($resource, '__toString')) {
return stream_for((string) $resource, $options);
}
break;
case 'NULL':
return new Stream(fopen('php://temp', 'r+'), $options);
}

if (is_callable($resource)) {
return new PumpStream($resource, $options);
}

throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
}











function parse_header($header)
{
static $trimmed = "\"'  \n\t\r";
$params = $matches = [];

foreach (normalize_header($header) as $val) {
$part = [];
foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
$m = $matches[0];
if (isset($m[1])) {
$part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
} else {
$part[] = trim($m[0], $trimmed);
}
}
}
if ($part) {
$params[] = $part;
}
}

return $params;
}









function normalize_header($header)
{
if (!is_array($header)) {
return array_map('trim', explode(',', $header));
}

$result = [];
foreach ($header as $value) {
foreach ((array) $value as $v) {
if (strpos($v, ',') === false) {
$result[] = $v;
continue;
}
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
$result[] = trim($vv);
}
}
}

return $result;
}


















function modify_request(RequestInterface $request, array $changes)
{
if (!$changes) {
return $request;
}

$headers = $request->getHeaders();

if (!isset($changes['uri'])) {
$uri = $request->getUri();
} else {

 if ($host = $changes['uri']->getHost()) {
$changes['set_headers']['Host'] = $host;

if ($port = $changes['uri']->getPort()) {
$standardPorts = ['http' => 80, 'https' => 443];
$scheme = $changes['uri']->getScheme();
if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
$changes['set_headers']['Host'] .= ':'.$port;
}
}
}
$uri = $changes['uri'];
}

if (!empty($changes['remove_headers'])) {
$headers = _caseless_remove($changes['remove_headers'], $headers);
}

if (!empty($changes['set_headers'])) {
$headers = _caseless_remove(array_keys($changes['set_headers']), $headers);
$headers = $changes['set_headers'] + $headers;
}

if (isset($changes['query'])) {
$uri = $uri->withQuery($changes['query']);
}

if ($request instanceof ServerRequestInterface) {
return new ServerRequest(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion(),
$request->getServerParams()
);
}

return new Request(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion()
);
}











function rewind_body(MessageInterface $message)
{
$body = $message->getBody();

if ($body->tell()) {
$body->rewind();
}
}













function try_fopen($filename, $mode)
{
$ex = null;
set_error_handler(function () use ($filename, $mode, &$ex) {
$ex = new \RuntimeException(sprintf(
'Unable to open %s using mode %s: %s',
$filename,
$mode,
func_get_args()[1]
));
});

$handle = fopen($filename, $mode);
restore_error_handler();

if ($ex) {

throw $ex;
}

return $handle;
}











function copy_to_string(StreamInterface $stream, $maxLen = -1)
{
$buffer = '';

if ($maxLen === -1) {
while (!$stream->eof()) {
$buf = $stream->read(1048576);

 if ($buf == null) {
break;
}
$buffer .= $buf;
}
return $buffer;
}

$len = 0;
while (!$stream->eof() && $len < $maxLen) {
$buf = $stream->read($maxLen - $len);

 if ($buf == null) {
break;
}
$buffer .= $buf;
$len = strlen($buffer);
}

return $buffer;
}












function copy_to_stream(
StreamInterface $source,
StreamInterface $dest,
$maxLen = -1
) {
$bufferSize = 8192;

if ($maxLen === -1) {
while (!$source->eof()) {
if (!$dest->write($source->read($bufferSize))) {
break;
}
}
} else {
$remaining = $maxLen;
while ($remaining > 0 && !$source->eof()) {
$buf = $source->read(min($bufferSize, $remaining));
$len = strlen($buf);
if (!$len) {
break;
}
$remaining -= $len;
$dest->write($buf);
}
}
}











function hash(
StreamInterface $stream,
$algo,
$rawOutput = false
) {
$pos = $stream->tell();

if ($pos > 0) {
$stream->rewind();
}

$ctx = hash_init($algo);
while (!$stream->eof()) {
hash_update($ctx, $stream->read(1048576));
}

$out = hash_final($ctx, (bool) $rawOutput);
$stream->seek($pos);

return $out;
}









function readline(StreamInterface $stream, $maxLength = null)
{
$buffer = '';
$size = 0;

while (!$stream->eof()) {

 if (null == ($byte = $stream->read(1))) {
return $buffer;
}
$buffer .= $byte;

 if ($byte === "\n" || ++$size === $maxLength - 1) {
break;
}
}

return $buffer;
}








function parse_request($message)
{
$data = _parse_message($message);
$matches = [];
if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
throw new \InvalidArgumentException('Invalid request string');
}
$parts = explode(' ', $data['start-line'], 3);
$version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';

$request = new Request(
$parts[0],
$matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1],
$data['headers'],
$data['body'],
$version
);

return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
}








function parse_response($message)
{
$data = _parse_message($message);

 
 
 if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
throw new \InvalidArgumentException('Invalid response string');
}
$parts = explode(' ', $data['start-line'], 3);

return new Response(
$parts[1],
$data['headers'],
$data['body'],
explode('/', $parts[0])[1],
isset($parts[2]) ? $parts[2] : null
);
}














function parse_query($str, $urlEncoding = true)
{
$result = [];

if ($str === '') {
return $result;
}

if ($urlEncoding === true) {
$decoder = function ($value) {
return rawurldecode(str_replace('+', ' ', $value));
};
} elseif ($urlEncoding == PHP_QUERY_RFC3986) {
$decoder = 'rawurldecode';
} elseif ($urlEncoding == PHP_QUERY_RFC1738) {
$decoder = 'urldecode';
} else {
$decoder = function ($str) { return $str; };
}

foreach (explode('&', $str) as $kvp) {
$parts = explode('=', $kvp, 2);
$key = $decoder($parts[0]);
$value = isset($parts[1]) ? $decoder($parts[1]) : null;
if (!isset($result[$key])) {
$result[$key] = $value;
} else {
if (!is_array($result[$key])) {
$result[$key] = [$result[$key]];
}
$result[$key][] = $value;
}
}

return $result;
}














function build_query(array $params, $encoding = PHP_QUERY_RFC3986)
{
if (!$params) {
return '';
}

if ($encoding === false) {
$encoder = function ($str) { return $str; };
} elseif ($encoding === PHP_QUERY_RFC3986) {
$encoder = 'rawurlencode';
} elseif ($encoding === PHP_QUERY_RFC1738) {
$encoder = 'urlencode';
} else {
throw new \InvalidArgumentException('Invalid type');
}

$qs = '';
foreach ($params as $k => $v) {
$k = $encoder($k);
if (!is_array($v)) {
$qs .= $k;
if ($v !== null) {
$qs .= '=' . $encoder($v);
}
$qs .= '&';
} else {
foreach ($v as $vv) {
$qs .= $k;
if ($vv !== null) {
$qs .= '=' . $encoder($vv);
}
$qs .= '&';
}
}
}

return $qs ? (string) substr($qs, 0, -1) : '';
}








function mimetype_from_filename($filename)
{
return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION));
}









function mimetype_from_extension($extension)
{
static $mimetypes = [
'7z' => 'application/x-7z-compressed',
'aac' => 'audio/x-aac',
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'asc' => 'text/plain',
'asf' => 'video/x-ms-asf',
'atom' => 'application/atom+xml',
'avi' => 'video/x-msvideo',
'bmp' => 'image/bmp',
'bz2' => 'application/x-bzip2',
'cer' => 'application/pkix-cert',
'crl' => 'application/pkix-crl',
'crt' => 'application/x-x509-ca-cert',
'css' => 'text/css',
'csv' => 'text/csv',
'cu' => 'application/cu-seeme',
'deb' => 'application/x-debian-package',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dvi' => 'application/x-dvi',
'eot' => 'application/vnd.ms-fontobject',
'eps' => 'application/postscript',
'epub' => 'application/epub+zip',
'etx' => 'text/x-setext',
'flac' => 'audio/flac',
'flv' => 'video/x-flv',
'gif' => 'image/gif',
'gz' => 'application/gzip',
'htm' => 'text/html',
'html' => 'text/html',
'ico' => 'image/x-icon',
'ics' => 'text/calendar',
'ini' => 'text/plain',
'iso' => 'application/x-iso9660-image',
'jar' => 'application/java-archive',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'js' => 'text/javascript',
'json' => 'application/json',
'latex' => 'application/x-latex',
'log' => 'text/plain',
'm4a' => 'audio/mp4',
'm4v' => 'video/mp4',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mov' => 'video/quicktime',
'mp3' => 'audio/mpeg',
'mp4' => 'video/mp4',
'mp4a' => 'audio/mp4',
'mp4v' => 'video/mp4',
'mpe' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpg4' => 'video/mp4',
'oga' => 'audio/ogg',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'pbm' => 'image/x-portable-bitmap',
'pdf' => 'application/pdf',
'pgm' => 'image/x-portable-graymap',
'png' => 'image/png',
'pnm' => 'image/x-portable-anymap',
'ppm' => 'image/x-portable-pixmap',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'ps' => 'application/postscript',
'qt' => 'video/quicktime',
'rar' => 'application/x-rar-compressed',
'ras' => 'image/x-cmu-raster',
'rss' => 'application/rss+xml',
'rtf' => 'application/rtf',
'sgm' => 'text/sgml',
'sgml' => 'text/sgml',
'svg' => 'image/svg+xml',
'swf' => 'application/x-shockwave-flash',
'tar' => 'application/x-tar',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'torrent' => 'application/x-bittorrent',
'ttf' => 'application/x-font-ttf',
'txt' => 'text/plain',
'wav' => 'audio/x-wav',
'webm' => 'video/webm',
'wma' => 'audio/x-ms-wma',
'wmv' => 'video/x-ms-wmv',
'woff' => 'application/x-font-woff',
'wsdl' => 'application/wsdl+xml',
'xbm' => 'image/x-xbitmap',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xml' => 'application/xml',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'yaml' => 'text/yaml',
'yml' => 'text/yaml',
'zip' => 'application/zip',
];

$extension = strtolower($extension);

return isset($mimetypes[$extension])
? $mimetypes[$extension]
: null;
}













function _parse_message($message)
{
if (!$message) {
throw new \InvalidArgumentException('Invalid message');
}


 $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE);
$result = ['start-line' => array_shift($lines), 'headers' => [], 'body' => ''];
array_shift($lines);

for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) {
$line = $lines[$i];

 if (empty($line)) {
if ($i < $totalLines - 1) {
$result['body'] = implode('', array_slice($lines, $i + 2));
}
break;
}
if (strpos($line, ':')) {
$parts = explode(':', $line, 2);
$key = trim($parts[0]);
$value = isset($parts[1]) ? trim($parts[1]) : '';
$result['headers'][$key][] = $value;
}
}

return $result;
}










function _parse_request_uri($path, array $headers)
{
$hostKey = array_filter(array_keys($headers), function ($k) {
return strtolower($k) === 'host';
});


 if (!$hostKey) {
return $path;
}

$host = $headers[reset($hostKey)][0];
$scheme = substr($host, -4) === ':443' ? 'https' : 'http';

return $scheme . '://' . $host . '/' . ltrim($path, '/');
}


function _caseless_remove($keys, array $data)
{
$result = [];

foreach ($keys as &$key) {
$key = strtolower($key);
}

foreach ($data as $k => $v) {
if (!in_array(strtolower($k), $keys)) {
$result[$k] = $v;
}
}

return $result;
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;






class AppendStream implements StreamInterface
{

private $streams = [];

private $seekable = true;
private $current = 0;
private $pos = 0;
private $detached = false;





public function __construct(array $streams = [])
{
foreach ($streams as $stream) {
$this->addStream($stream);
}
}

public function __toString()
{
try {
$this->rewind();
return $this->getContents();
} catch (\Exception $e) {
return '';
}
}








public function addStream(StreamInterface $stream)
{
if (!$stream->isReadable()) {
throw new \InvalidArgumentException('Each stream must be readable');
}


 if (!$stream->isSeekable()) {
$this->seekable = false;
}

$this->streams[] = $stream;
}

public function getContents()
{
return copy_to_string($this);
}






public function close()
{
$this->pos = $this->current = 0;

foreach ($this->streams as $stream) {
$stream->close();
}

$this->streams = [];
}






public function detach()
{
$this->close();
$this->detached = true;
}

public function tell()
{
return $this->pos;
}









public function getSize()
{
$size = 0;

foreach ($this->streams as $stream) {
$s = $stream->getSize();
if ($s === null) {
return null;
}
$size += $s;
}

return $size;
}

public function eof()
{
return !$this->streams ||
($this->current >= count($this->streams) - 1 &&
$this->streams[$this->current]->eof());
}

public function rewind()
{
$this->seek(0);
}






public function seek($offset, $whence = SEEK_SET)
{
if (!$this->seekable) {
throw new \RuntimeException('This AppendStream is not seekable');
} elseif ($whence !== SEEK_SET) {
throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
}

$this->pos = $this->current = 0;


 foreach ($this->streams as $i => $stream) {
try {
$stream->rewind();
} catch (\Exception $e) {
throw new \RuntimeException('Unable to seek stream '
. $i . ' of the AppendStream', 0, $e);
}
}


 while ($this->pos < $offset && !$this->eof()) {
$result = $this->read(min(8096, $offset - $this->pos));
if ($result === '') {
break;
}
}
}






public function read($length)
{
$buffer = '';
$total = count($this->streams) - 1;
$remaining = $length;
$progressToNext = false;

while ($remaining > 0) {


 if ($progressToNext || $this->streams[$this->current]->eof()) {
$progressToNext = false;
if ($this->current === $total) {
break;
}
$this->current++;
}

$result = $this->streams[$this->current]->read($remaining);


 if ($result == null) {
$progressToNext = true;
continue;
}

$buffer .= $result;
$remaining = $length - strlen($buffer);
}

$this->pos += strlen($buffer);

return $buffer;
}

public function isReadable()
{
return true;
}

public function isWritable()
{
return false;
}

public function isSeekable()
{
return $this->seekable;
}

public function write($string)
{
throw new \RuntimeException('Cannot write to an AppendStream');
}

public function getMetadata($key = null)
{
return $key ? null : [];
}
}
<?php
namespace GuzzleHttp\Psr7;

use InvalidArgumentException;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
use RuntimeException;

class UploadedFile implements UploadedFileInterface
{



private static $errors = [
UPLOAD_ERR_OK,
UPLOAD_ERR_INI_SIZE,
UPLOAD_ERR_FORM_SIZE,
UPLOAD_ERR_PARTIAL,
UPLOAD_ERR_NO_FILE,
UPLOAD_ERR_NO_TMP_DIR,
UPLOAD_ERR_CANT_WRITE,
UPLOAD_ERR_EXTENSION,
];




private $clientFilename;




private $clientMediaType;




private $error;




private $file;




private $moved = false;




private $size;




private $stream;








public function __construct(
$streamOrFile,
$size,
$errorStatus,
$clientFilename = null,
$clientMediaType = null
) {
$this->setError($errorStatus);
$this->setSize($size);
$this->setClientFilename($clientFilename);
$this->setClientMediaType($clientMediaType);

if ($this->isOk()) {
$this->setStreamOrFile($streamOrFile);
}
}







private function setStreamOrFile($streamOrFile)
{
if (is_string($streamOrFile)) {
$this->file = $streamOrFile;
} elseif (is_resource($streamOrFile)) {
$this->stream = new Stream($streamOrFile);
} elseif ($streamOrFile instanceof StreamInterface) {
$this->stream = $streamOrFile;
} else {
throw new InvalidArgumentException(
'Invalid stream or file provided for UploadedFile'
);
}
}





private function setError($error)
{
if (false === is_int($error)) {
throw new InvalidArgumentException(
'Upload file error status must be an integer'
);
}

if (false === in_array($error, UploadedFile::$errors)) {
throw new InvalidArgumentException(
'Invalid error status for UploadedFile'
);
}

$this->error = $error;
}





private function setSize($size)
{
if (false === is_int($size)) {
throw new InvalidArgumentException(
'Upload file size must be an integer'
);
}

$this->size = $size;
}





private function isStringOrNull($param)
{
return in_array(gettype($param), ['string', 'NULL']);
}





private function isStringNotEmpty($param)
{
return is_string($param) && false === empty($param);
}





private function setClientFilename($clientFilename)
{
if (false === $this->isStringOrNull($clientFilename)) {
throw new InvalidArgumentException(
'Upload file client filename must be a string or null'
);
}

$this->clientFilename = $clientFilename;
}





private function setClientMediaType($clientMediaType)
{
if (false === $this->isStringOrNull($clientMediaType)) {
throw new InvalidArgumentException(
'Upload file client media type must be a string or null'
);
}

$this->clientMediaType = $clientMediaType;
}






private function isOk()
{
return $this->error === UPLOAD_ERR_OK;
}




public function isMoved()
{
return $this->moved;
}




private function validateActive()
{
if (false === $this->isOk()) {
throw new RuntimeException('Cannot retrieve stream due to upload error');
}

if ($this->isMoved()) {
throw new RuntimeException('Cannot retrieve stream after it has already been moved');
}
}





public function getStream()
{
$this->validateActive();

if ($this->stream instanceof StreamInterface) {
return $this->stream;
}

return new LazyOpenStream($this->file, 'r+');
}












public function moveTo($targetPath)
{
$this->validateActive();

if (false === $this->isStringNotEmpty($targetPath)) {
throw new InvalidArgumentException(
'Invalid path provided for move operation; must be a non-empty string'
);
}

if ($this->file) {
$this->moved = php_sapi_name() == 'cli'
? rename($this->file, $targetPath)
: move_uploaded_file($this->file, $targetPath);
} else {
copy_to_stream(
$this->getStream(),
new LazyOpenStream($targetPath, 'w')
);

$this->moved = true;
}

if (false === $this->moved) {
throw new RuntimeException(
sprintf('Uploaded file could not be moved to %s', $targetPath)
);
}
}






public function getSize()
{
return $this->size;
}







public function getError()
{
return $this->error;
}







public function getClientFilename()
{
return $this->clientFilename;
}




public function getClientMediaType()
{
return $this->clientMediaType;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;







class FnStream implements StreamInterface
{

private $methods;


private static $slots = ['__toString', 'close', 'detach', 'rewind',
'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
'isReadable', 'read', 'getContents', 'getMetadata'];




public function __construct(array $methods)
{
$this->methods = $methods;


 foreach ($methods as $name => $fn) {
$this->{'_fn_' . $name} = $fn;
}
}





public function __get($name)
{
throw new \BadMethodCallException(str_replace('_fn_', '', $name)
. '() is not implemented in the FnStream');
}




public function __destruct()
{
if (isset($this->_fn_close)) {
call_user_func($this->_fn_close);
}
}










public static function decorate(StreamInterface $stream, array $methods)
{

 
 foreach (array_diff(self::$slots, array_keys($methods)) as $diff) {
$methods[$diff] = [$stream, $diff];
}

return new self($methods);
}

public function __toString()
{
return call_user_func($this->_fn___toString);
}

public function close()
{
return call_user_func($this->_fn_close);
}

public function detach()
{
return call_user_func($this->_fn_detach);
}

public function getSize()
{
return call_user_func($this->_fn_getSize);
}

public function tell()
{
return call_user_func($this->_fn_tell);
}

public function eof()
{
return call_user_func($this->_fn_eof);
}

public function isSeekable()
{
return call_user_func($this->_fn_isSeekable);
}

public function rewind()
{
call_user_func($this->_fn_rewind);
}

public function seek($offset, $whence = SEEK_SET)
{
call_user_func($this->_fn_seek, $offset, $whence);
}

public function isWritable()
{
return call_user_func($this->_fn_isWritable);
}

public function write($string)
{
return call_user_func($this->_fn_write, $string);
}

public function isReadable()
{
return call_user_func($this->_fn_isReadable);
}

public function read($length)
{
return call_user_func($this->_fn_read, $length);
}

public function getContents()
{
return call_user_func($this->_fn_getContents);
}

public function getMetadata($key = null)
{
return call_user_func($this->_fn_getMetadata, $key);
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\UriInterface;








class Uri implements UriInterface
{






const HTTP_DEFAULT_HOST = 'localhost';

private static $defaultPorts = [
'http' => 80,
'https' => 443,
'ftp' => 21,
'gopher' => 70,
'nntp' => 119,
'news' => 119,
'telnet' => 23,
'tn3270' => 23,
'imap' => 143,
'pop' => 110,
'ldap' => 389,
];

private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
private static $replaceQuery = ['=' => '%3D', '&' => '%26'];


private $scheme = '';


private $userInfo = '';


private $host = '';


private $port;


private $path = '';


private $query = '';


private $fragment = '';




public function __construct($uri = '')
{

 if ($uri != '') {
$parts = parse_url($uri);
if ($parts === false) {
throw new \InvalidArgumentException("Unable to parse URI: $uri");
}
$this->applyParts($parts);
}
}

public function __toString()
{
return self::composeComponents(
$this->scheme,
$this->getAuthority(),
$this->path,
$this->query,
$this->fragment
);
}



























public static function composeComponents($scheme, $authority, $path, $query, $fragment)
{
$uri = '';


 if ($scheme != '') {
$uri .= $scheme . ':';
}

if ($authority != ''|| $scheme === 'file') {
$uri .= '//' . $authority;
}

$uri .= $path;

if ($query != '') {
$uri .= '?' . $query;
}

if ($fragment != '') {
$uri .= '#' . $fragment;
}

return $uri;
}











public static function isDefaultPort(UriInterface $uri)
{
return $uri->getPort() === null
|| (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
}



















public static function isAbsolute(UriInterface $uri)
{
return $uri->getScheme() !== '';
}











public static function isNetworkPathReference(UriInterface $uri)
{
return $uri->getScheme() === '' && $uri->getAuthority() !== '';
}











public static function isAbsolutePathReference(UriInterface $uri)
{
return $uri->getScheme() === ''
&& $uri->getAuthority() === ''
&& isset($uri->getPath()[0])
&& $uri->getPath()[0] === '/';
}











public static function isRelativePathReference(UriInterface $uri)
{
return $uri->getScheme() === ''
&& $uri->getAuthority() === ''
&& (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
}














public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
{
if ($base !== null) {
$uri = UriResolver::resolve($base, $uri);

return ($uri->getScheme() === $base->getScheme())
&& ($uri->getAuthority() === $base->getAuthority())
&& ($uri->getPath() === $base->getPath())
&& ($uri->getQuery() === $base->getQuery());
}

return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
}











public static function removeDotSegments($path)
{
@trigger_error(
'GuzzleHttp\Psr7\Uri::removeDotSegments is deprecated since version 1.4. ' .
'Use GuzzleHttp\Psr7\UriResolver::removeDotSegments instead.',
E_USER_DEPRECATED
);

return UriResolver::removeDotSegments($path);
}












public static function resolve(UriInterface $base, $rel)
{
@trigger_error(
'GuzzleHttp\Psr7\Uri::resolve is deprecated since version 1.4. Use GuzzleHttp\Psr7\UriResolver::resolve instead.',
E_USER_DEPRECATED
);

if (!($rel instanceof UriInterface)) {
$rel = new self($rel);
}

return UriResolver::resolve($base, $rel);
}












public static function withoutQueryValue(UriInterface $uri, $key)
{
$current = $uri->getQuery();
if ($current === '') {
return $uri;
}

$decodedKey = rawurldecode($key);
$result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
});

return $uri->withQuery(implode('&', $result));
}
















public static function withQueryValue(UriInterface $uri, $key, $value)
{
$current = $uri->getQuery();

if ($current === '') {
$result = [];
} else {
$decodedKey = rawurldecode($key);
$result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
return rawurldecode(explode('=', $part)[0]) !== $decodedKey;
});
}


 
 
 $key = strtr($key, self::$replaceQuery);

if ($value !== null) {
$result[] = $key . '=' . strtr($value, self::$replaceQuery);
} else {
$result[] = $key;
}

return $uri->withQuery(implode('&', $result));
}











public static function fromParts(array $parts)
{
$uri = new self();
$uri->applyParts($parts);
$uri->validateState();

return $uri;
}

public function getScheme()
{
return $this->scheme;
}

public function getAuthority()
{
$authority = $this->host;
if ($this->userInfo !== '') {
$authority = $this->userInfo . '@' . $authority;
}

if ($this->port !== null) {
$authority .= ':' . $this->port;
}

return $authority;
}

public function getUserInfo()
{
return $this->userInfo;
}

public function getHost()
{
return $this->host;
}

public function getPort()
{
return $this->port;
}

public function getPath()
{
return $this->path;
}

public function getQuery()
{
return $this->query;
}

public function getFragment()
{
return $this->fragment;
}

public function withScheme($scheme)
{
$scheme = $this->filterScheme($scheme);

if ($this->scheme === $scheme) {
return $this;
}

$new = clone $this;
$new->scheme = $scheme;
$new->removeDefaultPort();
$new->validateState();

return $new;
}

public function withUserInfo($user, $password = null)
{
$info = $user;
if ($password != '') {
$info .= ':' . $password;
}

if ($this->userInfo === $info) {
return $this;
}

$new = clone $this;
$new->userInfo = $info;
$new->validateState();

return $new;
}

public function withHost($host)
{
$host = $this->filterHost($host);

if ($this->host === $host) {
return $this;
}

$new = clone $this;
$new->host = $host;
$new->validateState();

return $new;
}

public function withPort($port)
{
$port = $this->filterPort($port);

if ($this->port === $port) {
return $this;
}

$new = clone $this;
$new->port = $port;
$new->removeDefaultPort();
$new->validateState();

return $new;
}

public function withPath($path)
{
$path = $this->filterPath($path);

if ($this->path === $path) {
return $this;
}

$new = clone $this;
$new->path = $path;
$new->validateState();

return $new;
}

public function withQuery($query)
{
$query = $this->filterQueryAndFragment($query);

if ($this->query === $query) {
return $this;
}

$new = clone $this;
$new->query = $query;

return $new;
}

public function withFragment($fragment)
{
$fragment = $this->filterQueryAndFragment($fragment);

if ($this->fragment === $fragment) {
return $this;
}

$new = clone $this;
$new->fragment = $fragment;

return $new;
}






private function applyParts(array $parts)
{
$this->scheme = isset($parts['scheme'])
? $this->filterScheme($parts['scheme'])
: '';
$this->userInfo = isset($parts['user']) ? $parts['user'] : '';
$this->host = isset($parts['host'])
? $this->filterHost($parts['host'])
: '';
$this->port = isset($parts['port'])
? $this->filterPort($parts['port'])
: null;
$this->path = isset($parts['path'])
? $this->filterPath($parts['path'])
: '';
$this->query = isset($parts['query'])
? $this->filterQueryAndFragment($parts['query'])
: '';
$this->fragment = isset($parts['fragment'])
? $this->filterQueryAndFragment($parts['fragment'])
: '';
if (isset($parts['pass'])) {
$this->userInfo .= ':' . $parts['pass'];
}

$this->removeDefaultPort();
}








private function filterScheme($scheme)
{
if (!is_string($scheme)) {
throw new \InvalidArgumentException('Scheme must be a string');
}

return strtolower($scheme);
}








private function filterHost($host)
{
if (!is_string($host)) {
throw new \InvalidArgumentException('Host must be a string');
}

return strtolower($host);
}








private function filterPort($port)
{
if ($port === null) {
return null;
}

$port = (int) $port;
if (1 > $port || 0xffff < $port) {
throw new \InvalidArgumentException(
sprintf('Invalid port: %d. Must be between 1 and 65535', $port)
);
}

return $port;
}

private function removeDefaultPort()
{
if ($this->port !== null && self::isDefaultPort($this)) {
$this->port = null;
}
}










private function filterPath($path)
{
if (!is_string($path)) {
throw new \InvalidArgumentException('Path must be a string');
}

return preg_replace_callback(
'/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
[$this, 'rawurlencodeMatchZero'],
$path
);
}










private function filterQueryAndFragment($str)
{
if (!is_string($str)) {
throw new \InvalidArgumentException('Query and fragment must be a string');
}

return preg_replace_callback(
'/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
[$this, 'rawurlencodeMatchZero'],
$str
);
}

private function rawurlencodeMatchZero(array $match)
{
return rawurlencode($match[0]);
}

private function validateState()
{
if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
$this->host = self::HTTP_DEFAULT_HOST;
}

if ($this->getAuthority() === '') {
if (0 === strpos($this->path, '//')) {
throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
}
if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
}
} elseif (isset($this->path[0]) && $this->path[0] !== '/') {
@trigger_error(
'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
E_USER_DEPRECATED
);
$this->path = '/'. $this->path;

 }
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;





class MultipartStream implements StreamInterface
{
use StreamDecoratorTrait;

private $boundary;













public function __construct(array $elements = [], $boundary = null)
{
$this->boundary = $boundary ?: sha1(uniqid('', true));
$this->stream = $this->createStream($elements);
}






public function getBoundary()
{
return $this->boundary;
}

public function isWritable()
{
return false;
}




private function getHeaders(array $headers)
{
$str = '';
foreach ($headers as $key => $value) {
$str .= "{$key}: {$value}\r\n";
}

return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n";
}




protected function createStream(array $elements)
{
$stream = new AppendStream();

foreach ($elements as $element) {
$this->addElement($stream, $element);
}


 $stream->addStream(stream_for("--{$this->boundary}--\r\n"));

return $stream;
}

private function addElement(AppendStream $stream, array $element)
{
foreach (['contents', 'name'] as $key) {
if (!array_key_exists($key, $element)) {
throw new \InvalidArgumentException("A '{$key}' key is required");
}
}

$element['contents'] = stream_for($element['contents']);

if (empty($element['filename'])) {
$uri = $element['contents']->getMetadata('uri');
if (substr($uri, 0, 6) !== 'php://') {
$element['filename'] = $uri;
}
}

list($body, $headers) = $this->createElement(
$element['name'],
$element['contents'],
isset($element['filename']) ? $element['filename'] : null,
isset($element['headers']) ? $element['headers'] : []
);

$stream->addStream(stream_for($this->getHeaders($headers)));
$stream->addStream($body);
$stream->addStream(stream_for("\r\n"));
}




private function createElement($name, StreamInterface $stream, $filename, array $headers)
{

 $disposition = $this->getHeader($headers, 'content-disposition');
if (!$disposition) {
$headers['Content-Disposition'] = ($filename === '0' || $filename)
? sprintf('form-data; name="%s"; filename="%s"',
$name,
basename($filename))
: "form-data; name=\"{$name}\"";
}


 $length = $this->getHeader($headers, 'content-length');
if (!$length) {
if ($length = $stream->getSize()) {
$headers['Content-Length'] = (string) $length;
}
}


 $type = $this->getHeader($headers, 'content-type');
if (!$type && ($filename === '0' || $filename)) {
if ($type = mimetype_from_filename($filename)) {
$headers['Content-Type'] = $type;
}
}

return [$stream, $headers];
}

private function getHeader(array $headers, $key)
{
$lowercaseHeader = strtolower($key);
foreach ($headers as $k => $v) {
if (strtolower($k) === $lowercaseHeader) {
return $v;
}
}

return null;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;





class CachingStream implements StreamInterface
{
use StreamDecoratorTrait;


private $remoteStream;


private $skipReadBytes = 0;







public function __construct(
StreamInterface $stream,
StreamInterface $target = null
) {
$this->remoteStream = $stream;
$this->stream = $target ?: new Stream(fopen('php://temp', 'r+'));
}

public function getSize()
{
return max($this->stream->getSize(), $this->remoteStream->getSize());
}

public function rewind()
{
$this->seek(0);
}

public function seek($offset, $whence = SEEK_SET)
{
if ($whence == SEEK_SET) {
$byte = $offset;
} elseif ($whence == SEEK_CUR) {
$byte = $offset + $this->tell();
} elseif ($whence == SEEK_END) {
$size = $this->remoteStream->getSize();
if ($size === null) {
$size = $this->cacheEntireStream();
}
$byte = $size + $offset;
} else {
throw new \InvalidArgumentException('Invalid whence');
}

$diff = $byte - $this->stream->getSize();

if ($diff > 0) {

 
 while ($diff > 0 && !$this->remoteStream->eof()) {
$this->read($diff);
$diff = $byte - $this->stream->getSize();
}
} else {

 $this->stream->seek($byte);
}
}

public function read($length)
{

 $data = $this->stream->read($length);
$remaining = $length - strlen($data);


 if ($remaining) {

 
 
 
 $remoteData = $this->remoteStream->read(
$remaining + $this->skipReadBytes
);

if ($this->skipReadBytes) {
$len = strlen($remoteData);
$remoteData = substr($remoteData, $this->skipReadBytes);
$this->skipReadBytes = max(0, $this->skipReadBytes - $len);
}

$data .= $remoteData;
$this->stream->write($remoteData);
}

return $data;
}

public function write($string)
{

 
 
 
 $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
if ($overflow > 0) {
$this->skipReadBytes += $overflow;
}

return $this->stream->write($string);
}

public function eof()
{
return $this->stream->eof() && $this->remoteStream->eof();
}




public function close()
{
$this->remoteStream->close() && $this->stream->close();
}

private function cacheEntireStream()
{
$target = new FnStream(['write' => 'strlen']);
copy_to_stream($this, $target);

return $this->tell();
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;





trait StreamDecoratorTrait
{



public function __construct(StreamInterface $stream)
{
$this->stream = $stream;
}









public function __get($name)
{
if ($name == 'stream') {
$this->stream = $this->createStream();
return $this->stream;
}

throw new \UnexpectedValueException("$name not found on class");
}

public function __toString()
{
try {
if ($this->isSeekable()) {
$this->seek(0);
}
return $this->getContents();
} catch (\Exception $e) {

 trigger_error('StreamDecorator::__toString exception: '
. (string) $e, E_USER_ERROR);
return '';
}
}

public function getContents()
{
return copy_to_string($this);
}









public function __call($method, array $args)
{
$result = call_user_func_array([$this->stream, $method], $args);


 return $result === $this->stream ? $this : $result;
}

public function close()
{
$this->stream->close();
}

public function getMetadata($key = null)
{
return $this->stream->getMetadata($key);
}

public function detach()
{
return $this->stream->detach();
}

public function getSize()
{
return $this->stream->getSize();
}

public function eof()
{
return $this->stream->eof();
}

public function tell()
{
return $this->stream->tell();
}

public function isReadable()
{
return $this->stream->isReadable();
}

public function isWritable()
{
return $this->stream->isWritable();
}

public function isSeekable()
{
return $this->stream->isSeekable();
}

public function rewind()
{
$this->seek(0);
}

public function seek($offset, $whence = SEEK_SET)
{
$this->stream->seek($offset, $whence);
}

public function read($length)
{
return $this->stream->read($length);
}

public function write($string)
{
return $this->stream->write($string);
}







protected function createStream()
{
throw new \BadMethodCallException('Not implemented');
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;




class StreamWrapper
{

public $context;


private $stream;


private $mode;









public static function getResource(StreamInterface $stream)
{
self::register();

if ($stream->isReadable()) {
$mode = $stream->isWritable() ? 'r+' : 'r';
} elseif ($stream->isWritable()) {
$mode = 'w';
} else {
throw new \InvalidArgumentException('The stream must be readable, '
. 'writable, or both.');
}

return fopen('guzzle://stream', $mode, null, stream_context_create([
'guzzle' => ['stream' => $stream]
]));
}




public static function register()
{
if (!in_array('guzzle', stream_get_wrappers())) {
stream_wrapper_register('guzzle', __CLASS__);
}
}

public function stream_open($path, $mode, $options, &$opened_path)
{
$options = stream_context_get_options($this->context);

if (!isset($options['guzzle']['stream'])) {
return false;
}

$this->mode = $mode;
$this->stream = $options['guzzle']['stream'];

return true;
}

public function stream_read($count)
{
return $this->stream->read($count);
}

public function stream_write($data)
{
return (int) $this->stream->write($data);
}

public function stream_tell()
{
return $this->stream->tell();
}

public function stream_eof()
{
return $this->stream->eof();
}

public function stream_seek($offset, $whence)
{
$this->stream->seek($offset, $whence);

return true;
}

public function stream_stat()
{
static $modeMap = [
'r' => 33060,
'r+' => 33206,
'w' => 33188
];

return [
'dev' => 0,
'ino' => 0,
'mode' => $modeMap[$this->mode],
'nlink' => 0,
'uid' => 0,
'gid' => 0,
'rdev' => 0,
'size' => $this->stream->getSize() ?: 0,
'atime' => 0,
'mtime' => 0,
'ctime' => 0,
'blksize' => 0,
'blocks' => 0
];
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;





class LimitStream implements StreamInterface
{
use StreamDecoratorTrait;


private $offset;


private $limit;








public function __construct(
StreamInterface $stream,
$limit = -1,
$offset = 0
) {
$this->stream = $stream;
$this->setLimit($limit);
$this->setOffset($offset);
}

public function eof()
{

 if ($this->stream->eof()) {
return true;
}


 if ($this->limit == -1) {
return false;
}

return $this->stream->tell() >= $this->offset + $this->limit;
}





public function getSize()
{
if (null === ($length = $this->stream->getSize())) {
return null;
} elseif ($this->limit == -1) {
return $length - $this->offset;
} else {
return min($this->limit, $length - $this->offset);
}
}





public function seek($offset, $whence = SEEK_SET)
{
if ($whence !== SEEK_SET || $offset < 0) {
throw new \RuntimeException(sprintf(
'Cannot seek to offset % with whence %s',
$offset,
$whence
));
}

$offset += $this->offset;

if ($this->limit !== -1) {
if ($offset > $this->offset + $this->limit) {
$offset = $this->offset + $this->limit;
}
}

$this->stream->seek($offset);
}





public function tell()
{
return $this->stream->tell() - $this->offset;
}








public function setOffset($offset)
{
$current = $this->stream->tell();

if ($current !== $offset) {

 if ($this->stream->isSeekable()) {
$this->stream->seek($offset);
} elseif ($current > $offset) {
throw new \RuntimeException("Could not seek to stream offset $offset");
} else {
$this->stream->read($offset - $current);
}
}

$this->offset = $offset;
}








public function setLimit($limit)
{
$this->limit = $limit;
}

public function read($length)
{
if ($this->limit == -1) {
return $this->stream->read($length);
}


 
 $remaining = ($this->offset + $this->limit) - $this->stream->tell();
if ($remaining > 0) {

 
 return $this->stream->read(min($remaining, $length));
}

return '';
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\UriInterface;








final class UriResolver
{








public static function removeDotSegments($path)
{
if ($path === '' || $path === '/') {
return $path;
}

$results = [];
$segments = explode('/', $path);
foreach ($segments as $segment) {
if ($segment === '..') {
array_pop($results);
} elseif ($segment !== '.') {
$results[] = $segment;
}
}

$newPath = implode('/', $results);

if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) {

 $newPath = '/' . $newPath;
} elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) {

 
 $newPath .= '/';
}

return $newPath;
}










public static function resolve(UriInterface $base, UriInterface $rel)
{
if ((string) $rel === '') {

 return $base;
}

if ($rel->getScheme() != '') {
return $rel->withPath(self::removeDotSegments($rel->getPath()));
}

if ($rel->getAuthority() != '') {
$targetAuthority = $rel->getAuthority();
$targetPath = self::removeDotSegments($rel->getPath());
$targetQuery = $rel->getQuery();
} else {
$targetAuthority = $base->getAuthority();
if ($rel->getPath() === '') {
$targetPath = $base->getPath();
$targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery();
} else {
if ($rel->getPath()[0] === '/') {
$targetPath = $rel->getPath();
} else {
if ($targetAuthority != '' && $base->getPath() === '') {
$targetPath = '/' . $rel->getPath();
} else {
$lastSlashPos = strrpos($base->getPath(), '/');
if ($lastSlashPos === false) {
$targetPath = $rel->getPath();
} else {
$targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
}
}
}
$targetPath = self::removeDotSegments($targetPath);
$targetQuery = $rel->getQuery();
}
}

return new Uri(Uri::composeComponents(
$base->getScheme(),
$targetAuthority,
$targetPath,
$targetQuery,
$rel->getFragment()
));
}



























public static function relativize(UriInterface $base, UriInterface $target)
{
if ($target->getScheme() !== '' &&
($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')
) {
return $target;
}

if (Uri::isRelativePathReference($target)) {

 
 
 return $target;
}

if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) {
return $target->withScheme('');
}


 
 
 $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost('');

if ($base->getPath() !== $target->getPath()) {
return $emptyPathUri->withPath(self::getRelativePath($base, $target));
}

if ($base->getQuery() === $target->getQuery()) {

 return $emptyPathUri->withQuery('');
}


 
 if ($target->getQuery() === '') {
$segments = explode('/', $target->getPath());
$lastSegment = end($segments);

return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment);
}

return $emptyPathUri;
}

private static function getRelativePath(UriInterface $base, UriInterface $target)
{
$sourceSegments = explode('/', $base->getPath());
$targetSegments = explode('/', $target->getPath());
array_pop($sourceSegments);
$targetLastSegment = array_pop($targetSegments);
foreach ($sourceSegments as $i => $segment) {
if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) {
unset($sourceSegments[$i], $targetSegments[$i]);
} else {
break;
}
}
$targetSegments[] = $targetLastSegment;
$relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments);


 
 
 if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) {
$relativePath = "./$relativePath";
} elseif ('/' === $relativePath[0]) {
if ($base->getAuthority() != '' && $base->getPath() === '') {

 $relativePath = ".$relativePath";
} else {
$relativePath = "./$relativePath";
}
}

return $relativePath;
}

private function __construct()
{

 }
}
<?php
namespace GuzzleHttp\Psr7;

use InvalidArgumentException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;




class Request implements RequestInterface
{
use MessageTrait;


private $method;


private $requestTarget;


private $uri;








public function __construct(
$method,
$uri,
array $headers = [],
$body = null,
$version = '1.1'
) {
if (!($uri instanceof UriInterface)) {
$uri = new Uri($uri);
}

$this->method = strtoupper($method);
$this->uri = $uri;
$this->setHeaders($headers);
$this->protocol = $version;

if (!$this->hasHeader('Host')) {
$this->updateHostFromUri();
}

if ($body !== '' && $body !== null) {
$this->stream = stream_for($body);
}
}

public function getRequestTarget()
{
if ($this->requestTarget !== null) {
return $this->requestTarget;
}

$target = $this->uri->getPath();
if ($target == '') {
$target = '/';
}
if ($this->uri->getQuery() != '') {
$target .= '?' . $this->uri->getQuery();
}

return $target;
}

public function withRequestTarget($requestTarget)
{
if (preg_match('#\s#', $requestTarget)) {
throw new InvalidArgumentException(
'Invalid request target provided; cannot contain whitespace'
);
}

$new = clone $this;
$new->requestTarget = $requestTarget;
return $new;
}

public function getMethod()
{
return $this->method;
}

public function withMethod($method)
{
$new = clone $this;
$new->method = strtoupper($method);
return $new;
}

public function getUri()
{
return $this->uri;
}

public function withUri(UriInterface $uri, $preserveHost = false)
{
if ($uri === $this->uri) {
return $this;
}

$new = clone $this;
$new->uri = $uri;

if (!$preserveHost) {
$new->updateHostFromUri();
}

return $new;
}

private function updateHostFromUri()
{
$host = $this->uri->getHost();

if ($host == '') {
return;
}

if (($port = $this->uri->getPort()) !== null) {
$host .= ':' . $port;
}

if (isset($this->headerNames['host'])) {
$header = $this->headerNames['host'];
} else {
$header = 'Host';
$this->headerNames['host'] = 'Host';
}

 
 $this->headers = [$header => [$host]] + $this->headers;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;












class InflateStream implements StreamInterface
{
use StreamDecoratorTrait;

public function __construct(StreamInterface $stream)
{

 $header = $stream->read(10);
$filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);

 $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
$resource = StreamWrapper::getResource($stream);
stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
$this->stream = new Stream($resource);
}






private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
{
$filename_header_length = 0;

if (substr(bin2hex($header), 6, 2) === '08') {

 $filename_header_length = 1;
while ($stream->read(1) !== chr(0)) {
$filename_header_length++;
}
}

return $filename_header_length;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\UriInterface;








final class UriNormalizer
{






const PRESERVING_NORMALIZATIONS = 63;






const CAPITALIZE_PERCENT_ENCODING = 1;










const DECODE_UNRESERVED_CHARACTERS = 2;






const CONVERT_EMPTY_PATH = 4;












const REMOVE_DEFAULT_HOST = 8;






const REMOVE_DEFAULT_PORT = 16;









const REMOVE_DOT_SEGMENTS = 32;










const REMOVE_DUPLICATE_SLASHES = 64;












const SORT_QUERY_PARAMETERS = 128;


















public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS)
{
if ($flags & self::CAPITALIZE_PERCENT_ENCODING) {
$uri = self::capitalizePercentEncoding($uri);
}

if ($flags & self::DECODE_UNRESERVED_CHARACTERS) {
$uri = self::decodeUnreservedCharacters($uri);
}

if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' &&
($uri->getScheme() === 'http' || $uri->getScheme() === 'https')
) {
$uri = $uri->withPath('/');
}

if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') {
$uri = $uri->withHost('');
}

if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) {
$uri = $uri->withPort(null);
}

if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) {
$uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath()));
}

if ($flags & self::REMOVE_DUPLICATE_SLASHES) {
$uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath()));
}

if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') {
$queryKeyValues = explode('&', $uri->getQuery());
sort($queryKeyValues);
$uri = $uri->withQuery(implode('&', $queryKeyValues));
}

return $uri;
}
















public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS)
{
return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations);
}

private static function capitalizePercentEncoding(UriInterface $uri)
{
$regex = '/(?:%[A-Fa-f0-9]{2})++/';

$callback = function (array $match) {
return strtoupper($match[0]);
};

return
$uri->withPath(
preg_replace_callback($regex, $callback, $uri->getPath())
)->withQuery(
preg_replace_callback($regex, $callback, $uri->getQuery())
);
}

private static function decodeUnreservedCharacters(UriInterface $uri)
{
$regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';

$callback = function (array $match) {
return rawurldecode($match[0]);
};

return
$uri->withPath(
preg_replace_callback($regex, $callback, $uri->getPath())
)->withQuery(
preg_replace_callback($regex, $callback, $uri->getQuery())
);
}

private function __construct()
{

 }
}
<?php

namespace GuzzleHttp\Psr7;

use InvalidArgumentException;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;















class ServerRequest extends Request implements ServerRequestInterface
{



private $attributes = [];




private $cookieParams = [];




private $parsedBody;




private $queryParams = [];




private $serverParams;




private $uploadedFiles = [];









public function __construct(
$method,
$uri,
array $headers = [],
$body = null,
$version = '1.1',
array $serverParams = []
) {
$this->serverParams = $serverParams;

parent::__construct($method, $uri, $headers, $body, $version);
}








public static function normalizeFiles(array $files)
{
$normalized = [];

foreach ($files as $key => $value) {
if ($value instanceof UploadedFileInterface) {
$normalized[$key] = $value;
} elseif (is_array($value) && isset($value['tmp_name'])) {
$normalized[$key] = self::createUploadedFileFromSpec($value);
} elseif (is_array($value)) {
$normalized[$key] = self::normalizeFiles($value);
continue;
} else {
throw new InvalidArgumentException('Invalid value in files specification');
}
}

return $normalized;
}










private static function createUploadedFileFromSpec(array $value)
{
if (is_array($value['tmp_name'])) {
return self::normalizeNestedFileSpec($value);
}

return new UploadedFile(
$value['tmp_name'],
(int) $value['size'],
(int) $value['error'],
$value['name'],
$value['type']
);
}










private static function normalizeNestedFileSpec(array $files = [])
{
$normalizedFiles = [];

foreach (array_keys($files['tmp_name']) as $key) {
$spec = [
'tmp_name' => $files['tmp_name'][$key],
'size' => $files['size'][$key],
'error' => $files['error'][$key],
'name' => $files['name'][$key],
'type' => $files['type'][$key],
];
$normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
}

return $normalizedFiles;
}











public static function fromGlobals()
{
$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
$headers = function_exists('getallheaders') ? getallheaders() : [];
$uri = self::getUriFromGlobals();
$body = new LazyOpenStream('php://input', 'r+');
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';

$serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);

return $serverRequest
->withCookieParams($_COOKIE)
->withQueryParams($_GET)
->withParsedBody($_POST)
->withUploadedFiles(self::normalizeFiles($_FILES));
}






public static function getUriFromGlobals() {
$uri = new Uri('');

$uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');

$hasPort = false;
if (isset($_SERVER['HTTP_HOST'])) {
$hostHeaderParts = explode(':', $_SERVER['HTTP_HOST']);
$uri = $uri->withHost($hostHeaderParts[0]);
if (isset($hostHeaderParts[1])) {
$hasPort = true;
$uri = $uri->withPort($hostHeaderParts[1]);
}
} elseif (isset($_SERVER['SERVER_NAME'])) {
$uri = $uri->withHost($_SERVER['SERVER_NAME']);
} elseif (isset($_SERVER['SERVER_ADDR'])) {
$uri = $uri->withHost($_SERVER['SERVER_ADDR']);
}

if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
$uri = $uri->withPort($_SERVER['SERVER_PORT']);
}

$hasQuery = false;
if (isset($_SERVER['REQUEST_URI'])) {
$requestUriParts = explode('?', $_SERVER['REQUEST_URI']);
$uri = $uri->withPath($requestUriParts[0]);
if (isset($requestUriParts[1])) {
$hasQuery = true;
$uri = $uri->withQuery($requestUriParts[1]);
}
}

if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
$uri = $uri->withQuery($_SERVER['QUERY_STRING']);
}

return $uri;
}





public function getServerParams()
{
return $this->serverParams;
}




public function getUploadedFiles()
{
return $this->uploadedFiles;
}




public function withUploadedFiles(array $uploadedFiles)
{
$new = clone $this;
$new->uploadedFiles = $uploadedFiles;

return $new;
}




public function getCookieParams()
{
return $this->cookieParams;
}




public function withCookieParams(array $cookies)
{
$new = clone $this;
$new->cookieParams = $cookies;

return $new;
}




public function getQueryParams()
{
return $this->queryParams;
}




public function withQueryParams(array $query)
{
$new = clone $this;
$new->queryParams = $query;

return $new;
}




public function getParsedBody()
{
return $this->parsedBody;
}




public function withParsedBody($data)
{
$new = clone $this;
$new->parsedBody = $data;

return $new;
}




public function getAttributes()
{
return $this->attributes;
}




public function getAttribute($attribute, $default = null)
{
if (false === array_key_exists($attribute, $this->attributes)) {
return $default;
}

return $this->attributes[$attribute];
}




public function withAttribute($attribute, $value)
{
$new = clone $this;
$new->attributes[$attribute] = $value;

return $new;
}




public function withoutAttribute($attribute)
{
if (false === array_key_exists($attribute, $this->attributes)) {
return $this;
}

$new = clone $this;
unset($new->attributes[$attribute]);

return $new;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;






class Stream implements StreamInterface
{
private $stream;
private $size;
private $seekable;
private $readable;
private $writable;
private $uri;
private $customMetadata;


private static $readWriteHash = [
'read' => [
'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
'x+t' => true, 'c+t' => true, 'a+' => true
],
'write' => [
'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
]
];















public function __construct($stream, $options = [])
{
if (!is_resource($stream)) {
throw new \InvalidArgumentException('Stream must be a resource');
}

if (isset($options['size'])) {
$this->size = $options['size'];
}

$this->customMetadata = isset($options['metadata'])
? $options['metadata']
: [];

$this->stream = $stream;
$meta = stream_get_meta_data($this->stream);
$this->seekable = $meta['seekable'];
$this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
$this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
$this->uri = $this->getMetadata('uri');
}

public function __get($name)
{
if ($name == 'stream') {
throw new \RuntimeException('The stream is detached');
}

throw new \BadMethodCallException('No value for ' . $name);
}




public function __destruct()
{
$this->close();
}

public function __toString()
{
try {
$this->seek(0);
return (string) stream_get_contents($this->stream);
} catch (\Exception $e) {
return '';
}
}

public function getContents()
{
$contents = stream_get_contents($this->stream);

if ($contents === false) {
throw new \RuntimeException('Unable to read stream contents');
}

return $contents;
}

public function close()
{
if (isset($this->stream)) {
if (is_resource($this->stream)) {
fclose($this->stream);
}
$this->detach();
}
}

public function detach()
{
if (!isset($this->stream)) {
return null;
}

$result = $this->stream;
unset($this->stream);
$this->size = $this->uri = null;
$this->readable = $this->writable = $this->seekable = false;

return $result;
}

public function getSize()
{
if ($this->size !== null) {
return $this->size;
}

if (!isset($this->stream)) {
return null;
}


 if ($this->uri) {
clearstatcache(true, $this->uri);
}

$stats = fstat($this->stream);
if (isset($stats['size'])) {
$this->size = $stats['size'];
return $this->size;
}

return null;
}

public function isReadable()
{
return $this->readable;
}

public function isWritable()
{
return $this->writable;
}

public function isSeekable()
{
return $this->seekable;
}

public function eof()
{
return !$this->stream || feof($this->stream);
}

public function tell()
{
$result = ftell($this->stream);

if ($result === false) {
throw new \RuntimeException('Unable to determine stream position');
}

return $result;
}

public function rewind()
{
$this->seek(0);
}

public function seek($offset, $whence = SEEK_SET)
{
if (!$this->seekable) {
throw new \RuntimeException('Stream is not seekable');
} elseif (fseek($this->stream, $offset, $whence) === -1) {
throw new \RuntimeException('Unable to seek to stream position '
. $offset . ' with whence ' . var_export($whence, true));
}
}

public function read($length)
{
if (!$this->readable) {
throw new \RuntimeException('Cannot read from non-readable stream');
}
if ($length < 0) {
throw new \RuntimeException('Length parameter cannot be negative');
}

if (0 === $length) {
return '';
}

$string = fread($this->stream, $length);
if (false === $string) {
throw new \RuntimeException('Unable to read from stream');
}

return $string;
}

public function write($string)
{
if (!$this->writable) {
throw new \RuntimeException('Cannot write to a non-writable stream');
}


 $this->size = null;
$result = fwrite($this->stream, $string);

if ($result === false) {
throw new \RuntimeException('Unable to write to stream');
}

return $result;
}

public function getMetadata($key = null)
{
if (!isset($this->stream)) {
return $key ? null : [];
} elseif (!$key) {
return $this->customMetadata + stream_get_meta_data($this->stream);
} elseif (isset($this->customMetadata[$key])) {
return $this->customMetadata[$key];
}

$meta = stream_get_meta_data($this->stream);

return isset($meta[$key]) ? $meta[$key] : null;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;




class NoSeekStream implements StreamInterface
{
use StreamDecoratorTrait;

public function seek($offset, $whence = SEEK_SET)
{
throw new \RuntimeException('Cannot seek a NoSeekStream');
}

public function isSeekable()
{
return false;
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;





class LazyOpenStream implements StreamInterface
{
use StreamDecoratorTrait;


private $filename;


private $mode;





public function __construct($filename, $mode)
{
$this->filename = $filename;
$this->mode = $mode;
}






protected function createStream()
{
return stream_for(try_fopen($this->filename, $this->mode));
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;











class PumpStream implements StreamInterface
{

private $source;


private $size;


private $tellPos = 0;


private $metadata;


private $buffer;











public function __construct(callable $source, array $options = [])
{
$this->source = $source;
$this->size = isset($options['size']) ? $options['size'] : null;
$this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
$this->buffer = new BufferStream();
}

public function __toString()
{
try {
return copy_to_string($this);
} catch (\Exception $e) {
return '';
}
}

public function close()
{
$this->detach();
}

public function detach()
{
$this->tellPos = false;
$this->source = null;
}

public function getSize()
{
return $this->size;
}

public function tell()
{
return $this->tellPos;
}

public function eof()
{
return !$this->source;
}

public function isSeekable()
{
return false;
}

public function rewind()
{
$this->seek(0);
}

public function seek($offset, $whence = SEEK_SET)
{
throw new \RuntimeException('Cannot seek a PumpStream');
}

public function isWritable()
{
return false;
}

public function write($string)
{
throw new \RuntimeException('Cannot write to a PumpStream');
}

public function isReadable()
{
return true;
}

public function read($length)
{
$data = $this->buffer->read($length);
$readLen = strlen($data);
$this->tellPos += $readLen;
$remaining = $length - $readLen;

if ($remaining) {
$this->pump($remaining);
$data .= $this->buffer->read($remaining);
$this->tellPos += strlen($data) - $readLen;
}

return $data;
}

public function getContents()
{
$result = '';
while (!$this->eof()) {
$result .= $this->read(1000000);
}

return $result;
}

public function getMetadata($key = null)
{
if (!$key) {
return $this->metadata;
}

return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
}

private function pump($length)
{
if ($this->source) {
do {
$data = call_user_func($this->source, $length);
if ($data === false || $data === null) {
$this->source = null;
return;
}
$this->buffer->write($data);
$length -= strlen($data);
} while ($length > 0);
}
}
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;




trait MessageTrait
{

private $headers = [];


private $headerNames = [];


private $protocol = '1.1';


private $stream;

public function getProtocolVersion()
{
return $this->protocol;
}

public function withProtocolVersion($version)
{
if ($this->protocol === $version) {
return $this;
}

$new = clone $this;
$new->protocol = $version;
return $new;
}

public function getHeaders()
{
return $this->headers;
}

public function hasHeader($header)
{
return isset($this->headerNames[strtolower($header)]);
}

public function getHeader($header)
{
$header = strtolower($header);

if (!isset($this->headerNames[$header])) {
return [];
}

$header = $this->headerNames[$header];

return $this->headers[$header];
}

public function getHeaderLine($header)
{
return implode(', ', $this->getHeader($header));
}

public function withHeader($header, $value)
{
if (!is_array($value)) {
$value = [$value];
}

$value = $this->trimHeaderValues($value);
$normalized = strtolower($header);

$new = clone $this;
if (isset($new->headerNames[$normalized])) {
unset($new->headers[$new->headerNames[$normalized]]);
}
$new->headerNames[$normalized] = $header;
$new->headers[$header] = $value;

return $new;
}

public function withAddedHeader($header, $value)
{
if (!is_array($value)) {
$value = [$value];
}

$value = $this->trimHeaderValues($value);
$normalized = strtolower($header);

$new = clone $this;
if (isset($new->headerNames[$normalized])) {
$header = $this->headerNames[$normalized];
$new->headers[$header] = array_merge($this->headers[$header], $value);
} else {
$new->headerNames[$normalized] = $header;
$new->headers[$header] = $value;
}

return $new;
}

public function withoutHeader($header)
{
$normalized = strtolower($header);

if (!isset($this->headerNames[$normalized])) {
return $this;
}

$header = $this->headerNames[$normalized];

$new = clone $this;
unset($new->headers[$header], $new->headerNames[$normalized]);

return $new;
}

public function getBody()
{
if (!$this->stream) {
$this->stream = stream_for('');
}

return $this->stream;
}

public function withBody(StreamInterface $body)
{
if ($body === $this->stream) {
return $this;
}

$new = clone $this;
$new->stream = $body;
return $new;
}

private function setHeaders(array $headers)
{
$this->headerNames = $this->headers = [];
foreach ($headers as $header => $value) {
if (!is_array($value)) {
$value = [$value];
}

$value = $this->trimHeaderValues($value);
$normalized = strtolower($header);
if (isset($this->headerNames[$normalized])) {
$header = $this->headerNames[$normalized];
$this->headers[$header] = array_merge($this->headers[$header], $value);
} else {
$this->headerNames[$normalized] = $header;
$this->headers[$header] = $value;
}
}
}















private function trimHeaderValues(array $values)
{
return array_map(function ($value) {
return trim($value, " \t");
}, $values);
}
}
<?php


if (!function_exists('GuzzleHttp\Psr7\str')) {
require __DIR__ . '/functions.php';
}
<?php
namespace GuzzleHttp\Psr7;

use Psr\Http\Message\StreamInterface;









class BufferStream implements StreamInterface
{
private $hwm;
private $buffer = '';








public function __construct($hwm = 16384)
{
$this->hwm = $hwm;
}

public function __toString()
{
return $this->getContents();
}

public function getContents()
{
$buffer = $this->buffer;
$this->buffer = '';

return $buffer;
}

public function close()
{
$this->buffer = '';
}

public function detach()
{
$this->close();
}

public function getSize()
{
return strlen($this->buffer);
}

public function isReadable()
{
return true;
}

public function isWritable()
{
return true;
}

public function isSeekable()
{
return false;
}

public function rewind()
{
$this->seek(0);
}

public function seek($offset, $whence = SEEK_SET)
{
throw new \RuntimeException('Cannot seek a BufferStream');
}

public function eof()
{
return strlen($this->buffer) === 0;
}

public function tell()
{
throw new \RuntimeException('Cannot determine the position of a BufferStream');
}




public function read($length)
{
$currentLength = strlen($this->buffer);

if ($length >= $currentLength) {

 $result = $this->buffer;
$this->buffer = '';
} else {

 $result = substr($this->buffer, 0, $length);
$this->buffer = substr($this->buffer, $length);
}

return $result;
}




public function write($string)
{
$this->buffer .= $string;


 if (strlen($this->buffer) >= $this->hwm) {
return false;
}

return strlen($string);
}

public function getMetadata($key = null)
{
if ($key == 'hwm') {
return $this->hwm;
}

return $key ? null : [];
}
}
<?php



$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'd9d39f82a605ebe5918f683dd402334c' => $vendorDir . '/padraic/humbug_get_contents/src/function.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'8cd2fca4db21bffce1ad0612f7caeec4' => $vendorDir . '/ramsey/array_column/src/array_column.php',
);
<?php



namespace Composer\Autoload;

class ComposerStaticInit154b92334fcc3e94229a830a701cb9c1
{
public static $files = array (
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'd9d39f82a605ebe5918f683dd402334c' => __DIR__ . '/..' . '/padraic/humbug_get_contents/src/function.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'8cd2fca4db21bffce1ad0612f7caeec4' => __DIR__ . '/..' . '/ramsey/array_column/src/array_column.php',
);

public static $prefixLengthsPsr4 = array (
'X' => 
array (
'XdgBaseDir\\' => 11,
),
'S' => 
array (
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Component\\Yaml\\' => 23,
'Symfony\\Component\\Process\\' => 26,
'Symfony\\Component\\Filesystem\\' => 29,
'Symfony\\Component\\DependencyInjection\\' => 38,
'Symfony\\Component\\Debug\\' => 24,
'Symfony\\Component\\Console\\' => 26,
'Symfony\\Component\\Config\\' => 25,
'Shopware\\PluginInfo\\' => 20,
'ShopwareCli\\Tests\\' => 18,
'ShopwareCli\\' => 12,
),
'P' => 
array (
'Psr\\Log\\' => 8,
'Psr\\Http\\Message\\' => 17,
'Piwik\\Ini\\' => 10,
),
'J' => 
array (
'JsonSchema\\' => 11,
),
'H' => 
array (
'Humbug\\SelfUpdate\\' => 18,
'Humbug\\' => 7,
'Http\\Promise\\' => 13,
'Http\\Client\\' => 12,
'Http\\Adapter\\Guzzle6\\' => 21,
),
'G' => 
array (
'GuzzleHttp\\Psr7\\' => 16,
'GuzzleHttp\\Promise\\' => 19,
'GuzzleHttp\\' => 11,
),
'F' => 
array (
'Faker\\' => 6,
),
);

public static $prefixDirsPsr4 = array (
'XdgBaseDir\\' => 
array (
0 => __DIR__ . '/..' . '/dnoegel/php-xdg-base-dir/src',
),
'Symfony\\Polyfill\\Mbstring\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Component\\Yaml\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/yaml',
),
'Symfony\\Component\\Process\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/process',
),
'Symfony\\Component\\Filesystem\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/filesystem',
),
'Symfony\\Component\\DependencyInjection\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/dependency-injection',
),
'Symfony\\Component\\Debug\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/debug',
),
'Symfony\\Component\\Console\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/console',
),
'Symfony\\Component\\Config\\' => 
array (
0 => __DIR__ . '/..' . '/symfony/config',
),
'Shopware\\PluginInfo\\' => 
array (
0 => __DIR__ . '/..' . '/shopwarelabs/plugin-info/src',
),
'ShopwareCli\\Tests\\' => 
array (
0 => __DIR__ . '/../..' . '/tests',
),
'ShopwareCli\\' => 
array (
0 => __DIR__ . '/../..' . '/src',
),
'Psr\\Log\\' => 
array (
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
),
'Psr\\Http\\Message\\' => 
array (
0 => __DIR__ . '/..' . '/psr/http-message/src',
),
'Piwik\\Ini\\' => 
array (
0 => __DIR__ . '/..' . '/piwik/ini/src',
),
'JsonSchema\\' => 
array (
0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema',
),
'Humbug\\SelfUpdate\\' => 
array (
0 => __DIR__ . '/..' . '/padraic/phar-updater/src',
),
'Humbug\\' => 
array (
0 => __DIR__ . '/..' . '/padraic/humbug_get_contents/src/Humbug',
),
'Http\\Promise\\' => 
array (
0 => __DIR__ . '/..' . '/php-http/promise/src',
),
'Http\\Client\\' => 
array (
0 => __DIR__ . '/..' . '/php-http/httplug/src',
),
'Http\\Adapter\\Guzzle6\\' => 
array (
0 => __DIR__ . '/..' . '/php-http/guzzle6-adapter/src',
),
'GuzzleHttp\\Psr7\\' => 
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
),
'GuzzleHttp\\Promise\\' => 
array (
0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
),
'GuzzleHttp\\' => 
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Faker\\' => 
array (
0 => __DIR__ . '/..' . '/fzaninotto/faker/src/Faker',
),
);

public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit154b92334fcc3e94229a830a701cb9c1::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit154b92334fcc3e94229a830a701cb9c1::$prefixDirsPsr4;

}, null, ClassLoader::class);
}
}
<?php



class ComposerAutoloaderInit154b92334fcc3e94229a830a701cb9c1
{
private static $loader;

public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}

public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}

spl_autoload_register(array('ComposerAutoloaderInit154b92334fcc3e94229a830a701cb9c1', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit154b92334fcc3e94229a830a701cb9c1', 'loadClassLoader'));

$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';

call_user_func(\Composer\Autoload\ComposerStaticInit154b92334fcc3e94229a830a701cb9c1::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}

$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}

$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}

$loader->register(true);

if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit154b92334fcc3e94229a830a701cb9c1::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire154b92334fcc3e94229a830a701cb9c1($fileIdentifier, $file);
}

return $loader;
}
}

function composerRequire154b92334fcc3e94229a830a701cb9c1($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}
<?php



$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
'Symfony\\Component\\DependencyInjection\\' => array($vendorDir . '/symfony/dependency-injection'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'),
'Shopware\\PluginInfo\\' => array($vendorDir . '/shopwarelabs/plugin-info/src'),
'ShopwareCli\\Tests\\' => array($baseDir . '/tests'),
'ShopwareCli\\' => array($baseDir . '/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
'Piwik\\Ini\\' => array($vendorDir . '/piwik/ini/src'),
'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'),
'Humbug\\SelfUpdate\\' => array($vendorDir . '/padraic/phar-updater/src'),
'Humbug\\' => array($vendorDir . '/padraic/humbug_get_contents/src/Humbug'),
'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'),
'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'),
'Http\\Adapter\\Guzzle6\\' => array($vendorDir . '/php-http/guzzle6-adapter/src'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
);
<?php











namespace Composer\Autoload;





























class ClassLoader
{

 private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();


 private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();

private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;

public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}

return array();
}

public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}

public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}

public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}

public function getClassMap()
{
return $this->classMap;
}




public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}









public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}

return;
}

$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;

return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}











public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {

 if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {

 $length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {

 $this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {

 $this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}








public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}










public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}






public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}







public function getUseIncludePath()
{
return $this->useIncludePath;
}







public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}






public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}






public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}






public function getApcuPrefix()
{
return $this->apcuPrefix;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}







public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);

return true;
}
}








public function findFile($class)
{

 if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}

$file = $this->findFileWithExtension($class, '.php');


 if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}

if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}

if (false === $file) {

 $this->missingClasses[$class] = true;
}

return $file;
}

private function findFileWithExtension($class, $ext)
{

 $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}


 foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}


 if (false !== $pos = strrpos($class, '\\')) {

 $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {

 $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}

if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}


 foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}


 if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}

return false;
}
}






function includeFile($file)
{
include $file;
}
<?php



$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
);
<?php



$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
);
<?php
require __DIR__ .'/../vendor/autoload.php';
$faker = Faker\Factory::create();
$faker->seed(5);

echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<contacts>
<?php for ($i=0; $i < 10; $i++): ?>
  <contact firstName="<?php echo $faker->firstName ?>" lastName="<?php echo $faker->lastName ?>" email="<?php echo $faker->email ?>" >
    <phone number="<?php echo $faker->phoneNumber ?>"/>
<?php if ($faker->boolean(25)): ?>
    <birth date="<?php echo $faker->dateTimeThisCentury->format('Y-m-d') ?>" place="<?php echo $faker->city ?>"/>
<?php endif; ?>
    <address>
      <street><?php echo $faker->streetAddress ?></street>
      <city><?php echo $faker->city ?></city>
      <postcode><?php echo $faker->postcode ?></postcode>
      <state><?php echo $faker->state ?></state>
    </address>
    <company name="<?php echo $faker->company ?>" catchPhrase="<?php echo $faker->catchPhrase ?>">
<?php if ($faker->boolean(33)): ?>
      <offer><?php echo $faker->bs ?></offer>
<?php endif; ?>
<?php if ($faker->boolean(33)): ?>
      <director name="<?php echo $faker->name ?>" />
<?php endif; ?>
    </company>
<?php if ($faker->boolean(15)): ?>
    <details>
<![CDATA[
<?php echo $faker->text(400) ?>
]]>
    </details>
<?php endif; ?>
  </contact>
<?php endfor; ?>
</contacts>
<?php
require_once __DIR__ . '/../vendor/autoload.php';

$generator = Faker\Factory::create();
$generator->seed(1);
$documentor = new Faker\Documentor($generator);
?>
<?php foreach ($documentor->getFormatters() as $provider => $formatters): ?>

### `<?php echo $provider ?>`

<?php foreach ($formatters as $formatter => $example): ?>
    <?php echo str_pad($formatter, 23) ?><?php if ($example): ?> // <?php echo $example ?> <?php endif; ?>

<?php endforeach; ?>
<?php endforeach;
<?php

namespace Faker\Test\Provider;

use Faker\Calculator\Iban;
use Faker\Calculator\Luhn;
use Faker\Generator;
use Faker\Provider\Base as BaseProvider;
use Faker\Provider\DateTime as DateTimeProvider;
use Faker\Provider\Payment as PaymentProvider;
use Faker\Provider\Person as PersonProvider;

class PaymentTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new BaseProvider($faker));
$faker->addProvider(new DateTimeProvider($faker));
$faker->addProvider(new PersonProvider($faker));
$faker->addProvider(new PaymentProvider($faker));
$this->faker = $faker;
}

public function localeDataProvider()
{
$providerPath = realpath(__DIR__ . '/../../../src/Faker/Provider');
$localePaths = array_filter(glob($providerPath . '/*', GLOB_ONLYDIR));
foreach ($localePaths as $path) {
$parts = explode('/', $path);
$locales[] = array($parts[count($parts) - 1]);
}

return $locales;
}

public function loadLocalProviders($locale)
{
$providerPath = realpath(__DIR__ . '/../../../src/Faker/Provider');
if (file_exists($providerPath.'/'.$locale.'/Payment.php')) {
$payment = "\\Faker\\Provider\\$locale\\Payment";
$this->faker->addProvider(new $payment($this->faker));
}
}

public function testCreditCardTypeReturnsValidVendorName()
{
$this->assertTrue(in_array($this->faker->creditCardType, array('Visa', 'MasterCard', 'American Express', 'Discover Card')));
}

public function creditCardNumberProvider()
{
return array(
array('Discover Card', '/^6011\d{12}$/'),
array('Visa', '/^4\d{12,15}$/'),
array('MasterCard', '/^(5[1-5]|2[2-7])\d{14}$/')
);
}




public function testCreditCardNumberReturnsValidCreditCardNumber($type, $regexp)
{
$cardNumber = $this->faker->creditCardNumber($type);
$this->assertRegExp($regexp, $cardNumber);
$this->assertTrue(Luhn::isValid($cardNumber));
}

public function testCreditCardNumberCanFormatOutput()
{
$this->assertRegExp('/^6011-\d{4}-\d{4}-\d{4}$/', $this->faker->creditCardNumber('Discover Card', true));
}

public function testCreditCardExpirationDateReturnsValidDateByDefault()
{
$expirationDate = $this->faker->creditCardExpirationDate;
$this->assertTrue(intval($expirationDate->format('U')) > strtotime('now'));
$this->assertTrue(intval($expirationDate->format('U')) < strtotime('+36 months'));
}

public function testRandomCard()
{
$cardDetails = $this->faker->creditCardDetails;
$this->assertEquals(count($cardDetails), 4);
$this->assertEquals(array('type', 'number', 'name', 'expirationDate'), array_keys($cardDetails));
}

protected $ibanFormats = array(
'AD' => '/^AD\d{2}\d{4}\d{4}[A-Z0-9]{12}$/',
'AE' => '/^AE\d{2}\d{3}\d{16}$/',
'AL' => '/^AL\d{2}\d{8}[A-Z0-9]{16}$/',
'AT' => '/^AT\d{2}\d{5}\d{11}$/',
'AZ' => '/^AZ\d{2}[A-Z]{4}[A-Z0-9]{20}$/',
'BA' => '/^BA\d{2}\d{3}\d{3}\d{8}\d{2}$/',
'BE' => '/^BE\d{2}\d{3}\d{7}\d{2}$/',
'BG' => '/^BG\d{2}[A-Z]{4}\d{4}\d{2}[A-Z0-9]{8}$/',
'BH' => '/^BH\d{2}[A-Z]{4}[A-Z0-9]{14}$/',
'BR' => '/^BR\d{2}\d{8}\d{5}\d{10}[A-Z]{1}[A-Z0-9]{1}$/',
'CH' => '/^CH\d{2}\d{5}[A-Z0-9]{12}$/',
'CR' => '/^CR\d{2}\d{3}\d{14}$/',
'CY' => '/^CY\d{2}\d{3}\d{5}[A-Z0-9]{16}$/',
'CZ' => '/^CZ\d{2}\d{4}\d{6}\d{10}$/',
'DE' => '/^DE\d{2}\d{8}\d{10}$/',
'DK' => '/^DK\d{2}\d{4}\d{9}\d{1}$/',
'DO' => '/^DO\d{2}[A-Z0-9]{4}\d{20}$/',
'EE' => '/^EE\d{2}\d{2}\d{2}\d{11}\d{1}$/',
'ES' => '/^ES\d{2}\d{4}\d{4}\d{1}\d{1}\d{10}$/',
'FI' => '/^FI\d{2}\d{6}\d{7}\d{1}$/',
'FR' => '/^FR\d{2}\d{5}\d{5}[A-Z0-9]{11}\d{2}$/',
'GB' => '/^GB\d{2}[A-Z]{4}\d{6}\d{8}$/',
'GE' => '/^GE\d{2}[A-Z]{2}\d{16}$/',
'GI' => '/^GI\d{2}[A-Z]{4}[A-Z0-9]{15}$/',
'GR' => '/^GR\d{2}\d{3}\d{4}[A-Z0-9]{16}$/',
'GT' => '/^GT\d{2}[A-Z0-9]{4}[A-Z0-9]{20}$/',
'HR' => '/^HR\d{2}\d{7}\d{10}$/',
'HU' => '/^HU\d{2}\d{3}\d{4}\d{1}\d{15}\d{1}$/',
'IE' => '/^IE\d{2}[A-Z]{4}\d{6}\d{8}$/',
'IL' => '/^IL\d{2}\d{3}\d{3}\d{13}$/',
'IS' => '/^IS\d{2}\d{4}\d{2}\d{6}\d{10}$/',
'IT' => '/^IT\d{2}[A-Z]{1}\d{5}\d{5}[A-Z0-9]{12}$/',
'KW' => '/^KW\d{2}[A-Z]{4}\d{22}$/',
'KZ' => '/^KZ\d{2}\d{3}[A-Z0-9]{13}$/',
'LB' => '/^LB\d{2}\d{4}[A-Z0-9]{20}$/',
'LI' => '/^LI\d{2}\d{5}[A-Z0-9]{12}$/',
'LT' => '/^LT\d{2}\d{5}\d{11}$/',
'LU' => '/^LU\d{2}\d{3}[A-Z0-9]{13}$/',
'LV' => '/^LV\d{2}[A-Z]{4}[A-Z0-9]{13}$/',
'MC' => '/^MC\d{2}\d{5}\d{5}[A-Z0-9]{11}\d{2}$/',
'MD' => '/^MD\d{2}[A-Z0-9]{2}[A-Z0-9]{18}$/',
'ME' => '/^ME\d{2}\d{3}\d{13}\d{2}$/',
'MK' => '/^MK\d{2}\d{3}[A-Z0-9]{10}\d{2}$/',
'MR' => '/^MR\d{2}\d{5}\d{5}\d{11}\d{2}$/',
'MT' => '/^MT\d{2}[A-Z]{4}\d{5}[A-Z0-9]{18}$/',
'MU' => '/^MU\d{2}[A-Z]{4}\d{2}\d{2}\d{12}\d{3}[A-Z]{3}$/',
'NL' => '/^NL\d{2}[A-Z]{4}\d{10}$/',
'NO' => '/^NO\d{2}\d{4}\d{6}\d{1}$/',
'PK' => '/^PK\d{2}[A-Z]{4}[A-Z0-9]{16}$/',
'PL' => '/^PL\d{2}\d{8}\d{16}$/',
'PS' => '/^PS\d{2}[A-Z]{4}[A-Z0-9]{21}$/',
'PT' => '/^PT\d{2}\d{4}\d{4}\d{11}\d{2}$/',
'RO' => '/^RO\d{2}[A-Z]{4}[A-Z0-9]{16}$/',
'RS' => '/^RS\d{2}\d{3}\d{13}\d{2}$/',
'SA' => '/^SA\d{2}\d{2}[A-Z0-9]{18}$/',
'SE' => '/^SE\d{2}\d{3}\d{16}\d{1}$/',
'SI' => '/^SI\d{2}\d{5}\d{8}\d{2}$/',
'SK' => '/^SK\d{2}\d{4}\d{6}\d{10}$/',
'SM' => '/^SM\d{2}[A-Z]{1}\d{5}\d{5}[A-Z0-9]{12}$/',
'TN' => '/^TN\d{2}\d{2}\d{3}\d{13}\d{2}$/',
'TR' => '/^TR\d{2}\d{5}\d{1}[A-Z0-9]{16}$/',
'VG' => '/^VG\d{2}[A-Z]{4}\d{16}$/',
);




public function testBankAccountNumber($locale)
{
$parts = explode('_', $locale);
$countryCode = array_pop($parts);

if (!isset($this->ibanFormats[$countryCode])) {

 return;
}

$this->loadLocalProviders($locale);

try {
$iban = $this->faker->bankAccountNumber;
} catch (\InvalidArgumentException $e) {

 $this->markTestSkipped("bankAccountNumber not implemented for $locale");
return;
}


 $this->assertRegExp($this->ibanFormats[$countryCode], $iban);


 $this->assertTrue(Iban::isValid($iban), "Checksum for $iban is invalid");
}

public function ibanFormatProvider()
{
$return = array();
foreach ($this->ibanFormats as $countryCode => $regex) {
$return[] = array($countryCode, $regex);
}
return $return;
}



public function testIban($countryCode, $regex)
{
$iban = $this->faker->iban($countryCode);


 $this->assertRegExp($regex, $iban);


 $this->assertTrue(Iban::isValid($iban), "Checksum for $iban is invalid");
}
}
<?php

namespace Faker\Test\Provider\nl_BE;

use Faker\Generator;
use Faker\Provider\nl_BE\Payment;

class PaymentTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Payment($faker));
$this->faker = $faker;
}

public function testVatIsValid()
{
$vat = $this->faker->vat();
$unspacedVat = $this->faker->vat(false);
$this->assertRegExp('/^(BE 0\d{9})$/', $vat);
$this->assertRegExp('/^(BE0\d{9})$/', $unspacedVat);
}
}
<?php

namespace Faker\Test\Provider\id_ID;

use Faker\Generator;
use Faker\Provider\id_ID\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testIfFirstNameMaleCanReturnData()
{
$firstNameMale = $this->faker->firstNameMale();
$this->assertNotEmpty($firstNameMale);
}

public function testIfLastNameMaleCanReturnData()
{
$lastNameMale = $this->faker->lastNameMale();
$this->assertNotEmpty($lastNameMale);
}

public function testIfFirstNameFemaleCanReturnData()
{
$firstNameFemale = $this->faker->firstNameFemale();
$this->assertNotEmpty($firstNameFemale);
}

public function testIfLastNameFemaleCanReturnData()
{
$lastNameFemale = $this->faker->lastNameFemale();
$this->assertNotEmpty($lastNameFemale);
}
}
<?php

namespace Faker\Test\Provider\ar_JO;

use Faker\Generator;
use Faker\Provider\fi_FI\Person;
use Faker\Provider\fi_FI\Internet;
use Faker\Provider\fi_FI\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\ar_SA;

use Faker\Generator;
use Faker\Provider\ar_SA\Person;
use Faker\Provider\ar_SA\Internet;
use Faker\Provider\ar_SA\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\da_DK;

use Faker\Generator;
use Faker\Provider\da_DK\Person;
use Faker\Provider\da_DK\Internet;
use Faker\Provider\da_DK\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\de_AT;

use Faker\Generator;
use Faker\Provider\de_AT\Person;
use Faker\Provider\de_AT\Internet;
use Faker\Provider\de_AT\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\de_AT;

use Faker\Generator;
use Faker\Provider\de_AT\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumberFormat()
{
$number = $this->faker->phoneNumber;
$this->assertRegExp('/^06\d{2} \d{7}|\+43 \d{4} \d{4}(-\d{2})?$/', $number);
}
}
<?php

namespace Faker\Test\Provider\at_AT;

use Faker\Generator;
use Faker\Provider\at_AT\Payment;

class PaymentTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Payment($faker));
$this->faker = $faker;
}

public function testVatIsValid()
{
$vat = $this->faker->vat();
$unspacedVat = $this->faker->vat(false);
$this->assertRegExp('/^(AT U\d{8})$/', $vat);
$this->assertRegExp('/^(ATU\d{8})$/', $unspacedVat);
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Provider\Uuid as BaseProvider;

class UuidTest extends \PHPUnit_Framework_TestCase
{
public function testUuidReturnsUuid()
{
$uuid = BaseProvider::uuid();
$this->assertTrue($this->isUuid($uuid));
}

public function testUuidExpectedSeed()
{
$faker = new Generator();
$faker->seed(123);
$this->assertEquals("8e2e0c84-50dd-367c-9e66-f3ab455c78d6", BaseProvider::uuid());
$this->assertEquals("073eb60a-902c-30ab-93d0-a94db371f6c8", BaseProvider::uuid());
}

protected function isUuid($uuid)
{
return is_string($uuid) && (bool) preg_match('/^[a-f0-9]{8,8}-(?:[a-f0-9]{4,4}-){3,3}[a-f0-9]{12,12}$/i', $uuid);
}
}
<?php

namespace Faker\Test\Provider\fr_BE;

use Faker\Generator;
use Faker\Provider\fr_BE\Payment;

class PaymentTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Payment($faker));
$this->faker = $faker;
}

public function testVatIsValid()
{
$vat = $this->faker->vat();
$unspacedVat = $this->faker->vat(false);
$this->assertRegExp('/^(BE 0\d{9})$/', $vat);
$this->assertRegExp('/^(BE0\d{9})$/', $unspacedVat);
}
}
<?php

namespace Faker\Test\Provider\pt_BR;

use Faker\Generator;
use Faker\Provider\pt_BR\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testCpfFormatIsValid()
{
$cpf = $this->faker->cpf(false);
$this->assertRegExp('/\d{9}\d{2}/', $cpf);
$cpf = $this->faker->cpf(true);
$this->assertRegExp('/\d{3}\.\d{3}\.\d{3}-\d{2}/', $cpf);
}

public function testRgFormatIsValid()
{
$rg = $this->faker->rg(false);
$this->assertRegExp('/\d{8}\d/', $rg);
$rg = $this->faker->rg(true);
$this->assertRegExp('/\d{2}\.\d{3}\.\d{3}-[0-9X]/', $rg);
}
}
<?php

namespace Faker\Test\Provider\pt_BR;

use Faker\Generator;
use Faker\Provider\pt_BR\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testCnpjFormatIsValid()
{
$cnpj = $this->faker->cnpj(false);
$this->assertRegExp('/\d{8}\d{4}\d{2}/', $cnpj);
$cnpj = $this->faker->cnpj(true);
$this->assertRegExp('/\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}/', $cnpj);
}
}
<?php

namespace Faker\Test\Provider\en_NZ;

use Faker\Generator;
use Faker\Provider\en_NZ\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testIfPhoneNumberCanReturnData()
{
$number = $this->faker->phoneNumber;
$this->assertNotEmpty($number);
}

public function phoneNumberFormat()
{
$number = $this->faker->phoneNumber;
$this->assertRegExp('/(^\([0]\d{1}\))(\d{7}$)|(^\([0][2]\d{1}\))(\d{6,8}$)|([0][8][0][0])([\s])(\d{5,8}$)/', $number);
}
}
?>
<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Provider\Company;
use Faker\Provider\Internet;
use Faker\Provider\Lorem;
use Faker\Provider\Person;

class InternetTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Lorem($faker));
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function localeDataProvider()
{
$providerPath = realpath(__DIR__ . '/../../../src/Faker/Provider');
$localePaths = array_filter(glob($providerPath . '/*', GLOB_ONLYDIR));
foreach ($localePaths as $path) {
$parts = explode('/', $path);
$locales[] = array($parts[count($parts) - 1]);
}

return $locales;
}






public function testEmailIsValid($locale)
{
if ($locale !== 'en_US' && !class_exists('Transliterator')) {
$this->markTestSkipped('Transliterator class not available (intl extension)');
}

$this->loadLocalProviders($locale);
$pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD';
$emailAddress = $this->faker->email();
$this->assertRegExp($pattern, $emailAddress);
}




public function testUsernameIsValid($locale)
{
if ($locale !== 'en_US' && !class_exists('Transliterator')) {
$this->markTestSkipped('Transliterator class not available (intl extension)');
}

$this->loadLocalProviders($locale);
$pattern = '/^[A-Za-z0-9]+([._][A-Za-z0-9]+)*$/';
$username = $this->faker->username();
$this->assertRegExp($pattern, $username);
}




public function testDomainnameIsValid($locale)
{
if ($locale !== 'en_US' && !class_exists('Transliterator')) {
$this->markTestSkipped('Transliterator class not available (intl extension)');
}

$this->loadLocalProviders($locale);
$pattern = '/^[a-z]+(\.[a-z]+)+$/';
$domainName = $this->faker->domainName();
$this->assertRegExp($pattern, $domainName);
}




public function testDomainwordIsValid($locale)
{
if ($locale !== 'en_US' && !class_exists('Transliterator')) {
$this->markTestSkipped('Transliterator class not available (intl extension)');
}

$this->loadLocalProviders($locale);
$pattern = '/^[a-z]+$/';
$domainWord = $this->faker->domainWord();
$this->assertRegExp($pattern, $domainWord);
}

public function loadLocalProviders($locale)
{
$providerPath = realpath(__DIR__ . '/../../../src/Faker/Provider');
if (file_exists($providerPath.'/'.$locale.'/Internet.php')) {
$internet = "\\Faker\\Provider\\$locale\\Internet";
$this->faker->addProvider(new $internet($this->faker));
}
if (file_exists($providerPath.'/'.$locale.'/Person.php')) {
$person = "\\Faker\\Provider\\$locale\\Person";
$this->faker->addProvider(new $person($this->faker));
}
if (file_exists($providerPath.'/'.$locale.'/Company.php')) {
$company = "\\Faker\\Provider\\$locale\\Company";
$this->faker->addProvider(new $company($this->faker));
}
}

public function testPasswordIsValid()
{
$this->assertRegexp('/^.{6}$/', $this->faker->password(6, 6));
}

public function testSlugIsValid()
{
$pattern = '/^[a-z0-9-]+$/';
$slug = $this->faker->slug();
$this->assertSame(preg_match($pattern, $slug), 1);
}

public function testUrlIsValid()
{
$url = $this->faker->url();
$this->assertNotFalse(filter_var($url, FILTER_VALIDATE_URL));
}

public function testLocalIpv4()
{
$this->assertNotFalse(filter_var(Internet::localIpv4(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
}

public function testIpv4()
{
$this->assertNotFalse(filter_var($this->faker->ipv4(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
}

public function testIpv4NotLocalNetwork()
{
$this->assertNotRegExp('/\A0\./', $this->faker->ipv4());
}

public function testIpv4NotBroadcast()
{
$this->assertNotEquals('255.255.255.255', $this->faker->ipv4());
}

public function testIpv6()
{
$this->assertNotFalse(filter_var($this->faker->ipv6(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
}

public function testMacAddress()
{
$this->assertRegExp('/^([0-9A-F]{2}[:]){5}([0-9A-F]{2})$/i', Internet::macAddress());
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\Person;
use Faker\Generator;

class PersonTest extends \PHPUnit_Framework_TestCase
{



public function testFirstName($gender, $expected)
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->assertContains($faker->firstName($gender), $expected);
}

public function firstNameProvider()
{
return array(
array(null, array('John', 'Jane')),
array('foobar', array('John', 'Jane')),
array('male', array('John')),
array('female', array('Jane')),
);
}

public function testFirstNameMale()
{
$this->assertContains(Person::firstNameMale(), array('John'));
}

public function testFirstNameFemale()
{
$this->assertContains(Person::firstNameFemale(), array('Jane'));
}




public function testTitle($gender, $expected)
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->assertContains($faker->title($gender), $expected);
}

public function titleProvider()
{
return array(
array(null, array('Mr.', 'Mrs.', 'Ms.', 'Miss', 'Dr.', 'Prof.')),
array('foobar', array('Mr.', 'Mrs.', 'Ms.', 'Miss', 'Dr.', 'Prof.')),
array('male', array('Mr.', 'Dr.', 'Prof.')),
array('female', array('Mrs.', 'Ms.', 'Miss', 'Dr.', 'Prof.')),
);
}

public function testTitleMale()
{
$this->assertContains(Person::titleMale(), array('Mr.', 'Dr.', 'Prof.'));
}

public function testTitleFemale()
{
$this->assertContains(Person::titleFemale(), array('Mrs.', 'Ms.', 'Miss', 'Dr.', 'Prof.'));
}

public function testLastNameReturnsDoe()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->assertEquals($faker->lastName(), 'Doe');
}

public function testNameReturnsFirstNameAndLastName()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->assertContains($faker->name(), array('John Doe', 'Jane Doe'));
$this->assertContains($faker->name('foobar'), array('John Doe', 'Jane Doe'));
$this->assertContains($faker->name('male'), array('John Doe'));
$this->assertContains($faker->name('female'), array('Jane Doe'));
}
}
<?php

namespace Faker\Test\Provider\de_CH;

use Faker\Generator;
use Faker\Provider\de_CH\Person;
use Faker\Provider\de_CH\Internet;
use Faker\Provider\de_CH\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}




public function emailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\de_CH;

use Faker\Generator;
use Faker\Provider\de_CH\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumber()
{
$this->assertRegExp('/^0\d{2} ?\d{3} ?\d{2} ?\d{2}|\+41 ?(\(0\))?\d{2} ?\d{3} ?\d{2} ?\d{2}$/', $this->faker->phoneNumber());
}

public function testMobileNumber()
{
$this->assertRegExp('/^07[56789] ?\d{3} ?\d{2} ?\d{2}$/', $this->faker->mobileNumber());
}
}
<?php

namespace Faker\Test\Provider\de_CH;

use Faker\Generator;
use Faker\Provider\de_CH\Address;
use Faker\Provider\de_CH\Person;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}




public function canton ()
{
$canton = $this->faker->canton();
$this->assertInternalType('array', $canton);
$this->assertCount(1, $canton);

foreach ($canton as $cantonShort => $cantonName){
$this->assertInternalType('string', $cantonShort);
$this->assertEquals(2, strlen($cantonShort));
$this->assertInternalType('string', $cantonName);
$this->assertGreaterThan(2, strlen($cantonName));
}
}




public function cantonName ()
{
$cantonName = $this->faker->cantonName();
$this->assertInternalType('string', $cantonName);
$this->assertGreaterThan(2, strlen($cantonName));
}




public function cantonShort ()
{
$cantonShort = $this->faker->cantonShort();
$this->assertInternalType('string', $cantonShort);
$this->assertEquals(2, strlen($cantonShort));
}




public function address (){
$address = $this->faker->address();
$this->assertInternalType('string', $address);
}
}
<?php

namespace Faker\Test\Provider\en_ZA;

use Faker\Generator;
use Faker\Provider\en_ZA\Person;
use Faker\Provider\en_ZA\Internet;
use Faker\Provider\en_ZA\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\en_ZA;

use Faker\Generator;
use Faker\Provider\en_ZA\Person;
use Faker\Provider\DateTime;

class PersonTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new DateTime($faker));
$this->faker = $faker;
}

public function testIdNumberWithDefaults()
{
$idNumber = $this->faker->idNumber();

$this->assertEquals(13, strlen($idNumber));
$this->assertRegExp('#^\d{13}$#', $idNumber);
$this->assertInternalType('string', $idNumber);
}

public function testIdNumberForMales()
{
$idNumber = $this->faker->idNumber(new \DateTime(), true, 'male');

$genderDigit = substr($idNumber, 6, 1);

$this->assertContains($genderDigit, array('5', '6', '7', '8', '9'));
}

public function testIdNumberForFemales()
{
$idNumber = $this->faker->idNumber(new \DateTime(), true, 'female');

$genderDigit = substr($idNumber, 6, 1);

$this->assertContains($genderDigit, array('0', '1', '2', '3', '4'));
}
}
<?php

namespace Faker\Test\Provider\en_ZA;

use Faker\Generator;
use Faker\Provider\en_ZA\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testGenerateValidCompanyNumber()
{
$companyRegNo = $this->faker->companyNumber();

$this->assertEquals(14, strlen($companyRegNo));
$this->assertRegExp('#^\d{4}/\d{6}/\d{2}$#', $companyRegNo);
}
}<?php

namespace Faker\Test\Provider\en_ZA;

use Faker\Generator;
use Faker\Provider\en_ZA\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumber()
{
for ($i = 0; $i < 10; $i++) {
$number = $this->faker->phoneNumber;

$digits = array_values(array_filter(str_split($number), 'ctype_digit'));


 if($digits[0] = 2 && $digits[1] == 7) {
$this->assertLessThanOrEqual(11, count($digits));
} else {
$this->assertGreaterThanOrEqual(10, count($digits));
}
}
}

public function testTollFreePhoneNumber()
{
for ($i = 0; $i < 10; $i++) {
$number = $this->faker->tollFreeNumber;
$digits = array_values(array_filter(str_split($number), 'ctype_digit'));

if (count($digits) === 11) {
$this->assertEquals('0', $digits[0]);
}

$areaCode = $digits[0] . $digits[1] . $digits[2] . $digits[3];
$this->assertContains($areaCode, array('0800', '0860', '0861', '0862'));
}
}

public function testCellPhoneNumber()
{
for ($i = 0; $i < 10; $i++) {
$number = $this->faker->mobileNumber;
$digits = array_values(array_filter(str_split($number), 'ctype_digit'));

if($digits[0] = 2 && $digits[1] == 7) {
$this->assertLessThanOrEqual(11, count($digits));
} else {
$this->assertGreaterThanOrEqual(10, count($digits));
}

$this->assertRegExp('/^(\+27|27)?(\()?0?([6][0-4]|[7][1-9]|[8][1-9])(\))?( |-|\.|_)?(\d{3})( |-|\.|_)?(\d{4})/', $number);
}
}
}<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Provider\HtmlLorem;

class HtmlLoremTest extends \PHPUnit_Framework_TestCase
{

public function testProvider()
{
$faker = new Generator();
$faker->addProvider(new HtmlLorem($faker));
$node = $faker->randomHtml(6, 10);
$this->assertStringStartsWith("<html>", $node);
$this->assertStringEndsWith("</html>\n", $node);
}

public function testRandomHtmlReturnsValidHTMLString(){
$faker = new Generator();
$faker->addProvider(new HtmlLorem($faker));
$node = $faker->randomHtml(6, 10);
$dom = new \DOMDocument();
$error = $dom->loadHTML($node);
$this->assertTrue($error);
}

}
<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Provider\Company;
use Faker\Provider\Lorem;

class CompanyTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$faker->addProvider(new Lorem($faker));
$this->faker = $faker;
}

public function testJobTitle()
{
$jobTitle = $this->faker->jobTitle();
$pattern = '/^[A-Za-z]+$/';
$this->assertRegExp($pattern, $jobTitle);
}
}
<?php

namespace Faker\Test\Provider\fi_FI;

use Faker\Generator;
use Faker\Provider\fi_FI\Person;
use Faker\Provider\fi_FI\Internet;
use Faker\Provider\fi_FI\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\fi_FI;

use Faker\Generator;
use Faker\Provider\DateTime;
use Faker\Provider\fi_FI\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{

protected $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new DateTime($faker));
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function provideSeedAndExpectedReturn()
{
return array(
array(1, '1800-01-01', '010100+5207'),
array(2, '1930-08-08', '080830-508R'),
array(3, '1999-12-31', '311299-409D'),
array(4, '2000-01-01', '010100A039P'),
array(5, '2015-06-17', '170615A690X')
);
}




public function testPersonalIdentityNumberUsesBirthDateIfProvided($seed, $birthdate, $expected)
{
$faker = $this->faker;
$faker->seed($seed);
$pin = $faker->personalIdentityNumber(\DateTime::createFromFormat('Y-m-d', $birthdate));
$this->assertEquals($expected, $pin);
}

public function testPersonalIdentityNumberGeneratesCompliantNumbers()
{
for ($i = 0; $i < 10; $i++) {
$birthdate = $this->faker->dateTimeBetween('1800-01-01 00:00:00', '1899-12-31 23:59:59');
$pin = $this->faker->personalIdentityNumber($birthdate);
$this->assertRegExp('/^[0-9]{6}\+[0-9]{3}[0-9ABCDEFHJKLMNPRSTUVWXY]$/', $pin);
}
for ($i = 0; $i < 10; $i++) {
$birthdate = $this->faker->dateTimeBetween('1900-01-01 00:00:00', '1999-12-31 23:59:59');
$pin = $this->faker->personalIdentityNumber($birthdate);
$this->assertRegExp('/^[0-9]{6}-[0-9]{3}[0-9ABCDEFHJKLMNPRSTUVWXY]$/', $pin);
}
for ($i = 0; $i < 10; $i++) {
$birthdate = $this->faker->dateTimeBetween('2000-01-01 00:00:00', '2099-12-31 23:59:59');
$pin = $this->faker->personalIdentityNumber($birthdate);
$this->assertRegExp('/^[0-9]{6}A[0-9]{3}[0-9ABCDEFHJKLMNPRSTUVWXY]$/', $pin);
}
}

public function testPersonalIdentityNumberGeneratesOddValuesForMales()
{
$pin = $this->faker->personalIdentityNumber(null, 'male');
$this->assertEquals(1, $pin{9} % 2);
}

public function testPersonalIdentityNumberGeneratesEvenValuesForFemales()
{
$pin = $this->faker->personalIdentityNumber(null, 'female');
$this->assertEquals(0, $pin{9} % 2);
}
}
<?php

namespace Faker\Test\Provider\ja_JP;

use Faker\Generator;
use Faker\Provider\ja_JP\Internet;

class InternetTest extends \PHPUnit_Framework_TestCase
{
public function testUserName()
{
$faker = new Generator();
$faker->addProvider(new Internet($faker));
$faker->seed(1);

$this->assertEquals('akira72', $faker->userName);
}

public function testDomainName()
{
$faker = new Generator();
$faker->addProvider(new Internet($faker));
$faker->seed(1);

$this->assertEquals('nakajima.com', $faker->domainName);
}
}
<?php

namespace Faker\Test\Provider\ja_JP;

use Faker\Generator;
use Faker\Provider\ja_JP\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function testKanaNameMaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('アオタ ミノル', $faker->kanaName('male'));
}

public function testKanaNameFemaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('アオタ ミキ', $faker->kanaName('female'));
}

public function testFirstKanaNameMaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('ヒデキ', $faker->firstKanaName('male'));
}

public function testFirstKanaNameFemaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('マアヤ', $faker->firstKanaName('female'));
}

public function testLastKanaNameReturnsNakajima()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('ナカジマ', $faker->lastKanaName);
}
}
<?php

namespace Faker\Test\Provider\ja_JP;

use Faker\Generator;
use Faker\Provider\ja_JP\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{
public function testPhoneNumber()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));

for ($i = 0; $i < 10; $i++) {
$phoneNumber = $faker->phoneNumber;
$this->assertNotEmpty($phoneNumber);
$this->assertRegExp('/^0\d{1,4}-\d{1,4}-\d{3,4}$/', $phoneNumber);
}
}
}
<?php

namespace Faker\Test\Provider\uk_UA;

use Faker\Generator;
use Faker\Provider\uk_UA\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function testFirstNameMaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('Максим', $faker->firstNameMale());
}

public function testFirstNameFemaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('Людмила', $faker->firstNameFemale());
}

public function testMiddleNameMaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('Миколайович', $faker->middleNameMale());
}

public function testMiddleNameFemaleReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('Миколаївна', $faker->middleNameFemale());
}

public function testLastNameReturns()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertEquals('Броваренко', $faker->lastName());
}


}
<?php

namespace Faker\Test\Provider\uk_UA;

use Faker\Generator;
use Faker\Provider\uk_UA\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumberFormat()
{
$pattern = "/((\+38)(((\(\d{3}\))\d{7}|(\(\d{4}\))\d{6})|(\d{8})))|0\d{9}/";
$phoneNumber = $this->faker->phoneNumber;
$this->assertSame(
preg_match($pattern, $phoneNumber),
1,
'Phone number format ' . $phoneNumber . ' is wrong!'
);

}

}
<?php

namespace Faker\Test\Provider\uk_UA;

use Faker\Generator;
use Faker\Provider\uk_UA\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testPostCodeIsValid()
{
$main = '[0-9]{5}';
$pattern = "/^($main)|($main-[0-9]{3})+$/";
$postcode = $this->faker->postcode;
$this->assertRegExp($pattern, $postcode, 'Post code ' . $postcode . ' is wrong!');
}

public function testEmptySuffixes()
{
$this->assertEmpty($this->faker->citySuffix, 'City suffix should be empty!');
$this->assertEmpty($this->faker->streetSuffix, 'Street suffix should be empty!');
}

public function testStreetCyrOnly()
{
$pattern = "/[0-9А-ЩЯІЇЄЮа-щяіїєюьIVXCM][0-9А-ЩЯІЇЄЮа-щяіїєюь \'-.]*[А-Яа-я.]/u";
$streetName = $this->faker->streetName;
$this->assertSame(
preg_match($pattern, $streetName),
1,
'Street name ' . $streetName . ' is wrong!'
);
}

public function testCityNameCyrOnly()
{
$pattern = "/[А-ЩЯІЇЄЮа-щяіїєюь][0-9А-ЩЯІЇЄЮа-щяіїєюь \'-]*[А-Яа-я]/u";
$city = $this->faker->city;
$this->assertSame(
preg_match($pattern, $city),
1,
'City name ' . $city . ' is wrong!'
);
}

public function testRegionNameCyrOnly()
{
$pattern = "/[А-ЩЯІЇЄЮ][А-ЩЯІЇЄЮа-щяіїєюь]*а$/u";
$regionName = $this->faker->region;
$this->assertSame(
preg_match($pattern, $regionName),
1,
'Region name ' . $regionName . ' is wrong!'
);
}

public function testCountryCyrOnly()
{
$pattern = "/[А-ЩЯІЇЄЮа-щяіїєюьIVXCM][А-ЩЯІЇЄЮа-щяіїєюь \'-]*[А-Яа-я.]/u";
$country = $this->faker->country;
$this->assertSame(
preg_match($pattern, $country),
1,
'Country name ' . $country . ' is wrong!'
);
}
}
<?php


namespace Faker\Provider\en_US;

use Faker\Generator;

class PaymentTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Payment($faker));
$this->faker = $faker;
}

public function testBankAccountNumber()
{
$accNo = $this->faker->bankAccountNumber;
$this->assertTrue(ctype_digit($accNo));
$this->assertLessThanOrEqual(17, strlen($accNo));
}

public function testBankRoutingNumber()
{
$routingNo = $this->faker->bankRoutingNumber;
$this->assertRegExp('/^\d{9}$/', $routingNo);
$this->assertEquals(Payment::calculateRoutingNumberChecksum($routingNo), $routingNo[8]);
}

public function routingNumberProvider()
{
return array(
array('122105155'),
array('082000549'),
array('121122676'),
array('122235821'),
array('102101645'),
array('102000021'),
array('123103729'),
array('071904779'),
array('081202759'),
array('074900783'),
array('104000029'),
array('073000545'),
array('101000187'),
array('042100175'),
array('083900363'),
array('091215927'),
array('091300023'),
array('091000022'),
array('081000210'),
array('101200453'),
array('092900383'),
array('104000029'),
array('121201694'),
array('107002312'),
array('091300023'),
array('041202582'),
array('042000013'),
array('123000220'),
array('091408501'),
array('064000059'),
array('124302150'),
array('125000105'),
array('075000022'),
array('307070115'),
array('091000022'),
);
}




public function testCalculateRoutingNumberChecksum($routingNo)
{
$this->assertEquals($routingNo[8], Payment::calculateRoutingNumberChecksum($routingNo), $routingNo);
}
}
<?php

namespace Faker\Test\Provider\en_US;

use Faker\Provider\en_US\Person;
use Faker\Generator;

class PersonTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testSsn()
{
for ($i = 0; $i < 100; $i++) {
$number = $this->faker->ssn;


 $this->assertRegExp('/^[0-9]{3}-[0-9]{2}-[0-9]{4}$/', $number);

$parts = explode("-", $number);


 $this->assertNotEquals(666, $parts[0]);
$this->assertGreaterThan(0, $parts[0]);
$this->assertLessThan(900, $parts[0]);


 $this->assertGreaterThan(0, $parts[1]);
$this->assertLessThan(100, $parts[1]);


 $this->assertGreaterThan(0, $parts[2]);
$this->assertLessThan(10000, $parts[2]);
}
}
}
<?php

namespace Faker\Test\Provider\en_US;

use Faker\Generator;
use Faker\Provider\en_US\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumber()
{
for ($i = 0; $i < 100; $i++) {
$number = $this->faker->phoneNumber;
$baseNumber = preg_replace('/ *x.*$/', '', $number); 
 $digits = array_values(array_filter(str_split($baseNumber), 'ctype_digit'));


 if (count($digits) === 11) {
$this->assertEquals('1', $digits[0]);
$digits = array_slice($digits, 1);
}


 $this->assertEquals(10, count($digits));


 $this->assertNotEquals($digits[1], $digits[2]);


 if ($digits[4] === 1) {
$this->assertNotEquals($digits[4], $digits[5]);
}


 $this->assertRegExp('/^(\+?1)?([ -.]*\d{3}[ -.]*| *\(\d{3}\) *)\d{3}[-.]?\d{4}$/', $baseNumber);
}
}

public function testTollFreeAreaCode()
{
$this->assertContains($this->faker->tollFreeAreaCode, array(800, 822, 833, 844, 855, 866, 877, 888, 880, 887, 889));
}

public function testTollFreePhoneNumber()
{
for ($i = 0; $i < 100; $i++) {
$number = $this->faker->tollFreePhoneNumber;
$digits = array_values(array_filter(str_split($number), 'ctype_digit'));


 if (count($digits) === 11) {
$this->assertEquals('1', $digits[0]);
$digits = array_slice($digits, 1);
}


 $this->assertEquals(10, count($digits));

$areaCode = $digits[0] . $digits[1] . $digits[2];
$this->assertContains($areaCode, array('800', '822', '833', '844', '855', '866', '877', '888', '880', '887', '889'));


 if ($digits[4] === 1) {
$this->assertNotEquals($digits[4], $digits[5]);
}


 $this->assertRegExp('/^(\+?1)?([ -.]*\d{3}[ -.]*| *\(\d{3}\) *)\d{3}[-.]?\d{4}$/', $number);
}
}
}
<?php

namespace Faker\Test\Provider\en_UG;

use Faker\Generator;
use Faker\Provider\en_UG\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}




public function testCityName()
{
$city = $this->faker->cityName();
$this->assertNotEmpty($city);
$this->assertInternalType('string', $city);
}




public function testDistrict()
{
$district = $this->faker->district();
$this->assertNotEmpty($district);
$this->assertInternalType('string', $district);
}




public function testRegion()
{
$region = $this->faker->region();
$this->assertNotEmpty($region);
$this->assertInternaltype('string', $region);
}
}
<?php

namespace Faker\Test\Provider\sv_SE;

use Faker\Calculator\Luhn;
use Faker\Generator;
use Faker\Provider\sv_SE\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{

protected $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function provideSeedAndExpectedReturn()
{
return array(
array(1, '720727', '720727-5798'),
array(2, '710414', '710414-5664'),
array(3, '591012', '591012-4519'),
array(4, '180307', '180307-0356'),
array(5, '820904', '820904-7748')
);
}




public function testPersonalIdentityNumberUsesBirthDateIfProvided($seed, $birthdate, $expected)
{
$faker = $this->faker;
$faker->seed($seed);
$pin = $faker->personalIdentityNumber(\DateTime::createFromFormat('ymd', $birthdate));
$this->assertEquals($expected, $pin);
}

public function testPersonalIdentityNumberGeneratesLuhnCompliantNumbers()
{
$pin = str_replace('-', '', $this->faker->personalIdentityNumber());
$this->assertTrue(Luhn::isValid($pin));
}

public function testPersonalIdentityNumberGeneratesOddValuesForMales()
{
$pin = $this->faker->personalIdentityNumber(null, 'male');
$this->assertEquals(1, $pin{9} % 2);
}

public function testPersonalIdentityNumberGeneratesEvenValuesForFemales()
{
$pin = $this->faker->personalIdentityNumber(null, 'female');
$this->assertEquals(0, $pin{9} % 2);
}
}
<?php
namespace Faker\Test\Provider\kk_KZ;

use Faker\Generator;
use Faker\Provider\DateTime;
use Faker\Provider\kk_KZ\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{




public function setUp()
{
$this->faker = new Generator();

$this->faker->addProvider(new Person($this->faker));
}

public function testIndividualIdentificationNumberIsValid()
{
$birthDate = DateTime::dateTimeBetween('-30 years', '-10 years');
$individualIdentificationNumber = $this->faker->individualIdentificationNumber($birthDate);
$controlDigit = Person::checkSum($individualIdentificationNumber);

$this->assertTrue($controlDigit === (int)substr($individualIdentificationNumber, 11, 1));
}
}
<?php
namespace Faker\Test\Provider\kk_KZ;

use Faker\Generator;
use Faker\Provider\kk_KZ\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{




public function setUp()
{
$this->faker = new Generator();

$this->faker->addProvider(new Company($this->faker));
}

public function testBusinessIdentificationNumberIsValid()
{
$registrationDate = new \DateTime('now');
$businessIdentificationNumber = $this->faker->businessIdentificationNumber($registrationDate);
$registrationDateAsString = $registrationDate->format('ym');

$this->assertRegExp(
"/^(" . $registrationDateAsString . ")([4-6]{1})([0-3]{1})(\\d{6})$/",
$businessIdentificationNumber
);
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\Miscellaneous;

class MiscellaneousTest extends \PHPUnit_Framework_TestCase
{
public function testBoolean()
{
$this->assertContains(Miscellaneous::boolean(), array(true, false));
}

public function testMd5()
{
$this->assertRegExp('/^[a-z0-9]{32}$/', Miscellaneous::md5());
}

public function testSha1()
{
$this->assertRegExp('/^[a-z0-9]{40}$/', Miscellaneous::sha1());
}

public function testSha256()
{
$this->assertRegExp('/^[a-z0-9]{64}$/', Miscellaneous::sha256());
}

public function testLocale()
{
$this->assertRegExp('/^[a-z]{2,3}_[A-Z]{2}$/', Miscellaneous::locale());
}

public function testCountryCode()
{
$this->assertRegExp('/^[A-Z]{2}$/', Miscellaneous::countryCode());
}

public function testCountryISOAlpha3()
{
$this->assertRegExp('/^[A-Z]{3}$/', Miscellaneous::countryISOAlpha3());
}

public function testLanguage()
{
$this->assertRegExp('/^[a-z]{2}$/', Miscellaneous::languageCode());
}

public function testCurrencyCode()
{
$this->assertRegExp('/^[A-Z]{3}$/', Miscellaneous::currencyCode());
}

public function testEmoji()
{
$this->assertRegExp('/^[\x{1F600}-\x{1F637}]$/u', Miscellaneous::emoji());
}
}
<?php
namespace Faker\Test\Provider;

use Faker\Provider\en_US\Text;
use Faker\Generator;

class TextTest extends \PHPUnit_Framework_TestCase
{
public function testTextMaxLength()
{
$generator = new Generator();
$generator->addProvider(new Text($generator));
$generator->seed(0);

$lengths = array(10, 20, 50, 70, 90, 120, 150, 200, 500);

foreach ($lengths as $length) {
$this->assertLessThan($length, $generator->realText($length));
}
}




public function testTextMaxIndex()
{
$generator = new Generator();
$generator->addProvider(new Text($generator));
$generator->seed(0);
$generator->realText(200, 11);
}




public function testTextMinIndex()
{
$generator = new Generator();
$generator->addProvider(new Text($generator));
$generator->seed(0);
$generator->realText(200, 0);
}




public function testTextMinLength()
{
$generator = new Generator();
$generator->addProvider(new Text($generator));
$generator->seed(0);
$generator->realText(9);
}
}
<?php

namespace Faker\Test\Provider\it_IT;

use Faker\Generator;
use Faker\Provider\it_IT\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testIfTaxIdCanReturnData()
{
$taxId = $this->faker->taxId();
$this->assertRegExp('/^[a-zA-Z]{6}[0-9]{2}[a-zA-Z][0-9]{2}[a-zA-Z][0-9]{3}[a-zA-Z]$/', $taxId);
}

}
<?php

namespace Faker\Test\Provider\it_IT;

use Faker\Generator;
use Faker\Provider\it_IT\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testIfTaxIdCanReturnData()
{
$vatId = $this->faker->vatId();
$this->assertRegExp('/^IT[0-9]{11}$/', $vatId);
}

}
<?php

namespace Faker\Test\Provider\fr_FR;

use Faker\Generator;
use Faker\Provider\fr_FR\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testNIRReturnsTheRightGender()
{
$nir = $this->faker->nir(\Faker\Provider\Person::GENDER_MALE);
$this->assertStringStartsWith('1', $nir);
}

public function testNIRReturnsTheRightPattern()
{
$nir = $this->faker->nir;
$this->assertRegExp("/^[12]\d{5}[0-9A-B]\d{8}$/", $nir);
}

public function testNIRFormattedReturnsTheRightPattern()
{
$nir = $this->faker->nir(null, true);
$this->assertRegExp("/^[12]\s\d{2}\s\d{2}\s\d{1}[0-9A-B]\s\d{3}\s\d{3}\s\d{2}$/", $nir);
}
}
<?php

namespace Faker\Test\Provider\fr_FR;

use Faker\Calculator\Luhn;
use Faker\Generator;
use Faker\Provider\fr_FR\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testSiretReturnsAValidSiret()
{
$siret = $this->faker->siret(false);
$this->assertRegExp("/^\d{14}$/", $siret);
$this->assertTrue(Luhn::isValid($siret));
}

public function testSiretReturnsAWellFormattedSiret()
{
$siret = $this->faker->siret();
$this->assertRegExp("/^\d{3}\s\d{3}\s\d{3}\s\d{5}$/", $siret);
$siret = str_replace(' ', '', $siret);
$this->assertTrue(Luhn::isValid($siret));
}

public function testSirenReturnsAValidSiren()
{
$siren = $this->faker->siren(false);
$this->assertRegExp("/^\d{9}$/", $siren);
$this->assertTrue(Luhn::isValid($siren));
}

public function testSirenReturnsAWellFormattedSiren()
{
$siren = $this->faker->siren();
$this->assertRegExp("/^\d{3}\s\d{3}\s\d{3}$/", $siren);
$siren = str_replace(' ', '', $siren);
$this->assertTrue(Luhn::isValid($siren));
}

public function testCatchPhraseReturnsValidCatchPhrase()
{
$this->assertTrue(TestableCompany::isCatchPhraseValid($this->faker->catchPhrase()));
}

public function testIsCatchPhraseValidReturnsFalseWhenAWordsAppearsTwice()
{
$isCatchPhraseValid = TestableCompany::isCatchPhraseValid('La sécurité de rouler en toute sécurité');
$this->assertFalse($isCatchPhraseValid);
}

public function testIsCatchPhraseValidReturnsTrueWhenNoWordAppearsTwice()
{
$isCatchPhraseValid = TestableCompany::isCatchPhraseValid('La sécurité de rouler en toute simplicité');
$this->assertTrue($isCatchPhraseValid);
}
}

class TestableCompany extends Company
{
public static function isCatchPhraseValid($catchPhrase)
{
return parent::isCatchPhraseValid($catchPhrase);
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Factory;

class LocalizationTest extends \PHPUnit_Framework_TestCase
{
public function testLocalizedNameProvidersDoNotThrowErrors()
{
foreach (glob(__DIR__ . '/../../../src/Faker/Provider/*/Person.php') as $localizedPerson) {
preg_match('#/([a-zA-Z_]+)/Person\.php#', $localizedPerson, $matches);
$faker = Factory::create($matches[1]);
$this->assertNotNull($faker->name(), 'Localized Name Provider ' . $matches[1] . ' does not throw errors');
}
}

public function testLocalizedAddressProvidersDoNotThrowErrors()
{
foreach (glob(__DIR__ . '/../../../src/Faker/Provider/*/Address.php') as $localizedAddress) {
preg_match('#/([a-zA-Z_]+)/Address\.php#', $localizedAddress, $matches);
$faker = Factory::create($matches[1]);
$this->assertNotNull($faker->address(), 'Localized Address Provider ' . $matches[1] . ' does not throw errors');
}
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\DateTime as DateTimeProvider;

class DateTimeTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->originalTz = date_default_timezone_get();
$this->defaultTz = 'UTC';
date_default_timezone_set($this->defaultTz);
}

public function tearDown()
{
date_default_timezone_set($this->originalTz);
}

public function testUnixTime()
{
$timestamp = DateTimeProvider::unixTime();
$this->assertInternalType('int', $timestamp);
$this->assertTrue($timestamp >= 0);
$this->assertTrue($timestamp <= time());
}

public function testDateTime()
{
$date = DateTimeProvider::dateTime();
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime('@0'), $date);
$this->assertLessThanOrEqual(new \DateTime(), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function testDateTimeWithTimezone()
{
$date = DateTimeProvider::dateTime('now', 'America/New_York');
$this->assertEquals($date->getTimezone(), new \DateTimeZone('America/New_York'));
}

public function testDateTimeAD()
{
$date = DateTimeProvider::dateTimeAD();
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime('0000-01-01 00:00:00'), $date);
$this->assertLessThanOrEqual(new \DateTime(), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function testDateTimeThisCentury()
{
$date = DateTimeProvider::dateTimeThisCentury();
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime('-100 year'), $date);
$this->assertLessThanOrEqual(new \DateTime(), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function testDateTimeThisDecade()
{
$date = DateTimeProvider::dateTimeThisDecade();
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime('-10 year'), $date);
$this->assertLessThanOrEqual(new \DateTime(), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function testDateTimeThisYear()
{
$date = DateTimeProvider::dateTimeThisYear();
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime('-1 year'), $date);
$this->assertLessThanOrEqual(new \DateTime(), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function testDateTimeThisMonth()
{
$date = DateTimeProvider::dateTimeThisMonth();
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime('-1 month'), $date);
$this->assertLessThanOrEqual(new \DateTime(), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function testDateTimeThisCenturyWithTimezone()
{
$date = DateTimeProvider::dateTimeThisCentury('now', 'America/New_York');
$this->assertEquals($date->getTimezone(), new \DateTimeZone('America/New_York'));
}

public function testDateTimeThisDecadeWithTimezone()
{
$date = DateTimeProvider::dateTimeThisDecade('now', 'America/New_York');
$this->assertEquals($date->getTimezone(), new \DateTimeZone('America/New_York'));
}

public function testDateTimeThisYearWithTimezone()
{
$date = DateTimeProvider::dateTimeThisYear('now', 'America/New_York');
$this->assertEquals($date->getTimezone(), new \DateTimeZone('America/New_York'));
}

public function testDateTimeThisMonthWithTimezone()
{
$date = DateTimeProvider::dateTimeThisMonth('now', 'America/New_York');
$this->assertEquals($date->getTimezone(), new \DateTimeZone('America/New_York'));
}

public function testIso8601()
{
$date = DateTimeProvider::iso8601();
$this->assertRegExp('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-Z](\d{4})?$/', $date);
$this->assertGreaterThanOrEqual(new \DateTime('@0'), new \DateTime($date));
$this->assertLessThanOrEqual(new \DateTime(), new \DateTime($date));
}

public function testDate()
{
$date = DateTimeProvider::date();
$this->assertRegExp('/^\d{4}-\d{2}-\d{2}$/', $date);
$this->assertGreaterThanOrEqual(new \DateTime('@0'), new \DateTime($date));
$this->assertLessThanOrEqual(new \DateTime(), new \DateTime($date));
}

public function testTime()
{
$date = DateTimeProvider::time();
$this->assertRegExp('/^\d{2}:\d{2}:\d{2}$/', $date);
}





public function testDateTimeBetween($start, $end)
{
$date = DateTimeProvider::dateTimeBetween($start, $end);
$this->assertInstanceOf('\DateTime', $date);
$this->assertGreaterThanOrEqual(new \DateTime($start), $date);
$this->assertLessThanOrEqual(new \DateTime($end), $date);
$this->assertEquals(new \DateTimeZone($this->defaultTz), $date->getTimezone());
}

public function providerDateTimeBetween()
{
return array(
array('-1 year', false),
array('-1 year', null),
array('-1 day', '-1 hour'),
array('-1 day', 'now'),
);
}





public function testDateTimeInInterval($start, $interval = "+5 days", $isInFuture)
{
$date = DateTimeProvider::dateTimeInInterval($start, $interval);
$this->assertInstanceOf('\DateTime', $date);

$_interval = \DateInterval::createFromDateString($interval);
$_start = new \DateTime($start);
if ($isInFuture) {
$this->assertGreaterThanOrEqual($_start, $date);
$this->assertLessThanOrEqual($_start->add($_interval), $date);
} else {
$this->assertLessThanOrEqual($_start, $date);
$this->assertGreaterThanOrEqual($_start->add($_interval), $date);
}
}

public function providerDateTimeInInterval()
{
return array(
array('-1 year', '+5 days', true),
array('-1 day', '-1 hour', false),
array('-1 day', '+1 hour', true),
);
}

public function testFixedSeedWithMaximumTimestamp()
{
$max = '2018-03-01 12:00:00';

mt_srand(1);
$unixTime = DateTimeProvider::unixTime($max);
$datetimeAD = DateTimeProvider::dateTimeAD($max);
$dateTime1 = DateTimeProvider::dateTime($max);
$dateTimeBetween = DateTimeProvider::dateTimeBetween('2014-03-01 06:00:00', $max);
$date = DateTimeProvider::date('Y-m-d', $max);
$time = DateTimeProvider::time('H:i:s', $max);
$iso8601 = DateTimeProvider::iso8601($max);
$dateTimeThisCentury = DateTimeProvider::dateTimeThisCentury($max);
$dateTimeThisDecade = DateTimeProvider::dateTimeThisDecade($max);
$dateTimeThisMonth = DateTimeProvider::dateTimeThisMonth($max);
$amPm = DateTimeProvider::amPm($max);
$dayOfMonth = DateTimeProvider::dayOfMonth($max);
$dayOfWeek = DateTimeProvider::dayOfWeek($max);
$month = DateTimeProvider::month($max);
$monthName = DateTimeProvider::monthName($max);
$year = DateTimeProvider::year($max);
$dateTimeThisYear = DateTimeProvider::dateTimeThisYear($max);
mt_srand();


 mt_srand(1);
$this->assertEquals($unixTime, DateTimeProvider::unixTime($max));
$this->assertEquals($datetimeAD, DateTimeProvider::dateTimeAD($max));
$this->assertEquals($dateTime1, DateTimeProvider::dateTime($max));
$this->assertEquals($dateTimeBetween, DateTimeProvider::dateTimeBetween('2014-03-01 06:00:00', $max));
$this->assertEquals($date, DateTimeProvider::date('Y-m-d', $max));
$this->assertEquals($time, DateTimeProvider::time('H:i:s', $max));
$this->assertEquals($iso8601, DateTimeProvider::iso8601($max));
$this->assertEquals($dateTimeThisCentury, DateTimeProvider::dateTimeThisCentury($max));
$this->assertEquals($dateTimeThisDecade, DateTimeProvider::dateTimeThisDecade($max));
$this->assertEquals($dateTimeThisMonth, DateTimeProvider::dateTimeThisMonth($max));
$this->assertEquals($amPm, DateTimeProvider::amPm($max));
$this->assertEquals($dayOfMonth, DateTimeProvider::dayOfMonth($max));
$this->assertEquals($dayOfWeek, DateTimeProvider::dayOfWeek($max));
$this->assertEquals($month, DateTimeProvider::month($max));
$this->assertEquals($monthName, DateTimeProvider::monthName($max));
$this->assertEquals($year, DateTimeProvider::year($max));
$this->assertEquals($dateTimeThisYear, DateTimeProvider::dateTimeThisYear($max));
mt_srand();
}
}
<?php

namespace Faker\Provider\en_GB;

use Faker\Generator;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}




public function testPostcode()
{

$postcode = $this->faker->postcode();
$this->assertNotEmpty($postcode);
$this->assertInternalType('string', $postcode);
$this->assertRegExp('@^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$@i', $postcode);

}

}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\Image;

class ImageTest extends \PHPUnit_Framework_TestCase
{
public function testImageUrlUses640x680AsTheDefaultSize()
{
$this->assertRegExp('#^https://lorempixel.com/640/480/#', Image::imageUrl());
}

public function testImageUrlAcceptsCustomWidthAndHeight()
{
$this->assertRegExp('#^https://lorempixel.com/800/400/#', Image::imageUrl(800, 400));
}

public function testImageUrlAcceptsCustomCategory()
{
$this->assertRegExp('#^https://lorempixel.com/800/400/nature/#', Image::imageUrl(800, 400, 'nature'));
}

public function testImageUrlAcceptsCustomText()
{
$this->assertRegExp('#^https://lorempixel.com/800/400/nature/Faker#', Image::imageUrl(800, 400, 'nature', false, 'Faker'));
}

public function testImageUrlAddsARandomGetParameterByDefault()
{
$url = Image::imageUrl(800, 400);
$splitUrl = preg_split('/\?/', $url);

$this->assertEquals(count($splitUrl), 2);
$this->assertRegexp('#\d{5}#', $splitUrl[1]);
}




public function testUrlWithDimensionsAndBadCategory()
{
Image::imageUrl(800, 400, 'bullhonky');
}

public function testDownloadWithDefaults()
{
$url = "http://www.lorempixel.com/";
$curlPing = curl_init($url);
curl_setopt($curlPing, CURLOPT_TIMEOUT, 5);
curl_setopt($curlPing, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curlPing, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curlPing);
$httpCode = curl_getinfo($curlPing, CURLINFO_HTTP_CODE);
curl_close($curlPing);

if ($httpCode < 200 | $httpCode > 300) {
$this->markTestSkipped("LoremPixel is offline, skipping image download");
}

$file = Image::image(sys_get_temp_dir());
$this->assertFileExists($file);
if (function_exists('getimagesize')) {
list($width, $height, $type, $attr) = getimagesize($file);
$this->assertEquals(640, $width);
$this->assertEquals(480, $height);
$this->assertEquals(constant('IMAGETYPE_JPEG'), $type);
} else {
$this->assertEquals('jpg', pathinfo($file, PATHINFO_EXTENSION));
}
if (file_exists($file)) {
unlink($file);
}
}
}
<?php

namespace Faker\Test\Provider\en_SG;

use Faker\Factory;
use Faker\Provider\en_SG\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$this->faker = Factory::create('en_SG');
$this->faker->seed(1);
$this->faker->addProvider(new PhoneNumber($this->faker));
}


 
 
 public function testMobilePhoneNumberStartWith9Returns9yxxxxxx()
{
$startsWith9 = false;
while (!$startsWith9) {
$mobileNumber = $this->faker->mobileNumber();
$startsWith9 = preg_match('/^(\+65|65)?\s*9/', $mobileNumber);
}

$this->assertRegExp('/^(\+65|65)?\s*9\s*[0-8]{3}\s*\d{4}$/', $mobileNumber);
}


 
 
 public function testMobilePhoneNumberStartWith7Or8Returns7Or8zxxxxxx()
{
$startsWith7Or8 = false;
while (!$startsWith7Or8) {
$mobileNumber = $this->faker->mobileNumber();
$startsWith7Or8 = preg_match('/^(\+65|65)?\s*[7-8]/', $mobileNumber);
}
$this->assertRegExp('/^(\+65|65)?\s*[7-8]\s*[1-9]{3}\s*\d{4}$/', $mobileNumber);
}
}
<?php

namespace Faker\Test\Provider\en_SG;

use Faker\Factory;
use Faker\Provider\en_SG\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = Factory::create('en_SG');
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testStreetNumber()
{
$this->assertRegExp('/^\d{2,3}$/', $this->faker->streetNumber());
}

public function testBlockNumber()
{
$this->assertRegExp('/^Blk\s*\d{2,3}[A-H]*$/i', $this->faker->blockNumber());
}
}
<?php

namespace Faker\Test\Provider\fr_CH;

use Faker\Generator;
use Faker\Provider\fr_CH\Person;
use Faker\Provider\fr_CH\Internet;
use Faker\Provider\fr_CH\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}




public function emailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\fr_CH;

use Faker\Generator;
use Faker\Provider\fr_CH\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumber()
{
$this->assertRegExp('/^0\d{2} ?\d{3} ?\d{2} ?\d{2}|\+41 ?(\(0\))?\d{2} ?\d{3} ?\d{2} ?\d{2}$/', $this->faker->phoneNumber());
}

public function testMobileNumber()
{
$this->assertRegExp('/^07[56789] ?\d{3} ?\d{2} ?\d{2}$/', $this->faker->mobileNumber());
}
}
<?php

namespace Faker\Test\Provider\fr_CH;

use Faker\Generator;
use Faker\Provider\fr_CH\Address;
use Faker\Provider\fr_CH\Person;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}




public function canton ()
{
$canton = $this->faker->canton();
$this->assertInternalType('array', $canton);
$this->assertCount(1, $canton);

foreach ($canton as $cantonShort => $cantonName){
$this->assertInternalType('string', $cantonShort);
$this->assertEquals(2, strlen($cantonShort));
$this->assertInternalType('string', $cantonName);
$this->assertGreaterThan(2, strlen($cantonName));
}
}




public function cantonName ()
{
$cantonName = $this->faker->cantonName();
$this->assertInternalType('string', $cantonName);
$this->assertGreaterThan(2, strlen($cantonName));
}




public function cantonShort ()
{
$cantonShort = $this->faker->cantonShort();
$this->assertInternalType('string', $cantonShort);
$this->assertEquals(2, strlen($cantonShort));
}




public function address (){
$address = $this->faker->address();
$this->assertInternalType('string', $address);
}
}
<?php

namespace Faker\Test\Provider\zh_TW;

use Faker\Generator;
use Faker\Provider\zh_TW\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}




public function testPersonalIdentityNumber()
{
$id = $this->faker->personalIdentityNumber;

$firstChar = substr($id, 0, 1);
$codesString = Person::$idBirthplaceCode[$firstChar] . substr($id, 1);


 $this->assertRegExp("/^[0-9]{11}$/", $codesString);

$total = 0;
$codesArray = str_split($codesString);
foreach ($codesArray as $key => $code) {
$total += $code * Person::$idDigitValidator[$key];
}


 $this->assertEquals(0, ($total % 10));
}
}
<?php

namespace Faker\Test\Provider\zh_TW;

use Faker\Generator;
use Faker\Provider\zh_TW\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testVAT()
{
$this->assertEquals(8, floor(log10($this->faker->VAT) + 1));
}
}
<?php

namespace Faker\Test\Provider\zh_TW;

class TextTest extends \PHPUnit_Framework_TestCase
{
private $textClass;

public function setUp()
{
$this->textClass = new \ReflectionClass('Faker\Provider\zh_TW\Text');
}

protected function getMethod($name) {
$method = $this->textClass->getMethod($name);

$method->setAccessible(true);

return $method;
}


function testItShouldExplodeTheStringToArray()
{
$this->assertSame(
array('中', '文', '測', '試', '真', '有', '趣'),
$this->getMethod('explode')->invokeArgs(null, array('中文測試真有趣'))
);

$this->assertSame(
array('標', '點', ',', '符', '號', '!'),
$this->getMethod('explode')->invokeArgs(null, array('標點,符號!'))
);
}


function testItShouldReturnTheStringLength()
{
$this->assertContains(
$this->getMethod('strlen')->invokeArgs(null, array('中文測試真有趣')),
array(7, 21)
);
}


function testItShouldReturnTheCharacterIsValidStartOrNot()
{
$this->assertTrue($this->getMethod('validStart')->invokeArgs(null, array('中')));

$this->assertTrue($this->getMethod('validStart')->invokeArgs(null, array('2')));

$this->assertTrue($this->getMethod('validStart')->invokeArgs(null, array('Hello')));

$this->assertFalse($this->getMethod('validStart')->invokeArgs(null, array('。')));

$this->assertFalse($this->getMethod('validStart')->invokeArgs(null, array('!')));
}


function testItShouldAppendEndPunctToTheEndOfString()
{
$this->assertSame(
'中文測試真有趣。',
$this->getMethod('appendEnd')->invokeArgs(null, array('中文測試真有趣'))
);

$this->assertSame(
'中文測試真有趣。',
$this->getMethod('appendEnd')->invokeArgs(null, array('中文測試真有趣,'))
);

$this->assertSame(
'中文測試真有趣!',
$this->getMethod('appendEnd')->invokeArgs(null, array('中文測試真有趣!'))
);
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Provider\Barcode;

class BarcodeTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Barcode($faker));
$faker->seed(0);
$this->faker = $faker;
}

public function testEan8()
{
$code = $this->faker->ean8();
$this->assertRegExp('/^\d{8}$/i', $code);
$codeWithoutChecksum = substr($code, 0, -1);
$checksum = substr($code, -1);
$this->assertEquals(TestableBarcode::eanChecksum($codeWithoutChecksum), $checksum);
}

public function testEan13()
{
$code = $this->faker->ean13();
$this->assertRegExp('/^\d{13}$/i', $code);
$codeWithoutChecksum = substr($code, 0, -1);
$checksum = substr($code, -1);
$this->assertEquals(TestableBarcode::eanChecksum($codeWithoutChecksum), $checksum);
}
}

class TestableBarcode extends Barcode
{
public static function eanChecksum($input)
{
return parent::eanChecksum($input);
}
}
<?php

namespace Faker\Test\Provider\es_ES;

use Faker\Generator;
use Faker\Provider\es_ES\Payment;

class PaymentTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Payment($faker));
$this->faker = $faker;
}

public function testVAT()
{
$vat = $this->faker->vat();

$this->assertTrue($this->isValidCIF($vat));
}





function isValidCIF($docNumber)
{
$fixedDocNumber = strtoupper($docNumber);

return $this->isValidCIFFormat($fixedDocNumber);
}

function isValidCIFFormat($docNumber)
{
return $this->respectsDocPattern($docNumber, '/^[PQSNWR][0-9][0-9][0-9][0-9][0-9][0-9][0-9][A-Z0-9]/')
||
$this->respectsDocPattern($docNumber, '/^[ABCDEFGHJUV][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/');
}

function respectsDocPattern($givenString, $pattern)
{
$isValid = FALSE;
$fixedString = strtoupper($givenString);
if (is_int(substr($fixedString, 0, 1))) {
$fixedString = substr("000000000" . $givenString, -9);
}
if (preg_match($pattern, $fixedString)) {
$isValid = TRUE;
}
return $isValid;
}

}
<?php

namespace Faker\Test\Provider\es_ES;

use Faker\Generator;
use Faker\Provider\es_ES\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->seed(1);
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testDNI()
{
$dni = $this->faker->dni;
$this->assertTrue($this->isValidDNI($dni));
}


 public function isValidDNI($string)
{
if (strlen($string) != 9 ||
preg_match('/^[XYZ]?([0-9]{7,8})([A-Z])$/i', $string, $matches) !== 1) {
return false;
}

$map = 'TRWAGMYFPDXBNJZSQVHLCKE';

list(, $number, $letter) = $matches;

return strtoupper($letter) === $map[((int) $number) % 23];
}
}
<?php

namespace Faker\Test\Provider\es_ES;

use Faker\Generator;
use Faker\Provider\es_ES\Text;

class TextTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Text($faker));
$this->faker = $faker;
}

public function testText()
{
$this->assertNotSame('', $this->faker->realtext(200, 2));
}
}
<?php

namespace Faker\Test\Provider\pt_PT;

use Faker\Generator;
use Faker\Provider\pt_PT\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testTaxpayerIdentificationNumberIsValid()
{
$tin = $this->faker->taxpayerIdentificationNumber();
$this->assertTrue($this->isValidTin($tin), $tin);
}









public static function isValidTin($tin)
{
$regex = '(([1,2,3,5,6,8]{1}[0-9]{8})|((45)|(70)|(71)|(72)|(77)|(79)|(90|(98|(99))))[0-9]{7})';
if (is_null($tin) || !is_numeric($tin) || !strlen($tin) == 9 || preg_match("/$regex/", $tin) !== 1) {
return false;
}
$n = str_split($tin);

 $cd = ($n[0] * 9 + $n[1] * 8 + $n[2] * 7 + $n[3] * 6 + $n[4] * 5 + $n[5] * 4 + $n[6] * 3 + $n[7] * 2) % 11;
if ($cd === 0 || $cd === 1) {
$cd = 0;
} else {
$cd = 11 - $cd;
}
if ($cd === intval($n[8])) {
return true;
}

return false;
}
}
<?php

namespace Faker\Test\Provider\pt_PT;

use Faker\Generator;
use Faker\Provider\pt_PT\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumberReturnsPhoneNumberWithOrWithoutPrefix()
{
$this->assertRegExp('/^(9[1,2,3,6][0-9]{7})|(2[0-9]{8})|(\+351 [2][0-9]{8})|(\+351 9[1,2,3,6][0-9]{7})/', $this->faker->phoneNumber());
}
public function testMobileNumberReturnsMobileNumberWithOrWithoutPrefix()
{
$this->assertRegExp('/^(9[1,2,3,6][0-9]{7})/', $this->faker->mobileNumber());
}
}
<?php

namespace Faker\Test\Provider\pt_PT;

use Faker\Generator;
use Faker\Provider\pt_PT\Address;
use Faker\Provider\pt_PT\Person;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testPostCodeIsValid()
{
$main = '[1-9]{1}[0-9]{2}[0,1,4,5,9]{1}';
$pattern = "/^($main)|($main-[0-9]{3})+$/";
$postcode = $this->faker->postcode();
$this->assertSame(preg_match($pattern, $postcode), 1, $postcode);
}

public function testAddressIsSingleLine()
{
$this->faker->addProvider(new Person($this->faker));

$address = $this->faker->address();
$this->assertFalse(strstr($address, "\n"));
}
}
<?php

namespace Faker\Test\Provider\en_PH;

use Faker\Generator;
use Faker\Provider\en_PH\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testProvince()
{
$province = $this->faker->province();
$this->assertNotEmpty($province);
$this->assertInternalType('string', $province);
}

public function testCity()
{
$city = $this->faker->city();
$this->assertNotEmpty($city);
$this->assertInternalType('string', $city);
}

public function testMunicipality()
{
$municipality = $this->faker->municipality();
$this->assertNotEmpty($municipality);
$this->assertInternalType('string', $municipality);
}

public function testBarangay()
{
$barangay = $this->faker->barangay();
$this->assertInternalType('string', $barangay);
}
}
<?php

namespace Faker\Test\Provider\cs_CZ;

use Faker\Generator;
use Faker\Provider\cs_CZ\Person;
use Faker\Provider\Miscellaneous;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function testBirthNumber()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Miscellaneous($faker));

for ($i = 0; $i < 1000; $i++) { 
$birthNumber = $faker->birthNumber();
$birthNumber = str_replace('/', '', $birthNumber);


 $year = intval(substr($birthNumber, 0, 2), 10);
$month = intval(substr($birthNumber, 2, 2), 10);
$day = intval(substr($birthNumber, 4, 2), 10);


 $year += $year < 54 ? 2000 : 1900;


 if ($month > 50) $month -= 50;
if ($year >= 2004 && $month > 20) $month -= 20;

$this->assertTrue(checkdate($month, $day, $year), "Birth number $birthNumber: date $year/$month/$day is invalid.");


 if (strlen($birthNumber) == 10) {
$crc = intval(substr($birthNumber, -1), 10);
$refCrc = intval(substr($birthNumber, 0, -1), 10) % 11;
if ($refCrc == 10) {
$refCrc = 0;
}
$this->assertEquals($crc, $refCrc, "Birth number $birthNumber: checksum $crc doesn't match expected $refCrc.");
}
}
}
}
<?php

namespace Faker\Test\Provider\it_CH;

use Faker\Generator;
use Faker\Provider\it_CH\Person;
use Faker\Provider\it_CH\Internet;
use Faker\Provider\it_CH\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}




public function emailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider\it_CH;

use Faker\Generator;
use Faker\Provider\it_CH\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumber()
{
$this->assertRegExp('/^0\d{2} ?\d{3} ?\d{2} ?\d{2}|\+41 ?(\(0\))?\d{2} ?\d{3} ?\d{2} ?\d{2}$/', $this->faker->phoneNumber());
}

public function testMobileNumber()
{
$this->assertRegExp('/^07[56789] ?\d{3} ?\d{2} ?\d{2}$/', $this->faker->mobileNumber());
}
}
<?php

namespace Faker\Test\Provider\it_CH;

use Faker\Generator;
use Faker\Provider\it_CH\Address;
use Faker\Provider\it_CH\Person;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}




public function canton ()
{
$canton = $this->faker->canton();
$this->assertInternalType('array', $canton);
$this->assertCount(1, $canton);

foreach ($canton as $cantonShort => $cantonName){
$this->assertInternalType('string', $cantonShort);
$this->assertEquals(2, strlen($cantonShort));
$this->assertInternalType('string', $cantonName);
$this->assertGreaterThan(2, strlen($cantonName));
}
}




public function cantonName ()
{
$cantonName = $this->faker->cantonName();
$this->assertInternalType('string', $cantonName);
$this->assertGreaterThan(2, strlen($cantonName));
}




public function cantonShort ()
{
$cantonShort = $this->faker->cantonShort();
$this->assertInternalType('string', $cantonShort);
$this->assertEquals(2, strlen($cantonShort));
}




public function address (){
$address = $this->faker->address();
$this->assertInternalType('string', $address);
}
}
<?php

namespace Faker\Test\Provider\ng_NG;

use Faker\Generator;
use Faker\Provider\en_NG\Person;
use Faker\Provider\en_NG\Internet;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
$this->assertNotEmpty($email);
$this->assertInternalType('string', $email);
}
}
<?php

namespace Faker\Test\Provider\ng_NG;

use Faker\Generator;
use Faker\Provider\en_NG\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testPersonNameIsAValidString()
{
$name = $this->faker->name;

$this->assertNotEmpty($name);
$this->assertInternalType('string', $name);
}
}
<?php

namespace Faker\Test\Provider\ng_NG;

use Faker\Generator;
use Faker\Provider\en_NG\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumberReturnsPhoneNumberWithOrWithoutCountryCode()
{
$phoneNumber = $this->faker->phoneNumber();

$this->assertNotEmpty($phoneNumber);
$this->assertInternalType('string', $phoneNumber);
$this->assertRegExp('/^(0|(\+234))\s?[789][01]\d\s?(\d{3}\s?\d{4})/', $phoneNumber);
}
}
<?php

namespace Faker\Provider\ng_NG;

use Faker\Generator;
use Faker\Provider\en_NG\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}




public function testPostcodeIsNotEmptyAndIsValid()
{
$postcode = $this->faker->postcode();

$this->assertNotEmpty($postcode);
$this->assertInternalType('string', $postcode);
}




public function testCountyIsAValidString()
{
$county = $this->faker->county;

$this->assertNotEmpty($county);
$this->assertInternalType('string', $county);
}




public function testRegionIsAValidString()
{
$region = $this->faker->region;

$this->assertNotEmpty($region);
$this->assertInternalType('string', $region);
}

}<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Calculator\Luhn;
use Faker\Provider\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumberFormat()
{
$number = $this->faker->e164PhoneNumber();
$this->assertRegExp('/^\+[0-9]{11,}$/', $number);
}

public function testImeiReturnsValidNumber()
{
$imei = $this->faker->imei();
$this->assertTrue(Luhn::isValid($imei));
}
}
<?php

namespace Faker\Test\Provider\es_PE;

use Faker\Generator;
use Faker\Provider\es_PE\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->seed(1);
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testDNI()
{
$dni = $this->faker->dni;
$this->assertRegExp('/\A[0-9]{8}\Z/', $dni);
}
}
<?php

namespace Faker\Test\Provider\ro_RO;

use Faker\Generator;
use Faker\Provider\DateTime;
use Faker\Provider\ro_RO\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
const TEST_CNP_REGEX = '/^[1-9][0-9]{2}(?:0[1-9]|1[012])(?:0[1-9]|[12][0-9]|3[01])(?:0[1-9]|[123][0-9]|4[0-6]|5[12])[0-9]{3}[0-9]$/';





protected $faker;
protected $originalTz;

public function setUp()
{
$this->originalTz = @date_default_timezone_get();
date_default_timezone_set('Europe/Bucharest');

$faker = new Generator();
$faker->addProvider(new DateTime($faker));
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function tearDown()
{
date_default_timezone_set($this->originalTz);
}

public function invalidGenderProvider()
{
return array(
array('elf'),
array('ent'),
array('fmle'),
array('mal'),
);
}

public function invalidYearProvider()
{
return array(
array(1652),
array(1799),
array(2100),
array(2252),
);
}

public function validYearProvider()
{
return array(
array(null),
array(''),
array(1800),
array(1850),
array(1900),
array(1990),
array(2000),
array(2099),
);
}

public function validCountyCodeProvider()
{
return array(
array('AB'), array('AR'), array('AG'), array('B'), array('BC'), array('BH'), array('BN'), array('BT'),
array('BV'), array('BR'), array('BZ'), array('CS'), array('CL'), array('CJ'), array('CT'), array('CV'),
array('DB'), array('DJ'), array('GL'), array('GR'), array('GJ'), array('HR'), array('HD'), array('IL'),
array('IS'), array('IF'), array('MM'), array('MH'), array('MS'), array('NT'), array('OT'), array('PH'),
array('SM'), array('SJ'), array('SB'), array('SV'), array('TR'), array('TM'), array('TL'), array('VS'),
array('VL'), array('VN'), array('B1'), array('B2'), array('B3'), array('B4'), array('B5'), array('B6')
);
}

public function invalidCountyCodeProvider()
{
return array(
array('JK'), array('REW'), array('x'), array('FF'), array('aaaddadaada')
);
}

public function validInputDataProvider()
{
return array(
array(Person::GENDER_MALE, '1981-06-16','B2', true, '181061642'),
array(Person::GENDER_FEMALE, '1981-06-16','B2', true, '281061642'),
array(Person::GENDER_MALE, '1981-06-16','B2', false, '981061642'),
array(Person::GENDER_FEMALE, '1981-06-16','B2', false, '981061642'),
);
}



public function test_allRandom_returnsValidCnp()
{
$cnp = $this->faker->cnp;
$this->assertTrue(
$this->isValidCnp($cnp),
sprintf("Invalid CNP '%' generated", $cnp)
);
}




public function test_validGender_returnsValidCnp()
{
$cnp = $this->faker->cnp(Person::GENDER_MALE);
$this->assertTrue(
$this->isValidMaleCnp($cnp),
sprintf("Invalid CNP '%' generated for '%s' gender", $cnp, Person::GENDER_MALE)
);

$cnp = $this->faker->cnp(Person::GENDER_FEMALE);
$this->assertTrue(
$this->isValidFemaleCnp($cnp),
sprintf("Invalid CNP '%' generated for '%s' gender", $cnp, Person::GENDER_FEMALE)
);
}






public function test_invalidGender_throwsException($value)
{
$this->setExpectedException('InvalidArgumentException');
$this->faker->cnp($value);
}






public function test_validYear_returnsValidCnp($value)
{
$cnp = $this->faker->cnp(null, $value);
$this->assertTrue(
$this->isValidCnp($cnp),
sprintf("Invalid CNP '%' generated for valid year '%s'", $cnp, $value)
);
}






public function test_invalidYear_throwsException($value)
{
$this->setExpectedException('InvalidArgumentException');
$this->faker->cnp(null, $value);
}





public function test_validCountyCode_returnsValidCnp($value)
{
$cnp = $this->faker->cnp(null, null, $value);
$this->assertTrue(
$this->isValidCnp($cnp),
sprintf("Invalid CNP '%' generated for valid year '%s'", $cnp, $value)
);
}





public function test_invalidCountyCode_throwsException($value)
{
$this->setExpectedException('InvalidArgumentException');
$this->faker->cnp(null, null, $value);
}




public function test_nonResident_returnsValidCnp()
{
$cnp = $this->faker->cnp(null, null, null, false);
$this->assertTrue(
$this->isValidCnp($cnp),
sprintf("Invalid CNP '%' generated for non resident", $cnp)
);
$this->assertStringStartsWith(
'9',
$cnp,
sprintf("Invalid CNP '%' generated for non resident (should start with 9)", $cnp)
);
}











public function test_validInputData_returnsValidCnp($gender, $dateOfBirth, $county, $isResident, $expectedCnpStart)
{
$cnp = $this->faker->cnp($gender, $dateOfBirth, $county, $isResident);
$this->assertStringStartsWith(
$expectedCnpStart,
$cnp,
sprintf("Invalid CNP '%' generated for non valid data", $cnp)
);
}


protected function isValidFemaleCnp($value)
{
return $this->isValidCnp($value) && in_array($value[0], array(2, 4, 6, 8, 9));
}

protected function isValidMaleCnp($value)
{
return $this->isValidCnp($value) && in_array($value[0], array(1, 3, 5, 7, 9));
}

protected function isValidCnp($cnp)
{
if (preg_match(static::TEST_CNP_REGEX, $cnp) !== false) {
$checkNumber = 279146358279;

$checksum = 0;
foreach (range(0, 11) as $digit) {
$checksum += (int)substr($cnp, $digit, 1) * (int)substr($checkNumber, $digit, 1);
}
$checksum = $checksum % 11;
$checksum = $checksum == 10 ? 1 : $checksum;

if ($checksum == substr($cnp, -1)) {
return true;
}
}

return false;
}
}
<?php

namespace Faker\Test\Provider\ro_RO;

use Faker\Generator;
use Faker\Provider\ro_RO\PhoneNumber;

class PhoneNumberTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new PhoneNumber($faker));
$this->faker = $faker;
}

public function testPhoneNumberReturnsNormalPhoneNumber()
{
$this->assertRegExp('/^0(?:[23][13-7]|7\d)\d{7}$/', $this->faker->phoneNumber());
}

public function testTollFreePhoneNumberReturnsTollFreePhoneNumber()
{
$this->assertRegExp('/^08(?:0[01267]|70)\d{6}$/', $this->faker->tollFreePhoneNumber());
}

public function testPremiumRatePhoneNumberReturnsPremiumRatePhoneNumber()
{
$this->assertRegExp('/^090[036]\d{6}$/', $this->faker->premiumRatePhoneNumber());
}
}
<?php

namespace Faker\Test\Provider\ru_RU;

use Faker\Generator;
use Faker\Provider\ru_RU\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testINN()
{
$this->assertRegExp('/^[0-9]{10}$/', $this->faker->inn);
$this->assertEquals("77", substr($this->faker->inn("77"), 0, 2));
$this->assertEquals("02", substr($this->faker->inn(2), 0, 2));
}

public function testKPP()
{
$this->assertRegExp('/^[0-9]{9}$/', $this->faker->kpp);
$this->assertEquals("01001", substr($this->faker->kpp, -5, 5));
$inn = $this->faker->inn;
$this->assertEquals(substr($inn, 0, 4), substr($this->faker->kpp($inn), 0, 4));
}
}
<?php

namespace Faker\Provider\en_CA;

use Faker\Generator;
use Faker\Provider\en_CA\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}




public function testProvince()
{
$province = $this->faker->province();
$this->assertNotEmpty($province);
$this->assertInternalType('string', $province);
$this->assertRegExp('/[A-Z][a-z]+/', $province);
}




public function testProvinceAbbr()
{
$provinceAbbr = $this->faker->provinceAbbr();
$this->assertNotEmpty($provinceAbbr);
$this->assertInternalType('string', $provinceAbbr);
$this->assertRegExp('/^[A-Z]{2}$/', $provinceAbbr);
}




public function testPostcodeLetter()
{
$postcodeLetter = $this->faker->randomPostcodeLetter();
$this->assertNotEmpty($postcodeLetter);
$this->assertInternalType('string', $postcodeLetter);
$this->assertRegExp('/^[A-Z]{1}$/', $postcodeLetter);
}




public function testPostcode()
{
$postcode = $this->faker->postcode();
$this->assertNotEmpty($postcode);
$this->assertInternalType('string', $postcode);
$this->assertRegExp('/^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/', $postcode);
}
}

?>
<?php

namespace Faker\Provider\pl_PL;

use Faker\Generator;

class AddressTest extends \PHPUnit_Framework_TestCase
{



private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}




public function testState()
{
$state = $this->faker->state();
$this->assertNotEmpty($state);
$this->assertInternalType('string', $state);
$this->assertRegExp('/[a-z]+/', $state);
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\Base as BaseProvider;

class BaseTest extends \PHPUnit_Framework_TestCase
{
public function testRandomDigitReturnsInteger()
{
$this->assertTrue(is_integer(BaseProvider::randomDigit()));
}

public function testRandomDigitReturnsDigit()
{
$this->assertTrue(BaseProvider::randomDigit() >= 0);
$this->assertTrue(BaseProvider::randomDigit() < 10);
}

public function testRandomDigitNotNullReturnsNotNullDigit()
{
$this->assertTrue(BaseProvider::randomDigitNotNull() > 0);
$this->assertTrue(BaseProvider::randomDigitNotNull() < 10);
}


public function testRandomDigitNotReturnsValidDigit()
{
for ($i = 0; $i <= 9; $i++) {
$this->assertTrue(BaseProvider::randomDigitNot($i) >= 0);
$this->assertTrue(BaseProvider::randomDigitNot($i) < 10);
$this->assertTrue(BaseProvider::randomDigitNot($i) !== $i);
}
}




public function testRandomNumberThrowsExceptionWhenCalledWithAMax()
{
BaseProvider::randomNumber(5, 200);
}




public function testRandomNumberThrowsExceptionWhenCalledWithATooHighNumberOfDigits()
{
BaseProvider::randomNumber(10);
}

public function testRandomNumberReturnsInteger()
{
$this->assertTrue(is_integer(BaseProvider::randomNumber()));
$this->assertTrue(is_integer(BaseProvider::randomNumber(5, false)));
}

public function testRandomNumberReturnsDigit()
{
$this->assertTrue(BaseProvider::randomNumber(3) >= 0);
$this->assertTrue(BaseProvider::randomNumber(3) < 1000);
}

public function testRandomNumberAcceptsStrictParamToEnforceNumberSize()
{
$this->assertEquals(5, strlen((string) BaseProvider::randomNumber(5, true)));
}

public function testNumberBetween()
{
$min = 5;
$max = 6;

$this->assertGreaterThanOrEqual($min, BaseProvider::numberBetween($min, $max));
$this->assertGreaterThanOrEqual(BaseProvider::numberBetween($min, $max), $max);
}

public function testNumberBetweenAcceptsZeroAsMax()
{
$this->assertEquals(0, BaseProvider::numberBetween(0, 0));
}

public function testRandomFloat()
{
$min = 4;
$max = 10;
$nbMaxDecimals = 8;

$result = BaseProvider::randomFloat($nbMaxDecimals, $min, $max);

$parts = explode('.', $result);

$this->assertInternalType('float', $result);
$this->assertGreaterThanOrEqual($min, $result);
$this->assertLessThanOrEqual($max, $result);
$this->assertLessThanOrEqual($nbMaxDecimals, strlen($parts[1]));
}

public function testRandomLetterReturnsString()
{
$this->assertTrue(is_string(BaseProvider::randomLetter()));
}

public function testRandomLetterReturnsSingleLetter()
{
$this->assertEquals(1, strlen(BaseProvider::randomLetter()));
}

public function testRandomLetterReturnsLowercaseLetter()
{
$lowercaseLetters = 'abcdefghijklmnopqrstuvwxyz';
$this->assertTrue(strpos($lowercaseLetters, BaseProvider::randomLetter()) !== false);
}

public function testRandomAsciiReturnsString()
{
$this->assertTrue(is_string(BaseProvider::randomAscii()));
}

public function testRandomAsciiReturnsSingleCharacter()
{
$this->assertEquals(1, strlen(BaseProvider::randomAscii()));
}

public function testRandomAsciiReturnsAsciiCharacter()
{
$lowercaseLetters = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
$this->assertTrue(strpos($lowercaseLetters, BaseProvider::randomAscii()) !== false);
}

public function testRandomElementReturnsNullWhenArrayEmpty()
{
$this->assertNull(BaseProvider::randomElement(array()));
}

public function testRandomElementReturnsElementFromArray()
{
$elements = array('23', 'e', 32, '#');
$this->assertContains(BaseProvider::randomElement($elements), $elements);
}

public function testRandomElementReturnsElementFromAssociativeArray()
{
$elements = array('tata' => '23', 'toto' => 'e', 'tutu' => 32, 'titi' => '#');
$this->assertContains(BaseProvider::randomElement($elements), $elements);
}

public function testShuffleReturnsStringWhenPassedAStringArgument()
{
$this->assertInternalType('string', BaseProvider::shuffle('foo'));
}

public function testShuffleReturnsArrayWhenPassedAnArrayArgument()
{
$this->assertInternalType('array', BaseProvider::shuffle(array(1, 2, 3)));
}




public function testShuffleThrowsExceptionWhenPassedAnInvalidArgument()
{
BaseProvider::shuffle(false);
}

public function testShuffleArraySupportsEmptyArrays()
{
$this->assertEquals(array(), BaseProvider::shuffleArray(array()));
}

public function testShuffleArrayReturnsAnArrayOfTheSameSize()
{
$array = array(1, 2, 3, 4, 5);
$this->assertSameSize($array, BaseProvider::shuffleArray($array));
}

public function testShuffleArrayReturnsAnArrayWithSameElements()
{
$array = array(2, 4, 6, 8, 10);
$shuffleArray = BaseProvider::shuffleArray($array);
$this->assertContains(2, $shuffleArray);
$this->assertContains(4, $shuffleArray);
$this->assertContains(6, $shuffleArray);
$this->assertContains(8, $shuffleArray);
$this->assertContains(10, $shuffleArray);
}

public function testShuffleArrayReturnsADifferentArrayThanTheOriginal()
{
$arr = array(1, 2, 3, 4, 5);
$shuffledArray = BaseProvider::shuffleArray($arr);
$this->assertNotEquals($arr, $shuffledArray);
}

public function testShuffleArrayLeavesTheOriginalArrayUntouched()
{
$arr = array(1, 2, 3, 4, 5);
BaseProvider::shuffleArray($arr);
$this->assertEquals($arr, array(1, 2, 3, 4, 5));
}

public function testShuffleStringSupportsEmptyStrings()
{
$this->assertEquals('', BaseProvider::shuffleString(''));
}

public function testShuffleStringReturnsAnStringOfTheSameSize()
{
$string = 'abcdef';
$this->assertEquals(strlen($string), strlen(BaseProvider::shuffleString($string)));
}

public function testShuffleStringReturnsAnStringWithSameElements()
{
$string = 'acegi';
$shuffleString = BaseProvider::shuffleString($string);
$this->assertContains('a', $shuffleString);
$this->assertContains('c', $shuffleString);
$this->assertContains('e', $shuffleString);
$this->assertContains('g', $shuffleString);
$this->assertContains('i', $shuffleString);
}

public function testShuffleStringReturnsADifferentStringThanTheOriginal()
{
$string = 'abcdef';
$shuffledString = BaseProvider::shuffleString($string);
$this->assertNotEquals($string, $shuffledString);
}

public function testShuffleStringLeavesTheOriginalStringUntouched()
{
$string = 'abcdef';
BaseProvider::shuffleString($string);
$this->assertEquals($string, 'abcdef');
}

public function testNumerifyReturnsSameStringWhenItContainsNoHashSign()
{
$this->assertEquals('fooBar?', BaseProvider::numerify('fooBar?'));
}

public function testNumerifyReturnsStringWithHashSignsReplacedByDigits()
{
$this->assertRegExp('/foo\dBa\dr/', BaseProvider::numerify('foo#Ba#r'));
}

public function testNumerifyReturnsStringWithPercentageSignsReplacedByDigits()
{
$this->assertRegExp('/foo\dBa\dr/', BaseProvider::numerify('foo%Ba%r'));
}

public function testNumerifyReturnsStringWithPercentageSignsReplacedByNotNullDigits()
{
$this->assertNotEquals('0', BaseProvider::numerify('%'));
}

public function testNumerifyCanGenerateALargeNumberOfDigits()
{
$largePattern = str_repeat('#', 20); 
 $this->assertEquals(20, strlen(BaseProvider::numerify($largePattern)));
}

public function testLexifyReturnsSameStringWhenItContainsNoQuestionMark()
{
$this->assertEquals('fooBar#', BaseProvider::lexify('fooBar#'));
}

public function testLexifyReturnsStringWithQuestionMarksReplacedByLetters()
{
$this->assertRegExp('/foo[a-z]Ba[a-z]r/', BaseProvider::lexify('foo?Ba?r'));
}

public function testBothifyCombinesNumerifyAndLexify()
{
$this->assertRegExp('/foo[a-z]Ba\dr/', BaseProvider::bothify('foo?Ba#r'));
}

public function testBothifyAsterisk()
{
$this->assertRegExp('/foo([a-z]|\d)Ba([a-z]|\d)r/', BaseProvider::bothify('foo*Ba*r'));
}

public function testBothifyUtf()
{
$utf = 'œ∑´®†¥¨ˆøπ“‘和製╯°□°╯︵ ┻━┻🐵 🙈 ﺚﻣ ﻦﻔﺳ ﺲﻘﻄﺗ ﻮﺑﺎﻠﺘﺣﺪﻳﺩ،, ﺝﺰﻳﺮﺘﻳ ﺏﺎﺴﺘﺧﺩﺎﻣ ﺄﻧ ﺪﻧﻭ. ﺇﺫ ﻪﻧﺍ؟ ﺎﻠﺴﺗﺍﺭ ﻮﺘ';
$this->assertRegExp('/'.$utf.'foo\dB[a-z]a([a-z]|\d)r/u', BaseProvider::bothify($utf.'foo#B?a*r'));
}

public function testAsciifyReturnsSameStringWhenItContainsNoStarSign()
{
$this->assertEquals('fooBar?', BaseProvider::asciify('fooBar?'));
}

public function testAsciifyReturnsStringWithStarSignsReplacedByAsciiChars()
{
$this->assertRegExp('/foo.Ba.r/', BaseProvider::asciify('foo*Ba*r'));
}

public function regexifyBasicDataProvider()
{
return array(
array('azeQSDF1234', 'azeQSDF1234', 'does not change non regex chars'),
array('foo(bar){1}', 'foobar', 'replaces regex characters'),
array('', '', 'supports empty string'),
array('/^foo(bar){1}$/', 'foobar', 'ignores regex delimiters')
);
}




public function testRegexifyBasicFeatures($input, $output, $message)
{
$this->assertEquals($output, BaseProvider::regexify($input), $message);
}

public function regexifyDataProvider()
{
return array(
array('\d', 'numbers'),
array('\w', 'letters'),
array('(a|b)', 'alternation'),
array('[aeiou]', 'basic character class'),
array('[a-z]', 'character class range'),
array('[a-z1-9]', 'multiple character class range'),
array('a*b+c?', 'single character quantifiers'),
array('a{2}', 'brackets quantifiers'),
array('a{2,3}', 'min-max brackets quantifiers'),
array('[aeiou]{2,3}', 'brackets quantifiers on basic character class'),
array('[a-z]{2,3}', 'brackets quantifiers on character class range'),
array('(a|b){2,3}', 'brackets quantifiers on alternation'),
array('\.\*\?\+', 'escaped characters'),
array('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}', 'complex regex')
);
}




public function testRegexifySupportedRegexSyntax($pattern, $message)
{
$this->assertRegExp('/' . $pattern . '/', BaseProvider::regexify($pattern), 'Regexify supports ' . $message);
}

public function testOptionalReturnsProviderValueWhenCalledWithWeight1()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$this->assertNotNull($faker->optional(100)->randomDigit);
}

public function testOptionalReturnsNullWhenCalledWithWeight0()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$this->assertNull($faker->optional(0)->randomDigit);
}

public function testOptionalAllowsChainingPropertyAccess()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$faker->addProvider(new \ArrayObject(array(1))); 
 $this->assertEquals(1, $faker->optional(100)->count);
$this->assertNull($faker->optional(0)->count);
}

public function testOptionalAllowsChainingMethodCall()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$faker->addProvider(new \ArrayObject(array(1))); 
 $this->assertEquals(1, $faker->optional(100)->count());
$this->assertNull($faker->optional(0)->count());
}

public function testOptionalAllowsChainingProviderCallRandomlyReturnNull()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$values = array();
for ($i=0; $i < 10; $i++) {
$values[]= $faker->optional()->randomDigit;
}
$this->assertContains(null, $values);

$values = array();
for ($i=0; $i < 10; $i++) {
$values[]= $faker->optional(50)->randomDigit;
}
$this->assertContains(null, $values);
}




public function testOptionalPercentageAndWeight()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$faker->addProvider(new \Faker\Provider\Miscellaneous($faker));

$valuesOld = array();
$valuesNew = array();

for ($i = 0; $i < 10000; ++$i) {
$valuesOld[] = $faker->optional(0.5)->boolean(100);
$valuesNew[] = $faker->optional(50)->boolean(100);
}

$this->assertEquals(
round(array_sum($valuesOld) / 10000, 2),
round(array_sum($valuesNew) / 10000, 2)
);
}

public function testUniqueAllowsChainingPropertyAccess()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$faker->addProvider(new \ArrayObject(array(1))); 
 $this->assertEquals(1, $faker->unique()->count);
}

public function testUniqueAllowsChainingMethodCall()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$faker->addProvider(new \ArrayObject(array(1))); 
 $this->assertEquals(1, $faker->unique()->count());
}

public function testUniqueReturnsOnlyUniqueValues()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$values = array();
for ($i=0; $i < 10; $i++) {
$values[]= $faker->unique()->randomDigit;
}
sort($values);
$this->assertEquals(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), $values);
}




public function testUniqueThrowsExceptionWhenNoUniqueValueCanBeGenerated()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
for ($i=0; $i < 11; $i++) {
$faker->unique()->randomDigit;
}
}

public function testUniqueCanResetUniquesWhenPassedTrueAsArgument()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$values = array();
for ($i=0; $i < 10; $i++) {
$values[]= $faker->unique()->randomDigit;
}
$values[]= $faker->unique(true)->randomDigit;
for ($i=0; $i < 9; $i++) {
$values[]= $faker->unique()->randomDigit;
}
sort($values);
$this->assertEquals(array(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9), $values);
}

public function testValidAllowsChainingPropertyAccess()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$this->assertLessThan(10, $faker->valid()->randomDigit);
}

public function testValidAllowsChainingMethodCall()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$this->assertLessThan(10, $faker->valid()->numberBetween(5, 9));
}

public function testValidReturnsOnlyValidValues()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$values = array();
$evenValidator = function($digit) {
return $digit % 2 === 0;
};
for ($i=0; $i < 50; $i++) {
$values[$faker->valid($evenValidator)->randomDigit] = true;
}
$uniqueValues = array_keys($values);
sort($uniqueValues);
$this->assertEquals(array(0, 2, 4, 6, 8), $uniqueValues);
}




public function testValidThrowsExceptionWhenNoValidValueCanBeGenerated()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$evenValidator = function($digit) {
return $digit % 2 === 0;
};
for ($i=0; $i < 11; $i++) {
$faker->valid($evenValidator)->randomElement(array(1, 3, 5, 7, 9));
}
}




public function testValidThrowsExceptionWhenParameterIsNotCollable()
{
$faker = new \Faker\Generator();
$faker->addProvider(new \Faker\Provider\Base($faker));
$faker->valid(12)->randomElement(array(1, 3, 5, 7, 9));
}





public function testRandomElementsThrowsWhenRequestingTooManyKeys()
{
BaseProvider::randomElements(array('foo'), 2);
}

public function testRandomElements()
{
$this->assertCount(1, BaseProvider::randomElements(), 'Should work without any input');

$empty = BaseProvider::randomElements(array(), 0);
$this->assertInternalType('array', $empty);
$this->assertCount(0, $empty);

$shuffled = BaseProvider::randomElements(array('foo', 'bar', 'baz'), 3);
$this->assertContains('foo', $shuffled);
$this->assertContains('bar', $shuffled);
$this->assertContains('baz', $shuffled);

$allowDuplicates = BaseProvider::randomElements(array('foo', 'bar'), 3, true);
$this->assertCount(3, $allowDuplicates);
$this->assertContainsOnly('string', $allowDuplicates);
}
}
<?php

namespace Faker\Test\Provider\de_DE;

use Faker\Generator;
use Faker\Provider\de_DE\Person;
use Faker\Provider\de_DE\Internet;
use Faker\Provider\de_DE\Company;

class InternetTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->addProvider(new Internet($faker));
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testEmailIsValid()
{
$email = $this->faker->email();
$this->assertNotFalse(filter_var($email, FILTER_VALIDATE_EMAIL));
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\Color;

class ColorTest extends \PHPUnit_Framework_TestCase
{

public function testHexColor()
{
$this->assertRegExp('/^#[a-f0-9]{6}$/i', Color::hexColor());
}

public function testSafeHexColor()
{
$this->assertRegExp('/^#[a-f0-9]{6}$/i', Color::safeHexColor());
}

public function testRgbColorAsArray()
{
$this->assertEquals(3, count(Color::rgbColorAsArray()));
}

public function testRgbColor()
{
$regexp = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])';
$this->assertRegExp('/^' . $regexp . ',' . $regexp . ',' . $regexp . '$/i', Color::rgbColor());
}

public function testRgbCssColor()
{
$regexp = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])';
$this->assertRegExp('/^rgb\(' . $regexp . ',' . $regexp . ',' . $regexp . '\)$/i', Color::rgbCssColor());
}

public function testRgbaCssColor()
{
$regexp = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])';
$regexpAlpha = '([01]?(\.\d+)?)';
$this->assertRegExp('/^rgba\(' . $regexp . ',' . $regexp . ',' . $regexp . ',' . $regexpAlpha . '\)$/i', Color::rgbaCssColor());
}

public function testSafeColorName()
{
$this->assertRegExp('/^[\w]+$/', Color::safeColorName());
}

public function testColorName()
{
$this->assertRegExp('/^[\w]+$/', Color::colorName());
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\UserAgent;

class UserAgentTest extends \PHPUnit_Framework_TestCase
{
public function testRandomUserAgent()
{
$this->assertNotNull(UserAgent::userAgent());
}

public function testFirefoxUserAgent()
{
$this->stringContains(' Firefox/', UserAgent::firefox());
}

public function testSafariUserAgent()
{
$this->stringContains('Safari/', UserAgent::safari());
}

public function testInternetExplorerUserAgent()
{
$this->assertStringStartsWith('Mozilla/5.0 (compatible; MSIE ', UserAgent::internetExplorer());
}

public function testOperaUserAgent()
{
$this->assertStringStartsWith('Opera/', UserAgent::opera());
}

public function testChromeUserAgent()
{
$this->stringContains('(KHTML, like Gecko) Chrome/', UserAgent::chrome());
}
}
<?php

namespace Faker\Test\Provider\bg_BG;

use Faker\Generator;
use Faker\Provider\bg_BG\Payment;

class PaymentTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Payment($faker));
$this->faker = $faker;
}

public function testVatIsValid()
{
$vat = $this->faker->vat();
$unspacedVat = $this->faker->vat(false);
$this->assertRegExp('/^(BG \d{9,10})$/', $vat);
$this->assertRegExp('/^(BG\d{9,10})$/', $unspacedVat);
}
}
<?php
namespace Faker\Test\Provider;

use Faker\Provider\Biased;
use Faker\Generator;

class BiasedTest extends \PHPUnit_Framework_TestCase
{
const MAX = 10;
const NUMBERS = 25000;
protected $generator;
protected $results = array();

protected function setUp()
{
$this->generator = new Generator();
$this->generator->addProvider(new Biased($this->generator));

$this->results = array_fill(1, self::MAX, 0);
}

public function performFake($function)
{
for($i = 0; $i < self::NUMBERS; $i++) {
$this->results[$this->generator->biasedNumberBetween(1, self::MAX, $function)]++;
}
}

public function testUnbiased()
{
$this->performFake(array('\Faker\Provider\Biased', 'unbiased'));


 foreach ($this->results as $number => $amount) {

 $assumed = (1 / self::MAX * $number) - (1 / self::MAX * ($number - 1));

 $assumed /= 1;
$this->assertGreaterThan(self::NUMBERS * $assumed * .95, $amount, "Value was more than 5 percent under the expected value");
$this->assertLessThan(self::NUMBERS * $assumed * 1.05, $amount, "Value was more than 5 percent over the expected value");
}
}

public function testLinearHigh()
{
$this->performFake(array('\Faker\Provider\Biased', 'linearHigh'));

foreach ($this->results as $number => $amount) {

 $assumed = 0.5 * pow(1 / self::MAX * $number, 2) - 0.5 * pow(1 / self::MAX * ($number - 1), 2);

 $assumed /= pow(1, 2) * .5;
$this->assertGreaterThan(self::NUMBERS * $assumed * .9, $amount, "Value was more than 10 percent under the expected value");
$this->assertLessThan(self::NUMBERS * $assumed * 1.1, $amount, "Value was more than 10 percent over the expected value");
}
}

public function testLinearLow()
{
$this->performFake(array('\Faker\Provider\Biased', 'linearLow'));

foreach ($this->results as $number => $amount) {

 $assumed = -0.5 * pow(1 / self::MAX * $number, 2) - -0.5 * pow(1 / self::MAX * ($number - 1), 2);

 $assumed += 1 / self::MAX;

 $assumed /= pow(1, 2) * .5;
$this->assertGreaterThan(self::NUMBERS * $assumed * .9, $amount, "Value was more than 10 percent under the expected value");
$this->assertLessThan(self::NUMBERS * $assumed * 1.1, $amount, "Value was more than 10 percent over the expected value");
}
}
}
<?php




namespace Faker\Test\Provider;

use Faker;










class ProviderOverrideTest extends \PHPUnit_Framework_TestCase
{






const TEST_STRING_REGEX = '/.+/u';




const TEST_EMAIL_REGEX = '/^(.+)@(.+)$/ui';





public function testAddress($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->city);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->postcode);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->address);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->country);
}






public function testCompany($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->company);
}






public function testDateTime($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->century);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->timezone);
}






public function testInternet($locale = null)
{
if ($locale && $locale !== 'en_US' && !class_exists('Transliterator')) {
$this->markTestSkipped('Transliterator class not available (intl extension)');
}

$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->userName);

$this->assertRegExp(static::TEST_EMAIL_REGEX, $faker->email);
$this->assertRegExp(static::TEST_EMAIL_REGEX, $faker->safeEmail);
$this->assertRegExp(static::TEST_EMAIL_REGEX, $faker->freeEmail);
$this->assertRegExp(static::TEST_EMAIL_REGEX, $faker->companyEmail);
}






public function testPerson($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->name);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->title);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->firstName);
$this->assertRegExp(static::TEST_STRING_REGEX, $faker->lastName);
}






public function testPhoneNumber($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->phoneNumber);
}






public function testUserAgent($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->userAgent);
}








public function testUuid($locale = null)
{
$faker = Faker\Factory::create($locale);

$this->assertRegExp(static::TEST_STRING_REGEX, $faker->uuid);
}





public function localeDataProvider()
{
$locales = $this->getAllLocales();
$data = array();

foreach ($locales as $locale) {
$data[] = array(
$locale
);
}

return $data;
}







private function getAllLocales()
{
static $locales = array();

if ( ! empty($locales)) {
return $locales;
}


 $providerDir = __DIR__ .'/../../../src/Faker/Provider';
foreach (glob($providerDir .'/*_*/*.php') as $file) {
$localisation = basename(dirname($file));

if (isset($locales[ $localisation ])) {
continue;
}

$locales[ $localisation ] = $localisation;
}

return $locales;
}
}
<?php

namespace Faker\Test\Provider\nl_NL;

use Faker\Generator;
use Faker\Provider\nl_NL\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testGenerateValidVatNumber()
{
$vatNo = $this->faker->vat();

$this->assertEquals(14, strlen($vatNo));
$this->assertRegExp('/^NL[0-9]{9}B[0-9]{2}$/', $vatNo);
}

public function testGenerateValidBtwNumberAlias()
{
$btwNo = $this->faker->btw();

$this->assertEquals(14, strlen($btwNo));
$this->assertRegExp('/^NL[0-9]{9}B[0-9]{2}$/', $btwNo);
}
}
<?php

namespace Faker\Provider\en_IN;

use Faker\Generator;
use Faker\Provider\en_IN\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testCity()
{
$city = $this->faker->city();
$this->assertNotEmpty($city);
$this->assertInternalType('string', $city);
$this->assertRegExp('/[A-Z][a-z]+/', $city);
}

public function testCountry()
{
$country = $this->faker->country();
$this->assertNotEmpty($country);
$this->assertInternalType('string', $country);
$this->assertRegExp('/[A-Z][a-z]+/', $country);
}

public function testLocalityName()
{
$localityName = $this->faker->localityName();
$this->assertNotEmpty($localityName);
$this->assertInternalType('string', $localityName);
$this->assertRegExp('/[A-Z][a-z]+/', $localityName);
}

public function testAreaSuffix()
{
$areaSuffix = $this->faker->areaSuffix();
$this->assertNotEmpty($areaSuffix);
$this->assertInternalType('string', $areaSuffix);
$this->assertRegExp('/[A-Z][a-z]+/', $areaSuffix);
}
}

?>
<?php

namespace Faker\Test\Provider\bn_BD;

use Faker\Generator;
use Faker\Provider\bn_BD\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testIfFirstNameMaleCanReturnData()
{
$firstNameMale = $this->faker->firstNameMale();
$this->assertNotEmpty($firstNameMale);
}

public function testIfFirstNameFemaleCanReturnData()
{
$firstNameFemale = $this->faker->firstNameFemale();
$this->assertNotEmpty($firstNameFemale);
}
}
?>
<?php

namespace Faker\Test\Provider\mn_MN;

use Faker\Generator;
use Faker\Provider\mn_MN\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
public function testName()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(1);

$this->assertRegExp('/^[А-Я]{1}\.[\w\W]+$/u', $faker->name);
}

public function testIdNumber()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$faker->seed(2);

$this->assertRegExp('/^[А-Я]{2}\d{8}$/u', $faker->idNumber);
}
}
<?php

namespace Faker\Provider\en_AU;

use Faker\Generator;
use Faker\Provider\en_AU\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{




private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testCityPrefix()
{
$cityPrefix = $this->faker->cityPrefix();
$this->assertNotEmpty($cityPrefix);
$this->assertInternalType('string', $cityPrefix);
$this->assertRegExp('/[A-Z][a-z]+/', $cityPrefix);
}

public function testStreetSuffix()
{
$streetSuffix = $this->faker->streetSuffix();
$this->assertNotEmpty($streetSuffix);
$this->assertInternalType('string', $streetSuffix);
$this->assertRegExp('/[A-Z][a-z]+/', $streetSuffix);
}

public function testState()
{
$state = $this->faker->state();
$this->assertNotEmpty($state);
$this->assertInternalType('string', $state);
$this->assertRegExp('/[A-Z][a-z]+/', $state);
}
}

?>
<?php

namespace Faker\Test\Provider;

use Faker\Generator;
use Faker\Provider\Address;

class AddressTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Address($faker));
$this->faker = $faker;
}

public function testLatitude()
{
$latitude = $this->faker->latitude();
$this->assertInternalType('float', $latitude);
$this->assertGreaterThanOrEqual(-90, $latitude);
$this->assertLessThanOrEqual(90, $latitude);
}

public function testLongitude()
{
$longitude = $this->faker->longitude();
$this->assertInternalType('float', $longitude);
$this->assertGreaterThanOrEqual(-180, $longitude);
$this->assertLessThanOrEqual(180, $longitude);
}

public function testCoordinate()
{
$coordinate = $this->faker->localCoordinates();
$this->assertInternalType('array', $coordinate);
$this->assertInternalType('float', $coordinate['latitude']);
$this->assertGreaterThanOrEqual(-90, $coordinate['latitude']);
$this->assertLessThanOrEqual(90, $coordinate['latitude']);
$this->assertInternalType('float', $coordinate['longitude']);
$this->assertGreaterThanOrEqual(-180, $coordinate['longitude']);
$this->assertLessThanOrEqual(180, $coordinate['longitude']);
}
}
<?php

namespace Faker\Test\Provider;

use Faker\Provider\Lorem;

class LoremTest extends \PHPUnit_Framework_TestCase
{



public function testTextThrowsExceptionWhenAskedTextSizeLessThan5()
{
Lorem::text(4);
}

public function testTextReturnsWordsWhenAskedSizeLessThan25()
{
$this->assertEquals('Word word word word.', TestableLorem::text(24));
}

public function testTextReturnsSentencesWhenAskedSizeLessThan100()
{
$this->assertEquals('This is a test sentence. This is a test sentence. This is a test sentence.', TestableLorem::text(99));
}

public function testTextReturnsParagraphsWhenAskedSizeGreaterOrEqualThanThan100()
{
$this->assertEquals('This is a test paragraph. It has three sentences. Exactly three.', TestableLorem::text(100));
}

public function testSentenceWithZeroNbWordsReturnsEmptyString()
{
$this->assertEquals('', Lorem::sentence(0));
}

public function testSentenceWithNegativeNbWordsReturnsEmptyString()
{
$this->assertEquals('', Lorem::sentence(-1));
}

public function testParagraphWithZeroNbSentencesReturnsEmptyString()
{
$this->assertEquals('', Lorem::paragraph(0));
}

public function testParagraphWithNegativeNbSentencesReturnsEmptyString()
{
$this->assertEquals('', Lorem::paragraph(-1));
}

public function testSentenceWithPositiveNbWordsReturnsAtLeastOneWord()
{
$sentence = Lorem::sentence(1);

$this->assertGreaterThan(1, strlen($sentence));
$this->assertGreaterThanOrEqual(1, count(explode(' ', $sentence)));
}

public function testParagraphWithPositiveNbSentencesReturnsAtLeastOneWord()
{
$paragraph = Lorem::paragraph(1);

$this->assertGreaterThan(1, strlen($paragraph));
$this->assertGreaterThanOrEqual(1, count(explode(' ', $paragraph)));
}

public function testWordssAsText()
{
$words = TestableLorem::words(2, true);

$this->assertEquals('word word', $words);
}

public function testSentencesAsText()
{
$sentences = TestableLorem::sentences(2, true);

$this->assertEquals('This is a test sentence. This is a test sentence.', $sentences);
}

public function testParagraphsAsText()
{
$paragraphs = TestableLorem::paragraphs(2, true);

$expected = "This is a test paragraph. It has three sentences. Exactly three.\n\nThis is a test paragraph. It has three sentences. Exactly three.";
$this->assertEquals($expected, $paragraphs);
}
}

class TestableLorem extends Lorem
{

public static function word()
{
return 'word';
}

public static function sentence($nbWords = 5, $variableNbWords = true)
{
return 'This is a test sentence.';
}

public static function paragraph($nbSentences = 3, $variableNbSentences = true)
{
return 'This is a test paragraph. It has three sentences. Exactly three.';
}
}
<?php

namespace Faker\Test;

use Faker\Generator;

class GeneratorTest extends \PHPUnit_Framework_TestCase
{
public function testAddProviderGivesPriorityToNewlyAddedProvider()
{
$generator = new Generator;
$generator->addProvider(new FooProvider());
$generator->addProvider(new BarProvider());
$this->assertEquals('barfoo', $generator->format('fooFormatter'));
}

public function testGetFormatterReturnsCallable()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertTrue(is_callable($generator->getFormatter('fooFormatter')));
}

public function testGetFormatterReturnsCorrectFormatter()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$expected = array($provider, 'fooFormatter');
$this->assertEquals($expected, $generator->getFormatter('fooFormatter'));
}




public function testGetFormatterThrowsExceptionOnIncorrectProvider()
{
$generator = new Generator;
$generator->getFormatter('fooFormatter');
}




public function testGetFormatterThrowsExceptionOnIncorrectFormatter()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$generator->getFormatter('barFormatter');
}

public function testFormatCallsFormatterOnProvider()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertEquals('foobar', $generator->format('fooFormatter'));
}

public function testFormatTransfersArgumentsToFormatter()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertEquals('bazfoo', $generator->format('fooFormatterWithArguments', array('foo')));
}

public function testParseReturnsSameStringWhenItContainsNoCurlyBraces()
{
$generator = new Generator();
$this->assertEquals('fooBar#?', $generator->parse('fooBar#?'));
}

public function testParseReturnsStringWithTokensReplacedByFormatters()
{
$generator = new Generator();
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertEquals('This is foobar a text with foobar', $generator->parse('This is {{fooFormatter}} a text with {{ fooFormatter }}'));
}

public function testMagicGetCallsFormat()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertEquals('foobar', $generator->fooFormatter);
}

public function testMagicCallCallsFormat()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertEquals('foobar', $generator->fooFormatter());
}

public function testMagicCallCallsFormatWithArguments()
{
$generator = new Generator;
$provider = new FooProvider();
$generator->addProvider($provider);
$this->assertEquals('bazfoo', $generator->fooFormatterWithArguments('foo'));
}

public function testSeed()
{
$generator = new Generator;

$generator->seed(0);
$mtRandWithSeedZero = mt_rand();
$generator->seed(0);
$this->assertEquals($mtRandWithSeedZero, mt_rand(), 'seed(0) should be deterministic.');

$generator->seed();
$mtRandWithoutSeed = mt_rand();
$this->assertNotEquals($mtRandWithSeedZero, $mtRandWithoutSeed, 'seed() should be different than seed(0)');
$generator->seed();
$this->assertNotEquals($mtRandWithoutSeed, mt_rand(), 'seed() should not be deterministic.');

$generator->seed('10');
$this->assertTrue(true, 'seeding with a non int value doesn\'t throw an exception');
}
}

class FooProvider
{
public function fooFormatter()
{
return 'foobar';
}

public function fooFormatterWithArguments($value = '')
{
return 'baz' . $value;
}
}

class BarProvider
{
public function fooFormatter()
{
return 'barfoo';
}
}
<?php

namespace Faker\Test;

use Faker\DefaultGenerator;

class DefaultGeneratorTest extends \PHPUnit_Framework_TestCase
{
public function testGeneratorReturnsNullByDefault()
{
$generator = new DefaultGenerator;
$this->assertSame(null, $generator->value);
}

public function testGeneratorReturnsDefaultValueForAnyPropertyGet()
{
$generator = new DefaultGenerator(123);
$this->assertSame(123, $generator->foo);
$this->assertNotSame(null, $generator->bar);
}

public function testGeneratorReturnsDefaultValueForAnyMethodCall()
{
$generator = new DefaultGenerator(123);
$this->assertSame(123, $generator->foobar());
}
}
<?php

namespace Faker\Test\Calculator;

use Faker\Calculator\Luhn;

class LuhnTest extends \PHPUnit_Framework_TestCase
{

public function checkDigitProvider()
{
return array(
array('7992739871', '3'),
array('3852000002323', '7'),
array('37144963539843', '1'),
array('561059108101825', '0'),
array('601100099013942', '4'),
array('510510510510510', '0'),
array(7992739871, '3'),
array(3852000002323, '7'),
array('37144963539843', '1'),
array('561059108101825', '0'),
array('601100099013942', '4'),
array('510510510510510', '0')
);
}




public function testComputeCheckDigit($partialNumber, $checkDigit)
{
$this->assertInternalType('string', $checkDigit);
$this->assertEquals($checkDigit, Luhn::computeCheckDigit($partialNumber));
}

public function validatorProvider()
{
return array(
array('79927398710', false),
array('79927398711', false),
array('79927398712', false),
array('79927398713', true),
array('79927398714', false),
array('79927398715', false),
array('79927398716', false),
array('79927398717', false),
array('79927398718', false),
array('79927398719', false),
array(79927398713, true),
array(79927398714, false),
);
}




public function testIsValid($number, $isValid)
{
$this->assertEquals($isValid, Luhn::isValid($number));
}





public function testGenerateLuhnNumberWithInvalidPrefix()
{
Luhn::generateLuhnNumber('abc');
}
}
<?php

namespace Faker\Test\Calculator;

use Faker\Calculator\Inn;

class InnTest extends \PHPUnit_Framework_TestCase
{

public function checksumProvider()
{
return array(
array('143525744', '4'),
array('500109285', '3'),
array('500109285', '3'),
array('500109285', '3'),
array('027615723', '1')
);
}




public function testChecksum($inn, $checksum)
{
$this->assertEquals($checksum, Inn::checksum($inn), $inn);
}

public function validatorProvider()
{
return array(
array('5902179757', true),
array('5408294405', true),
array('2724164617', true),
array('0726000515', true),
array('6312123552', true),

array('1111111111', false),
array('0123456789', false),
);
}




public function testIsValid($inn, $isValid)
{
$this->assertEquals($isValid, Inn::isValid($inn), $inn);
}
}
<?php

namespace Faker\Test\Calculator;

use Faker\Calculator\Iban;

class IbanTest extends \PHPUnit_Framework_TestCase
{

public function checksumProvider()
{
return array(
array('AL47212110090000000235698741', '47'),
array('AD1200012030200359100100', '12'),
array('AT611904300234573201', '61'),
array('AZ21NABZ00000000137010001944', '21'),
array('BH67BMAG00001299123456', '67'),
array('BE68539007547034', '68'),
array('BA391290079401028494', '39'),
array('BR7724891749412660603618210F3', '77'),
array('BG80BNBG96611020345678', '80'),
array('CR0515202001026284066', '05'),
array('HR1210010051863000160', '12'),
array('CY17002001280000001200527600', '17'),
array('CZ6508000000192000145399', '65'),
array('DK5000400440116243', '50'),
array('DO28BAGR00000001212453611324', '28'),
array('EE382200221020145685', '38'),
array('FO6264600001631634', '62'),
array('FI2112345600000785', '21'),
array('FR1420041010050500013M02606', '14'),
array('GE29NB0000000101904917', '29'),
array('DE89370400440532013000', '89'),
array('GI75NWBK000000007099453', '75'),
array('GR1601101250000000012300695', '16'),
array('GL8964710001000206', '89'),
array('GT82TRAJ01020000001210029690', '82'),
array('HU42117730161111101800000000', '42'),
array('IS140159260076545510730339', '14'),
array('IE29AIBK93115212345678', '29'),
array('IL620108000000099999999', '62'),
array('IT60X0542811101000000123456', '60'),
array('KZ86125KZT5004100100', '86'),
array('KW81CBKU0000000000001234560101', '81'),
array('LV80BANK0000435195001', '80'),
array('LB62099900000001001901229114', '62'),
array('LI21088100002324013AA', '21'),
array('LT121000011101001000', '12'),
array('LU280019400644750000', '28'),
array('MK07250120000058984', '07'),
array('MT84MALT011000012345MTLCAST001S', '84'),
array('MR1300020001010000123456753', '13'),
array('MU17BOMM0101101030300200000MUR', '17'),
array('MD24AG000225100013104168', '24'),
array('MC5811222000010123456789030', '58'),
array('ME25505000012345678951', '25'),
array('NL91ABNA0417164300', '91'),
array('NO9386011117947', '93'),
array('PK36SCBL0000001123456702', '36'),
array('PL61109010140000071219812874', '61'),
array('PS92PALS000000000400123456702', '92'),
array('PT50000201231234567890154', '50'),
array('QA58DOHB00001234567890ABCDEFG', '58'),
array('RO49AAAA1B31007593840000', '49'),
array('SM86U0322509800000000270100', '86'),
array('SA0380000000608010167519', '03'),
array('RS35260005601001611379', '35'),
array('SK3112000000198742637541', '31'),
array('SI56263300012039086', '56'),
array('ES9121000418450200051332', '91'),
array('SE4550000000058398257466', '45'),
array('CH9300762011623852957', '93'),
array('TN5910006035183598478831', '59'),
array('TR330006100519786457841326', '33'),
array('AE070331234567890123456', '07'),
array('GB29NWBK60161331926819', '29'),
array('VG96VPVG0000012345678901', '96'),
array('YY24KIHB12476423125915947930915268', '24'),
array('ZZ25VLQT382332233206588011313776421', '25'),
);
}




public function testChecksum($iban, $checksum)
{
$this->assertEquals($checksum, Iban::checksum($iban), $iban);
}

public function validatorProvider()
{
return array(
array('AL47212110090000000235698741', true),
array('AD1200012030200359100100', true),
array('AT611904300234573201', true),
array('AZ21NABZ00000000137010001944', true),
array('BH67BMAG00001299123456', true),
array('BE68539007547034', true),
array('BA391290079401028494', true),
array('BR7724891749412660603618210F3', true),
array('BG80BNBG96611020345678', true),
array('CR0515202001026284066', true),
array('HR1210010051863000160', true),
array('CY17002001280000001200527600', true),
array('CZ6508000000192000145399', true),
array('DK5000400440116243', true),
array('DO28BAGR00000001212453611324', true),
array('EE382200221020145685', true),
array('FO6264600001631634', true),
array('FI2112345600000785', true),
array('FR1420041010050500013M02606', true),
array('GE29NB0000000101904917', true),
array('DE89370400440532013000', true),
array('GI75NWBK000000007099453', true),
array('GR1601101250000000012300695', true),
array('GL8964710001000206', true),
array('GT82TRAJ01020000001210029690', true),
array('HU42117730161111101800000000', true),
array('IS140159260076545510730339', true),
array('IE29AIBK93115212345678', true),
array('IL620108000000099999999', true),
array('IT60X0542811101000000123456', true),
array('KZ86125KZT5004100100', true),
array('KW81CBKU0000000000001234560101', true),
array('LV80BANK0000435195001', true),
array('LB62099900000001001901229114', true),
array('LI21088100002324013AA', true),
array('LT121000011101001000', true),
array('LU280019400644750000', true),
array('MK07250120000058984', true),
array('MT84MALT011000012345MTLCAST001S', true),
array('MR1300020001010000123456753', true),
array('MU17BOMM0101101030300200000MUR', true),
array('MD24AG000225100013104168', true),
array('MC5811222000010123456789030', true),
array('ME25505000012345678951', true),
array('NL91ABNA0417164300', true),
array('NO9386011117947', true),
array('PK36SCBL0000001123456702', true),
array('PL61109010140000071219812874', true),
array('PS92PALS000000000400123456702', true),
array('PT50000201231234567890154', true),
array('QA58DOHB00001234567890ABCDEFG', true),
array('RO49AAAA1B31007593840000', true),
array('SM86U0322509800000000270100', true),
array('SA0380000000608010167519', true),
array('RS35260005601001611379', true),
array('SK3112000000198742637541', true),
array('SI56263300012039086', true),
array('ES9121000418450200051332', true),
array('SE4550000000058398257466', true),
array('CH9300762011623852957', true),
array('TN5910006035183598478831', true),
array('TR330006100519786457841326', true),
array('AE070331234567890123456', true),
array('GB29NWBK60161331926819', true),
array('VG96VPVG0000012345678901', true),
array('YY24KIHB12476423125915947930915268', true),
array('ZZ25VLQT382332233206588011313776421', true),


array('AL4721211009000000023569874', false),
array('AD120001203020035910010', false),
array('AT61190430023457320', false),
array('AZ21NABZ0000000013701000194', false),
array('BH67BMAG0000129912345', false),
array('BE6853900754703', false),
array('BA39129007940102849', false),
array('BR7724891749412660603618210F', false),
array('BG80BNBG9661102034567', false),
array('CR051520200102628406', false),
array('HR121001005186300016', false),
array('CY1700200128000000120052760', false),
array('CZ650800000019200014539', false),
array('DK500040044011624', false),
array('DO28BAGR0000000121245361132', false),
array('EE38220022102014568', false),
array('FO626460000163163', false),
array('FI2112345600000780', false),
array('FR1420041010050500013M0260', false),
array('GE29NB000000010190491', false),
array('DE8937040044053201300', false),
array('GI75NWBK00000000709945', false),
array('GR160110125000000001230069', false),
array('GL896471000100020', false),
array('GT82TRAJ0102000000121002969', false),
array('HU4211773016111110180000000', false),
array('IS14015926007654551073033', false),
array('IE29AIBK9311521234567', false),
array('IL62010800000009999999', false),
array('IT60X054281110100000012345', false),
array('KZ86125KZT500410010', false),
array('KW81CBKU000000000000123456010', false),
array('LV80BANK000043519500', false),
array('LB6209990000000100190122911', false),
array('LI21088100002324013A', false),
array('LT12100001110100100', false),
array('LU28001940064475000', false),
array('MK0725012000005898', false),
array('MT84MALT011000012345MTLCAST001', false),
array('MR130002000101000012345675', false),
array('MU17BOMM0101101030300200000MU', false),
array('MD24AG00022510001310416', false),
array('MC58112220000101234567890', false),
array('ME2550500001234567895', false),
array('NL91ABNA041716430', false),
array('NO938601111794', false),
array('PK36SCBL000000112345670', false),
array('PL6110901014000007121981287', false),
array('PS92PALS00000000040012345670', false),
array('PT5000020123123456789015', false),
array('QA58DOHB00001234567890ABCDEF', false),
array('RO49AAAA1B3100759384000', false),
array('SM86U032250980000000027010', false),
array('SA038000000060801016751', false),
array('RS3526000560100161137', false),
array('SK311200000019874263754', false),
array('SI5626330001203908', false),
array('ES912100041845020005133', false),
array('SE455000000005839825746', false),
array('CH930076201162385295', false),
array('TN591000603518359847883', false),
array('TR33000610051978645784132', false),
array('AE07033123456789012345', false),
array('GB29NWBK6016133192681', false),
array('VG96VPVG000001234567890', false),
array('YY24KIHB1247642312591594793091526', false),
array('ZZ25VLQT38233223320658801131377642', false),
);
}




public function testIsValid($iban, $isValid)
{
$this->assertEquals($isValid, Iban::isValid($iban), $iban);
}

public function alphaToNumberProvider()
{
return array(
array('A', 10),
array('B', 11),
array('C', 12),
array('D', 13),
array('E', 14),
array('F', 15),
array('G', 16),
array('H', 17),
array('I', 18),
array('J', 19),
array('K', 20),
array('L', 21),
array('M', 22),
array('N', 23),
array('O', 24),
array('P', 25),
array('Q', 26),
array('R', 27),
array('S', 28),
array('T', 29),
array('U', 30),
array('V', 31),
array('W', 32),
array('X', 33),
array('Y', 34),
array('Z', 35),
);
}




public function testAlphaToNumber($letter, $number)
{
$this->assertEquals($number, Iban::alphaToNumber($letter), $letter);
}

public function mod97Provider()
{

 $return = array(
array('123456789123456789', 7),
array('111222333444555666', 73),
array('4242424242424242424242', 19),
array('271828182845904523536028', 68),
);


 for ($i = 0; $i < 200; $i++) {
$return[] = array((string)$i, $i % 97);
}

return $return;
}



public function testMod97($number, $result)
{
$this->assertEquals($result, Iban::mod97($number), $number);
}
}
<?php

namespace Faker\Provider;

class DateTime extends Base
{
protected static $century = array('I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII','XIII','XIV','XV','XVI','XVII','XVIII','XIX','XX','XXI');

protected static function getMaxTimestamp($max = 'now')
{
if (is_numeric($max)) {
return (int) $max;
}

if ($max instanceof \DateTime) {
return $max->getTimestamp();
}

return strtotime(empty($max) ? 'now' : $max);
}









public static function unixTime($max = 'now')
{
return mt_rand(0, static::getMaxTimestamp($max));
}











public static function dateTime($max = 'now', $timezone = null)
{
return static::setTimezone(
new \DateTime('@' . static::unixTime($max)),
(null === $timezone ? date_default_timezone_get() : $timezone)
);
}











public static function dateTimeAD($max = 'now', $timezone = null)
{
$min = (PHP_INT_SIZE>4 ? -62135597361 : -PHP_INT_MAX);
return static::setTimezone(
new \DateTime('@' . mt_rand($min, static::getMaxTimestamp($max))),
(null === $timezone ? date_default_timezone_get() : $timezone)
);
}








public static function iso8601($max = 'now')
{
return static::date(\DateTime::ISO8601, $max);
}









public static function date($format = 'Y-m-d', $max = 'now')
{
return static::dateTime($max)->format($format);
}









public static function time($format = 'H:i:s', $max = 'now')
{
return static::dateTime($max)->format($format);
}













public static function dateTimeBetween($startDate = '-30 years', $endDate = 'now', $timezone = null)
{
$startTimestamp = $startDate instanceof \DateTime ? $startDate->getTimestamp() : strtotime($startDate);
$endTimestamp = static::getMaxTimestamp($endDate);

if ($startTimestamp > $endTimestamp) {
throw new \InvalidArgumentException('Start date must be anterior to end date.');
}

$timestamp = mt_rand($startTimestamp, $endTimestamp);

return static::setTimezone(
new \DateTime('@' . $timestamp),
(null === $timezone ? date_default_timezone_get() : $timezone)
);
}














public static function dateTimeInInterval($date = '-30 years', $interval = '+5 days', $timezone = null)
{
$intervalObject = \DateInterval::createFromDateString($interval);
$datetime = $date instanceof \DateTime ? $date : new \DateTime($date);
$otherDatetime = clone $datetime;
$otherDatetime->add($intervalObject);

$begin = $datetime > $otherDatetime ? $otherDatetime : $datetime;
$end = $datetime===$begin ? $otherDatetime : $datetime;

return static::dateTimeBetween(
$begin,
$end,
(null === $timezone ? date_default_timezone_get() : $timezone)
);
}







public static function dateTimeThisCentury($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-100 year', $max, $timezone);
}







public static function dateTimeThisDecade($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-10 year', $max, $timezone);
}







public static function dateTimeThisYear($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-1 year', $max, $timezone);
}







public static function dateTimeThisMonth($max = 'now', $timezone = null)
{
return static::dateTimeBetween('-1 month', $max, $timezone);
}






public static function amPm($max = 'now')
{
return static::dateTime($max)->format('a');
}






public static function dayOfMonth($max = 'now')
{
return static::dateTime($max)->format('d');
}






public static function dayOfWeek($max = 'now')
{
return static::dateTime($max)->format('l');
}






public static function month($max = 'now')
{
return static::dateTime($max)->format('m');
}






public static function monthName($max = 'now')
{
return static::dateTime($max)->format('F');
}






public static function year($max = 'now')
{
return static::dateTime($max)->format('Y');
}





public static function century()
{
return static::randomElement(static::$century);
}





public static function timezone()
{
return static::randomElement(\DateTimeZone::listIdentifiers());
}









private static function setTimezone(\DateTime $dt, $timezone)
{
return $dt->setTimezone(new \DateTimeZone($timezone));
}
}
<?php

namespace Faker\Provider;

class Miscellaneous extends Base
{






protected static $emoji = array(
'\uD83D\uDE00', '\uD83D\uDE01', '\uD83D\uDE02', '\uD83D\uDE03',
'\uD83D\uDE04', '\uD83D\uDE05', '\uD83D\uDE06', '\uD83D\uDE07',
'\uD83D\uDE08', '\uD83D\uDE09', '\uD83D\uDE0A', '\uD83D\uDE0B',
'\uD83D\uDE0C', '\uD83D\uDE0D', '\uD83D\uDE0E', '\uD83D\uDE0F',
'\uD83D\uDE10', '\uD83D\uDE11', '\uD83D\uDE12', '\uD83D\uDE13',
'\uD83D\uDE14', '\uD83D\uDE15', '\uD83D\uDE16', '\uD83D\uDE17',
'\uD83D\uDE18', '\uD83D\uDE19', '\uD83D\uDE1A', '\uD83D\uDE1B',
'\uD83D\uDE1C', '\uD83D\uDE1D', '\uD83D\uDE1E', '\uD83D\uDE1F',
'\uD83D\uDE20', '\uD83D\uDE21', '\uD83D\uDE22', '\uD83D\uDE23',
'\uD83D\uDE24', '\uD83D\uDE25', '\uD83D\uDE26', '\uD83D\uDE27',
'\uD83D\uDE28', '\uD83D\uDE29', '\uD83D\uDE2A', '\uD83D\uDE2B',
'\uD83D\uDE2C', '\uD83D\uDE2D', '\uD83D\uDE2E', '\uD83D\uDE2F',
'\uD83D\uDE30', '\uD83D\uDE31', '\uD83D\uDE32', '\uD83D\uDE33',
'\uD83D\uDE34', '\uD83D\uDE35', '\uD83D\uDE36', '\uD83D\uDE37',
);





protected static $languageCode = array(
'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av',
'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo',
'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv',
'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es',
'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga',
'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr',
'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik',
'io', 'is', 'it', 'iu', 'ja', 'jv', 'ka', 'kg', 'ki', 'kj',
'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw',
'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv',
'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mr', 'ms', 'mt', 'my',
'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv',
'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps',
'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd',
'se', 'sg', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr',
'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti',
'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug',
'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi',
'yo', 'za', 'zh', 'zu',
);





protected static $countryCode = array(
'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR',
'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE',
'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ',
'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD',
'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR',
'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM',
'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI',
'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF',
'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS',
'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU',
'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT',
'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN',
'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK',
'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME',
'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ',
'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA',
'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU',
'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM',
'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS',
'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI',
'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV',
'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK',
'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA',
'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI',
'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW',
);





protected static $countryISOAlpha3 = array(
'ABW', 'AFG', 'AGO', 'AIA', 'ALA', 'ALB', 'AND', 'ARE', 'ARG', 'ARM',
'ASM', 'ATA', 'ATF', 'ATG', 'AUS', 'AUT', 'AZE', 'BDI', 'BEL', 'BEN',
'BES', 'BFA', 'BGD', 'BGR', 'BHR', 'BHS', 'BIH', 'BLM', 'BLR', 'BLZ',
'BMU', 'BOL', 'BRA', 'BRB', 'BRN', 'BTN', 'BVT', 'BWA', 'CAF', 'CAN',
'CCK', 'CHE', 'CHL', 'CHN', 'CIV', 'CMR', 'COD', 'COG', 'COK', 'COL',
'COM', 'CPV', 'CRI', 'CUB', 'CUW', 'CXR', 'CYM', 'CYP', 'CZE', 'DEU',
'DJI', 'DMA', 'DNK', 'DOM', 'DZA', 'ECU', 'EGY', 'ERI', 'ESH', 'ESP',
'EST', 'ETH', 'FIN', 'FJI', 'FLK', 'FRA', 'FRO', 'FSM', 'GAB', 'GBR',
'GEO', 'GGY', 'GHA', 'GIB', 'GIN', 'GLP', 'GMB', 'GNB', 'GNQ', 'GRC',
'GRD', 'GRL', 'GTM', 'GUF', 'GUM', 'GUY', 'HKG', 'HMD', 'HND', 'HRV',
'HTI', 'HUN', 'IDN', 'IMN', 'IND', 'IOT', 'IRL', 'IRN', 'IRQ', 'ISL',
'ISR', 'ITA', 'JAM', 'JEY', 'JOR', 'JPN', 'KAZ', 'KEN', 'KGZ', 'KHM',
'KIR', 'KNA', 'KOR', 'KWT', 'LAO', 'LBN', 'LBR', 'LBY', 'LCA', 'LIE',
'LKA', 'LSO', 'LTU', 'LUX', 'LVA', 'MAC', 'MAF', 'MAR', 'MCO', 'MDA',
'MDG', 'MDV', 'MEX', 'MHL', 'MKD', 'MLI', 'MLT', 'MMR', 'MNE', 'MNG',
'MNP', 'MOZ', 'MRT', 'MSR', 'MTQ', 'MUS', 'MWI', 'MYS', 'MYT', 'NAM',
'NCL', 'NER', 'NFK', 'NGA', 'NIC', 'NIU', 'NLD', 'NOR', 'NPL', 'NRU',
'NZL', 'OMN', 'PAK', 'PAN', 'PCN', 'PER', 'PHL', 'PLW', 'PNG', 'POL',
'PRI', 'PRK', 'PRT', 'PRY', 'PSE', 'PYF', 'QAT', 'REU', 'ROU', 'RUS',
'RWA', 'SAU', 'SDN', 'SEN', 'SGP', 'SGS', 'SHN', 'SJM', 'SLB', 'SLE',
'SLV', 'SMR', 'SOM', 'SPM', 'SRB', 'SSD', 'STP', 'SUR', 'SVK', 'SVN',
'SWE', 'SWZ', 'SXM', 'SYC', 'SYR', 'TCA', 'TCD', 'TGO', 'THA', 'TJK',
'TKL', 'TKM', 'TLS', 'TON', 'TTO', 'TUN', 'TUR', 'TUV', 'TWN', 'TZA',
'UGA', 'UKR', 'UMI', 'URY', 'USA', 'UZB', 'VAT', 'VCT', 'VEN', 'VGB',
'VIR', 'VNM', 'VUT', 'WLF', 'WSM', 'YEM', 'ZAF', 'ZMB', 'ZWE',
);

protected static $localeData = array(
'aa_DJ', 'aa_ER', 'aa_ET',
'af_NA', 'af_ZA', 'ak_GH',
'am_ET', 'ar_AE', 'ar_BH', 'ar_DZ',
'ar_EG', 'ar_IQ', 'ar_JO', 'ar_KW', 'ar_LB',
'ar_LY', 'ar_MA', 'ar_OM', 'ar_QA', 'ar_SA',
'ar_SD', 'ar_SY', 'ar_TN', 'ar_YE',
'as_IN', 'az_AZ', 'be_BY',
'bg_BG', 'bn_BD', 'bn_IN',
'bo_CN', 'bo_IN', 'bs_BA',
'byn_ER', 'ca_ES',
'cch_NG', 'cs_CZ',
'cy_GB', 'da_DK', 'de_AT',
'de_BE', 'de_CH', 'de_DE', 'de_LI', 'de_LU',
'dv_MV', 'dz_BT',
'ee_GH', 'ee_TG', 'el_CY', 'el_GR',
'en_AS', 'en_AU', 'en_BE', 'en_BW',
'en_BZ', 'en_CA', 'en_GB', 'en_GU', 'en_HK',
'en_IE', 'en_IN', 'en_JM', 'en_MH', 'en_MP',
'en_MT', 'en_NA', 'en_NZ', 'en_PH', 'en_PK',
'en_SG', 'en_TT', 'en_UM', 'en_US', 'en_VI',
'en_ZA', 'en_ZW', 'es_AR',
'es_BO', 'es_CL', 'es_CO', 'es_CR', 'es_DO',
'es_EC', 'es_ES', 'es_GT', 'es_HN', 'es_MX',
'es_NI', 'es_PA', 'es_PE', 'es_PR', 'es_PY',
'es_SV', 'es_US', 'es_UY', 'es_VE',
'et_EE', 'eu_ES', 'fa_AF',
'fa_IR', 'fi_FI', 'fil_PH',
'fo_FO', 'fr_BE', 'fr_CA',
'fr_CH', 'fr_FR', 'fr_LU', 'fr_MC', 'fr_SN',
'fur_IT', 'ga_IE',
'gaa_GH', 'gez_ER', 'gez_ET',
'gl_ES', 'gsw_CH', 'gu_IN',
'gv_GB', 'ha_GH', 'ha_NE',
'ha_NG', 'ha_SD', 'haw_US',
'he_IL', 'hi_IN', 'hr_HR',
'hu_HU', 'hy_AM',
'id_ID', 'ig_NG',
'ii_CN', 'is_IS',
'it_CH', 'it_IT',
'ja_JP', 'ka_GE', 'kaj_NG',
'kam_KE', 'kcg_NG',
'kfo_CI', 'kk_KZ', 'kl_GL',
'km_KH', 'kn_IN',
'ko_KR', 'kok_IN', 'kpe_GN',
'kpe_LR', 'ku_IQ', 'ku_IR', 'ku_SY',
'ku_TR', 'kw_GB', 'ky_KG',
'ln_CD', 'ln_CG', 'lo_LA',
'lt_LT', 'lv_LV',
'mk_MK', 'ml_IN', 'mn_CN',
'mn_MN', 'mr_IN',
'ms_BN', 'ms_MY', 'mt_MT',
'my_MM', 'nb_NO', 'nds_DE',
'ne_IN', 'ne_NP', 'nl_BE',
'nl_NL', 'nn_NO',
'nr_ZA', 'nso_ZA', 'ny_MW',
'oc_FR', 'om_ET', 'om_KE',
'or_IN', 'pa_IN', 'pa_PK',
'pl_PL', 'ps_AF',
'pt_BR', 'pt_PT', 'ro_MD', 'ro_RO',
'ru_RU', 'ru_UA', 'rw_RW',
'sa_IN', 'se_FI', 'se_NO',
'sh_BA', 'sh_CS', 'sh_YU',
'si_LK', 'sid_ET', 'sk_SK',
'sl_SI', 'so_DJ', 'so_ET',
'so_KE', 'so_SO', 'sq_AL',
'sr_BA', 'sr_CS', 'sr_ME', 'sr_RS', 'sr_YU',
'ss_SZ', 'ss_ZA', 'st_LS',
'st_ZA', 'sv_FI', 'sv_SE',
'sw_KE', 'sw_TZ', 'syr_SY',
'ta_IN', 'te_IN', 'tg_TJ',
'th_TH', 'ti_ER', 'ti_ET',
'tig_ER', 'tn_ZA',
'to_TO', 'tr_TR',
'trv_TW', 'ts_ZA', 'tt_RU',
'ug_CN', 'uk_UA',
'ur_IN', 'ur_PK', 'uz_AF', 'uz_UZ',
've_ZA', 'vi_VN',
'wal_ET', 'wo_SN', 'xh_ZA',
'yo_NG', 'zh_CN', 'zh_HK',
'zh_MO', 'zh_SG', 'zh_TW', 'zu_ZA',
);





protected static $currencyCode = array(
'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN',
'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL',
'BSD', 'BTN', 'BWP', 'BYN', 'BZD', 'CAD', 'CDF', 'CHF', 'CLP', 'CNY',
'COP', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD',
'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GHS', 'GIP',
'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR',
'ILS', 'INR', 'IQD', 'IRR', 'ISK', 'JMD', 'JOD', 'JPY', 'KES', 'KGS',
'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR',
'LRD', 'LSL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP',
'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO',
'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN',
'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG',
'SEK', 'SGD', 'SHP', 'SLL', 'SOS', 'SRD', 'SSP', 'STD', 'SVC', 'SYP',
'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TWD', 'TZS',
'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VEF', 'VND', 'VUV', 'WST', 'XAF',
'XCD', 'XOF', 'XPF', 'YER', 'ZAR', 'ZMW', 'ZWL',
);










public static function boolean($chanceOfGettingTrue = 50)
{
return mt_rand(1, 100) <= $chanceOfGettingTrue;
}




public static function md5()
{
return md5(mt_rand());
}




public static function sha1()
{
return sha1(mt_rand());
}




public static function sha256()
{
return hash('sha256', mt_rand());
}




public static function locale()
{
return static::randomElement(static::$localeData);
}






public static function countryCode()
{
return static::randomElement(static::$countryCode);
}






public static function countryISOAlpha3()
{
return static::randomElement(static::$countryISOAlpha3);
}




public static function languageCode()
{
return static::randomElement(static::$languageCode);
}






public static function currencyCode()
{
return static::randomElement(static::$currencyCode);
}






public static function emoji()
{
return json_decode('"' . static::randomElement(static::$emoji) . '"');
}
}
<?php

namespace Faker\Provider;

class Person extends Base
{
const GENDER_MALE = 'male';
const GENDER_FEMALE = 'female';

protected static $titleFormat = array(
'{{titleMale}}',
'{{titleFemale}}',
);

protected static $firstNameFormat = array(
'{{firstNameMale}}',
'{{firstNameFemale}}',
);

protected static $maleNameFormats = array(
'{{firstNameMale}} {{lastName}}',
);

protected static $femaleNameFormats = array(
'{{firstNameFemale}} {{lastName}}',
);

protected static $firstNameMale = array(
'John',
);

protected static $firstNameFemale = array(
'Jane',
);

protected static $lastName = array('Doe');

protected static $titleMale = array('Mr.', 'Dr.', 'Prof.');

protected static $titleFemale = array('Mrs.', 'Ms.', 'Miss', 'Dr.', 'Prof.');






public function name($gender = null)
{
if ($gender === static::GENDER_MALE) {
$format = static::randomElement(static::$maleNameFormats);
} elseif ($gender === static::GENDER_FEMALE) {
$format = static::randomElement(static::$femaleNameFormats);
} else {
$format = static::randomElement(array_merge(static::$maleNameFormats, static::$femaleNameFormats));
}

return $this->generator->parse($format);
}






public function firstName($gender = null)
{
if ($gender === static::GENDER_MALE) {
return static::firstNameMale();
} elseif ($gender === static::GENDER_FEMALE) {
return static::firstNameFemale();
}

return $this->generator->parse(static::randomElement(static::$firstNameFormat));
}

public static function firstNameMale()
{
return static::randomElement(static::$firstNameMale);
}

public static function firstNameFemale()
{
return static::randomElement(static::$firstNameFemale);
}





public function lastName()
{
return static::randomElement(static::$lastName);
}






public function title($gender = null)
{
if ($gender === static::GENDER_MALE) {
return static::titleMale();
} elseif ($gender === static::GENDER_FEMALE) {
return static::titleFemale();
}

return $this->generator->parse(static::randomElement(static::$titleFormat));
}




public static function titleMale()
{
return static::randomElement(static::$titleMale);
}




public static function titleFemale()
{
return static::randomElement(static::$titleFemale);
}
}
<?php

namespace Faker\Provider;

class UserAgent extends Base
{
protected static $userAgents = array('firefox', 'chrome', 'internetExplorer', 'opera', 'safari');

protected static $windowsPlatformTokens = array(
'Windows NT 6.2', 'Windows NT 6.1', 'Windows NT 6.0', 'Windows NT 5.2', 'Windows NT 5.1',
'Windows NT 5.01', 'Windows NT 5.0', 'Windows NT 4.0', 'Windows 98; Win 9x 4.90', 'Windows 98',
'Windows 95', 'Windows CE'
);




protected static $linuxProcessor = array('i686', 'x86_64');




protected static $macProcessor = array('Intel', 'PPC', 'U; Intel', 'U; PPC');




protected static $lang = array('en-US', 'sl-SI');






public static function macProcessor()
{
return static::randomElement(static::$macProcessor);
}






public static function linuxProcessor()
{
return static::randomElement(static::$linuxProcessor);
}






public static function userAgent()
{
$userAgentName = static::randomElement(static::$userAgents);

return static::$userAgentName();
}






public static function chrome()
{
$saf = mt_rand(531, 536) . mt_rand(0, 2);

$platforms = array(
'(' . static::linuxPlatformToken() . ") AppleWebKit/$saf (KHTML, like Gecko) Chrome/" . mt_rand(36, 40) . '.0.' . mt_rand(800, 899) . ".0 Mobile Safari/$saf",
'(' . static::windowsPlatformToken() . ") AppleWebKit/$saf (KHTML, like Gecko) Chrome/" . mt_rand(36, 40) . '.0.' . mt_rand(800, 899) . ".0 Mobile Safari/$saf",
'(' . static::macPlatformToken() . ") AppleWebKit/$saf (KHTML, like Gecko) Chrome/" . mt_rand(36, 40) . '.0.' . mt_rand(800, 899) . ".0 Mobile Safari/$saf"
);

return 'Mozilla/5.0 ' . static::randomElement($platforms);
}






public static function firefox()
{
$ver = 'Gecko/' . date('Ymd', mt_rand(strtotime('2010-1-1'), time())) . ' Firefox/' . mt_rand(35, 37) . '.0';

$platforms = array(
'(' . static::windowsPlatformToken() . '; ' . static::randomElement(static::$lang) . '; rv:1.9.' . mt_rand(0, 2) . '.20) ' . $ver,
'(' . static::linuxPlatformToken() . '; rv:' . mt_rand(5, 7) . '.0) ' . $ver,
'(' . static::macPlatformToken() . ' rv:' . mt_rand(2, 6) . '.0) ' . $ver
);

return "Mozilla/5.0 " . static::randomElement($platforms);
}






public static function safari()
{
$saf = mt_rand(531, 535) . '.' . mt_rand(1, 50) . '.' . mt_rand(1, 7);
if (mt_rand(0, 1) == 0) {
$ver = mt_rand(4, 5) . '.' . mt_rand(0, 1);
} else {
$ver = mt_rand(4, 5) . '.0.' . mt_rand(1, 5);
}

$mobileDevices = array(
'iPhone; CPU iPhone OS',
'iPad; CPU OS'
);

$platforms = array(
'(Windows; U; ' . static::windowsPlatformToken() . ") AppleWebKit/$saf (KHTML, like Gecko) Version/$ver Safari/$saf",
'(' . static::macPlatformToken() . ' rv:' . mt_rand(2, 6) . '.0; ' . static::randomElement(static::$lang) . ") AppleWebKit/$saf (KHTML, like Gecko) Version/$ver Safari/$saf",
'(' . static::randomElement($mobileDevices) . ' ' . mt_rand(7, 8) . '_' . mt_rand(0, 2) . '_' . mt_rand(1, 2) . ' like Mac OS X; ' . static::randomElement(static::$lang) . ") AppleWebKit/$saf (KHTML, like Gecko) Version/" . mt_rand(3, 4) . ".0.5 Mobile/8B" . mt_rand(111, 119) . " Safari/6$saf",
);

return "Mozilla/5.0 " . static::randomElement($platforms);
}






public static function opera()
{
$platforms = array(
'(' . static::linuxPlatformToken() . '; ' . static::randomElement(static::$lang) . ') Presto/2.' . mt_rand(8, 12) . '.' . mt_rand(160, 355) . ' Version/' . mt_rand(10, 12) . '.00',
'(' . static::windowsPlatformToken() . '; ' . static::randomElement(static::$lang) . ') Presto/2.' . mt_rand(8, 12) . '.' . mt_rand(160, 355) . ' Version/' . mt_rand(10, 12) . '.00'
);

return "Opera/" . mt_rand(8, 9) . '.' . mt_rand(10, 99) . ' ' . static::randomElement($platforms);
}






public static function internetExplorer()
{
return 'Mozilla/5.0 (compatible; MSIE ' . mt_rand(5, 11) . '.0; ' . static::windowsPlatformToken() . '; Trident/' . mt_rand(3, 5) . '.' . mt_rand(0, 1) . ')';
}

public static function windowsPlatformToken()
{
return static::randomElement(static::$windowsPlatformTokens);
}

public static function macPlatformToken()
{
return 'Macintosh; ' . static::randomElement(static::$macProcessor) . ' Mac OS X 10_' . mt_rand(5, 8) . '_' . mt_rand(0, 9);
}

public static function linuxPlatformToken()
{
return 'X11; Linux ' . static::randomElement(static::$linuxProcessor);
}
}
<?php

namespace Faker\Provider;

class Biased extends Base
{















public function biasedNumberBetween($min = 0, $max = 100, $function = 'sqrt')
{
do {
$x = mt_rand() / mt_getrandmax();
$y = mt_rand() / (mt_getrandmax() + 1);
} while (call_user_func($function, $x) < $y);

return floor($x * ($max - $min + 1) + $min);
}







protected static function unbiased()
{
return 1;
}







protected static function linearLow($x)
{
return 1 - $x;
}







protected static function linearHigh($x)
{
return $x;
}
}
<?php

namespace Faker\Provider;

class Company extends Base
{
protected static $formats = array(
'{{lastName}} {{companySuffix}}',
);

protected static $companySuffix = array('Ltd');

protected static $jobTitleFormat = array(
'{{word}}',
);




public function company()
{
$format = static::randomElement(static::$formats);

return $this->generator->parse($format);
}




public static function companySuffix()
{
return static::randomElement(static::$companySuffix);
}




public function jobTitle()
{
$format = static::randomElement(static::$jobTitleFormat);

return $this->generator->parse($format);
}
}
<?php

namespace Faker\Provider\en_US;

class Person extends \Faker\Provider\Person
{
protected static $maleNameFormats = array(
'{{firstNameMale}} {{lastName}}',
'{{firstNameMale}} {{lastName}}',
'{{firstNameMale}} {{lastName}}',
'{{firstNameMale}} {{lastName}}',
'{{titleMale}} {{firstNameMale}} {{lastName}}',
'{{firstNameMale}} {{lastName}} {{suffix}}',
'{{titleMale}} {{firstNameMale}} {{lastName}} {{suffix}}',
);

protected static $femaleNameFormats = array(
'{{firstNameFemale}} {{lastName}}',
'{{firstNameFemale}} {{lastName}}',
'{{firstNameFemale}} {{lastName}}',
'{{firstNameFemale}} {{lastName}}',
'{{titleFemale}} {{firstNameFemale}} {{lastName}}',
'{{firstNameFemale}} {{lastName}} {{suffix}}',
'{{titleFemale}} {{firstNameFemale}} {{lastName}} {{suffix}}',
);

protected static $firstNameMale = array(
'Aaron', 'Abdiel', 'Abdul', 'Abdullah', 'Abe', 'Abel', 'Abelardo', 'Abner', 'Abraham', 'Adalberto', 'Adam', 'Adan', 'Adelbert', 'Adolf', 'Adolfo', 'Adolph', 'Adolphus', 'Adonis', 'Adrain', 'Adrian', 'Adriel', 'Adrien', 'Afton', 'Agustin', 'Ahmad', 'Ahmed', 'Aidan', 'Aiden', 'Akeem', 'Al', 'Alan', 'Albert', 'Alberto', 'Albin', 'Alden', 'Alec', 'Alejandrin', 'Alek', 'Alessandro', 'Alex', 'Alexander', 'Alexandre', 'Alexandro', 'Alexie', 'Alexis', 'Alexys', 'Alexzander', 'Alf', 'Alfonso', 'Alfonzo', 'Alford', 'Alfred', 'Alfredo', 'Ali', 'Allan', 'Allen', 'Alphonso', 'Alvah', 'Alvis', 'Amani', 'Amari', 'Ambrose', 'Americo', 'Amir', 'Amos', 'Amparo', 'Anastacio', 'Anderson', 'Andre', 'Andres', 'Andrew', 'Andy', 'Angel', 'Angelo', 'Angus', 'Anibal', 'Ansel', 'Ansley', 'Anthony', 'Antone', 'Antonio', 'Antwan', 'Antwon', 'Arch', 'Archibald', 'Arden', 'Arely', 'Ari', 'Aric', 'Ariel', 'Arjun', 'Arlo', 'Armand', 'Armando', 'Armani', 'Arnaldo', 'Arne', 'Arno', 'Arnold', 'Arnoldo', 'Arnulfo', 'Aron', 'Art', 'Arthur', 'Arturo', 'Arvel', 'Arvid', 'Ashton', 'August', 'Augustus', 'Aurelio', 'Austen', 'Austin', 'Austyn', 'Avery', 'Axel', 'Ayden',
'Bailey', 'Barney', 'Baron', 'Barrett', 'Barry', 'Bart', 'Bartholome', 'Barton', 'Baylee', 'Beau', 'Bell', 'Ben', 'Benedict', 'Benjamin', 'Bennett', 'Bennie', 'Benny', 'Benton', 'Bernard', 'Bernardo', 'Bernhard', 'Bernie', 'Berry', 'Berta', 'Bertha', 'Bertram', 'Bertrand', 'Bill', 'Billy', 'Blair', 'Blaise', 'Blake', 'Blaze', 'Bo', 'Bobbie', 'Bobby', 'Boris', 'Boyd', 'Brad', 'Braden', 'Bradford', 'Bradley', 'Bradly', 'Brady', 'Braeden', 'Brain', 'Brando', 'Brandon', 'Brandt', 'Brannon', 'Branson', 'Brant', 'Braulio', 'Braxton', 'Brayan', 'Brendan', 'Brenden', 'Brendon', 'Brennan', 'Brennon', 'Brent', 'Bret', 'Brett', 'Brian', 'Brice', 'Brock', 'Broderick', 'Brody', 'Brook', 'Brooks', 'Brown', 'Bruce', 'Bryce', 'Brycen', 'Bryon', 'Buck', 'Bud', 'Buddy', 'Buford', 'Burley', 'Buster',
'Cade', 'Caden', 'Caesar', 'Cale', 'Caleb', 'Camden', 'Cameron', 'Camren', 'Camron', 'Camryn', 'Candelario', 'Candido', 'Carey', 'Carleton', 'Carlo', 'Carlos', 'Carmel', 'Carmelo', 'Carmine', 'Carol', 'Carroll', 'Carson', 'Carter', 'Cary', 'Casey', 'Casimer', 'Casimir', 'Casper', 'Ceasar', 'Cecil', 'Cedrick', 'Celestino', 'Cesar', 'Chad', 'Chadd', 'Chadrick', 'Chaim', 'Chance', 'Chandler', 'Charles', 'Charley', 'Charlie', 'Chase', 'Chauncey', 'Chaz', 'Chelsey', 'Chesley', 'Chester', 'Chet', 'Chris', 'Christ', 'Christian', 'Christop', 'Christophe', 'Christopher', 'Cicero', 'Cielo', 'Clair', 'Clark', 'Claud', 'Claude', 'Clay', 'Clemens', 'Clement', 'Cleo', 'Cletus', 'Cleve', 'Cleveland', 'Clifford', 'Clifton', 'Clint', 'Clinton', 'Clovis', 'Cloyd', 'Clyde', 'Coby', 'Cody', 'Colby', 'Cole', 'Coleman', 'Colin', 'Collin', 'Colt', 'Colten', 'Colton', 'Columbus', 'Conner', 'Connor', 'Conor', 'Conrad', 'Constantin', 'Consuelo', 'Cooper', 'Corbin', 'Cordelia', 'Cordell', 'Cornelius', 'Cornell', 'Cortez', 'Cory', 'Coty', 'Coy', 'Craig', 'Crawford', 'Cristian', 'Cristina', 'Cristobal', 'Cristopher', 'Cruz', 'Cullen', 'Curt', 'Curtis', 'Cyril', 'Cyrus',
'Dagmar', 'Dale', 'Dallas', 'Dallin', 'Dalton', 'Dameon', 'Damian', 'Damien', 'Damion', 'Damon', 'Dan', 'Dane', 'D\'angelo', 'Dangelo', 'Danial', 'Danny', 'Dante', 'Daren', 'Darian', 'Darien', 'Dario', 'Darion', 'Darius', 'Daron', 'Darrel', 'Darrell', 'Darren', 'Darrick', 'Darrin', 'Darrion', 'Darron', 'Darryl', 'Darwin', 'Daryl', 'Dashawn', 'Dave', 'David', 'Davin', 'Davion', 'Davon', 'Davonte', 'Dawson', 'Dax', 'Dayne', 'Dayton', 'Dean', 'Deangelo', 'Declan', 'Dedric', 'Dedrick', 'Dee', 'Deion', 'Dejon', 'Dejuan', 'Delaney', 'Delbert', 'Dell','Delmer', 'Demarco', 'Demarcus', 'Demario', 'Demetrius', 'Demond', 'Denis', 'Dennis', 'Deon', 'Deondre', 'Deontae', 'Deonte', 'Dereck', 'Derek', 'Derick', 'Deron', 'Derrick', 'Deshaun', 'Deshawn', 'Desmond', 'Destin', 'Devan', 'Devante', 'Deven', 'Devin', 'Devon', 'Devonte', 'Devyn', 'Dewayne', 'Dewitt', 'Dexter', 'Diamond', 'Diego', 'Dillan', 'Dillon', 'Dimitri', 'Dino', 'Dion', 'Dock','Domenic', 'Domenick', 'Domenico', 'Domingo', 'Dominic', 'Don', 'Donald', 'Donato', 'Donavon', 'Donnell', 'Donnie', 'Donny', 'Dorcas', 'Dorian', 'Doris', 'Dorthy', 'Doug', 'Douglas', 'Doyle', 'Drake', 'Dudley', 'Duncan', 'Durward', 'Dustin', 'Dusty', 'Dwight', 'Dylan',
'Earl', 'Earnest', 'Easter', 'Easton', 'Ed', 'Edd', 'Eddie', 'Edgar', 'Edgardo', 'Edison', 'Edmond', 'Edmund', 'Eduardo', 'Edward', 'Edwardo', 'Edwin', 'Efrain', 'Efren', 'Einar', 'Eino', 'Eladio', 'Elbert', 'Eldon', 'Eldred', 'Eleazar', 'Eli', 'Elian', 'Elias', 'Eliezer', 'Elijah', 'Eliseo', 'Elliot', 'Elliott', 'Ellis', 'Ellsworth', 'Elmer', 'Elmo', 'Elmore', 'Eloy', 'Elroy', 'Elton', 'Elvis', 'Elwin', 'Elwyn', 'Emanuel', 'Emerald', 'Emerson', 'Emery', 'Emil', 'Emile', 'Emiliano', 'Emilio', 'Emmanuel', 'Emmet', 'Emmett', 'Emmitt', 'Emory', 'Enid', 'Enoch', 'Enos', 'Enrico', 'Enrique', 'Ephraim', 'Eriberto', 'Eric', 'Erich', 'Erick', 'Erik', 'Erin', 'Erling', 'Ernest', 'Ernesto', 'Ernie', 'Ervin', 'Erwin', 'Esteban', 'Estevan', 'Ethan', 'Ethel', 'Eugene', 'Eusebio', 'Evan', 'Evans', 'Everardo', 'Everett', 'Evert', 'Ewald', 'Ewell', 'Ezekiel', 'Ezequiel', 'Ezra',
'Fabian', 'Faustino', 'Fausto', 'Favian', 'Federico', 'Felipe', 'Felix', 'Felton', 'Fermin', 'Fern', 'Fernando', 'Ferne', 'Fidel', 'Filiberto', 'Finn', 'Flavio','Fletcher', 'Florencio', 'Florian', 'Floy', 'Floyd', 'Ford', 'Forest', 'Forrest', 'Foster', 'Francesco', 'Francis', 'Francisco', 'Franco', 'Frank', 'Frankie', 'Franz', 'Fred', 'Freddie', 'Freddy', 'Frederic', 'Frederick', 'Frederik', 'Fredrick', 'Fredy', 'Freeman', 'Friedrich', 'Fritz', 'Furman',
'Gabe', 'Gabriel', 'Gaetano', 'Gage', 'Gardner', 'Garett', 'Garfield', 'Garland', 'Garnet', 'Garnett', 'Garret', 'Garrett', 'Garrick', 'Garrison', 'Garry', 'Garth', 'Gaston', 'Gavin', 'Gay', 'Gayle', 'Gaylord', 'Gene', 'General', 'Gennaro', 'Geo', 'Geoffrey', 'George', 'Geovanni', 'Geovanny', 'Geovany', 'Gerald', 'Gerard', 'Gerardo', 'Gerhard', 'German', 'Gerson', 'Gianni', 'Gideon', 'Gilbert', 'Gilberto', 'Giles', 'Gillian', 'Gino', 'Giovani', 'Giovanni', 'Giovanny','Giuseppe', 'Glen', 'Glennie', 'Godfrey', 'Golden', 'Gonzalo', 'Gordon', 'Grady', 'Graham', 'Grant', 'Granville', 'Grayce', 'Grayson', 'Green', 'Greg', 'Gregg', 'Gregorio', 'Gregory', 'Greyson', 'Griffin', 'Grover', 'Guido', 'Guillermo', 'Guiseppe', 'Gunnar', 'Gunner', 'Gus', 'Gussie', 'Gust', 'Gustave', 'Guy',
'Hadley', 'Hailey', 'Hal', 'Haleigh', 'Haley', 'Halle', 'Hank', 'Hans', 'Hardy', 'Harley', 'Harmon', 'Harold', 'Harrison', 'Harry', 'Harvey', 'Haskell', 'Hassan', 'Hayden', 'Hayley', 'Hazel', 'Hazle', 'Heber', 'Hector', 'Helmer', 'Henderson', 'Henri', 'Henry', 'Herbert', 'Herman', 'Hermann', 'Herminio', 'Hershel', 'Hester', 'Hilario', 'Hilbert', 'Hillard', 'Hilton', 'Hipolito', 'Hiram', 'Hobart', 'Holden', 'Hollis', 'Horace', 'Horacio', 'Houston', 'Howard', 'Howell', 'Hoyt', 'Hubert', 'Hudson', 'Hugh', 'Humberto', 'Hunter', 'Hyman',
'Ian', 'Ibrahim', 'Ignacio', 'Ignatius', 'Ike', 'Imani', 'Immanuel', 'Irving', 'Irwin', 'Isaac', 'Isac', 'Isadore', 'Isai', 'Isaiah', 'Isaias', 'Isidro', 'Ismael', 'Isom', 'Israel', 'Issac', 'Izaiah',
'Jabari', 'Jace', 'Jacey', 'Jacinto', 'Jack', 'Jackson', 'Jacques', 'Jaden', 'Jadon', 'Jaeden', 'Jaiden', 'Jaime', 'Jairo', 'Jake', 'Jakob', 'Jaleel', 'Jalen', 'Jalon', 'Jamaal', 'Jamal', 'Jamar', 'Jamarcus', 'Jamel', 'Jameson', 'Jamey', 'Jamie', 'Jamil', 'Jamir', 'Jamison', 'Jan', 'Janick', 'Jaquan', 'Jared', 'Jaren', 'Jarod', 'Jaron', 'Jarred', 'Jarrell', 'Jarret', 'Jarrett', 'Jarrod', 'Jarvis', 'Jasen', 'Jasmin', 'Jason', 'Jasper', 'Javier', 'Javon', 'Javonte', 'Jay', 'Jayce', 'Jaycee', 'Jayde', 'Jayden', 'Jaydon', 'Jaylan', 'Jaylen', 'Jaylin', 'Jaylon', 'Jayme', 'Jayson', 'Jean', 'Jed', 'Jedediah', 'Jedidiah', 'Jeff', 'Jefferey', 'Jeffery', 'Jeffrey', 'Jeffry', 'Jennings', 'Jensen', 'Jerad', 'Jerald', 'Jeramie', 'Jeramy', 'Jerel', 'Jeremie', 'Jeremy', 'Jermain', 'Jermey', 'Jerod', 'Jerome', 'Jeromy', 'Jerrell', 'Jerrod', 'Jerrold', 'Jerry', 'Jess', 'Jesse', 'Jessie', 'Jessy', 'Jesus', 'Jett', 'Jettie', 'Jevon', 'Jillian', 'Jimmie', 'Jimmy', 'Jo', 'Joan', 'Joany', 'Joaquin', 'Jocelyn', 'Joe', 'Joel', 'Joesph', 'Joey', 'Johan', 'Johann', 'Johathan', 'John', 'Johnathan', 'Johnathon', 'Johnnie', 'Johnny', 'Johnpaul', 'Johnson', 'Jon', 'Jonas', 'Jonatan', 'Jonathan', 'Jonathon', 'Jordan', 'Jordi', 'Jordon', 'Jordy', 'Jordyn', 'Jorge', 'Jose', 'Joseph', 'Josh', 'Joshua', 'Joshuah', 'Josiah', 'Josue', 'Jovan', 'Jovani', 'Jovanny', 'Jovany', 'Judah', 'Judd', 'Judge', 'Judson', 'Jules', 'Julian', 'Julien', 'Julio', 'Julius', 'Junior', 'Junius', 'Justen', 'Justice', 'Juston', 'Justus', 'Justyn', 'Juvenal', 'Juwan',
'Kacey', 'Kade', 'Kaden', 'Kadin', 'Kale', 'Kaleb', 'Kaleigh', 'Kaley', 'Kameron', 'Kamren', 'Kamron', 'Kamryn', 'Kane', 'Kareem', 'Karl', 'Karley', 'Karson', 'Kay', 'Kayden', 'Kayleigh', 'Kayley', 'Keagan', 'Keanu', 'Keaton', 'Keegan', 'Keeley', 'Keenan', 'Keith', 'Kellen', 'Kelley', 'Kelton', 'Kelvin', 'Ken', 'Kendall', 'Kendrick', 'Kennedi', 'Kennedy', 'Kenneth', 'Kennith', 'Kenny', 'Kenton', 'Kenyon', 'Keon', 'Keshaun', 'Keshawn', 'Keven', 'Kevin', 'Kevon', 'Keyon', 'Keyshawn', 'Khalid', 'Khalil', 'Kian', 'Kiel', 'Kieran', 'Kiley', 'Kim', 'King', 'Kip', 'Kirk', 'Kobe', 'Koby', 'Kody', 'Kolby', 'Kole', 'Korbin', 'Korey', 'Kory', 'Kraig', 'Kris', 'Kristian', 'Kristofer', 'Kristoffer', 'Kristopher', 'Kurt', 'Kurtis', 'Kyle', 'Kyleigh', 'Kyler',
'Ladarius', 'Lafayette', 'Lamar', 'Lambert', 'Lamont', 'Lance', 'Landen', 'Lane', 'Laron', 'Larry', 'Larue', 'Laurel', 'Lavern', 'Laverna', 'Laverne', 'Lavon', 'Lawrence', 'Lawson', 'Layne', 'Lazaro', 'Lee', 'Leif', 'Leland', 'Lemuel', 'Lennie', 'Lenny', 'Leo', 'Leon', 'Leonard', 'Leonardo', 'Leone', 'Leonel', 'Leopold', 'Leopoldo', 'Lesley', 'Lester', 'Levi', 'Lew', 'Lewis', 'Lexus', 'Liam', 'Lincoln', 'Lindsey', 'Linwood', 'Lionel', 'Lisandro', 'Llewellyn', 'Lloyd', 'Logan', 'Lon', 'London', 'Lonnie', 'Lonny', 'Lonzo', 'Lorenz', 'Lorenza', 'Lorenzo', 'Louie', 'Louisa', 'Lourdes', 'Louvenia', 'Lowell', 'Loy', 'Loyal', 'Lucas', 'Luciano', 'Lucio', 'Lucious', 'Lucius', 'Ludwig', 'Luigi', 'Luis', 'Lukas', 'Lula', 'Luther', 'Lyric',
'Mac', 'Macey', 'Mack', 'Mackenzie', 'Madisen', 'Madison', 'Madyson', 'Magnus', 'Major', 'Makenna', 'Malachi', 'Malcolm', 'Mallory', 'Manley', 'Manuel', 'Manuela', 'Marc', 'Marcel', 'Marcelino', 'Marcellus', 'Marcelo', 'Marco', 'Marcos', 'Marcus', 'Mariano', 'Mario', 'Mark', 'Markus', 'Marley', 'Marlin', 'Marlon', 'Marques', 'Marquis', 'Marshall', 'Martin', 'Marty', 'Marvin', 'Mason', 'Mateo', 'Mathew', 'Mathias', 'Matt', 'Matteo', 'Maurice', 'Mauricio', 'Maverick', 'Mavis', 'Max', 'Maxime', 'Maximilian', 'Maximillian', 'Maximo', 'Maximus', 'Maxine', 'Maxwell', 'Maynard', 'Mckenna', 'Mckenzie', 'Mekhi', 'Melany', 'Melvin', 'Melvina', 'Merl', 'Merle', 'Merlin', 'Merritt', 'Mervin', 'Micah', 'Michael', 'Michale', 'Micheal', 'Michel', 'Miguel', 'Mike', 'Mikel', 'Milan', 'Miles', 'Milford', 'Miller', 'Milo', 'Milton', 'Misael', 'Mitchel', 'Mitchell', 'Modesto', 'Mohamed', 'Mohammad', 'Mohammed', 'Moises', 'Monroe', 'Monserrat', 'Monserrate', 'Montana', 'Monte', 'Monty', 'Morgan', 'Moriah', 'Morris', 'Mortimer', 'Morton', 'Mose', 'Moses', 'Moshe', 'Muhammad', 'Murl', 'Murphy', 'Murray', 'Mustafa', 'Myles', 'Myrl', 'Myron',
'Napoleon', 'Narciso', 'Nash', 'Nasir', 'Nat', 'Nathan', 'Nathanael', 'Nathanial', 'Nathaniel', 'Nathen', 'Neal', 'Ned', 'Neil', 'Nels', 'Nelson', 'Nestor', 'Newell', 'Newton', 'Nicholas', 'Nicholaus', 'Nick', 'Nicklaus', 'Nickolas', 'Nico', 'Nicola', 'Nicolas', 'Nigel', 'Nikko', 'Niko', 'Nikolas', 'Nils', 'Noah', 'Noble', 'Noe', 'Noel', 'Nolan', 'Norbert', 'Norberto', 'Norris', 'Norval', 'Norwood',
'Obie', 'Oda', 'Odell', 'Okey', 'Ola', 'Olaf', 'Ole', 'Olen', 'Olin', 'Oliver', 'Omari', 'Omer', 'Oral', 'Oran', 'Oren', 'Orin', 'Orion', 'Orland', 'Orlando', 'Orlo', 'Orrin', 'Orval', 'Orville', 'Osbaldo', 'Osborne', 'Oscar', 'Osvaldo', 'Oswald', 'Oswaldo', 'Otho', 'Otis', 'Ottis', 'Otto', 'Owen',
'Pablo', 'Paolo', 'Paris', 'Parker', 'Patrick', 'Paul', 'Paxton', 'Payton', 'Pedro', 'Percival', 'Percy', 'Perry', 'Pete', 'Peter', 'Peyton', 'Philip', 'Pierce', 'Pierre', 'Pietro', 'Porter', 'Presley', 'Preston', 'Price', 'Prince',
'Quentin', 'Quincy', 'Quinn', 'Quinten', 'Quinton',
'Rafael', 'Raheem', 'Rahul', 'Raleigh', 'Ralph', 'Ramiro', 'Ramon', 'Randal', 'Randall', 'Randi', 'Randy', 'Ransom', 'Raoul', 'Raphael', 'Rashad', 'Rashawn', 'Rasheed', 'Raul', 'Raven', 'Ray', 'Raymond', 'Raymundo', 'Reagan', 'Reece', 'Reed', 'Reese', 'Regan', 'Reggie', 'Reginald', 'Reid', 'Reilly','Reinhold', 'Remington', 'Rene', 'Reuben', 'Rex', 'Rey', 'Reyes', 'Reymundo', 'Reynold', 'Rhett', 'Rhiannon', 'Ricardo', 'Richard', 'Richie', 'Richmond', 'Rick', 'Rickey', 'Rickie', 'Ricky', 'Rico', 'Rigoberto', 'Riley', 'Robb', 'Robbie', 'Robert', 'Roberto', 'Robin', 'Rocio', 'Rocky', 'Rod', 'Roderick', 'Rodger', 'Rodolfo', 'Rodrick', 'Rodrigo', 'Roel', 'Rogelio', 'Roger', 'Rogers', 'Rolando', 'Rollin', 'Roman', 'Ron', 'Ronaldo', 'Ronny', 'Roosevelt', 'Rory', 'Rosario', 'Roscoe', 'Rosendo', 'Ross', 'Rowan', 'Rowland', 'Roy', 'Royal', 'Royce', 'Ruben', 'Rudolph', 'Rudy', 'Rupert', 'Russ', 'Russel', 'Russell', 'Rusty', 'Ryan', 'Ryann', 'Ryder', 'Rylan', 'Ryleigh', 'Ryley',
'Sage', 'Saige', 'Salvador', 'Salvatore', 'Sam', 'Samir', 'Sammie', 'Sammy', 'Samson', 'Sanford', 'Santa', 'Santiago', 'Santino', 'Santos', 'Saul', 'Savion', 'Schuyler', 'Scot', 'Scottie', 'Scotty', 'Seamus', 'Sean', 'Sebastian', 'Sedrick', 'Selmer', 'Seth', 'Shad', 'Shane', 'Shaun', 'Shawn', 'Shayne', 'Sheldon', 'Sheridan', 'Sherman', 'Sherwood', 'Sid', 'Sidney', 'Sigmund', 'Sigrid', 'Sigurd', 'Silas', 'Sim', 'Simeon', 'Skye', 'Skylar', 'Sofia', 'Soledad', 'Solon', 'Sonny', 'Spencer', 'Stan', 'Stanford', 'Stanley', 'Stanton', 'Stefan', 'Stephan', 'Stephen', 'Stephon', 'Sterling', 'Steve', 'Stevie', 'Stewart', 'Stone', 'Stuart', 'Sven', 'Sydney', 'Sylvan', 'Sylvester',
'Tad', 'Talon', 'Tanner', 'Tate', 'Tatum', 'Taurean', 'Tavares', 'Taylor', 'Ted', 'Terence', 'Terrance', 'Terrell', 'Terrence', 'Terrill', 'Terry', 'Tevin', 'Thad', 'Thaddeus', 'Theo', 'Theodore', 'Theron', 'Thomas', 'Thurman', 'Tillman', 'Timmothy', 'Timmy', 'Timothy', 'Tito', 'Titus', 'Tobin', 'Toby', 'Tod', 'Tom', 'Tomas', 'Tommie', 'Toney', 'Toni', 'Tony', 'Torey', 'Torrance', 'Torrey', 'Toy', 'Trace', 'Tracey', 'Travis', 'Travon', 'Tre', 'Tremaine', 'Tremayne', 'Trent', 'Trenton', 'Trever', 'Trevion', 'Trevor', 'Trey', 'Tristian', 'Tristin', 'Triston', 'Troy', 'Trystan', 'Turner','Tyler', 'Tyree', 'Tyreek', 'Tyrel', 'Tyrell', 'Tyrese', 'Tyrique', 'Tyshawn', 'Tyson',
'Ubaldo', 'Ulices', 'Ulises', 'Unique', 'Urban', 'Uriah', 'Uriel',
'Valentin', 'Van', 'Vance', 'Vaughn', 'Vern', 'Verner', 'Vernon', 'Vicente', 'Victor', 'Vidal', 'Vince', 'Vincent', 'Vincenzo', 'Vinnie', 'Virgil', 'Vito', 'Vladimir',
'Wade', 'Waino', 'Waldo', 'Walker', 'Wallace', 'Walter', 'Walton', 'Ward', 'Warren', 'Watson', 'Waylon', 'Wayne', 'Webster', 'Weldon', 'Wellington', 'Wendell', 'Werner', 'Westley', 'Weston', 'Wilber', 'Wilbert', 'Wilburn', 'Wiley', 'Wilford', 'Wilfred', 'Wilfredo', 'Wilfrid', 'Wilhelm', 'Will', 'Willard', 'William', 'Willis', 'Willy', 'Wilmer', 'Wilson', 'Wilton', 'Winfield', 'Winston', 'Woodrow', 'Wyatt', 'Wyman',
'Xavier', 'Xzavier', 'Xander',
'Zachariah', 'Zachary', 'Zachery', 'Zack', 'Zackary', 'Zackery', 'Zakary', 'Zander', 'Zane', 'Zechariah', 'Zion',
);

protected static $firstNameFemale = array(
'Aaliyah', 'Abagail', 'Abbey', 'Abbie', 'Abbigail', 'Abby', 'Abigail', 'Abigale', 'Abigayle', 'Ada', 'Adah', 'Adaline', 'Addie', 'Addison', 'Adela', 'Adele', 'Adelia', 'Adeline', 'Adell', 'Adella', 'Adelle', 'Aditya', 'Adriana', 'Adrianna', 'Adrienne', 'Aglae', 'Agnes', 'Agustina', 'Aida', 'Aileen', 'Aimee', 'Aisha', 'Aiyana', 'Alaina', 'Alana', 'Alanis', 'Alanna', 'Alayna', 'Alba', 'Alberta', 'Albertha', 'Albina', 'Alda', 'Aleen', 'Alejandra', 'Alena', 'Alene', 'Alessandra', 'Alessia', 'Aletha', 'Alexa', 'Alexandra', 'Alexandrea', 'Alexandria', 'Alexandrine', 'Alexane', 'Alexanne', 'Alfreda', 'Alia', 'Alice', 'Alicia', 'Alisa', 'Alisha', 'Alison', 'Alivia', 'Aliya', 'Aliyah', 'Aliza', 'Alize', 'Allene', 'Allie', 'Allison', 'Ally', 'Alta', 'Althea', 'Alva', 'Alvena', 'Alvera', 'Alverta', 'Alvina', 'Alyce', 'Alycia', 'Alysa', 'Alysha', 'Alyson', 'Alysson', 'Amalia', 'Amanda', 'Amara', 'Amaya', 'Amber', 'Amelia', 'Amelie', 'Amely', 'America', 'Amie', 'Amina', 'Amira', 'Amiya', 'Amy', 'Amya', 'Ana', 'Anabel', 'Anabelle', 'Anahi', 'Anais', 'Anastasia', 'Andreane', 'Andreanne', 'Angela', 'Angelica', 'Angelina', 'Angeline', 'Angelita', 'Angie', 'Anika', 'Anissa', 'Anita', 'Aniya', 'Aniyah', 'Anjali', 'Anna', 'Annabel', 'Annabell', 'Annabelle', 'Annalise', 'Annamae', 'Annamarie', 'Anne', 'Annetta', 'Annette', 'Annie', 'Antoinette', 'Antonetta', 'Antonette', 'Antonia', 'Antonietta', 'Antonina', 'Anya', 'April', 'Ara', 'Araceli', 'Aracely', 'Ardella', 'Ardith', 'Ariane', 'Arianna', 'Arielle', 'Arlene', 'Arlie', 'Arvilla', 'Aryanna', 'Asa', 'Asha', 'Ashlee', 'Ashleigh', 'Ashley', 'Ashly', 'Ashlynn', 'Ashtyn', 'Asia', 'Assunta', 'Astrid', 'Athena', 'Aubree', 'Aubrey', 'Audie', 'Audra', 'Audreanne', 'Audrey', 'Augusta', 'Augustine', 'Aurelia', 'Aurelie', 'Aurore', 'Autumn', 'Ava', 'Avis', 'Ayana', 'Ayla', 'Aylin',
'Baby', 'Bailee', 'Barbara', 'Beatrice', 'Beaulah', 'Bella', 'Belle', 'Berenice', 'Bernadette', 'Bernadine', 'Berneice', 'Bernice', 'Berniece', 'Bernita', 'Bert', 'Beryl', 'Bessie', 'Beth', 'Bethany', 'Bethel', 'Betsy', 'Bette', 'Bettie', 'Betty', 'Bettye', 'Beulah', 'Beverly', 'Bianka', 'Billie', 'Birdie', 'Blanca', 'Blanche', 'Bonita', 'Bonnie', 'Brandi', 'Brandy', 'Brandyn', 'Breana', 'Breanna', 'Breanne', 'Brenda', 'Brenna', 'Bria', 'Briana', 'Brianne', 'Bridget', 'Bridgette', 'Bridie', 'Brielle', 'Brigitte', 'Brionna', 'Brisa', 'Britney', 'Brittany', 'Brooke', 'Brooklyn', 'Bryana', 'Bulah', 'Burdette', 'Burnice',
'Caitlyn', 'Caleigh', 'Cali', 'Calista', 'Callie', 'Camila', 'Camilla', 'Camille', 'Camylle', 'Candace', 'Candice', 'Candida', 'Cara', 'Carissa', 'Carlee', 'Carley', 'Carli', 'Carlie', 'Carlotta', 'Carmela', 'Carmella', 'Carmen', 'Carolanne', 'Carole', 'Carolina', 'Caroline', 'Carolyn', 'Carolyne', 'Carrie', 'Casandra', 'Cassandra', 'Cassandre', 'Cassidy', 'Cassie', 'Catalina', 'Caterina', 'Catharine', 'Catherine', 'Cathrine', 'Cathryn', 'Cathy', 'Cayla', 'Cecelia', 'Cecile', 'Cecilia', 'Celestine', 'Celia', 'Celine', 'Chanel', 'Chanelle', 'Charity', 'Charlene', 'Charlotte', 'Chasity', 'Chaya', 'Chelsea', 'Chelsie', 'Cheyanne', 'Cheyenne', 'Chloe', 'Christa', 'Christelle', 'Christiana', 'Christina', 'Christine', 'Christy', 'Chyna', 'Ciara', 'Cierra', 'Cindy', 'Citlalli', 'Claire', 'Clara', 'Clarabelle', 'Clare', 'Clarissa', 'Claudia', 'Claudie', 'Claudine', 'Clementina', 'Clementine', 'Clemmie', 'Cleora', 'Cleta', 'Clotilde', 'Colleen', 'Concepcion', 'Connie', 'Constance', 'Cora', 'Coralie', 'Cordia', 'Cordie', 'Corene', 'Corine', 'Corrine', 'Cortney', 'Courtney', 'Creola', 'Cristal', 'Crystal', 'Crystel', 'Cydney', 'Cynthia',
'Dahlia', 'Daija', 'Daisha', 'Daisy', 'Dakota', 'Damaris', 'Dana', 'Dandre', 'Daniela', 'Daniella', 'Danielle', 'Danika', 'Dannie', 'Danyka', 'Daphne', 'Daphnee', 'Daphney', 'Darby', 'Dariana', 'Darlene', 'Dasia', 'Dawn', 'Dayana', 'Dayna', 'Deanna', 'Deborah', 'Deja', 'Dejah', 'Delfina', 'Delia', 'Delilah', 'Della', 'Delores', 'Delpha', 'Delphia', 'Delphine', 'Delta', 'Demetris', 'Dena', 'Desiree', 'Dessie', 'Destany', 'Destinee', 'Destiney', 'Destini', 'Destiny', 'Diana', 'Dianna', 'Dina', 'Dixie', 'Dolly', 'Dolores', 'Domenica', 'Dominique', 'Donna', 'Dora', 'Dorothea', 'Dorothy', 'Dorris', 'Dortha', 'Dovie', 'Drew', 'Duane', 'Dulce',
'Earlene', 'Earline', 'Earnestine', 'Ebba', 'Ebony', 'Eda', 'Eden', 'Edna', 'Edwina', 'Edyth', 'Edythe', 'Effie', 'Eileen', 'Elaina', 'Elda', 'Eldora', 'Eldridge', 'Eleanora', 'Eleanore', 'Electa', 'Elena', 'Elenor', 'Elenora', 'Eleonore', 'Elfrieda', 'Eliane', 'Elinor', 'Elinore', 'Elisa', 'Elisabeth', 'Elise', 'Elisha', 'Elissa', 'Eliza', 'Elizabeth', 'Ella', 'Ellen', 'Ellie', 'Elmira', 'Elna', 'Elnora', 'Elody', 'Eloisa', 'Eloise', 'Elouise', 'Elsa', 'Else', 'Elsie', 'Elta', 'Elva', 'Elvera', 'Elvie', 'Elyse', 'Elyssa', 'Elza', 'Emelia', 'Emelie', 'Emely', 'Emie', 'Emilia', 'Emilie', 'Emily', 'Emma', 'Emmalee', 'Emmanuelle', 'Emmie', 'Emmy', 'Ena', 'Enola', 'Era', 'Erica', 'Ericka', 'Erika', 'Erna', 'Ernestina', 'Ernestine', 'Eryn', 'Esmeralda', 'Esperanza', 'Esta', 'Estefania', 'Estel', 'Estell', 'Estella', 'Estelle', 'Esther', 'Estrella', 'Etha', 'Ethelyn', 'Ethyl', 'Ettie', 'Eudora', 'Eugenia', 'Eula', 'Eulah', 'Eulalia', 'Euna', 'Eunice', 'Eva', 'Evalyn', 'Evangeline', 'Eve', 'Eveline', 'Evelyn', 'Everette', 'Evie',
'Fabiola', 'Fae', 'Fannie', 'Fanny', 'Fatima', 'Fay', 'Faye', 'Felicia', 'Felicita', 'Felicity', 'Felipa', 'Filomena', 'Fiona', 'Flavie', 'Fleta', 'Flo', 'Florence', 'Florida', 'Florine', 'Flossie', 'Frances', 'Francesca', 'Francisca', 'Freda', 'Frederique', 'Freeda', 'Freida', 'Frida', 'Frieda',
'Gabriella', 'Gabrielle', 'Gail', 'Genesis', 'Genevieve', 'Genoveva', 'Georgette', 'Georgiana', 'Georgianna', 'Geraldine', 'Gerda', 'Germaine', 'Gerry', 'Gertrude', 'Gia', 'Gilda', 'Gina', 'Giovanna', 'Gisselle', 'Gladyce', 'Gladys', 'Glenda', 'Glenna', 'Gloria', 'Golda', 'Grace', 'Gracie', 'Graciela', 'Gregoria', 'Greta', 'Gretchen', 'Guadalupe', 'Gudrun', 'Gwen', 'Gwendolyn',
'Hailee', 'Hailie', 'Halie', 'Hallie', 'Hanna', 'Hannah', 'Harmony', 'Hassie', 'Hattie', 'Haven', 'Haylee', 'Haylie', 'Heath', 'Heather', 'Heaven', 'Heidi', 'Helen', 'Helena', 'Helene', 'Helga', 'Hellen', 'Heloise', 'Henriette', 'Hermina', 'Herminia', 'Herta', 'Hertha', 'Hettie', 'Hilda', 'Hildegard', 'Hillary', 'Hilma', 'Hollie', 'Holly', 'Hope', 'Hortense', 'Hosea', 'Hulda',
'Icie', 'Ida', 'Idell', 'Idella', 'Ila', 'Ilene', 'Iliana', 'Ima', 'Imelda', 'Imogene', 'Ines', 'Irma', 'Isabel', 'Isabell', 'Isabella', 'Isabelle', 'Isobel', 'Itzel', 'Iva', 'Ivah', 'Ivory', 'Ivy', 'Izabella',
'Jacinthe', 'Jackeline', 'Jackie', 'Jacklyn', 'Jacky', 'Jaclyn', 'Jacquelyn', 'Jacynthe', 'Jada', 'Jade', 'Jadyn', 'Jaida', 'Jailyn', 'Jakayla', 'Jalyn', 'Jammie', 'Jana', 'Janae', 'Jane', 'Janelle', 'Janessa', 'Janet', 'Janice', 'Janie', 'Janis', 'Janiya', 'Jannie', 'Jany', 'Jaquelin', 'Jaqueline', 'Jaunita', 'Jayda', 'Jayne', 'Jazlyn', 'Jazmin', 'Jazmyn', 'Jazmyne', 'Jeanette', 'Jeanie', 'Jeanne', 'Jena', 'Jenifer', 'Jennie', 'Jennifer', 'Jennyfer', 'Jermaine', 'Jessica', 'Jessika', 'Jessyca', 'Jewel', 'Jewell', 'Joana', 'Joanie', 'Joanne', 'Joannie', 'Joanny', 'Jodie', 'Jody', 'Joelle', 'Johanna', 'Jolie', 'Jordane', 'Josefa', 'Josefina', 'Josephine', 'Josiane', 'Josianne', 'Josie', 'Joy', 'Joyce', 'Juana', 'Juanita', 'Jude', 'Judy', 'Julia', 'Juliana', 'Julianne', 'Julie', 'Juliet', 'June', 'Justina', 'Justine',
'Kaci', 'Kacie', 'Kaela', 'Kaelyn', 'Kaia', 'Kailee', 'Kailey', 'Kailyn', 'Kaitlin', 'Kaitlyn', 'Kali', 'Kallie', 'Kamille', 'Kara', 'Karelle', 'Karen', 'Kari', 'Kariane', 'Karianne', 'Karina', 'Karine', 'Karlee', 'Karli', 'Karlie', 'Karolann', 'Kasandra', 'Kasey', 'Kassandra', 'Katarina', 'Katelin', 'Katelyn', 'Katelynn', 'Katharina', 'Katherine', 'Katheryn', 'Kathleen', 'Kathlyn', 'Kathryn', 'Kathryne', 'Katlyn', 'Katlynn', 'Katrina', 'Katrine', 'Kattie', 'Kavon', 'Kaya', 'Kaycee', 'Kayla', 'Kaylah', 'Kaylee', 'Kayli', 'Kaylie', 'Kaylin', 'Keara', 'Keely', 'Keira', 'Kelli', 'Kellie', 'Kelly', 'Kelsi', 'Kelsie', 'Kendra', 'Kenna', 'Kenya', 'Kenyatta', 'Kiana', 'Kianna', 'Kiara', 'Kiarra', 'Kiera', 'Kimberly', 'Kira', 'Kirsten', 'Kirstin', 'Kitty', 'Krista', 'Kristin', 'Kristina', 'Kristy', 'Krystal', 'Krystel', 'Krystina', 'Kyla', 'Kylee', 'Kylie', 'Kyra',
'Lacey', 'Lacy', 'Laila', 'Laisha', 'Laney', 'Larissa', 'Laura', 'Lauren', 'Laurence', 'Lauretta', 'Lauriane', 'Laurianne', 'Laurie', 'Laurine', 'Laury', 'Lauryn', 'Lavada', 'Lavina', 'Lavinia', 'Lavonne', 'Layla', 'Lea', 'Leann', 'Leanna', 'Leanne', 'Leatha', 'Leda', 'Leila', 'Leilani', 'Lela', 'Lelah', 'Lelia', 'Lempi', 'Lenna', 'Lenora', 'Lenore', 'Leola', 'Leonie', 'Leonor', 'Leonora', 'Leora', 'Lera', 'Leslie', 'Lesly', 'Lessie', 'Leta', 'Letha', 'Letitia', 'Lexi', 'Lexie', 'Lia', 'Liana', 'Libbie', 'Libby', 'Lila', 'Lilian', 'Liliana', 'Liliane', 'Lilla', 'Lillian', 'Lilliana', 'Lillie', 'Lilly', 'Lily', 'Lilyan', 'Lina', 'Linda', 'Lindsay', 'Linnea', 'Linnie', 'Lisa', 'Lisette', 'Litzy', 'Liza', 'Lizeth', 'Lizzie', 'Lois', 'Lola', 'Lolita', 'Loma', 'Lonie', 'Lora', 'Loraine', 'Loren', 'Lorena', 'Lori', 'Lorine', 'Lorna', 'Lottie', 'Lou', 'Loyce', 'Lucie', 'Lucienne', 'Lucile', 'Lucinda', 'Lucy', 'Ludie', 'Lue', 'Luella', 'Luisa', 'Lulu', 'Luna', 'Lupe', 'Lura', 'Lurline', 'Luz', 'Lyda', 'Lydia', 'Lyla', 'Lynn', 'Lysanne',
'Mabel', 'Mabelle', 'Mable', 'Maci', 'Macie', 'Macy', 'Madaline', 'Madalyn', 'Maddison', 'Madeline', 'Madelyn', 'Madelynn', 'Madge', 'Madie', 'Madilyn', 'Madisyn', 'Madonna', 'Mae', 'Maegan', 'Maeve', 'Mafalda', 'Magali', 'Magdalen', 'Magdalena', 'Maggie', 'Magnolia', 'Maia', 'Maida', 'Maiya', 'Makayla', 'Makenzie', 'Malika', 'Malinda', 'Mallie', 'Malvina', 'Mandy', 'Mara', 'Marcelina', 'Marcella', 'Marcelle', 'Marcia', 'Margaret', 'Margarete', 'Margarett', 'Margaretta', 'Margarette', 'Margarita', 'Marge', 'Margie', 'Margot', 'Margret', 'Marguerite', 'Maria', 'Mariah', 'Mariam', 'Marian', 'Mariana', 'Mariane', 'Marianna', 'Marianne', 'Maribel', 'Marie', 'Mariela', 'Marielle', 'Marietta', 'Marilie', 'Marilou', 'Marilyne', 'Marina', 'Marion', 'Marisa', 'Marisol', 'Maritza', 'Marjolaine', 'Marjorie', 'Marjory', 'Marlee', 'Marlen', 'Marlene', 'Marquise', 'Marta', 'Martina', 'Martine', 'Mary', 'Maryam', 'Maryjane', 'Maryse', 'Mathilde', 'Matilda', 'Matilde', 'Mattie', 'Maud', 'Maude', 'Maudie', 'Maureen', 'Maurine', 'Maxie', 'Maximillia', 'May', 'Maya', 'Maybell', 'Maybelle', 'Maye', 'Maymie', 'Mayra', 'Mazie', 'Mckayla', 'Meagan', 'Meaghan', 'Meda', 'Megane', 'Meggie', 'Meghan', 'Melba', 'Melisa', 'Melissa', 'Mellie', 'Melody', 'Melyna', 'Melyssa', 'Mercedes', 'Meredith', 'Mertie', 'Meta', 'Mia', 'Micaela', 'Michaela', 'Michele', 'Michelle', 'Mikayla', 'Millie', 'Mina', 'Minerva', 'Minnie', 'Miracle', 'Mireille', 'Mireya', 'Missouri', 'Misty', 'Mittie', 'Modesta', 'Mollie', 'Molly', 'Mona', 'Monica', 'Monique', 'Mossie', 'Mozell', 'Mozelle', 'Muriel', 'Mya', 'Myah', 'Mylene', 'Myra', 'Myriam', 'Myrna', 'Myrtice', 'Myrtie', 'Myrtis', 'Myrtle',
'Nadia', 'Nakia', 'Name', 'Nannie', 'Naomi', 'Naomie', 'Natalia', 'Natalie', 'Natasha', 'Nayeli', 'Nedra', 'Neha', 'Nelda', 'Nella', 'Nelle', 'Nellie', 'Neoma', 'Nettie', 'Neva', 'Nia', 'Nichole', 'Nicole', 'Nicolette', 'Nikita', 'Nikki', 'Nina', 'Noelia', 'Noemi', 'Noemie', 'Noemy', 'Nola', 'Nona', 'Nora', 'Norene', 'Norma', 'Nova', 'Novella', 'Nya', 'Nyah', 'Nyasia',
'Oceane', 'Ocie', 'Octavia', 'Odessa', 'Odie', 'Ofelia', 'Oleta', 'Olga', 'Ollie', 'Oma', 'Ona', 'Onie', 'Opal', 'Ophelia', 'Ora', 'Orie', 'Orpha', 'Otha', 'Otilia', 'Ottilie', 'Ova', 'Ozella',
'Paige', 'Palma', 'Pamela', 'Pansy', 'Pascale', 'Pasquale', 'Pat', 'Patience', 'Patricia', 'Patsy', 'Pattie', 'Paula', 'Pauline', 'Pearl', 'Pearlie', 'Pearline', 'Peggie', 'Penelope', 'Petra', 'Phoebe', 'Phyllis', 'Pink', 'Pinkie', 'Piper', 'Polly', 'Precious', 'Princess', 'Priscilla', 'Providenci', 'Prudence',
'Queen', 'Queenie',
'Rachael', 'Rachel', 'Rachelle', 'Rae', 'Raegan', 'Rafaela', 'Rahsaan', 'Raina', 'Ramona', 'Raphaelle', 'Raquel', 'Reanna', 'Reba', 'Rebeca', 'Rebecca', 'Rebeka', 'Rebekah', 'Reina', 'Renee', 'Ressie', 'Reta', 'Retha', 'Retta', 'Reva', 'Reyna', 'Rhea', 'Rhianna', 'Rhoda', 'Rita', 'River', 'Roberta', 'Robyn', 'Roma', 'Romaine', 'Rosa', 'Rosalee', 'Rosalia', 'Rosalind', 'Rosalinda', 'Rosalyn', 'Rosamond', 'Rosanna', 'Rose', 'Rosella', 'Roselyn', 'Rosemarie', 'Rosemary', 'Rosetta', 'Rosie', 'Rosina', 'Roslyn', 'Rossie', 'Rowena', 'Roxane', 'Roxanne', 'Rozella', 'Rubie', 'Ruby', 'Rubye', 'Ruth', 'Ruthe', 'Ruthie', 'Rylee',
'Sabina', 'Sabrina', 'Sabryna', 'Sadie', 'Sadye', 'Sallie', 'Sally', 'Salma', 'Samanta', 'Samantha', 'Samara', 'Sandra', 'Sandrine', 'Sandy', 'Santina', 'Sarah', 'Sarai', 'Sarina', 'Sasha', 'Savanah', 'Savanna', 'Savannah', 'Scarlett', 'Selena', 'Selina', 'Serena', 'Serenity', 'Shaina', 'Shakira', 'Shana', 'Shanel', 'Shanelle', 'Shania', 'Shanie', 'Shaniya', 'Shanna', 'Shannon', 'Shanny', 'Shanon', 'Shany', 'Sharon', 'Shawna', 'Shaylee', 'Shayna', 'Shea', 'Sheila', 'Shemar', 'Shirley', 'Shyann', 'Shyanne', 'Sibyl', 'Sienna', 'Sierra', 'Simone', 'Sincere', 'Sister', 'Skyla', 'Sonia', 'Sonya', 'Sophia', 'Sophie', 'Stacey', 'Stacy', 'Stefanie', 'Stella', 'Stephania', 'Stephanie', 'Stephany', 'Summer', 'Sunny', 'Susan', 'Susana', 'Susanna', 'Susie', 'Suzanne', 'Syble', 'Sydnee', 'Sydni', 'Sydnie', 'Sylvia',
'Tabitha', 'Talia', 'Tamara', 'Tamia', 'Tania', 'Tanya', 'Tara', 'Taryn', 'Tatyana', 'Taya', 'Teagan', 'Telly', 'Teresa', 'Tess', 'Tessie', 'Thalia', 'Thea', 'Thelma', 'Theodora', 'Theresa', 'Therese', 'Theresia', 'Thora', 'Tia', 'Tiana', 'Tianna', 'Tiara', 'Tierra', 'Tiffany', 'Tina', 'Tomasa', 'Tracy', 'Tressa', 'Tressie', 'Treva', 'Trinity', 'Trisha', 'Trudie', 'Trycia', 'Twila', 'Tyra',
'Una', 'Ursula',
'Vada', 'Valentina', 'Valentine', 'Valerie', 'Vallie', 'Vanessa', 'Veda', 'Velda', 'Vella', 'Velma', 'Velva', 'Vena', 'Verda', 'Verdie', 'Vergie', 'Verla', 'Verlie', 'Verna', 'Vernice', 'Vernie', 'Verona', 'Veronica', 'Vesta', 'Vicenta', 'Vickie', 'Vicky', 'Victoria', 'Vida', 'Vilma', 'Vincenza', 'Viola', 'Violet', 'Violette', 'Virgie', 'Virginia', 'Virginie', 'Vita', 'Viva', 'Vivian', 'Viviane', 'Vivianne', 'Vivien', 'Vivienne',
'Wanda', 'Wava', 'Wendy', 'Whitney', 'Wilhelmine', 'Willa', 'Willie', 'Willow', 'Wilma', 'Winifred', 'Winnifred', 'Winona',
'Yadira', 'Yasmeen', 'Yasmin', 'Yasmine', 'Yazmin', 'Yesenia', 'Yessenia', 'Yolanda', 'Yoshiko', 'Yvette', 'Yvonne',
'Zaria', 'Zelda', 'Zella', 'Zelma', 'Zena', 'Zetta', 'Zita', 'Zoe', 'Zoey', 'Zoie', 'Zoila', 'Zola', 'Zora', 'Zula'
);

protected static $lastName = array(
'Abbott', 'Abernathy', 'Abshire', 'Adams', 'Altenwerth', 'Anderson', 'Ankunding', 'Armstrong', 'Auer', 'Aufderhar',
'Bahringer', 'Bailey', 'Balistreri', 'Barrows', 'Bartell', 'Bartoletti', 'Barton', 'Bashirian', 'Batz', 'Bauch', 'Baumbach', 'Bayer', 'Beahan', 'Beatty', 'Bechtelar', 'Becker', 'Bednar', 'Beer', 'Beier', 'Berge', 'Bergnaum', 'Bergstrom', 'Bernhard', 'Bernier', 'Bins', 'Blanda', 'Blick', 'Block', 'Bode', 'Boehm', 'Bogan', 'Bogisich', 'Borer', 'Bosco', 'Botsford', 'Boyer', 'Boyle', 'Bradtke', 'Brakus', 'Braun', 'Breitenberg', 'Brekke', 'Brown', 'Bruen', 'Buckridge',
'Carroll', 'Carter', 'Cartwright', 'Casper', 'Cassin', 'Champlin', 'Christiansen', 'Cole', 'Collier', 'Collins', 'Conn', 'Connelly', 'Conroy', 'Considine', 'Corkery', 'Cormier', 'Corwin', 'Cremin', 'Crist', 'Crona', 'Cronin', 'Crooks', 'Cruickshank', 'Cummerata', 'Cummings',
'Dach', 'D\'Amore', 'Daniel', 'Dare', 'Daugherty', 'Davis', 'Deckow', 'Denesik', 'Dibbert', 'Dickens', 'Dicki', 'Dickinson', 'Dietrich', 'Donnelly', 'Dooley', 'Douglas', 'Doyle', 'DuBuque', 'Durgan',
'Ebert', 'Effertz', 'Eichmann', 'Emard', 'Emmerich', 'Erdman', 'Ernser', 'Fadel',
'Fahey', 'Farrell', 'Fay', 'Feeney', 'Feest', 'Feil', 'Ferry', 'Fisher', 'Flatley', 'Frami', 'Franecki', 'Friesen', 'Fritsch', 'Funk',
'Gaylord', 'Gerhold', 'Gerlach', 'Gibson', 'Gislason', 'Gleason', 'Gleichner', 'Glover', 'Goldner', 'Goodwin', 'Gorczany', 'Gottlieb', 'Goyette', 'Grady', 'Graham', 'Grant', 'Green', 'Greenfelder', 'Greenholt', 'Grimes', 'Gulgowski', 'Gusikowski', 'Gutkowski', 'Gutmann',
'Haag', 'Hackett', 'Hagenes', 'Hahn', 'Haley', 'Halvorson', 'Hamill', 'Hammes', 'Hand', 'Hane', 'Hansen', 'Harber', 'Harris', 'Hartmann', 'Harvey', 'Hauck', 'Hayes', 'Heaney', 'Heathcote', 'Hegmann', 'Heidenreich', 'Heller', 'Herman', 'Hermann', 'Hermiston', 'Herzog', 'Hessel', 'Hettinger', 'Hickle', 'Hilll', 'Hills', 'Hilpert', 'Hintz', 'Hirthe', 'Hodkiewicz', 'Hoeger', 'Homenick', 'Hoppe', 'Howe', 'Howell', 'Hudson', 'Huel', 'Huels', 'Hyatt',
'Jacobi', 'Jacobs', 'Jacobson', 'Jakubowski', 'Jaskolski', 'Jast', 'Jenkins', 'Jerde', 'Johns', 'Johnson', 'Johnston', 'Jones',
'Kassulke', 'Kautzer', 'Keebler', 'Keeling', 'Kemmer', 'Kerluke', 'Kertzmann', 'Kessler', 'Kiehn', 'Kihn', 'Kilback', 'King', 'Kirlin', 'Klein', 'Kling', 'Klocko', 'Koch', 'Koelpin', 'Koepp', 'Kohler', 'Konopelski', 'Koss', 'Kovacek', 'Kozey', 'Krajcik', 'Kreiger', 'Kris', 'Kshlerin', 'Kub', 'Kuhic', 'Kuhlman', 'Kuhn', 'Kulas', 'Kunde', 'Kunze', 'Kuphal', 'Kutch', 'Kuvalis',
'Labadie', 'Lakin', 'Lang', 'Langosh', 'Langworth', 'Larkin', 'Larson', 'Leannon', 'Lebsack', 'Ledner', 'Leffler', 'Legros', 'Lehner', 'Lemke', 'Lesch', 'Leuschke', 'Lind', 'Lindgren', 'Littel', 'Little', 'Lockman', 'Lowe', 'Lubowitz', 'Lueilwitz', 'Luettgen', 'Lynch',
'Macejkovic', 'Maggio', 'Mann', 'Mante', 'Marks', 'Marquardt', 'Marvin', 'Mayer', 'Mayert', 'McClure', 'McCullough', 'McDermott', 'McGlynn', 'McKenzie', 'McLaughlin', 'Medhurst', 'Mertz', 'Metz', 'Miller', 'Mills', 'Mitchell', 'Moen', 'Mohr', 'Monahan', 'Moore', 'Morar', 'Morissette', 'Mosciski', 'Mraz', 'Mueller', 'Muller', 'Murazik', 'Murphy', 'Murray',
'Nader', 'Nicolas', 'Nienow', 'Nikolaus', 'Nitzsche', 'Nolan',
'Oberbrunner', 'O\'Connell', 'O\'Conner', 'O\'Hara', 'O\'Keefe', 'O\'Kon', 'Okuneva', 'Olson', 'Ondricka', 'O\'Reilly', 'Orn', 'Ortiz', 'Osinski',
'Pacocha', 'Padberg', 'Pagac', 'Parisian', 'Parker', 'Paucek', 'Pfannerstill', 'Pfeffer', 'Pollich', 'Pouros', 'Powlowski', 'Predovic', 'Price', 'Prohaska', 'Prosacco', 'Purdy',
'Quigley', 'Quitzon',
'Rath', 'Ratke', 'Rau', 'Raynor', 'Reichel', 'Reichert', 'Reilly', 'Reinger', 'Rempel', 'Renner', 'Reynolds', 'Rice', 'Rippin', 'Ritchie', 'Robel', 'Roberts', 'Rodriguez', 'Rogahn', 'Rohan', 'Rolfson', 'Romaguera', 'Roob', 'Rosenbaum', 'Rowe', 'Ruecker', 'Runolfsdottir', 'Runolfsson', 'Runte', 'Russel', 'Rutherford', 'Ryan', 'Sanford', 'Satterfield', 'Sauer', 'Sawayn',
'Schaden', 'Schaefer', 'Schamberger', 'Schiller', 'Schimmel', 'Schinner', 'Schmeler', 'Schmidt', 'Schmitt', 'Schneider', 'Schoen', 'Schowalter', 'Schroeder', 'Schulist', 'Schultz', 'Schumm', 'Schuppe', 'Schuster', 'Senger', 'Shanahan', 'Shields', 'Simonis', 'Sipes', 'Skiles', 'Smith', 'Smitham', 'Spencer', 'Spinka', 'Sporer', 'Stamm', 'Stanton', 'Stark', 'Stehr', 'Steuber', 'Stiedemann', 'Stokes', 'Stoltenberg', 'Stracke', 'Streich', 'Stroman', 'Strosin', 'Swaniawski', 'Swift',
'Terry', 'Thiel', 'Thompson', 'Tillman', 'Torp', 'Torphy', 'Towne', 'Toy', 'Trantow', 'Tremblay', 'Treutel', 'Tromp', 'Turcotte', 'Turner',
'Ullrich', 'Upton',
'Vandervort', 'Veum', 'Volkman', 'Von', 'VonRueden',
'Waelchi', 'Walker', 'Walsh', 'Walter', 'Ward', 'Waters', 'Watsica', 'Weber', 'Wehner', 'Weimann', 'Weissnat', 'Welch', 'West', 'White', 'Wiegand', 'Wilderman', 'Wilkinson', 'Will', 'Williamson', 'Willms', 'Windler', 'Wintheiser', 'Wisoky', 'Wisozk', 'Witting', 'Wiza', 'Wolf', 'Wolff', 'Wuckert', 'Wunsch', 'Wyman',
'Yost', 'Yundt',
'Zboncak', 'Zemlak', 'Ziemann', 'Zieme', 'Zulauf'
);

private static $suffix = array('Jr.', 'Sr.', 'I', 'II', 'III', 'IV', 'V', 'MD', 'DDS', 'PhD', 'DVM');




public static function suffix()
{
return static::randomElement(static::$suffix);
}




public static function ssn()
{
$area = mt_rand(0, 1) ? static::numberBetween(1, 665) : static::numberBetween(667, 899);
$group = static::numberBetween(1, 99);
$serial = static::numberBetween(1, 9999);

return sprintf("%03d-%02d-%04d", $area, $group, $serial);
}
}
<?php

namespace Faker\Provider\en_US;

class Company extends \Faker\Provider\Company
{
protected static $formats = array(
'{{lastName}} {{companySuffix}}',
'{{lastName}}-{{lastName}}',
'{{lastName}}, {{lastName}} and {{lastName}}',
);

protected static $catchPhraseWords = array(
array(
'Adaptive', 'Advanced', 'Ameliorated', 'Assimilated', 'Automated', 'Balanced', 'Business-focused', 'Centralized', 'Cloned', 'Compatible', 'Configurable', 'Cross-group', 'Cross-platform', 'Customer-focused', 'Customizable', 'Decentralized', 'De-engineered', 'Devolved', 'Digitized', 'Distributed', 'Diverse', 'Down-sized', 'Enhanced', 'Enterprise-wide', 'Ergonomic', 'Exclusive', 'Expanded', 'Extended', 'Facetoface', 'Focused', 'Front-line', 'Fully-configurable', 'Function-based', 'Fundamental', 'Future-proofed', 'Grass-roots', 'Horizontal', 'Implemented', 'Innovative', 'Integrated', 'Intuitive', 'Inverse', 'Managed', 'Mandatory', 'Monitored', 'Multi-channelled', 'Multi-lateral', 'Multi-layered', 'Multi-tiered', 'Networked', 'Object-based', 'Open-architected', 'Open-source', 'Operative', 'Optimized', 'Optional', 'Organic', 'Organized', 'Persevering', 'Persistent', 'Phased', 'Polarised', 'Pre-emptive', 'Proactive', 'Profit-focused', 'Profound', 'Programmable', 'Progressive', 'Public-key', 'Quality-focused', 'Reactive', 'Realigned', 'Re-contextualized', 'Re-engineered', 'Reduced', 'Reverse-engineered', 'Right-sized', 'Robust', 'Seamless', 'Secured', 'Self-enabling', 'Sharable', 'Stand-alone', 'Streamlined', 'Switchable', 'Synchronised', 'Synergistic', 'Synergized', 'Team-oriented', 'Total', 'Triple-buffered', 'Universal', 'Up-sized', 'Upgradable', 'User-centric', 'User-friendly', 'Versatile', 'Virtual', 'Visionary', 'Vision-oriented',
),
array(
'24hour', '24/7', '3rdgeneration', '4thgeneration', '5thgeneration', '6thgeneration', 'actuating', 'analyzing', 'assymetric', 'asynchronous', 'attitude-oriented', 'background', 'bandwidth-monitored', 'bi-directional', 'bifurcated', 'bottom-line', 'clear-thinking', 'client-driven', 'client-server', 'coherent', 'cohesive', 'composite', 'context-sensitive', 'contextually-based', 'content-based', 'dedicated', 'demand-driven', 'didactic', 'directional', 'discrete', 'disintermediate', 'dynamic', 'eco-centric', 'empowering', 'encompassing', 'even-keeled', 'executive', 'explicit', 'exuding', 'fault-tolerant', 'foreground', 'fresh-thinking', 'full-range', 'global', 'grid-enabled', 'heuristic', 'high-level', 'holistic', 'homogeneous', 'human-resource', 'hybrid', 'impactful', 'incremental', 'intangible', 'interactive', 'intermediate', 'leadingedge', 'local', 'logistical', 'maximized', 'methodical', 'mission-critical', 'mobile', 'modular', 'motivating', 'multimedia', 'multi-state', 'multi-tasking', 'national', 'needs-based', 'neutral', 'nextgeneration', 'non-volatile', 'object-oriented', 'optimal', 'optimizing', 'radical', 'real-time', 'reciprocal', 'regional', 'responsive', 'scalable', 'secondary', 'solution-oriented', 'stable', 'static', 'systematic', 'systemic', 'system-worthy', 'tangible', 'tertiary', 'transitional', 'uniform', 'upward-trending', 'user-facing', 'value-added', 'web-enabled', 'well-modulated', 'zeroadministration', 'zerodefect', 'zerotolerance',
),
array(
'ability', 'access', 'adapter', 'algorithm', 'alliance', 'analyzer', 'application', 'approach', 'architecture', 'archive', 'artificialintelligence', 'array', 'attitude', 'benchmark', 'budgetarymanagement', 'capability', 'capacity', 'challenge', 'circuit', 'collaboration', 'complexity', 'concept', 'conglomeration', 'contingency', 'core', 'customerloyalty', 'database', 'data-warehouse', 'definition', 'emulation', 'encoding', 'encryption', 'extranet', 'firmware', 'flexibility', 'focusgroup', 'forecast', 'frame', 'framework', 'function', 'functionalities', 'GraphicInterface', 'groupware', 'GraphicalUserInterface', 'hardware', 'help-desk', 'hierarchy', 'hub', 'implementation', 'info-mediaries', 'infrastructure', 'initiative', 'installation', 'instructionset', 'interface', 'internetsolution', 'intranet', 'knowledgeuser', 'knowledgebase', 'localareanetwork', 'leverage', 'matrices', 'matrix', 'methodology', 'middleware', 'migration', 'model', 'moderator', 'monitoring', 'moratorium', 'neural-net', 'openarchitecture', 'opensystem', 'orchestration', 'paradigm', 'parallelism', 'policy', 'portal', 'pricingstructure', 'processimprovement', 'product', 'productivity', 'project', 'projection', 'protocol', 'securedline', 'service-desk', 'software', 'solution', 'standardization', 'strategy', 'structure', 'success', 'superstructure', 'support', 'synergy', 'systemengine', 'task-force', 'throughput', 'time-frame', 'toolset', 'utilisation', 'website', 'workforce',
),
);

protected static $bsWords = array(
array(
'implement', 'utilize', 'integrate', 'streamline', 'optimize', 'evolve', 'transform', 'embrace', 'enable', 'orchestrate', 'leverage', 'reinvent', 'aggregate', 'architect', 'enhance', 'incentivize', 'morph', 'empower', 'envisioneer', 'monetize', 'harness', 'facilitate', 'seize', 'disintermediate', 'synergize', 'strategize', 'deploy', 'brand', 'grow', 'target', 'syndicate', 'synthesize', 'deliver', 'mesh', 'incubate', 'engage', 'maximize', 'benchmark', 'expedite', 'reintermediate', 'whiteboard', 'visualize', 'repurpose', 'innovate', 'scale', 'unleash', 'drive', 'extend', 'engineer', 'revolutionize', 'generate', 'exploit', 'transition', 'e-enable', 'iterate', 'cultivate', 'matrix', 'productize', 'redefine', 'recontextualize',
),
array(
'clicks-and-mortar', 'value-added', 'vertical', 'proactive', 'robust', 'revolutionary', 'scalable', 'leading-edge', 'innovative', 'intuitive', 'strategic', 'e-business', 'mission-critical', 'sticky', 'one-to-one', '24/7', 'end-to-end', 'global', 'B2B', 'B2C', 'granular', 'frictionless', 'virtual', 'viral', 'dynamic', '24/365', 'best-of-breed', 'killer', 'magnetic', 'bleeding-edge', 'web-enabled', 'interactive', 'dot-com', 'sexy', 'back-end', 'real-time', 'efficient', 'front-end', 'distributed', 'seamless', 'extensible', 'turn-key', 'world-class', 'open-source', 'cross-platform', 'cross-media', 'synergistic', 'bricks-and-clicks', 'out-of-the-box', 'enterprise', 'integrated', 'impactful', 'wireless', 'transparent', 'next-generation', 'cutting-edge', 'user-centric', 'visionary', 'customized', 'ubiquitous', 'plug-and-play', 'collaborative', 'compelling', 'holistic', 'rich',
),
array(
'synergies', 'web-readiness', 'paradigms', 'markets', 'partnerships', 'infrastructures', 'platforms', 'initiatives', 'channels', 'eyeballs', 'communities', 'ROI', 'solutions', 'e-tailers', 'e-services', 'action-items', 'portals', 'niches', 'technologies', 'content', 'vortals', 'supply-chains', 'convergence', 'relationships', 'architectures', 'interfaces', 'e-markets', 'e-commerce', 'systems', 'bandwidth', 'infomediaries', 'models', 'mindshare', 'deliverables', 'users', 'schemas', 'networks', 'applications', 'metrics', 'e-business', 'functionalities', 'experiences', 'webservices', 'methodologies',
),
);




protected static $jobTitleFormat = array(
'Able Seamen', 'Account Manager', 'Accountant', 'Actor', 'Actuary', 'Adjustment Clerk', 'Admin', 'Administrative Law Judge', 'Administrative Services Manager', 'Administrative Support Supervisors', 'Advertising Manager OR Promotions Manager', 'Advertising Sales Agent', 'Aerospace Engineer', 'Agricultural Crop Farm Manager', 'Agricultural Crop Worker', 'Agricultural Engineer', 'Agricultural Equipment Operator', 'Agricultural Inspector', 'Agricultural Manager', 'Agricultural Product Grader Sorter', 'Agricultural Sales Representative', 'Agricultural Science Technician', 'Agricultural Sciences Teacher', 'Agricultural Technician', 'Agricultural Worker', 'Air Crew Member', 'Air Crew Officer', 'Air Traffic Controller', 'Aircraft Assembler', 'Aircraft Body Repairer', 'Aircraft Cargo Handling Supervisor', 'Aircraft Engine Specialist', 'Aircraft Launch and Recovery Officer', 'Aircraft Launch Specialist', 'Aircraft Mechanics OR Aircraft Service Technician', 'Aircraft Rigging Assembler', 'Aircraft Structure Assemblers', 'Airfield Operations Specialist', 'Airframe Mechanic', 'Airline Pilot OR Copilot OR Flight Engineer', 'Algorithm Developer', 'Alteration Tailor', 'Ambulance Driver', 'Amusement Attendant', 'Anesthesiologist', 'Animal Breeder', 'Animal Care Workers', 'Animal Control Worker', 'Animal Husbandry Worker', 'Animal Scientist', 'Animal Trainer', 'Annealing Machine Operator', 'Announcer', 'Answering Service', 'Anthropologist', 'Anthropologist OR Archeologist', 'Anthropology Teacher', 'Appliance Repairer', 'Arbitrator', 'Archeologist', 'Architect', 'Architectural Drafter', 'Architectural Drafter OR Civil Drafter', 'Architecture Teacher', 'Archivist', 'Armored Assault Vehicle Crew Member', 'Armored Assault Vehicle Officer', 'Art Director', 'Art Teacher', 'Artillery Officer', 'Artillery Crew Member', 'Artist', 'Assembler', 'Assessor', 'Astronomer', 'Athletes and Sports Competitor', 'Athletic Trainer', 'Atmospheric and Space Scientist', 'Audio and Video Equipment Technician', 'Audiologist', 'Audio-Visual Collections Specialist', 'Auditor', 'Auditor', 'Automatic Teller Machine Servicer', 'Automotive Body Repairer', 'Automotive Glass Installers', 'Automotive Master Mechanic', 'Automotive Mechanic', 'Automotive Specialty Technician', 'Automotive Technician', 'Auxiliary Equipment Operator', 'Aviation Inspector', 'Avionics Technician',
'Bailiff', 'Baker', 'Barber', 'Bartender', 'Bartender Helper', 'Battery Repairer', 'Bellhop', 'Bench Jeweler', 'Benefits Specialist', 'Bicycle Repairer', 'Bill and Account Collector', 'Bindery Machine Operator', 'Bindery Worker', 'Biochemist', 'Biochemist or Biophysicist', 'Biological Science Teacher', 'Biological Scientist', 'Biological Technician', 'Biologist', 'Biomedical Engineer', 'Biophysicist', 'Board Of Directors', 'Boat Builder and Shipwright', 'Boiler Operator', 'Boilermaker', 'Bookbinder', 'Bookkeeper', 'Brake Machine Setter', 'Brattice Builder', 'Brazer', 'Brazing Machine Operator', 'Brickmason', 'Bridge Tender OR Lock Tender', 'Broadcast News Analyst', 'Broadcast Technician', 'Brokerage Clerk', 'Budget Analyst', 'Buffing and Polishing Operator', 'Building Cleaning Worker', 'Building Inspector', 'Bulldozer Operator', 'Bus Driver', 'Business Development Manager', 'Business Manager', 'Business Operations Specialist', 'Business Teacher', 'Butcher', 'Buyer',
'Cabinetmaker', 'Cafeteria Cook', 'Calibration Technician OR Instrumentation Technician', 'Camera Operator', 'Camera Repairer', 'Captain', 'Caption Writer', 'Cardiovascular Technologist', 'Career Counselor', 'Carpenter', 'Carpenter Assembler and Repairer', 'Carpet Installer', 'Cartographer', 'Cartoonist', 'Carver', 'Cashier', 'Casting Machine Operator', 'Casting Machine Set-Up Operator', 'ccc', 'Ceiling Tile Installer', 'Cement Mason and Concrete Finisher', 'Central Office', 'Central Office and PBX Installers', 'Central Office Operator', 'CEO', 'CFO', 'Chef', 'Chemical Engineer', 'Chemical Equipment Controller', 'Chemical Equipment Operator', 'Chemical Equipment Tender', 'Chemical Plant Operator', 'Chemical Technician', 'Chemist', 'Chemistry Teacher', 'Child Care', 'Child Care Worker', 'Chiropractor', 'Choreographer', 'City', 'City Planning Aide', 'Civil Drafter', 'Civil Engineer', 'Civil Engineering Technician', 'Claims Adjuster', 'Claims Examiner', 'Claims Taker', 'Cleaners of Vehicles', 'Clergy', 'Clerk', 'Clinical Laboratory Technician', 'Clinical Psychologist', 'Clinical School Psychologist', 'Coaches and Scout', 'Coating Machine Operator', 'Coil Winders', 'Command Control Center Officer', 'Command Control Center Specialist', 'Commercial and Industrial Designer', 'Commercial Diver', 'Commercial Pilot', 'Communication Equipment Repairer', 'Communication Equipment Worker', 'Communications Equipment Operator', 'Communications Teacher', 'Community Service Manager', 'Compacting Machine Operator', 'Compensation and Benefits Manager', 'Compliance Officers', 'Composer', 'Computer', 'Computer Hardware Engineer', 'Computer Operator', 'Computer Programmer', 'Computer Repairer', 'Computer Science Teacher', 'Computer Scientist', 'Computer Security Specialist', 'Computer Software Engineer', 'Computer Specialist', 'Computer Support Specialist', 'Computer Systems Analyst', 'Computer-Controlled Machine Tool Operator', 'Concierge', 'Conservation Scientist', 'Construction', 'Construction Carpenter', 'Construction Driller', 'Construction Equipment Operator', 'Construction Laborer', 'Construction Manager', 'Continuous Mining Machine Operator', 'Control Valve Installer', 'Conveyor Operator', 'Cook', 'Cooling and Freezing Equipment Operator', 'Copy Machine Operator', 'Copy Writer', 'Coremaking Machine Operator', 'Coroner', 'Corporate Trainer', 'Correctional Officer', 'Correspondence Clerk', 'Cost Estimator', 'Costume Attendant', 'Counseling Psychologist', 'Counselor', 'Counsil', 'Courier', 'Court Clerk', 'Court Reporter', 'Craft Artist', 'Crane and Tower Operator', 'Creative Writer', 'Credit Checkers Clerk', 'Credit Analyst', 'Credit Authorizer', 'Credit Checker', 'Criminal Investigator', 'Crossing Guard', 'Crushing Grinding Machine Operator', 'CSI', 'CTO', 'Cultural Studies Teacher', 'Curator', 'Custom Tailor', 'Customer Service Representative', 'Cutting Machine Operator', 'Cutting Machine Operator',
'Dancer', 'Data Entry Operator', 'Data Processing Equipment Repairer', 'Database Administrator', 'Database Manager', 'Deburring Machine Operator', 'Decorator', 'Dental Assistant', 'Dental Hygienist', 'Dental Laboratory Technician', 'Dentist', 'Designer', 'Desktop Publisher', 'Detective', 'Diagnostic Medical Sonographer', 'Diamond Worker', 'Diesel Engine Specialist', 'Dietetic Technician', 'Director Of Business Development', 'Director Of Marketing', 'Director Of Social Media Marketing', 'Director Of Talent Acquisition', 'Director Religious Activities', 'Directory Assistance Operator', 'Dishwasher', 'Dispatcher', 'Distribution Manager', 'Door To Door Sales', 'Dot Etcher', 'Drafter', 'Dragline Operator', 'Dredge Operator', 'Drilling and Boring Machine Tool Setter', 'Driver-Sales Worker', 'Drycleaning Machine Operator', 'Drywall Ceiling Tile Installer', 'Drywall Installer',
'Earth Driller', 'Economics Teacher', 'Economist', 'Editor', 'Education Administrator', 'Education Teacher', 'Educational Counselor OR Vocationall Counselor', 'Educational Psychologist', 'Electric Meter Installer', 'Electric Motor Repairer', 'Electrical and Electronic Inspector and Tester', 'Electrical and Electronics Drafter', 'Electrical Drafter', 'Electrical Engineer', 'Electrical Engineering Technician', 'Electrical Parts Reconditioner', 'Electrical Power-Line Installer', 'Electrical Sales Representative', 'Electrician', 'Electrician', 'Electrolytic Plating Machine Operator', 'Electromechanical Equipment Assembler', 'Electro-Mechanical Technician', 'Electronic Drafter', 'Electronic Engineering Technician', 'Electronic Equipment Assembler', 'Electronic Masking System Operator', 'Electronics Engineer', 'Electronics Engineering Technician', 'Electrotyper', 'Elementary and Secondary School Administrators', 'Elementary School Teacher', 'Elevator Installer and Repairer', 'Eligibility Interviewer', 'Embalmer', 'Embossing Machine Operator', 'Emergency Management Specialist', 'Emergency Medical Technician and Paramedic', 'Employment Interviewer', 'Engine Assembler', 'Engineer', 'Engineering', 'Engineering Manager', 'Engineering Teacher', 'Engineering Technician', 'English Language Teacher', 'Engraver', 'Entertainer and Performer', 'Entertainment Attendant', 'Environmental Compliance Inspector', 'Environmental Engineer', 'Environmental Engineering Technician', 'Environmental Science Teacher', 'Environmental Science Technician', 'Environmental Scientist', 'Epidemiologist', 'Equal Opportunity Representative', 'Etcher', 'Etcher and Engraver', 'Event Planner', 'Excavating Machine Operator', 'Executive Secretary', 'Exhibit Designer', 'Explosives Expert', 'Extraction Worker', 'Extruding and Drawing Machine Operator', 'Extruding Machine Operator',
'Fabric Mender', 'Fabric Pressers', 'Farm and Home Management Advisor', 'Farm Equipment Mechanic', 'Farm Labor Contractor', 'Farmer', 'Farmworker', 'Fashion Designer', 'Fashion Model', 'Fast Food Cook', 'Fence Erector', 'Fiber Product Cutting Machine Operator', 'Fiberglass Laminator and Fabricator', 'File Clerk', 'Film Laboratory Technician', 'Financial Analyst', 'Financial Examiner', 'Financial Manager', 'Financial Services Sales Agent', 'Financial Specialist', 'Fire Fighter', 'Fire Inspector', 'Fire Investigator', 'Fire-Prevention Engineer', 'First-Line Supervisor-Manager of Landscaping, Lawn Service, and Groundskeeping Worker', 'Fish Game Warden', 'Fish Hatchery Manager', 'Fishery Worker', 'Fishing OR Forestry Supervisor', 'Fitness Trainer', 'Fitter', 'Flight Attendant', 'Floor Finisher', 'Floor Layer', 'Floral Designer', 'Food Batchmaker', 'Food Cooking Machine Operators', 'Food Preparation', 'Food Preparation and Serving Worker', 'Food Preparation Worker', 'Food Science Technician', 'Food Scientists and Technologist', 'Food Servers', 'Food Service Manager', 'Food Tobacco Roasting', 'Foreign Language Teacher', 'Forensic Investigator', 'Forensic Science Technician', 'Forest and Conservation Technician', 'Forest and Conservation Worker', 'Forest Fire Fighter', 'Forest Fire Fighting Supervisor', 'Forest Fire Inspector', 'Forester', 'Forestry Conservation Science Teacher', 'Forging Machine Setter', 'Forming Machine Operator', 'Forming Machine Operator', 'Foundry Mold and Coremaker', 'Fraud Investigator', 'Freight Agent', 'Freight and Material Mover', 'Freight Inspector', 'Funeral Attendant', 'Funeral Director', 'Furnace Operator', 'Furniture Finisher',
'Gaming Cage Worker', 'Gaming Dealer', 'Gaming Manager', 'Gaming Service Worker', 'Gaming Supervisor', 'Gaming Surveillance Officer', 'Garment', 'Gas Appliance Repairer', 'Gas Compressor Operator', 'Gas Distribution Plant Operator', 'Gas Plant Operator', 'Gas Processing Plant Operator', 'Gas Pumping Station Operator', 'Gas Pumping Station Operator', 'Gauger', 'GED Teacher', 'General Farmworker', 'General Manager', 'General Practitioner', 'Geographer', 'Geography Teacher', 'Geological Data Technician', 'Geological Sample Test Technician', 'Geologist', 'Geoscientists', 'Glass Blower', 'Glass Cutting Machine Operator', 'Glazier', 'Gluing Machine Operator', 'Government', 'Government Property Inspector', 'Government Service Executive', 'Graduate Teaching Assistant', 'Graphic Designer', 'Grinder OR Polisher', 'Grinding Machine Operator', 'Grips', 'Grounds Maintenance Worker',
'Hairdresser OR Cosmetologist', 'Hand Trimmer', 'Hand Presser', 'Hand Sewer', 'Hazardous Materials Removal Worker', 'Head Nurse', 'Health Educator', 'Health Practitioner', 'Health Services Manager', 'Health Specialties Teacher', 'Health Technologist', 'Healthcare', 'Healthcare Practitioner', 'Healthcare Support Worker', 'Heat Treating Equipment Operator', 'Heaters', 'Heating and Air Conditioning Mechanic', 'Heating Equipment Operator', 'Heavy Equipment Mechanic', 'Highway Maintenance Worker', 'Highway Patrol Pilot', 'Historian', 'History Teacher', 'Hoist and Winch Operator', 'Home', 'Home Appliance Installer', 'Home Appliance Repairer', 'Home Economics Teacher', 'Home Entertainment Equipment Installer', 'Home Health Aide', 'Homeland Security', 'Horticultural Worker', 'Host and Hostess', 'Hotel Desk Clerk', 'House Cleaner', 'Housekeeper', 'Housekeeping Supervisor', 'HR Manager', 'HR Specialist', 'Human Resource Director', 'Human Resource Manager', 'Human Resources Assistant', 'Human Resources Manager', 'Human Resources Specialist', 'Hunter and Trapper', 'HVAC Mechanic', 'Hydrologist',
'Illustrator', 'Immigration Inspector OR Customs Inspector', 'Industrial Engineer', 'Industrial Engineering Technician', 'Industrial Equipment Maintenance', 'Industrial Machinery Mechanic', 'Industrial Production Manager', 'Industrial Safety Engineer', 'Industrial-Organizational Psychologist', 'Infantry', 'Infantry Officer', 'Information Systems Manager', 'Inspector', 'Installation and Repair Technician', 'Instructional Coordinator', 'Instrument Sales Representative', 'Insulation Installer', 'Insulation Worker', 'Insurance Investigator', 'Insurance Appraiser', 'Insurance Claims Clerk', 'Insurance Policy Processing Clerk', 'Insurance Sales Agent', 'Insurance Underwriter', 'Interaction Designer', 'Interior Designer', 'Internist', 'Interpreter OR Translator', 'Interviewer', 'Irradiated-Fuel Handler',
'Janitor', 'Janitorial Supervisor', 'Jeweler', 'Jewelry Model OR Mold Makers', 'Job Printer', 'Judge',
'Keyboard Instrument Repairer and Tuner', 'Kindergarten Teacher',
'Landscape Architect', 'Landscape Artist', 'Landscaper', 'Landscaping', 'Lathe Operator', 'Laundry OR Dry-Cleaning Worker', 'Law Clerk', 'Law Enforcement Teacher', 'Law Teacher', 'Lawn Service Manager', 'Lawyer', 'Lay-Out Worker', 'Legal Secretary', 'Legal Support Worker', 'Legislator', 'Letterpress Setters Operator', 'Librarian', 'Library Assistant', 'Library Science Teacher', 'Library Technician', 'Library Worker', 'License Clerk', 'Licensed Practical Nurse', 'Licensing Examiner and Inspector', 'Life Science Technician', 'Life Scientists', 'Lifeguard', 'Loading Machine Operator', 'Loan Counselor', 'Loan Interviewer', 'Loan Officer', 'Locker Room Attendant', 'Locksmith', 'Locomotive Engineer', 'Locomotive Firer', 'Lodging Manager', 'Log Grader and Scaler', 'Logging Equipment Operator', 'Logging Supervisor', 'Logging Tractor Operator', 'Logging Worker', 'Logistician',
'Machine Feeder', 'Machine Operator', 'Machine Tool Operator', 'Machinery Maintenance', 'Machinist', 'Maid', 'Mail Clerk', 'Mail Machine Operator', 'Maintenance and Repair Worker', 'Maintenance Equipment Operator', 'Maintenance Supervisor', 'Maintenance Worker', 'Makeup Artists', 'Management Analyst', 'Manager', 'Manager of Air Crew', 'Manager of Food Preparation', 'Manager of Weapons Specialists', 'Manager Tactical Operations', 'Manicurists', 'Manufactured Building Installer', 'Manufacturing Sales Representative', 'Mapping Technician', 'MARCOM Director', 'MARCOM Manager', 'Marine Architect', 'Marine Cargo Inspector', 'Marine Engineer', 'Marine Oiler', 'Market Research Analyst', 'Marketing Manager', 'Marketing VP', 'Marking Clerk', 'Marking Machine Operator', 'Marriage and Family Therapist', 'Massage Therapist', 'Material Movers', 'Material Moving Worker', 'Materials Engineer', 'Materials Inspector', 'Materials Scientist', 'Mathematical Science Teacher', 'Mathematical Scientist', 'Mathematical Technician', 'Mathematician', 'Meat Packer', 'Mechanical Door Repairer', 'Mechanical Drafter', 'Mechanical Engineer', 'Mechanical Engineering Technician', 'Mechanical Equipment Sales Representative', 'Mechanical Inspector', 'Media and Communication Worker', 'Medical Appliance Technician', 'Medical Assistant', 'Medical Equipment Preparer', 'Medical Equipment Repairer', 'Medical Laboratory Technologist', 'Medical Records Technician', 'Medical Sales Representative', 'Medical Scientists', 'Medical Secretary', 'Medical Technician', 'Medical Transcriptionist', 'Mental Health Counselor', 'Merchandise Displayer OR Window Trimmer', 'Metal Fabricator', 'Metal Molding Operator', 'Metal Pourer and Caster', 'Metal Worker', 'Metal-Refining Furnace Operator', 'Meter Mechanic', 'Microbiologist', 'Middle School Teacher', 'Military Officer', 'Milling Machine Operator', 'Millwright', 'Mine Cutting Machine Operator', 'Mining Engineer OR Geological Engineer', 'Mining Machine Operator', 'Mixing and Blending Machine Operator', 'Model Maker', 'Mold Maker', 'Molder', 'Molding and Casting Worker', 'Molding Machine Operator', 'Motion Picture Projectionist', 'Motor Vehicle Inspector', 'Motor Vehicle Operator', 'Motorboat Mechanic', 'Motorboat Operator', 'Motorcycle Mechanic', 'Movers', 'Movie Director oR Theatre Director', 'Multi-Media Artist', 'Multiple Machine Tool Setter', 'Municipal Clerk', 'Municipal Court Clerk', 'Municipal Fire Fighter', 'Municipal Fire Fighting Supervisor', 'Museum Conservator', 'Music Arranger and Orchestrator', 'Music Composer', 'Music Director', 'Musical Instrument Tuner', 'Musician', 'Musician OR Singer',
'Natural Sciences Manager', 'Naval Architects', 'Network Admin OR Computer Systems Administrator', 'Network Systems Analyst', 'New Accounts Clerk', 'Night Security Guard', 'Night Shift', 'Nonfarm Animal Caretaker', 'Nuclear Engineer', 'Nuclear Equipment Operation Technician', 'Nuclear Medicine Technologist', 'Nuclear Monitoring Technician', 'Nuclear Power Reactor Operator', 'Nuclear Technician', 'Numerical Control Machine Tool Operator', 'Numerical Tool Programmer OR Process Control Programmer', 'Nursery Manager', 'Nursery Worker', 'Nursing Aide', 'Nursing Instructor', 'Nutritionist',
'Obstetrician', 'Occupational Health Safety Specialist', 'Occupational Health Safety Technician', 'Occupational Therapist', 'Occupational Therapist Aide', 'Occupational Therapist Assistant', 'Office and Administrative Support Worker', 'Office Clerk', 'Office Machine and Cash Register Servicer', 'Office Machine Operator', 'Offset Lithographic Press Operator', 'Oil and gas Operator', 'Oil Service Unit Operator', 'Online Marketing Analyst', 'Operating Engineer', 'Operations Research Analyst', 'Ophthalmic Laboratory Technician', 'Optical Instrument Assembler', 'Opticians', 'Optometrist', 'Oral Surgeon', 'Order Clerk', 'Order Filler', 'Order Filler OR Stock Clerk', 'Organizational Development Manager', 'Orthodontist', 'Orthotist OR Prosthetist', 'Outdoor Power Equipment Mechanic',
'Packaging Machine Operator', 'Packer and Packager', 'Painter', 'Painter and Illustrator', 'Painting Machine Operator', 'Pantograph Engraver', 'Paper Goods Machine Operator', 'Paperhanger', 'Paralegal', 'Park Naturalist', 'Parking Enforcement Worker', 'Parking Lot Attendant', 'Parts Salesperson', 'Paste-Up Worker', 'Pastry Chef', 'Patrol Officer', 'Patternmaker', 'Paving Equipment Operator', 'Payroll Clerk', 'Pediatricians', 'Percussion Instrument Repairer', 'Personal Care Worker', 'Personal Financial Advisor', 'Personal Home Care Aide', 'Personal Service Worker', 'Personal Trainer', 'Personnel Recruiter', 'Pest Control Worker', 'Pesticide Sprayer', 'Petroleum Engineer', 'Petroleum Pump Operator', 'Petroleum Pump System Operator', 'Petroleum Technician', 'Pewter Caster', 'Pharmaceutical Sales Representative', 'Pharmacist', 'Pharmacy Aide', 'Pharmacy Technician', 'Philosophy and Religion Teacher', 'Photoengraver', 'Photoengraving Machine Operator', 'Photographer', 'Photographic Restorer', 'Photographic Developer', 'Photographic Process Worker', 'Photographic Processing Machine Operator', 'Photographic Reproduction Technician', 'Physical Scientist', 'Physical Therapist', 'Physical Therapist Aide', 'Physical Therapist Assistant', 'Physician', 'Physician Assistant', 'Physicist', 'Physics Teacher', 'Pile-Driver Operator', 'Pipe Fitter', 'Pipefitter', 'Pipelayer', 'Pipelaying Fitter', 'Plant and System Operator', 'Plant Scientist', 'Plasterer OR Stucco Mason', 'Plastic Molding Machine Operator', 'Plate Finisher', 'Platemaker', 'Plating Machine Operator', 'Plating Operator', 'Plating Operator OR Coating Machine Operator', 'Plumber', 'Plumber OR Pipefitter OR Steamfitter', 'Podiatrist', 'Poet OR Lyricist', 'Police and Sheriffs Patrol Officer', 'Police Detective', 'Police Identification OR Records Officer', 'Political Science Teacher', 'Political Scientist', 'Portable Power Tool Repairer', 'Postal Clerk', 'Postal Service Clerk', 'Postal Service Mail Carrier', 'Postal Service Mail Sorter', 'Postmasters', 'Postsecondary Education Administrators', 'Postsecondary Teacher', 'Potter', 'Poultry Cutter', 'Power Distributors OR Dispatcher', 'Power Generating Plant Operator', 'Power Plant Operator', 'PR Manager', 'Precious Stone Worker', 'Precision Aircraft Systems Assemblers', 'Precision Devices Inspector', 'Precision Dyer', 'Precision Etcher and Engraver', 'Precision Instrument Repairer', 'Precision Lens Grinders and Polisher', 'Precision Mold and Pattern Caster', 'Precision Pattern and Die Caster', 'Precision Printing Worker', 'Prepress Technician', 'Preschool Education Administrators', 'Preschool Teacher', 'Press Machine Setter, Operator', 'Pressing Machine Operator', 'Pressure Vessel Inspector', 'Printing Machine Operator', 'Printing Press Machine Operator', 'Private Detective and Investigator', 'Private Household Cook', 'Private Sector Executive', 'Probation Officers and Correctional Treatment Specialist', 'Procurement Clerk', 'Producer', 'Producers and Director', 'Product Management Leader', 'Product Promoter', 'Product Safety Engineer', 'Product Specialist', 'Production Control Manager', 'Production Helper', 'Production Inspector', 'Production Laborer', 'Production Manager', 'Production Planner', 'Production Planning', 'Production Worker', 'Professional Photographer', 'Professor', 'Program Director', 'Project Manager', 'Proofreaders and Copy Marker', 'Prosthodontist', 'Protective Service Worker', 'Protective Service Worker', 'Psychiatric Aide', 'Psychiatric Technician', 'Psychiatrist', 'Psychologist', 'Psychology Teacher', 'Public Health Social Worker', 'Public Relations Manager', 'Public Relations Specialist', 'Public Transportation Inspector', 'Pump Operators', 'Punching Machine Setters', 'Purchasing Agent', 'Purchasing Manager',
'Radar Technician', 'Radiation Therapist', 'Radio and Television Announcer', 'Radio Mechanic', 'Radio Operator', 'Radiologic Technician', 'Radiologic Technologist', 'Radiologic Technologist and Technician', 'Rail Car Repairer', 'Rail Transportation Worker', 'Rail Yard Engineer', 'Railroad Conductors', 'Railroad Inspector', 'Railroad Switch Operator', 'Railroad Yard Worker', 'Range Manager', 'Real Estate Appraiser', 'Real Estate Association Manager', 'Real Estate Broker', 'Real Estate Sales Agent', 'Receptionist and Information Clerk', 'Record Clerk', 'Recordkeeping Clerk', 'Recreation and Fitness Studies Teacher', 'Recreation Worker', 'Recreational Therapist', 'Recreational Vehicle Service Technician', 'Recruiter', 'Recyclable Material Collector', 'Refinery Operator', 'Refractory Materials Repairer', 'Refrigeration Mechanic', 'Registered Nurse', 'Rehabilitation Counselor', 'Religious Worker', 'Rental Clerk', 'Reporters OR Correspondent', 'Reservation Agent OR Transportation Ticket Agent', 'Residential Advisor', 'Respiratory Therapist', 'Respiratory Therapy Technician', 'Restaurant Cook', 'Retail Sales person', 'Retail Salesperson', 'Rigger', 'RN', 'Rock Splitter', 'Rolling Machine Setter', 'Roof Bolters Mining', 'Roofer', 'Rotary Drill Operator', 'Rough Carpenter', 'Roustabouts',
'Safety Engineer', 'Sailor', 'Sales and Related Workers', 'Sales Engineer', 'Sales Manager', 'Sales Person', 'Sales Representative', 'Sawing Machine Operator', 'Sawing Machine Setter', 'Sawing Machine Tool Setter', 'Scanner Operator', 'School Bus Driver', 'School Social Worker', 'Scientific Photographer', 'Screen Printing Machine Operator', 'Sculptor', 'Secondary School Teacher', 'Secretary', 'Securities Sales Agent', 'Security Guard', 'Security Systems Installer OR Fire Alarm Systems Installer', 'Segmental Paver', 'Self-Enrichment Education Teacher', 'Semiconductor Processor', 'Separating Machine Operators', 'Septic Tank Servicer', 'Service Station Attendant', 'Set and Exhibit Designer', 'Set Designer', 'Sewing Machine Operator', 'Shampooer', 'Shear Machine Set-Up Operator', 'Sheet Metal Worker', 'Sheriff', 'Ship Captain', 'Ship Carpenter and Joiner', 'Ship Engineer', 'Ship Mates', 'Ship Pilot', 'Shipping and Receiving Clerk', 'Shoe and Leather Repairer', 'Shoe Machine Operators', 'Short Order Cook', 'Shuttle Car Operator', 'Signal Repairer OR Track Switch Repairer', 'Silversmith', 'Singer', 'Sketch Artist', 'Skin Care Specialist', 'Slot Key Person', 'Social and Human Service Assistant', 'Social Media Marketing Manager', 'Social Science Research Assistant', 'Social Sciences Teacher', 'Social Scientists', 'Social Service Specialists', 'Social Work Teacher', 'Social Worker', 'Sociologist', 'Sociology Teacher', 'Software Engineer', 'Soil Conservationist', 'Soil Scientist', 'Soil Scientist OR Plant Scientist', 'Solderer', 'Soldering Machine Setter', 'Sound Engineering Technician', 'Space Sciences Teacher', 'Special Education Teacher', 'Special Force', 'Special Forces Officer', 'Speech-Language Pathologist', 'Sports Book Writer', 'Spotters', 'Spraying Machine Operator', 'Staff Psychologist', 'State', 'Statement Clerk', 'Stationary Engineer', 'Stationary Engineer OR Boiler Operator', 'Statistical Assistant', 'Statistician', 'Steel Worker', 'Stevedore', 'Stock Broker', 'Stock Clerk', 'Stone Cutter', 'Stone Sawyer', 'Stonemason', 'Stonemason', 'Storage Manager OR Distribution Manager', 'Streetcar Operator', 'Stringed Instrument Repairer and Tuner', 'Structural Iron and Steel Worker', 'Structural Metal Fabricator', 'Substance Abuse Counselor', 'Substance Abuse Social Worker', 'Substation Maintenance', 'Supervisor Correctional Officer', 'Supervisor Fire Fighting Worker', 'Supervisor of Customer Service', 'Supervisor of Police', 'Surgeon', 'Surgical Technologist', 'Survey Researcher', 'Surveying and Mapping Technician', 'Surveying Technician', 'Surveyor', 'Sys Admin', 'System Administrator',
'Tailor', 'Talent Acquisition Manager', 'Talent Director', 'Tank Car', 'Taper', 'Tax Examiner', 'Tax Preparer', 'Taxi Drivers and Chauffeur', 'Teacher', 'Teacher Assistant', 'Team Assembler', 'Technical Director', 'Technical Program Manager', 'Technical Specialist', 'Technical Writer', 'Telecommunications Equipment Installer', 'Telecommunications Facility Examiner', 'Telecommunications Line Installer', 'Telemarketer', 'Telephone Operator', 'Telephone Station Installer and Repairer', 'Teller', 'Terrazzo Workes and Finisher', 'Textile Cutting Machine Operator', 'Textile Dyeing Machine Operator', 'Textile Knitting Machine Operator', 'Textile Machine Operator', 'Textile Worker', 'Therapist', 'Ticket Agent', 'Tile Setter OR Marble Setter', 'Timing Device Assemblers', 'Tire Builder', 'Tire Changer', 'Title Abstractor', 'Title Examiner', 'Title Searcher', 'Tool and Die Maker', 'Tool Set-Up Operator', 'Tool Sharpener', 'Tour Guide', 'Tractor Operator', 'Tractor-Trailer Truck Driver', 'Traffic Technician', 'Train Crew', 'Trainer', 'Training Manager OR Development Manager', 'Transformer Repairer', 'Transit Police OR Railroad Police', 'Transportation and Material-Moving', 'Transportation Attendant', 'Transportation Equipment Maintenance', 'Transportation Equipment Painters', 'Transportation Inspector', 'Transportation Manager', 'Transportation Worker', 'Travel Agent', 'Travel Clerk', 'Travel Guide', 'Tree Trimmer', 'Truck Driver', 'TSA', 'Typesetter', 'Typesetting Machine Operator',
'Umpire and Referee', 'Underground Mining', 'University', 'Upholsterer', 'Urban Planner', 'User Experience Manager', 'User Experience Researcher', 'Usher', 'Utility Meter Reader',
'Valve Repairer OR Regulator Repairer', 'Vending Machine Servicer', 'Veterinarian', 'Veterinary Assistant OR Laboratory Animal Caretaker', 'Veterinary Technician', 'Vice President Of Human Resources', 'Vice President Of Marketing', 'Video Editor', 'Visual Designer', 'Vocational Education Teacher',
'Waiter', 'Waitress', 'Warehouse', 'Washing Equipment Operator', 'Waste Treatment Plant Operator', 'Watch Repairer', 'Weapons Specialists', 'Web Developer', 'Webmaster', 'Welder', 'Welder', 'Welder and Cutter', 'Welder-Fitter', 'Welding Machine Tender', 'Welding Machine Operator', 'Welding Machine Setter', 'Welfare Eligibility Clerk', 'Well and Core Drill Operator', 'Wellhead Pumper', 'Wholesale Buyer', 'Wind Instrument Repairer', 'Woodworker', 'Woodworking Machine Operator', 'Woodworking Machine Setter', 'Word Processors and Typist', 'Writer OR Author',
'Zoologists OR Wildlife Biologist',
);

protected static $companySuffix = array('Inc', 'and Sons', 'LLC', 'Group', 'PLC', 'Ltd');




public function catchPhrase()
{
$result = array();
foreach (static::$catchPhraseWords as &$word) {
$result[] = static::randomElement($word);
}

return join($result, ' ');
}




public function bs()
{
$result = array();
foreach (static::$bsWords as &$word) {
$result[] = static::randomElement($word);
}

return join($result, ' ');
}
}
<?php

namespace Faker\Provider\en_US;

class Text extends \Faker\Provider\Text
{































protected static $baseText = <<<'EOT'
CHAPTER I. Down the Rabbit-Hole

Alice was beginning to get very tired of sitting by her sister on the
bank, and of having nothing to do: once or twice she had peeped into the
book her sister was reading, but it had no pictures or conversations in
it, 'and what is the use of a book,' thought Alice 'without pictures or
conversations?'

So she was considering in her own mind (as well as she could, for the
hot day made her feel very sleepy and stupid), whether the pleasure
of making a daisy-chain would be worth the trouble of getting up and
picking the daisies, when suddenly a White Rabbit with pink eyes ran
close by her.

There was nothing so VERY remarkable in that; nor did Alice think it so
VERY much out of the way to hear the Rabbit say to itself, 'Oh dear!
Oh dear! I shall be late!' (when she thought it over afterwards, it
occurred to her that she ought to have wondered at this, but at the time
it all seemed quite natural); but when the Rabbit actually TOOK A WATCH
OUT OF ITS WAISTCOAT-POCKET, and looked at it, and then hurried on,
Alice started to her feet, for it flashed across her mind that she had
never before seen a rabbit with either a waistcoat-pocket, or a watch
to take out of it, and burning with curiosity, she ran across the field
after it, and fortunately was just in time to see it pop down a large
rabbit-hole under the hedge.

In another moment down went Alice after it, never once considering how
in the world she was to get out again.

The rabbit-hole went straight on like a tunnel for some way, and then
dipped suddenly down, so suddenly that Alice had not a moment to think
about stopping herself before she found herself falling down a very deep
well.

Either the well was very deep, or she fell very slowly, for she had
plenty of time as she went down to look about her and to wonder what was
going to happen next. First, she tried to look down and make out what
she was coming to, but it was too dark to see anything; then she
looked at the sides of the well, and noticed that they were filled with
cupboards and book-shelves; here and there she saw maps and pictures
hung upon pegs. She took down a jar from one of the shelves as
she passed; it was labelled 'ORANGE MARMALADE', but to her great
disappointment it was empty: she did not like to drop the jar for fear
of killing somebody, so managed to put it into one of the cupboards as
she fell past it.

'Well!' thought Alice to herself, 'after such a fall as this, I shall
think nothing of tumbling down stairs! How brave they'll all think me at
home! Why, I wouldn't say anything about it, even if I fell off the top
of the house!' (Which was very likely true.)

Down, down, down. Would the fall NEVER come to an end! 'I wonder how
many miles I've fallen by this time?' she said aloud. 'I must be getting
somewhere near the centre of the earth. Let me see: that would be four
thousand miles down, I think--' (for, you see, Alice had learnt several
things of this sort in her lessons in the schoolroom, and though this
was not a VERY good opportunity for showing off her knowledge, as there
was no one to listen to her, still it was good practice to say it over)
'--yes, that's about the right distance--but then I wonder what Latitude
or Longitude I've got to?' (Alice had no idea what Latitude was, or
Longitude either, but thought they were nice grand words to say.)

Presently she began again. 'I wonder if I shall fall right THROUGH the
earth! How funny it'll seem to come out among the people that walk with
their heads downward! The Antipathies, I think--' (she was rather glad
there WAS no one listening, this time, as it didn't sound at all the
right word) '--but I shall have to ask them what the name of the country
is, you know. Please, Ma'am, is this New Zealand or Australia?' (and
she tried to curtsey as she spoke--fancy CURTSEYING as you're falling
through the air! Do you think you could manage it?) 'And what an
ignorant little girl she'll think me for asking! No, it'll never do to
ask: perhaps I shall see it written up somewhere.'

Down, down, down. There was nothing else to do, so Alice soon began
talking again. 'Dinah'll miss me very much to-night, I should think!'
(Dinah was the cat.) 'I hope they'll remember her saucer of milk at
tea-time. Dinah my dear! I wish you were down here with me! There are no
mice in the air, I'm afraid, but you might catch a bat, and that's very
like a mouse, you know. But do cats eat bats, I wonder?' And here Alice
began to get rather sleepy, and went on saying to herself, in a dreamy
sort of way, 'Do cats eat bats? Do cats eat bats?' and sometimes, 'Do
bats eat cats?' for, you see, as she couldn't answer either question,
it didn't much matter which way she put it. She felt that she was dozing
off, and had just begun to dream that she was walking hand in hand with
Dinah, and saying to her very earnestly, 'Now, Dinah, tell me the truth:
did you ever eat a bat?' when suddenly, thump! thump! down she came upon
a heap of sticks and dry leaves, and the fall was over.

Alice was not a bit hurt, and she jumped up on to her feet in a moment:
she looked up, but it was all dark overhead; before her was another
long passage, and the White Rabbit was still in sight, hurrying down it.
There was not a moment to be lost: away went Alice like the wind, and
was just in time to hear it say, as it turned a corner, 'Oh my ears
and whiskers, how late it's getting!' She was close behind it when she
turned the corner, but the Rabbit was no longer to be seen: she found
herself in a long, low hall, which was lit up by a row of lamps hanging
from the roof.

There were doors all round the hall, but they were all locked; and when
Alice had been all the way down one side and up the other, trying every
door, she walked sadly down the middle, wondering how she was ever to
get out again.

Suddenly she came upon a little three-legged table, all made of solid
glass; there was nothing on it except a tiny golden key, and Alice's
first thought was that it might belong to one of the doors of the hall;
but, alas! either the locks were too large, or the key was too small,
but at any rate it would not open any of them. However, on the second
time round, she came upon a low curtain she had not noticed before, and
behind it was a little door about fifteen inches high: she tried the
little golden key in the lock, and to her great delight it fitted!

Alice opened the door and found that it led into a small passage, not
much larger than a rat-hole: she knelt down and looked along the passage
into the loveliest garden you ever saw. How she longed to get out of
that dark hall, and wander about among those beds of bright flowers and
those cool fountains, but she could not even get her head through the
doorway; 'and even if my head would go through,' thought poor Alice, 'it
would be of very little use without my shoulders. Oh, how I wish I could
shut up like a telescope! I think I could, if I only knew how to begin.'
For, you see, so many out-of-the-way things had happened lately,
that Alice had begun to think that very few things indeed were really
impossible.

There seemed to be no use in waiting by the little door, so she went
back to the table, half hoping she might find another key on it, or at
any rate a book of rules for shutting people up like telescopes: this
time she found a little bottle on it, ('which certainly was not here
before,' said Alice,) and round the neck of the bottle was a paper
label, with the words 'DRINK ME' beautifully printed on it in large
letters.

It was all very well to say 'Drink me,' but the wise little Alice was
not going to do THAT in a hurry. 'No, I'll look first,' she said, 'and
see whether it's marked "poison" or not'; for she had read several nice
little histories about children who had got burnt, and eaten up by wild
beasts and other unpleasant things, all because they WOULD not remember
the simple rules their friends had taught them: such as, that a red-hot
poker will burn you if you hold it too long; and that if you cut your
finger VERY deeply with a knife, it usually bleeds; and she had never
forgotten that, if you drink much from a bottle marked 'poison,' it is
almost certain to disagree with you, sooner or later.

However, this bottle was NOT marked 'poison,' so Alice ventured to taste
it, and finding it very nice, (it had, in fact, a sort of mixed flavour
of cherry-tart, custard, pine-apple, roast turkey, toffee, and hot
buttered toast,) she very soon finished it off.

  *    *    *    *    *    *    *

    *    *    *    *    *    *

  *    *    *    *    *    *    *

'What a curious feeling!' said Alice; 'I must be shutting up like a
telescope.'

And so it was indeed: she was now only ten inches high, and her face
brightened up at the thought that she was now the right size for going
through the little door into that lovely garden. First, however, she
waited for a few minutes to see if she was going to shrink any further:
she felt a little nervous about this; 'for it might end, you know,' said
Alice to herself, 'in my going out altogether, like a candle. I wonder
what I should be like then?' And she tried to fancy what the flame of a
candle is like after the candle is blown out, for she could not remember
ever having seen such a thing.

After a while, finding that nothing more happened, she decided on going
into the garden at once; but, alas for poor Alice! when she got to the
door, she found she had forgotten the little golden key, and when she
went back to the table for it, she found she could not possibly reach
it: she could see it quite plainly through the glass, and she tried her
best to climb up one of the legs of the table, but it was too slippery;
and when she had tired herself out with trying, the poor little thing
sat down and cried.

'Come, there's no use in crying like that!' said Alice to herself,
rather sharply; 'I advise you to leave off this minute!' She generally
gave herself very good advice, (though she very seldom followed it),
and sometimes she scolded herself so severely as to bring tears into
her eyes; and once she remembered trying to box her own ears for having
cheated herself in a game of croquet she was playing against herself,
for this curious child was very fond of pretending to be two people.
'But it's no use now,' thought poor Alice, 'to pretend to be two people!
Why, there's hardly enough of me left to make ONE respectable person!'

Soon her eye fell on a little glass box that was lying under the table:
she opened it, and found in it a very small cake, on which the words
'EAT ME' were beautifully marked in currants. 'Well, I'll eat it,' said
Alice, 'and if it makes me grow larger, I can reach the key; and if it
makes me grow smaller, I can creep under the door; so either way I'll
get into the garden, and I don't care which happens!'

She ate a little bit, and said anxiously to herself, 'Which way? Which
way?', holding her hand on the top of her head to feel which way it was
growing, and she was quite surprised to find that she remained the same
size: to be sure, this generally happens when one eats cake, but Alice
had got so much into the way of expecting nothing but out-of-the-way
things to happen, that it seemed quite dull and stupid for life to go on
in the common way.

So she set to work, and very soon finished off the cake.

  *    *    *    *    *    *    *

    *    *    *    *    *    *

  *    *    *    *    *    *    *

CHAPTER II. The Pool of Tears

'Curiouser and curiouser!' cried Alice (she was so much surprised, that
for the moment she quite forgot how to speak good English); 'now I'm
opening out like the largest telescope that ever was! Good-bye, feet!'
(for when she looked down at her feet, they seemed to be almost out of
sight, they were getting so far off). 'Oh, my poor little feet, I wonder
who will put on your shoes and stockings for you now, dears? I'm sure
_I_ shan't be able! I shall be a great deal too far off to trouble
myself about you: you must manage the best way you can;--but I must be
kind to them,' thought Alice, 'or perhaps they won't walk the way I want
to go! Let me see: I'll give them a new pair of boots every Christmas.'

And she went on planning to herself how she would manage it. 'They must
go by the carrier,' she thought; 'and how funny it'll seem, sending
presents to one's own feet! And how odd the directions will look!

     ALICE'S RIGHT FOOT, ESQ.
       HEARTHRUG,
         NEAR THE FENDER,
           (WITH ALICE'S LOVE).

Oh dear, what nonsense I'm talking!'

Just then her head struck against the roof of the hall: in fact she was
now more than nine feet high, and she at once took up the little golden
key and hurried off to the garden door.

Poor Alice! It was as much as she could do, lying down on one side, to
look through into the garden with one eye; but to get through was more
hopeless than ever: she sat down and began to cry again.

'You ought to be ashamed of yourself,' said Alice, 'a great girl like
you,' (she might well say this), 'to go on crying in this way! Stop this
moment, I tell you!' But she went on all the same, shedding gallons of
tears, until there was a large pool all round her, about four inches
deep and reaching half down the hall.

After a time she heard a little pattering of feet in the distance, and
she hastily dried her eyes to see what was coming. It was the White
Rabbit returning, splendidly dressed, with a pair of white kid gloves in
one hand and a large fan in the other: he came trotting along in a great
hurry, muttering to himself as he came, 'Oh! the Duchess, the Duchess!
Oh! won't she be savage if I've kept her waiting!' Alice felt so
desperate that she was ready to ask help of any one; so, when the Rabbit
came near her, she began, in a low, timid voice, 'If you please, sir--'
The Rabbit started violently, dropped the white kid gloves and the fan,
and skurried away into the darkness as hard as he could go.

Alice took up the fan and gloves, and, as the hall was very hot, she
kept fanning herself all the time she went on talking: 'Dear, dear! How
queer everything is to-day! And yesterday things went on just as usual.
I wonder if I've been changed in the night? Let me think: was I the
same when I got up this morning? I almost think I can remember feeling a
little different. But if I'm not the same, the next question is, Who
in the world am I? Ah, THAT'S the great puzzle!' And she began thinking
over all the children she knew that were of the same age as herself, to
see if she could have been changed for any of them.

'I'm sure I'm not Ada,' she said, 'for her hair goes in such long
ringlets, and mine doesn't go in ringlets at all; and I'm sure I can't
be Mabel, for I know all sorts of things, and she, oh! she knows such a
very little! Besides, SHE'S she, and I'm I, and--oh dear, how puzzling
it all is! I'll try if I know all the things I used to know. Let me
see: four times five is twelve, and four times six is thirteen, and
four times seven is--oh dear! I shall never get to twenty at that rate!
However, the Multiplication Table doesn't signify: let's try Geography.
London is the capital of Paris, and Paris is the capital of Rome, and
Rome--no, THAT'S all wrong, I'm certain! I must have been changed for
Mabel! I'll try and say "How doth the little--"' and she crossed her
hands on her lap as if she were saying lessons, and began to repeat it,
but her voice sounded hoarse and strange, and the words did not come the
same as they used to do:--

     'How doth the little crocodile
      Improve his shining tail,
     And pour the waters of the Nile
      On every golden scale!

     'How cheerfully he seems to grin,
      How neatly spread his claws,
     And welcome little fishes in
      With gently smiling jaws!'

'I'm sure those are not the right words,' said poor Alice, and her eyes
filled with tears again as she went on, 'I must be Mabel after all, and
I shall have to go and live in that poky little house, and have next to
no toys to play with, and oh! ever so many lessons to learn! No, I've
made up my mind about it; if I'm Mabel, I'll stay down here! It'll be no
use their putting their heads down and saying "Come up again, dear!" I
shall only look up and say "Who am I then? Tell me that first, and then,
if I like being that person, I'll come up: if not, I'll stay down here
till I'm somebody else"--but, oh dear!' cried Alice, with a sudden burst
of tears, 'I do wish they WOULD put their heads down! I am so VERY tired
of being all alone here!'

As she said this she looked down at her hands, and was surprised to see
that she had put on one of the Rabbit's little white kid gloves while
she was talking. 'How CAN I have done that?' she thought. 'I must
be growing small again.' She got up and went to the table to measure
herself by it, and found that, as nearly as she could guess, she was now
about two feet high, and was going on shrinking rapidly: she soon found
out that the cause of this was the fan she was holding, and she dropped
it hastily, just in time to avoid shrinking away altogether.

'That WAS a narrow escape!' said Alice, a good deal frightened at the
sudden change, but very glad to find herself still in existence; 'and
now for the garden!' and she ran with all speed back to the little door:
but, alas! the little door was shut again, and the little golden key was
lying on the glass table as before, 'and things are worse than ever,'
thought the poor child, 'for I never was so small as this before, never!
And I declare it's too bad, that it is!'

As she said these words her foot slipped, and in another moment, splash!
she was up to her chin in salt water. Her first idea was that she
had somehow fallen into the sea, 'and in that case I can go back by
railway,' she said to herself. (Alice had been to the seaside once in
her life, and had come to the general conclusion, that wherever you go
to on the English coast you find a number of bathing machines in the
sea, some children digging in the sand with wooden spades, then a row
of lodging houses, and behind them a railway station.) However, she soon
made out that she was in the pool of tears which she had wept when she
was nine feet high.

'I wish I hadn't cried so much!' said Alice, as she swam about, trying
to find her way out. 'I shall be punished for it now, I suppose, by
being drowned in my own tears! That WILL be a queer thing, to be sure!
However, everything is queer to-day.'

Just then she heard something splashing about in the pool a little way
off, and she swam nearer to make out what it was: at first she thought
it must be a walrus or hippopotamus, but then she remembered how small
she was now, and she soon made out that it was only a mouse that had
slipped in like herself.

'Would it be of any use, now,' thought Alice, 'to speak to this mouse?
Everything is so out-of-the-way down here, that I should think very
likely it can talk: at any rate, there's no harm in trying.' So she
began: 'O Mouse, do you know the way out of this pool? I am very tired
of swimming about here, O Mouse!' (Alice thought this must be the right
way of speaking to a mouse: she had never done such a thing before, but
she remembered having seen in her brother's Latin Grammar, 'A mouse--of
a mouse--to a mouse--a mouse--O mouse!') The Mouse looked at her rather
inquisitively, and seemed to her to wink with one of its little eyes,
but it said nothing.

'Perhaps it doesn't understand English,' thought Alice; 'I daresay it's
a French mouse, come over with William the Conqueror.' (For, with all
her knowledge of history, Alice had no very clear notion how long ago
anything had happened.) So she began again: 'Ou est ma chatte?' which
was the first sentence in her French lesson-book. The Mouse gave a
sudden leap out of the water, and seemed to quiver all over with fright.
'Oh, I beg your pardon!' cried Alice hastily, afraid that she had hurt
the poor animal's feelings. 'I quite forgot you didn't like cats.'

'Not like cats!' cried the Mouse, in a shrill, passionate voice. 'Would
YOU like cats if you were me?'

'Well, perhaps not,' said Alice in a soothing tone: 'don't be angry
about it. And yet I wish I could show you our cat Dinah: I think you'd
take a fancy to cats if you could only see her. She is such a dear quiet
thing,' Alice went on, half to herself, as she swam lazily about in the
pool, 'and she sits purring so nicely by the fire, licking her paws and
washing her face--and she is such a nice soft thing to nurse--and she's
such a capital one for catching mice--oh, I beg your pardon!' cried
Alice again, for this time the Mouse was bristling all over, and she
felt certain it must be really offended. 'We won't talk about her any
more if you'd rather not.'

'We indeed!' cried the Mouse, who was trembling down to the end of his
tail. 'As if I would talk on such a subject! Our family always HATED
cats: nasty, low, vulgar things! Don't let me hear the name again!'

'I won't indeed!' said Alice, in a great hurry to change the subject of
conversation. 'Are you--are you fond--of--of dogs?' The Mouse did not
answer, so Alice went on eagerly: 'There is such a nice little dog near
our house I should like to show you! A little bright-eyed terrier, you
know, with oh, such long curly brown hair! And it'll fetch things when
you throw them, and it'll sit up and beg for its dinner, and all sorts
of things--I can't remember half of them--and it belongs to a farmer,
you know, and he says it's so useful, it's worth a hundred pounds! He
says it kills all the rats and--oh dear!' cried Alice in a sorrowful
tone, 'I'm afraid I've offended it again!' For the Mouse was swimming
away from her as hard as it could go, and making quite a commotion in
the pool as it went.

So she called softly after it, 'Mouse dear! Do come back again, and we
won't talk about cats or dogs either, if you don't like them!' When the
Mouse heard this, it turned round and swam slowly back to her: its
face was quite pale (with passion, Alice thought), and it said in a low
trembling voice, 'Let us get to the shore, and then I'll tell you my
history, and you'll understand why it is I hate cats and dogs.'

It was high time to go, for the pool was getting quite crowded with the
birds and animals that had fallen into it: there were a Duck and a Dodo,
a Lory and an Eaglet, and several other curious creatures. Alice led the
way, and the whole party swam to the shore.




CHAPTER III. A Caucus-Race and a Long Tale

They were indeed a queer-looking party that assembled on the bank--the
birds with draggled feathers, the animals with their fur clinging close
to them, and all dripping wet, cross, and uncomfortable.

The first question of course was, how to get dry again: they had a
consultation about this, and after a few minutes it seemed quite natural
to Alice to find herself talking familiarly with them, as if she had
known them all her life. Indeed, she had quite a long argument with the
Lory, who at last turned sulky, and would only say, 'I am older than
you, and must know better'; and this Alice would not allow without
knowing how old it was, and, as the Lory positively refused to tell its
age, there was no more to be said.

At last the Mouse, who seemed to be a person of authority among them,
called out, 'Sit down, all of you, and listen to me! I'LL soon make you
dry enough!' They all sat down at once, in a large ring, with the Mouse
in the middle. Alice kept her eyes anxiously fixed on it, for she felt
sure she would catch a bad cold if she did not get dry very soon.

'Ahem!' said the Mouse with an important air, 'are you all ready? This
is the driest thing I know. Silence all round, if you please! "William
the Conqueror, whose cause was favoured by the pope, was soon submitted
to by the English, who wanted leaders, and had been of late much
accustomed to usurpation and conquest. Edwin and Morcar, the earls of
Mercia and Northumbria--"'

'Ugh!' said the Lory, with a shiver.

'I beg your pardon!' said the Mouse, frowning, but very politely: 'Did
you speak?'

'Not I!' said the Lory hastily.

'I thought you did,' said the Mouse. '--I proceed. "Edwin and Morcar,
the earls of Mercia and Northumbria, declared for him: and even Stigand,
the patriotic archbishop of Canterbury, found it advisable--"'

'Found WHAT?' said the Duck.

'Found IT,' the Mouse replied rather crossly: 'of course you know what
"it" means.'

'I know what "it" means well enough, when I find a thing,' said the
Duck: 'it's generally a frog or a worm. The question is, what did the
archbishop find?'

The Mouse did not notice this question, but hurriedly went on, '"--found
it advisable to go with Edgar Atheling to meet William and offer him the
crown. William's conduct at first was moderate. But the insolence of his
Normans--" How are you getting on now, my dear?' it continued, turning
to Alice as it spoke.

'As wet as ever,' said Alice in a melancholy tone: 'it doesn't seem to
dry me at all.'

'In that case,' said the Dodo solemnly, rising to its feet, 'I move
that the meeting adjourn, for the immediate adoption of more energetic
remedies--'

'Speak English!' said the Eaglet. 'I don't know the meaning of half
those long words, and, what's more, I don't believe you do either!' And
the Eaglet bent down its head to hide a smile: some of the other birds
tittered audibly.

'What I was going to say,' said the Dodo in an offended tone, 'was, that
the best thing to get us dry would be a Caucus-race.'

'What IS a Caucus-race?' said Alice; not that she wanted much to know,
but the Dodo had paused as if it thought that SOMEBODY ought to speak,
and no one else seemed inclined to say anything.

'Why,' said the Dodo, 'the best way to explain it is to do it.' (And, as
you might like to try the thing yourself, some winter day, I will tell
you how the Dodo managed it.)

First it marked out a race-course, in a sort of circle, ('the exact
shape doesn't matter,' it said,) and then all the party were placed
along the course, here and there. There was no 'One, two, three, and
away,' but they began running when they liked, and left off when they
liked, so that it was not easy to know when the race was over. However,
when they had been running half an hour or so, and were quite dry again,
the Dodo suddenly called out 'The race is over!' and they all crowded
round it, panting, and asking, 'But who has won?'

This question the Dodo could not answer without a great deal of thought,
and it sat for a long time with one finger pressed upon its forehead
(the position in which you usually see Shakespeare, in the pictures
of him), while the rest waited in silence. At last the Dodo said,
'EVERYBODY has won, and all must have prizes.'

'But who is to give the prizes?' quite a chorus of voices asked.

'Why, SHE, of course,' said the Dodo, pointing to Alice with one finger;
and the whole party at once crowded round her, calling out in a confused
way, 'Prizes! Prizes!'

Alice had no idea what to do, and in despair she put her hand in her
pocket, and pulled out a box of comfits, (luckily the salt water had
not got into it), and handed them round as prizes. There was exactly one
a-piece all round.

'But she must have a prize herself, you know,' said the Mouse.

'Of course,' the Dodo replied very gravely. 'What else have you got in
your pocket?' he went on, turning to Alice.

'Only a thimble,' said Alice sadly.

'Hand it over here,' said the Dodo.

Then they all crowded round her once more, while the Dodo solemnly
presented the thimble, saying 'We beg your acceptance of this elegant
thimble'; and, when it had finished this short speech, they all cheered.

Alice thought the whole thing very absurd, but they all looked so grave
that she did not dare to laugh; and, as she could not think of anything
to say, she simply bowed, and took the thimble, looking as solemn as she
could.

The next thing was to eat the comfits: this caused some noise and
confusion, as the large birds complained that they could not taste
theirs, and the small ones choked and had to be patted on the back.
However, it was over at last, and they sat down again in a ring, and
begged the Mouse to tell them something more.

'You promised to tell me your history, you know,' said Alice, 'and why
it is you hate--C and D,' she added in a whisper, half afraid that it
would be offended again.

'Mine is a long and a sad tale!' said the Mouse, turning to Alice, and
sighing.

'It IS a long tail, certainly,' said Alice, looking down with wonder at
the Mouse's tail; 'but why do you call it sad?' And she kept on puzzling
about it while the Mouse was speaking, so that her idea of the tale was
something like this:--

         'Fury said to a
         mouse, That he
        met in the
       house,
     "Let us
      both go to
       law: I will
        prosecute
         YOU.--Come,
           I'll take no
           denial; We
          must have a
        trial: For
      really this
     morning I've
    nothing
    to do."
     Said the
      mouse to the
       cur, "Such
        a trial,
         dear Sir,
            With
          no jury
        or judge,
       would be
      wasting
      our
      breath."
       "I'll be
        judge, I'll
         be jury,"
            Said
         cunning
          old Fury:
          "I'll
          try the
            whole
            cause,
              and
           condemn
           you
          to
           death."'


'You are not attending!' said the Mouse to Alice severely. 'What are you
thinking of?'

'I beg your pardon,' said Alice very humbly: 'you had got to the fifth
bend, I think?'

'I had NOT!' cried the Mouse, sharply and very angrily.

'A knot!' said Alice, always ready to make herself useful, and looking
anxiously about her. 'Oh, do let me help to undo it!'

'I shall do nothing of the sort,' said the Mouse, getting up and walking
away. 'You insult me by talking such nonsense!'

'I didn't mean it!' pleaded poor Alice. 'But you're so easily offended,
you know!'

The Mouse only growled in reply.

'Please come back and finish your story!' Alice called after it; and the
others all joined in chorus, 'Yes, please do!' but the Mouse only shook
its head impatiently, and walked a little quicker.

'What a pity it wouldn't stay!' sighed the Lory, as soon as it was quite
out of sight; and an old Crab took the opportunity of saying to her
daughter 'Ah, my dear! Let this be a lesson to you never to lose
YOUR temper!' 'Hold your tongue, Ma!' said the young Crab, a little
snappishly. 'You're enough to try the patience of an oyster!'

'I wish I had our Dinah here, I know I do!' said Alice aloud, addressing
nobody in particular. 'She'd soon fetch it back!'

'And who is Dinah, if I might venture to ask the question?' said the
Lory.

Alice replied eagerly, for she was always ready to talk about her pet:
'Dinah's our cat. And she's such a capital one for catching mice you
can't think! And oh, I wish you could see her after the birds! Why,
she'll eat a little bird as soon as look at it!'

This speech caused a remarkable sensation among the party. Some of the
birds hurried off at once: one old Magpie began wrapping itself up very
carefully, remarking, 'I really must be getting home; the night-air
doesn't suit my throat!' and a Canary called out in a trembling voice to
its children, 'Come away, my dears! It's high time you were all in bed!'
On various pretexts they all moved off, and Alice was soon left alone.

'I wish I hadn't mentioned Dinah!' she said to herself in a melancholy
tone. 'Nobody seems to like her, down here, and I'm sure she's the best
cat in the world! Oh, my dear Dinah! I wonder if I shall ever see you
any more!' And here poor Alice began to cry again, for she felt very
lonely and low-spirited. In a little while, however, she again heard
a little pattering of footsteps in the distance, and she looked up
eagerly, half hoping that the Mouse had changed his mind, and was coming
back to finish his story.




CHAPTER IV. The Rabbit Sends in a Little Bill

It was the White Rabbit, trotting slowly back again, and looking
anxiously about as it went, as if it had lost something; and she heard
it muttering to itself 'The Duchess! The Duchess! Oh my dear paws! Oh
my fur and whiskers! She'll get me executed, as sure as ferrets are
ferrets! Where CAN I have dropped them, I wonder?' Alice guessed in a
moment that it was looking for the fan and the pair of white kid gloves,
and she very good-naturedly began hunting about for them, but they were
nowhere to be seen--everything seemed to have changed since her swim in
the pool, and the great hall, with the glass table and the little door,
had vanished completely.

Very soon the Rabbit noticed Alice, as she went hunting about, and
called out to her in an angry tone, 'Why, Mary Ann, what ARE you doing
out here? Run home this moment, and fetch me a pair of gloves and a fan!
Quick, now!' And Alice was so much frightened that she ran off at once
in the direction it pointed to, without trying to explain the mistake it
had made.

'He took me for his housemaid,' she said to herself as she ran. 'How
surprised he'll be when he finds out who I am! But I'd better take him
his fan and gloves--that is, if I can find them.' As she said this, she
came upon a neat little house, on the door of which was a bright brass
plate with the name 'W. RABBIT' engraved upon it. She went in without
knocking, and hurried upstairs, in great fear lest she should meet the
real Mary Ann, and be turned out of the house before she had found the
fan and gloves.

'How queer it seems,' Alice said to herself, 'to be going messages for
a rabbit! I suppose Dinah'll be sending me on messages next!' And she
began fancying the sort of thing that would happen: '"Miss Alice! Come
here directly, and get ready for your walk!" "Coming in a minute,
nurse! But I've got to see that the mouse doesn't get out." Only I don't
think,' Alice went on, 'that they'd let Dinah stop in the house if it
began ordering people about like that!'

By this time she had found her way into a tidy little room with a table
in the window, and on it (as she had hoped) a fan and two or three pairs
of tiny white kid gloves: she took up the fan and a pair of the gloves,
and was just going to leave the room, when her eye fell upon a little
bottle that stood near the looking-glass. There was no label this time
with the words 'DRINK ME,' but nevertheless she uncorked it and put it
to her lips. 'I know SOMETHING interesting is sure to happen,' she said
to herself, 'whenever I eat or drink anything; so I'll just see what
this bottle does. I do hope it'll make me grow large again, for really
I'm quite tired of being such a tiny little thing!'

It did so indeed, and much sooner than she had expected: before she had
drunk half the bottle, she found her head pressing against the ceiling,
and had to stoop to save her neck from being broken. She hastily put
down the bottle, saying to herself 'That's quite enough--I hope I shan't
grow any more--As it is, I can't get out at the door--I do wish I hadn't
drunk quite so much!'

Alas! it was too late to wish that! She went on growing, and growing,
and very soon had to kneel down on the floor: in another minute there
was not even room for this, and she tried the effect of lying down with
one elbow against the door, and the other arm curled round her head.
Still she went on growing, and, as a last resource, she put one arm out
of the window, and one foot up the chimney, and said to herself 'Now I
can do no more, whatever happens. What WILL become of me?'

Luckily for Alice, the little magic bottle had now had its full effect,
and she grew no larger: still it was very uncomfortable, and, as there
seemed to be no sort of chance of her ever getting out of the room
again, no wonder she felt unhappy.

'It was much pleasanter at home,' thought poor Alice, 'when one wasn't
always growing larger and smaller, and being ordered about by mice and
rabbits. I almost wish I hadn't gone down that rabbit-hole--and yet--and
yet--it's rather curious, you know, this sort of life! I do wonder what
CAN have happened to me! When I used to read fairy-tales, I fancied that
kind of thing never happened, and now here I am in the middle of one!
There ought to be a book written about me, that there ought! And when I
grow up, I'll write one--but I'm grown up now,' she added in a sorrowful
tone; 'at least there's no room to grow up any more HERE.'

'But then,' thought Alice, 'shall I NEVER get any older than I am
now? That'll be a comfort, one way--never to be an old woman--but
then--always to have lessons to learn! Oh, I shouldn't like THAT!'

'Oh, you foolish Alice!' she answered herself. 'How can you learn
lessons in here? Why, there's hardly room for YOU, and no room at all
for any lesson-books!'

And so she went on, taking first one side and then the other, and making
quite a conversation of it altogether; but after a few minutes she heard
a voice outside, and stopped to listen.

'Mary Ann! Mary Ann!' said the voice. 'Fetch me my gloves this moment!'
Then came a little pattering of feet on the stairs. Alice knew it was
the Rabbit coming to look for her, and she trembled till she shook the
house, quite forgetting that she was now about a thousand times as large
as the Rabbit, and had no reason to be afraid of it.

Presently the Rabbit came up to the door, and tried to open it; but, as
the door opened inwards, and Alice's elbow was pressed hard against it,
that attempt proved a failure. Alice heard it say to itself 'Then I'll
go round and get in at the window.'

'THAT you won't' thought Alice, and, after waiting till she fancied
she heard the Rabbit just under the window, she suddenly spread out her
hand, and made a snatch in the air. She did not get hold of anything,
but she heard a little shriek and a fall, and a crash of broken glass,
from which she concluded that it was just possible it had fallen into a
cucumber-frame, or something of the sort.

Next came an angry voice--the Rabbit's--'Pat! Pat! Where are you?' And
then a voice she had never heard before, 'Sure then I'm here! Digging
for apples, yer honour!'

'Digging for apples, indeed!' said the Rabbit angrily. 'Here! Come and
help me out of THIS!' (Sounds of more broken glass.)

'Now tell me, Pat, what's that in the window?'

'Sure, it's an arm, yer honour!' (He pronounced it 'arrum.')

'An arm, you goose! Who ever saw one that size? Why, it fills the whole
window!'

'Sure, it does, yer honour: but it's an arm for all that.'

'Well, it's got no business there, at any rate: go and take it away!'

There was a long silence after this, and Alice could only hear whispers
now and then; such as, 'Sure, I don't like it, yer honour, at all, at
all!' 'Do as I tell you, you coward!' and at last she spread out her
hand again, and made another snatch in the air. This time there were
TWO little shrieks, and more sounds of broken glass. 'What a number of
cucumber-frames there must be!' thought Alice. 'I wonder what they'll do
next! As for pulling me out of the window, I only wish they COULD! I'm
sure I don't want to stay in here any longer!'

She waited for some time without hearing anything more: at last came a
rumbling of little cartwheels, and the sound of a good many voices
all talking together: she made out the words: 'Where's the other
ladder?--Why, I hadn't to bring but one; Bill's got the other--Bill!
fetch it here, lad!--Here, put 'em up at this corner--No, tie 'em
together first--they don't reach half high enough yet--Oh! they'll
do well enough; don't be particular--Here, Bill! catch hold of this
rope--Will the roof bear?--Mind that loose slate--Oh, it's coming
down! Heads below!' (a loud crash)--'Now, who did that?--It was Bill, I
fancy--Who's to go down the chimney?--Nay, I shan't! YOU do it!--That I
won't, then!--Bill's to go down--Here, Bill! the master says you're to
go down the chimney!'

'Oh! So Bill's got to come down the chimney, has he?' said Alice to
herself. 'Shy, they seem to put everything upon Bill! I wouldn't be in
Bill's place for a good deal: this fireplace is narrow, to be sure; but
I THINK I can kick a little!'

She drew her foot as far down the chimney as she could, and waited
till she heard a little animal (she couldn't guess of what sort it was)
scratching and scrambling about in the chimney close above her: then,
saying to herself 'This is Bill,' she gave one sharp kick, and waited to
see what would happen next.

The first thing she heard was a general chorus of 'There goes Bill!'
then the Rabbit's voice along--'Catch him, you by the hedge!' then
silence, and then another confusion of voices--'Hold up his head--Brandy
now--Don't choke him--How was it, old fellow? What happened to you? Tell
us all about it!'

Last came a little feeble, squeaking voice, ('That's Bill,' thought
Alice,) 'Well, I hardly know--No more, thank ye; I'm better now--but I'm
a deal too flustered to tell you--all I know is, something comes at me
like a Jack-in-the-box, and up I goes like a sky-rocket!'

'So you did, old fellow!' said the others.

'We must burn the house down!' said the Rabbit's voice; and Alice called
out as loud as she could, 'If you do. I'll set Dinah at you!'

There was a dead silence instantly, and Alice thought to herself, 'I
wonder what they WILL do next! If they had any sense, they'd take the
roof off.' After a minute or two, they began moving about again, and
Alice heard the Rabbit say, 'A barrowful will do, to begin with.'

'A barrowful of WHAT?' thought Alice; but she had not long to doubt,
for the next moment a shower of little pebbles came rattling in at the
window, and some of them hit her in the face. 'I'll put a stop to this,'
she said to herself, and shouted out, 'You'd better not do that again!'
which produced another dead silence.

Alice noticed with some surprise that the pebbles were all turning into
little cakes as they lay on the floor, and a bright idea came into her
head. 'If I eat one of these cakes,' she thought, 'it's sure to make
SOME change in my size; and as it can't possibly make me larger, it must
make me smaller, I suppose.'

So she swallowed one of the cakes, and was delighted to find that she
began shrinking directly. As soon as she was small enough to get through
the door, she ran out of the house, and found quite a crowd of little
animals and birds waiting outside. The poor little Lizard, Bill, was
in the middle, being held up by two guinea-pigs, who were giving it
something out of a bottle. They all made a rush at Alice the moment she
appeared; but she ran off as hard as she could, and soon found herself
safe in a thick wood.

'The first thing I've got to do,' said Alice to herself, as she wandered
about in the wood, 'is to grow to my right size again; and the second
thing is to find my way into that lovely garden. I think that will be
the best plan.'

It sounded an excellent plan, no doubt, and very neatly and simply
arranged; the only difficulty was, that she had not the smallest idea
how to set about it; and while she was peering about anxiously among
the trees, a little sharp bark just over her head made her look up in a
great hurry.

An enormous puppy was looking down at her with large round eyes, and
feebly stretching out one paw, trying to touch her. 'Poor little thing!'
said Alice, in a coaxing tone, and she tried hard to whistle to it; but
she was terribly frightened all the time at the thought that it might be
hungry, in which case it would be very likely to eat her up in spite of
all her coaxing.

Hardly knowing what she did, she picked up a little bit of stick, and
held it out to the puppy; whereupon the puppy jumped into the air off
all its feet at once, with a yelp of delight, and rushed at the stick,
and made believe to worry it; then Alice dodged behind a great thistle,
to keep herself from being run over; and the moment she appeared on the
other side, the puppy made another rush at the stick, and tumbled head
over heels in its hurry to get hold of it; then Alice, thinking it was
very like having a game of play with a cart-horse, and expecting every
moment to be trampled under its feet, ran round the thistle again; then
the puppy began a series of short charges at the stick, running a very
little way forwards each time and a long way back, and barking hoarsely
all the while, till at last it sat down a good way off, panting, with
its tongue hanging out of its mouth, and its great eyes half shut.

This seemed to Alice a good opportunity for making her escape; so she
set off at once, and ran till she was quite tired and out of breath, and
till the puppy's bark sounded quite faint in the distance.

'And yet what a dear little puppy it was!' said Alice, as she leant
against a buttercup to rest herself, and fanned herself with one of the
leaves: 'I should have liked teaching it tricks very much, if--if I'd
only been the right size to do it! Oh dear! I'd nearly forgotten that
I've got to grow up again! Let me see--how IS it to be managed? I
suppose I ought to eat or drink something or other; but the great
question is, what?'

The great question certainly was, what? Alice looked all round her at
the flowers and the blades of grass, but she did not see anything that
looked like the right thing to eat or drink under the circumstances.
There was a large mushroom growing near her, about the same height as
herself; and when she had looked under it, and on both sides of it, and
behind it, it occurred to her that she might as well look and see what
was on the top of it.

She stretched herself up on tiptoe, and peeped over the edge of the
mushroom, and her eyes immediately met those of a large caterpillar,
that was sitting on the top with its arms folded, quietly smoking a long
hookah, and taking not the smallest notice of her or of anything else.




CHAPTER V. Advice from a Caterpillar

The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.

'Who are YOU?' said the Caterpillar.

This was not an encouraging opening for a conversation. Alice replied,
rather shyly, 'I--I hardly know, sir, just at present--at least I know
who I WAS when I got up this morning, but I think I must have been
changed several times since then.'

'What do you mean by that?' said the Caterpillar sternly. 'Explain
yourself!'

'I can't explain MYSELF, I'm afraid, sir' said Alice, 'because I'm not
myself, you see.'

'I don't see,' said the Caterpillar.

'I'm afraid I can't put it more clearly,' Alice replied very politely,
'for I can't understand it myself to begin with; and being so many
different sizes in a day is very confusing.'

'It isn't,' said the Caterpillar.

'Well, perhaps you haven't found it so yet,' said Alice; 'but when you
have to turn into a chrysalis--you will some day, you know--and then
after that into a butterfly, I should think you'll feel it a little
queer, won't you?'

'Not a bit,' said the Caterpillar.

'Well, perhaps your feelings may be different,' said Alice; 'all I know
is, it would feel very queer to ME.'

'You!' said the Caterpillar contemptuously. 'Who are YOU?'

Which brought them back again to the beginning of the conversation.
Alice felt a little irritated at the Caterpillar's making such VERY
short remarks, and she drew herself up and said, very gravely, 'I think,
you ought to tell me who YOU are, first.'

'Why?' said the Caterpillar.

Here was another puzzling question; and as Alice could not think of any
good reason, and as the Caterpillar seemed to be in a VERY unpleasant
state of mind, she turned away.

'Come back!' the Caterpillar called after her. 'I've something important
to say!'

This sounded promising, certainly: Alice turned and came back again.

'Keep your temper,' said the Caterpillar.

'Is that all?' said Alice, swallowing down her anger as well as she
could.

'No,' said the Caterpillar.

Alice thought she might as well wait, as she had nothing else to do, and
perhaps after all it might tell her something worth hearing. For some
minutes it puffed away without speaking, but at last it unfolded its
arms, took the hookah out of its mouth again, and said, 'So you think
you're changed, do you?'

'I'm afraid I am, sir,' said Alice; 'I can't remember things as I
used--and I don't keep the same size for ten minutes together!'

'Can't remember WHAT things?' said the Caterpillar.

'Well, I've tried to say "HOW DOTH THE LITTLE BUSY BEE," but it all came
different!' Alice replied in a very melancholy voice.

'Repeat, "YOU ARE OLD, FATHER WILLIAM,"' said the Caterpillar.

Alice folded her hands, and began:--

   'You are old, Father William,' the young man said,
    'And your hair has become very white;
   And yet you incessantly stand on your head--
    Do you think, at your age, it is right?'

   'In my youth,' Father William replied to his son,
    'I feared it might injure the brain;
   But, now that I'm perfectly sure I have none,
    Why, I do it again and again.'

   'You are old,' said the youth, 'as I mentioned before,
    And have grown most uncommonly fat;
   Yet you turned a back-somersault in at the door--
    Pray, what is the reason of that?'

   'In my youth,' said the sage, as he shook his grey locks,
    'I kept all my limbs very supple
   By the use of this ointment--one shilling the box--
    Allow me to sell you a couple?'

   'You are old,' said the youth, 'and your jaws are too weak
    For anything tougher than suet;
   Yet you finished the goose, with the bones and the beak--
    Pray how did you manage to do it?'

   'In my youth,' said his father, 'I took to the law,
    And argued each case with my wife;
   And the muscular strength, which it gave to my jaw,
    Has lasted the rest of my life.'

   'You are old,' said the youth, 'one would hardly suppose
    That your eye was as steady as ever;
   Yet you balanced an eel on the end of your nose--
    What made you so awfully clever?'

   'I have answered three questions, and that is enough,'
    Said his father; 'don't give yourself airs!
   Do you think I can listen all day to such stuff?
    Be off, or I'll kick you down stairs!'


'That is not said right,' said the Caterpillar.

'Not QUITE right, I'm afraid,' said Alice, timidly; 'some of the words
have got altered.'

'It is wrong from beginning to end,' said the Caterpillar decidedly, and
there was silence for some minutes.

The Caterpillar was the first to speak.

'What size do you want to be?' it asked.

'Oh, I'm not particular as to size,' Alice hastily replied; 'only one
doesn't like changing so often, you know.'

'I DON'T know,' said the Caterpillar.

Alice said nothing: she had never been so much contradicted in her life
before, and she felt that she was losing her temper.

'Are you content now?' said the Caterpillar.

'Well, I should like to be a LITTLE larger, sir, if you wouldn't mind,'
said Alice: 'three inches is such a wretched height to be.'

'It is a very good height indeed!' said the Caterpillar angrily, rearing
itself upright as it spoke (it was exactly three inches high).

'But I'm not used to it!' pleaded poor Alice in a piteous tone. And
she thought of herself, 'I wish the creatures wouldn't be so easily
offended!'

'You'll get used to it in time,' said the Caterpillar; and it put the
hookah into its mouth and began smoking again.

This time Alice waited patiently until it chose to speak again. In
a minute or two the Caterpillar took the hookah out of its mouth
and yawned once or twice, and shook itself. Then it got down off the
mushroom, and crawled away in the grass, merely remarking as it went,
'One side will make you grow taller, and the other side will make you
grow shorter.'

'One side of WHAT? The other side of WHAT?' thought Alice to herself.

'Of the mushroom,' said the Caterpillar, just as if she had asked it
aloud; and in another moment it was out of sight.

Alice remained looking thoughtfully at the mushroom for a minute, trying
to make out which were the two sides of it; and as it was perfectly
round, she found this a very difficult question. However, at last she
stretched her arms round it as far as they would go, and broke off a bit
of the edge with each hand.

'And now which is which?' she said to herself, and nibbled a little of
the right-hand bit to try the effect: the next moment she felt a violent
blow underneath her chin: it had struck her foot!

She was a good deal frightened by this very sudden change, but she felt
that there was no time to be lost, as she was shrinking rapidly; so she
set to work at once to eat some of the other bit. Her chin was pressed
so closely against her foot, that there was hardly room to open her
mouth; but she did it at last, and managed to swallow a morsel of the
lefthand bit.


  *    *    *    *    *    *    *

    *    *    *    *    *    *

  *    *    *    *    *    *    *

'Come, my head's free at last!' said Alice in a tone of delight, which
changed into alarm in another moment, when she found that her shoulders
were nowhere to be found: all she could see, when she looked down, was
an immense length of neck, which seemed to rise like a stalk out of a
sea of green leaves that lay far below her.

'What CAN all that green stuff be?' said Alice. 'And where HAVE my
shoulders got to? And oh, my poor hands, how is it I can't see you?'
She was moving them about as she spoke, but no result seemed to follow,
except a little shaking among the distant green leaves.

As there seemed to be no chance of getting her hands up to her head, she
tried to get her head down to them, and was delighted to find that her
neck would bend about easily in any direction, like a serpent. She had
just succeeded in curving it down into a graceful zigzag, and was going
to dive in among the leaves, which she found to be nothing but the tops
of the trees under which she had been wandering, when a sharp hiss made
her draw back in a hurry: a large pigeon had flown into her face, and
was beating her violently with its wings.

'Serpent!' screamed the Pigeon.

'I'm NOT a serpent!' said Alice indignantly. 'Let me alone!'

'Serpent, I say again!' repeated the Pigeon, but in a more subdued tone,
and added with a kind of sob, 'I've tried every way, and nothing seems
to suit them!'

'I haven't the least idea what you're talking about,' said Alice.

'I've tried the roots of trees, and I've tried banks, and I've tried
hedges,' the Pigeon went on, without attending to her; 'but those
serpents! There's no pleasing them!'

Alice was more and more puzzled, but she thought there was no use in
saying anything more till the Pigeon had finished.

'As if it wasn't trouble enough hatching the eggs,' said the Pigeon;
'but I must be on the look-out for serpents night and day! Why, I
haven't had a wink of sleep these three weeks!'

'I'm very sorry you've been annoyed,' said Alice, who was beginning to
see its meaning.

'And just as I'd taken the highest tree in the wood,' continued the
Pigeon, raising its voice to a shriek, 'and just as I was thinking I
should be free of them at last, they must needs come wriggling down from
the sky! Ugh, Serpent!'

'But I'm NOT a serpent, I tell you!' said Alice. 'I'm a--I'm a--'

'Well! WHAT are you?' said the Pigeon. 'I can see you're trying to
invent something!'

'I--I'm a little girl,' said Alice, rather doubtfully, as she remembered
the number of changes she had gone through that day.

'A likely story indeed!' said the Pigeon in a tone of the deepest
contempt. 'I've seen a good many little girls in my time, but never ONE
with such a neck as that! No, no! You're a serpent; and there's no use
denying it. I suppose you'll be telling me next that you never tasted an
egg!'

'I HAVE tasted eggs, certainly,' said Alice, who was a very truthful
child; 'but little girls eat eggs quite as much as serpents do, you
know.'

'I don't believe it,' said the Pigeon; 'but if they do, why then they're
a kind of serpent, that's all I can say.'

This was such a new idea to Alice, that she was quite silent for a
minute or two, which gave the Pigeon the opportunity of adding, 'You're
looking for eggs, I know THAT well enough; and what does it matter to me
whether you're a little girl or a serpent?'

'It matters a good deal to ME,' said Alice hastily; 'but I'm not looking
for eggs, as it happens; and if I was, I shouldn't want YOURS: I don't
like them raw.'

'Well, be off, then!' said the Pigeon in a sulky tone, as it settled
down again into its nest. Alice crouched down among the trees as well as
she could, for her neck kept getting entangled among the branches, and
every now and then she had to stop and untwist it. After a while she
remembered that she still held the pieces of mushroom in her hands, and
she set to work very carefully, nibbling first at one and then at the
other, and growing sometimes taller and sometimes shorter, until she had
succeeded in bringing herself down to her usual height.

It was so long since she had been anything near the right size, that it
felt quite strange at first; but she got used to it in a few minutes,
and began talking to herself, as usual. 'Come, there's half my plan done
now! How puzzling all these changes are! I'm never sure what I'm going
to be, from one minute to another! However, I've got back to my right
size: the next thing is, to get into that beautiful garden--how IS that
to be done, I wonder?' As she said this, she came suddenly upon an open
place, with a little house in it about four feet high. 'Whoever lives
there,' thought Alice, 'it'll never do to come upon them THIS size: why,
I should frighten them out of their wits!' So she began nibbling at the
righthand bit again, and did not venture to go near the house till she
had brought herself down to nine inches high.




CHAPTER VI. Pig and Pepper

For a minute or two she stood looking at the house, and wondering what
to do next, when suddenly a footman in livery came running out of the
wood--(she considered him to be a footman because he was in livery:
otherwise, judging by his face only, she would have called him a
fish)--and rapped loudly at the door with his knuckles. It was opened
by another footman in livery, with a round face, and large eyes like a
frog; and both footmen, Alice noticed, had powdered hair that curled all
over their heads. She felt very curious to know what it was all about,
and crept a little way out of the wood to listen.

The Fish-Footman began by producing from under his arm a great letter,
nearly as large as himself, and this he handed over to the other,
saying, in a solemn tone, 'For the Duchess. An invitation from the Queen
to play croquet.' The Frog-Footman repeated, in the same solemn tone,
only changing the order of the words a little, 'From the Queen. An
invitation for the Duchess to play croquet.'

Then they both bowed low, and their curls got entangled together.

Alice laughed so much at this, that she had to run back into the
wood for fear of their hearing her; and when she next peeped out the
Fish-Footman was gone, and the other was sitting on the ground near the
door, staring stupidly up into the sky.

Alice went timidly up to the door, and knocked.

'There's no sort of use in knocking,' said the Footman, 'and that for
two reasons. First, because I'm on the same side of the door as you
are; secondly, because they're making such a noise inside, no one could
possibly hear you.' And certainly there was a most extraordinary noise
going on within--a constant howling and sneezing, and every now and then
a great crash, as if a dish or kettle had been broken to pieces.

'Please, then,' said Alice, 'how am I to get in?'

'There might be some sense in your knocking,' the Footman went on
without attending to her, 'if we had the door between us. For instance,
if you were INSIDE, you might knock, and I could let you out, you know.'
He was looking up into the sky all the time he was speaking, and this
Alice thought decidedly uncivil. 'But perhaps he can't help it,' she
said to herself; 'his eyes are so VERY nearly at the top of his head.
But at any rate he might answer questions.--How am I to get in?' she
repeated, aloud.

'I shall sit here,' the Footman remarked, 'till tomorrow--'

At this moment the door of the house opened, and a large plate came
skimming out, straight at the Footman's head: it just grazed his nose,
and broke to pieces against one of the trees behind him.

'--or next day, maybe,' the Footman continued in the same tone, exactly
as if nothing had happened.

'How am I to get in?' asked Alice again, in a louder tone.

'ARE you to get in at all?' said the Footman. 'That's the first
question, you know.'

It was, no doubt: only Alice did not like to be told so. 'It's really
dreadful,' she muttered to herself, 'the way all the creatures argue.
It's enough to drive one crazy!'

The Footman seemed to think this a good opportunity for repeating his
remark, with variations. 'I shall sit here,' he said, 'on and off, for
days and days.'

'But what am I to do?' said Alice.

'Anything you like,' said the Footman, and began whistling.

'Oh, there's no use in talking to him,' said Alice desperately: 'he's
perfectly idiotic!' And she opened the door and went in.

The door led right into a large kitchen, which was full of smoke from
one end to the other: the Duchess was sitting on a three-legged stool in
the middle, nursing a baby; the cook was leaning over the fire, stirring
a large cauldron which seemed to be full of soup.

'There's certainly too much pepper in that soup!' Alice said to herself,
as well as she could for sneezing.

There was certainly too much of it in the air. Even the Duchess
sneezed occasionally; and as for the baby, it was sneezing and howling
alternately without a moment's pause. The only things in the kitchen
that did not sneeze, were the cook, and a large cat which was sitting on
the hearth and grinning from ear to ear.

'Please would you tell me,' said Alice, a little timidly, for she was
not quite sure whether it was good manners for her to speak first, 'why
your cat grins like that?'

'It's a Cheshire cat,' said the Duchess, 'and that's why. Pig!'

She said the last word with such sudden violence that Alice quite
jumped; but she saw in another moment that it was addressed to the baby,
and not to her, so she took courage, and went on again:--

'I didn't know that Cheshire cats always grinned; in fact, I didn't know
that cats COULD grin.'

'They all can,' said the Duchess; 'and most of 'em do.'

'I don't know of any that do,' Alice said very politely, feeling quite
pleased to have got into a conversation.

'You don't know much,' said the Duchess; 'and that's a fact.'

Alice did not at all like the tone of this remark, and thought it would
be as well to introduce some other subject of conversation. While she
was trying to fix on one, the cook took the cauldron of soup off the
fire, and at once set to work throwing everything within her reach at
the Duchess and the baby--the fire-irons came first; then followed a
shower of saucepans, plates, and dishes. The Duchess took no notice of
them even when they hit her; and the baby was howling so much already,
that it was quite impossible to say whether the blows hurt it or not.

'Oh, PLEASE mind what you're doing!' cried Alice, jumping up and down in
an agony of terror. 'Oh, there goes his PRECIOUS nose'; as an unusually
large saucepan flew close by it, and very nearly carried it off.

'If everybody minded their own business,' the Duchess said in a hoarse
growl, 'the world would go round a deal faster than it does.'

'Which would NOT be an advantage,' said Alice, who felt very glad to get
an opportunity of showing off a little of her knowledge. 'Just think of
what work it would make with the day and night! You see the earth takes
twenty-four hours to turn round on its axis--'

'Talking of axes,' said the Duchess, 'chop off her head!'

Alice glanced rather anxiously at the cook, to see if she meant to take
the hint; but the cook was busily stirring the soup, and seemed not to
be listening, so she went on again: 'Twenty-four hours, I THINK; or is
it twelve? I--'

'Oh, don't bother ME,' said the Duchess; 'I never could abide figures!'
And with that she began nursing her child again, singing a sort of
lullaby to it as she did so, and giving it a violent shake at the end of
every line:

   'Speak roughly to your little boy,
    And beat him when he sneezes:
   He only does it to annoy,
    Because he knows it teases.'

         CHORUS.

 (In which the cook and the baby joined):--

       'Wow! wow! wow!'

While the Duchess sang the second verse of the song, she kept tossing
the baby violently up and down, and the poor little thing howled so,
that Alice could hardly hear the words:--

   'I speak severely to my boy,
    I beat him when he sneezes;
   For he can thoroughly enjoy
    The pepper when he pleases!'

         CHORUS.

       'Wow! wow! wow!'

'Here! you may nurse it a bit, if you like!' the Duchess said to Alice,
flinging the baby at her as she spoke. 'I must go and get ready to play
croquet with the Queen,' and she hurried out of the room. The cook threw
a frying-pan after her as she went out, but it just missed her.

Alice caught the baby with some difficulty, as it was a queer-shaped
little creature, and held out its arms and legs in all directions, 'just
like a star-fish,' thought Alice. The poor little thing was snorting
like a steam-engine when she caught it, and kept doubling itself up and
straightening itself out again, so that altogether, for the first minute
or two, it was as much as she could do to hold it.

As soon as she had made out the proper way of nursing it, (which was to
twist it up into a sort of knot, and then keep tight hold of its right
ear and left foot, so as to prevent its undoing itself,) she carried
it out into the open air. 'IF I don't take this child away with me,'
thought Alice, 'they're sure to kill it in a day or two: wouldn't it be
murder to leave it behind?' She said the last words out loud, and the
little thing grunted in reply (it had left off sneezing by this time).
'Don't grunt,' said Alice; 'that's not at all a proper way of expressing
yourself.'

The baby grunted again, and Alice looked very anxiously into its face to
see what was the matter with it. There could be no doubt that it had
a VERY turn-up nose, much more like a snout than a real nose; also its
eyes were getting extremely small for a baby: altogether Alice did not
like the look of the thing at all. 'But perhaps it was only sobbing,'
she thought, and looked into its eyes again, to see if there were any
tears.

No, there were no tears. 'If you're going to turn into a pig, my dear,'
said Alice, seriously, 'I'll have nothing more to do with you. Mind
now!' The poor little thing sobbed again (or grunted, it was impossible
to say which), and they went on for some while in silence.

Alice was just beginning to think to herself, 'Now, what am I to do with
this creature when I get it home?' when it grunted again, so violently,
that she looked down into its face in some alarm. This time there could
be NO mistake about it: it was neither more nor less than a pig, and she
felt that it would be quite absurd for her to carry it further.

So she set the little creature down, and felt quite relieved to see
it trot away quietly into the wood. 'If it had grown up,' she said
to herself, 'it would have made a dreadfully ugly child: but it makes
rather a handsome pig, I think.' And she began thinking over other
children she knew, who might do very well as pigs, and was just saying
to herself, 'if one only knew the right way to change them--' when she
was a little startled by seeing the Cheshire Cat sitting on a bough of a
tree a few yards off.

The Cat only grinned when it saw Alice. It looked good-natured, she
thought: still it had VERY long claws and a great many teeth, so she
felt that it ought to be treated with respect.

'Cheshire Puss,' she began, rather timidly, as she did not at all know
whether it would like the name: however, it only grinned a little wider.
'Come, it's pleased so far,' thought Alice, and she went on. 'Would you
tell me, please, which way I ought to go from here?'

'That depends a good deal on where you want to get to,' said the Cat.

'I don't much care where--' said Alice.

'Then it doesn't matter which way you go,' said the Cat.

'--so long as I get SOMEWHERE,' Alice added as an explanation.

'Oh, you're sure to do that,' said the Cat, 'if you only walk long
enough.'

Alice felt that this could not be denied, so she tried another question.
'What sort of people live about here?'

'In THAT direction,' the Cat said, waving its right paw round, 'lives
a Hatter: and in THAT direction,' waving the other paw, 'lives a March
Hare. Visit either you like: they're both mad.'

'But I don't want to go among mad people,' Alice remarked.

'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad.
You're mad.'

'How do you know I'm mad?' said Alice.

'You must be,' said the Cat, 'or you wouldn't have come here.'

Alice didn't think that proved it at all; however, she went on 'And how
do you know that you're mad?'

'To begin with,' said the Cat, 'a dog's not mad. You grant that?'

'I suppose so,' said Alice.

'Well, then,' the Cat went on, 'you see, a dog growls when it's angry,
and wags its tail when it's pleased. Now I growl when I'm pleased, and
wag my tail when I'm angry. Therefore I'm mad.'

'I call it purring, not growling,' said Alice.

'Call it what you like,' said the Cat. 'Do you play croquet with the
Queen to-day?'

'I should like it very much,' said Alice, 'but I haven't been invited
yet.'

'You'll see me there,' said the Cat, and vanished.

Alice was not much surprised at this, she was getting so used to queer
things happening. While she was looking at the place where it had been,
it suddenly appeared again.

'By-the-bye, what became of the baby?' said the Cat. 'I'd nearly
forgotten to ask.'

'It turned into a pig,' Alice quietly said, just as if it had come back
in a natural way.

'I thought it would,' said the Cat, and vanished again.

Alice waited a little, half expecting to see it again, but it did not
appear, and after a minute or two she walked on in the direction in
which the March Hare was said to live. 'I've seen hatters before,' she
said to herself; 'the March Hare will be much the most interesting, and
perhaps as this is May it won't be raving mad--at least not so mad as
it was in March.' As she said this, she looked up, and there was the Cat
again, sitting on a branch of a tree.

'Did you say pig, or fig?' said the Cat.

'I said pig,' replied Alice; 'and I wish you wouldn't keep appearing and
vanishing so suddenly: you make one quite giddy.'

'All right,' said the Cat; and this time it vanished quite slowly,
beginning with the end of the tail, and ending with the grin, which
remained some time after the rest of it had gone.

'Well! I've often seen a cat without a grin,' thought Alice; 'but a grin
without a cat! It's the most curious thing I ever saw in my life!'

She had not gone much farther before she came in sight of the house
of the March Hare: she thought it must be the right house, because the
chimneys were shaped like ears and the roof was thatched with fur. It
was so large a house, that she did not like to go nearer till she had
nibbled some more of the lefthand bit of mushroom, and raised herself to
about two feet high: even then she walked up towards it rather timidly,
saying to herself 'Suppose it should be raving mad after all! I almost
wish I'd gone to see the Hatter instead!'




CHAPTER VII. A Mad Tea-Party

There was a table set out under a tree in front of the house, and the
March Hare and the Hatter were having tea at it: a Dormouse was sitting
between them, fast asleep, and the other two were using it as a
cushion, resting their elbows on it, and talking over its head. 'Very
uncomfortable for the Dormouse,' thought Alice; 'only, as it's asleep, I
suppose it doesn't mind.'

The table was a large one, but the three were all crowded together at
one corner of it: 'No room! No room!' they cried out when they saw Alice
coming. 'There's PLENTY of room!' said Alice indignantly, and she sat
down in a large arm-chair at one end of the table.

'Have some wine,' the March Hare said in an encouraging tone.

Alice looked all round the table, but there was nothing on it but tea.
'I don't see any wine,' she remarked.

'There isn't any,' said the March Hare.

'Then it wasn't very civil of you to offer it,' said Alice angrily.

'It wasn't very civil of you to sit down without being invited,' said
the March Hare.

'I didn't know it was YOUR table,' said Alice; 'it's laid for a great
many more than three.'

'Your hair wants cutting,' said the Hatter. He had been looking at Alice
for some time with great curiosity, and this was his first speech.

'You should learn not to make personal remarks,' Alice said with some
severity; 'it's very rude.'

The Hatter opened his eyes very wide on hearing this; but all he SAID
was, 'Why is a raven like a writing-desk?'

'Come, we shall have some fun now!' thought Alice. 'I'm glad they've
begun asking riddles.--I believe I can guess that,' she added aloud.

'Do you mean that you think you can find out the answer to it?' said the
March Hare.

'Exactly so,' said Alice.

'Then you should say what you mean,' the March Hare went on.

'I do,' Alice hastily replied; 'at least--at least I mean what I
say--that's the same thing, you know.'

'Not the same thing a bit!' said the Hatter. 'You might just as well say
that "I see what I eat" is the same thing as "I eat what I see"!'

'You might just as well say,' added the March Hare, 'that "I like what I
get" is the same thing as "I get what I like"!'

'You might just as well say,' added the Dormouse, who seemed to be
talking in his sleep, 'that "I breathe when I sleep" is the same thing
as "I sleep when I breathe"!'

'It IS the same thing with you,' said the Hatter, and here the
conversation dropped, and the party sat silent for a minute, while Alice
thought over all she could remember about ravens and writing-desks,
which wasn't much.

The Hatter was the first to break the silence. 'What day of the month
is it?' he said, turning to Alice: he had taken his watch out of his
pocket, and was looking at it uneasily, shaking it every now and then,
and holding it to his ear.

Alice considered a little, and then said 'The fourth.'

'Two days wrong!' sighed the Hatter. 'I told you butter wouldn't suit
the works!' he added looking angrily at the March Hare.

'It was the BEST butter,' the March Hare meekly replied.

'Yes, but some crumbs must have got in as well,' the Hatter grumbled:
'you shouldn't have put it in with the bread-knife.'

The March Hare took the watch and looked at it gloomily: then he dipped
it into his cup of tea, and looked at it again: but he could think of
nothing better to say than his first remark, 'It was the BEST butter,
you know.'

Alice had been looking over his shoulder with some curiosity. 'What a
funny watch!' she remarked. 'It tells the day of the month, and doesn't
tell what o'clock it is!'

'Why should it?' muttered the Hatter. 'Does YOUR watch tell you what
year it is?'

'Of course not,' Alice replied very readily: 'but that's because it
stays the same year for such a long time together.'

'Which is just the case with MINE,' said the Hatter.

Alice felt dreadfully puzzled. The Hatter's remark seemed to have no
sort of meaning in it, and yet it was certainly English. 'I don't quite
understand you,' she said, as politely as she could.

'The Dormouse is asleep again,' said the Hatter, and he poured a little
hot tea upon its nose.

The Dormouse shook its head impatiently, and said, without opening its
eyes, 'Of course, of course; just what I was going to remark myself.'

'Have you guessed the riddle yet?' the Hatter said, turning to Alice
again.

'No, I give it up,' Alice replied: 'what's the answer?'

'I haven't the slightest idea,' said the Hatter.

'Nor I,' said the March Hare.

Alice sighed wearily. 'I think you might do something better with the
time,' she said, 'than waste it in asking riddles that have no answers.'

'If you knew Time as well as I do,' said the Hatter, 'you wouldn't talk
about wasting IT. It's HIM.'

'I don't know what you mean,' said Alice.

'Of course you don't!' the Hatter said, tossing his head contemptuously.
'I dare say you never even spoke to Time!'

'Perhaps not,' Alice cautiously replied: 'but I know I have to beat time
when I learn music.'

'Ah! that accounts for it,' said the Hatter. 'He won't stand beating.
Now, if you only kept on good terms with him, he'd do almost anything
you liked with the clock. For instance, suppose it were nine o'clock in
the morning, just time to begin lessons: you'd only have to whisper a
hint to Time, and round goes the clock in a twinkling! Half-past one,
time for dinner!'

('I only wish it was,' the March Hare said to itself in a whisper.)

'That would be grand, certainly,' said Alice thoughtfully: 'but then--I
shouldn't be hungry for it, you know.'

'Not at first, perhaps,' said the Hatter: 'but you could keep it to
half-past one as long as you liked.'

'Is that the way YOU manage?' Alice asked.

The Hatter shook his head mournfully. 'Not I!' he replied. 'We
quarrelled last March--just before HE went mad, you know--' (pointing
with his tea spoon at the March Hare,) '--it was at the great concert
given by the Queen of Hearts, and I had to sing

     "Twinkle, twinkle, little bat!
     How I wonder what you're at!"

You know the song, perhaps?'

'I've heard something like it,' said Alice.

'It goes on, you know,' the Hatter continued, 'in this way:--

     "Up above the world you fly,
     Like a tea-tray in the sky.
         Twinkle, twinkle--"'

Here the Dormouse shook itself, and began singing in its sleep 'Twinkle,
twinkle, twinkle, twinkle--' and went on so long that they had to pinch
it to make it stop.

'Well, I'd hardly finished the first verse,' said the Hatter, 'when the
Queen jumped up and bawled out, "He's murdering the time! Off with his
head!"'

'How dreadfully savage!' exclaimed Alice.

'And ever since that,' the Hatter went on in a mournful tone, 'he won't
do a thing I ask! It's always six o'clock now.'

A bright idea came into Alice's head. 'Is that the reason so many
tea-things are put out here?' she asked.

'Yes, that's it,' said the Hatter with a sigh: 'it's always tea-time,
and we've no time to wash the things between whiles.'

'Then you keep moving round, I suppose?' said Alice.

'Exactly so,' said the Hatter: 'as the things get used up.'

'But what happens when you come to the beginning again?' Alice ventured
to ask.

'Suppose we change the subject,' the March Hare interrupted, yawning.
'I'm getting tired of this. I vote the young lady tells us a story.'

'I'm afraid I don't know one,' said Alice, rather alarmed at the
proposal.

'Then the Dormouse shall!' they both cried. 'Wake up, Dormouse!' And
they pinched it on both sides at once.

The Dormouse slowly opened his eyes. 'I wasn't asleep,' he said in a
hoarse, feeble voice: 'I heard every word you fellows were saying.'

'Tell us a story!' said the March Hare.

'Yes, please do!' pleaded Alice.

'And be quick about it,' added the Hatter, 'or you'll be asleep again
before it's done.'

'Once upon a time there were three little sisters,' the Dormouse began
in a great hurry; 'and their names were Elsie, Lacie, and Tillie; and
they lived at the bottom of a well--'

'What did they live on?' said Alice, who always took a great interest in
questions of eating and drinking.

'They lived on treacle,' said the Dormouse, after thinking a minute or
two.

'They couldn't have done that, you know,' Alice gently remarked; 'they'd
have been ill.'

'So they were,' said the Dormouse; 'VERY ill.'

Alice tried to fancy to herself what such an extraordinary ways of
living would be like, but it puzzled her too much, so she went on: 'But
why did they live at the bottom of a well?'

'Take some more tea,' the March Hare said to Alice, very earnestly.

'I've had nothing yet,' Alice replied in an offended tone, 'so I can't
take more.'

'You mean you can't take LESS,' said the Hatter: 'it's very easy to take
MORE than nothing.'

'Nobody asked YOUR opinion,' said Alice.

'Who's making personal remarks now?' the Hatter asked triumphantly.

Alice did not quite know what to say to this: so she helped herself
to some tea and bread-and-butter, and then turned to the Dormouse, and
repeated her question. 'Why did they live at the bottom of a well?'

The Dormouse again took a minute or two to think about it, and then
said, 'It was a treacle-well.'

'There's no such thing!' Alice was beginning very angrily, but the
Hatter and the March Hare went 'Sh! sh!' and the Dormouse sulkily
remarked, 'If you can't be civil, you'd better finish the story for
yourself.'

'No, please go on!' Alice said very humbly; 'I won't interrupt again. I
dare say there may be ONE.'

'One, indeed!' said the Dormouse indignantly. However, he consented to
go on. 'And so these three little sisters--they were learning to draw,
you know--'

'What did they draw?' said Alice, quite forgetting her promise.

'Treacle,' said the Dormouse, without considering at all this time.

'I want a clean cup,' interrupted the Hatter: 'let's all move one place
on.'

He moved on as he spoke, and the Dormouse followed him: the March Hare
moved into the Dormouse's place, and Alice rather unwillingly took
the place of the March Hare. The Hatter was the only one who got any
advantage from the change: and Alice was a good deal worse off than
before, as the March Hare had just upset the milk-jug into his plate.

Alice did not wish to offend the Dormouse again, so she began very
cautiously: 'But I don't understand. Where did they draw the treacle
from?'

'You can draw water out of a water-well,' said the Hatter; 'so I should
think you could draw treacle out of a treacle-well--eh, stupid?'

'But they were IN the well,' Alice said to the Dormouse, not choosing to
notice this last remark.

'Of course they were', said the Dormouse; '--well in.'

This answer so confused poor Alice, that she let the Dormouse go on for
some time without interrupting it.

'They were learning to draw,' the Dormouse went on, yawning and rubbing
its eyes, for it was getting very sleepy; 'and they drew all manner of
things--everything that begins with an M--'

'Why with an M?' said Alice.

'Why not?' said the March Hare.

Alice was silent.

The Dormouse had closed its eyes by this time, and was going off into
a doze; but, on being pinched by the Hatter, it woke up again with
a little shriek, and went on: '--that begins with an M, such as
mouse-traps, and the moon, and memory, and muchness--you know you say
things are "much of a muchness"--did you ever see such a thing as a
drawing of a muchness?'

'Really, now you ask me,' said Alice, very much confused, 'I don't
think--'

'Then you shouldn't talk,' said the Hatter.

This piece of rudeness was more than Alice could bear: she got up in
great disgust, and walked off; the Dormouse fell asleep instantly, and
neither of the others took the least notice of her going, though she
looked back once or twice, half hoping that they would call after her:
the last time she saw them, they were trying to put the Dormouse into
the teapot.

'At any rate I'll never go THERE again!' said Alice as she picked her
way through the wood. 'It's the stupidest tea-party I ever was at in all
my life!'

Just as she said this, she noticed that one of the trees had a door
leading right into it. 'That's very curious!' she thought. 'But
everything's curious today. I think I may as well go in at once.' And in
she went.

Once more she found herself in the long hall, and close to the little
glass table. 'Now, I'll manage better this time,' she said to herself,
and began by taking the little golden key, and unlocking the door that
led into the garden. Then she went to work nibbling at the mushroom (she
had kept a piece of it in her pocket) till she was about a foot high:
then she walked down the little passage: and THEN--she found herself at
last in the beautiful garden, among the bright flower-beds and the cool
fountains.




CHAPTER VIII. The Queen's Croquet-Ground

A large rose-tree stood near the entrance of the garden: the roses
growing on it were white, but there were three gardeners at it, busily
painting them red. Alice thought this a very curious thing, and she went
nearer to watch them, and just as she came up to them she heard one of
them say, 'Look out now, Five! Don't go splashing paint over me like
that!'

'I couldn't help it,' said Five, in a sulky tone; 'Seven jogged my
elbow.'

On which Seven looked up and said, 'That's right, Five! Always lay the
blame on others!'

'YOU'D better not talk!' said Five. 'I heard the Queen say only
yesterday you deserved to be beheaded!'

'What for?' said the one who had spoken first.

'That's none of YOUR business, Two!' said Seven.

'Yes, it IS his business!' said Five, 'and I'll tell him--it was for
bringing the cook tulip-roots instead of onions.'

Seven flung down his brush, and had just begun 'Well, of all the unjust
things--' when his eye chanced to fall upon Alice, as she stood watching
them, and he checked himself suddenly: the others looked round also, and
all of them bowed low.

'Would you tell me,' said Alice, a little timidly, 'why you are painting
those roses?'

Five and Seven said nothing, but looked at Two. Two began in a low
voice, 'Why the fact is, you see, Miss, this here ought to have been a
RED rose-tree, and we put a white one in by mistake; and if the Queen
was to find it out, we should all have our heads cut off, you know.
So you see, Miss, we're doing our best, afore she comes, to--' At this
moment Five, who had been anxiously looking across the garden, called
out 'The Queen! The Queen!' and the three gardeners instantly threw
themselves flat upon their faces. There was a sound of many footsteps,
and Alice looked round, eager to see the Queen.

First came ten soldiers carrying clubs; these were all shaped like
the three gardeners, oblong and flat, with their hands and feet at the
corners: next the ten courtiers; these were ornamented all over with
diamonds, and walked two and two, as the soldiers did. After these came
the royal children; there were ten of them, and the little dears came
jumping merrily along hand in hand, in couples: they were all ornamented
with hearts. Next came the guests, mostly Kings and Queens, and among
them Alice recognised the White Rabbit: it was talking in a hurried
nervous manner, smiling at everything that was said, and went by without
noticing her. Then followed the Knave of Hearts, carrying the King's
crown on a crimson velvet cushion; and, last of all this grand
procession, came THE KING AND QUEEN OF HEARTS.

Alice was rather doubtful whether she ought not to lie down on her face
like the three gardeners, but she could not remember ever having heard
of such a rule at processions; 'and besides, what would be the use of
a procession,' thought she, 'if people had all to lie down upon their
faces, so that they couldn't see it?' So she stood still where she was,
and waited.

When the procession came opposite to Alice, they all stopped and looked
at her, and the Queen said severely 'Who is this?' She said it to the
Knave of Hearts, who only bowed and smiled in reply.

'Idiot!' said the Queen, tossing her head impatiently; and, turning to
Alice, she went on, 'What's your name, child?'

'My name is Alice, so please your Majesty,' said Alice very politely;
but she added, to herself, 'Why, they're only a pack of cards, after
all. I needn't be afraid of them!'

'And who are THESE?' said the Queen, pointing to the three gardeners who
were lying round the rosetree; for, you see, as they were lying on their
faces, and the pattern on their backs was the same as the rest of the
pack, she could not tell whether they were gardeners, or soldiers, or
courtiers, or three of her own children.

'How should I know?' said Alice, surprised at her own courage. 'It's no
business of MINE.'

The Queen turned crimson with fury, and, after glaring at her for a
moment like a wild beast, screamed 'Off with her head! Off--'

'Nonsense!' said Alice, very loudly and decidedly, and the Queen was
silent.

The King laid his hand upon her arm, and timidly said 'Consider, my
dear: she is only a child!'

The Queen turned angrily away from him, and said to the Knave 'Turn them
over!'

The Knave did so, very carefully, with one foot.

'Get up!' said the Queen, in a shrill, loud voice, and the three
gardeners instantly jumped up, and began bowing to the King, the Queen,
the royal children, and everybody else.

'Leave off that!' screamed the Queen. 'You make me giddy.' And then,
turning to the rose-tree, she went on, 'What HAVE you been doing here?'

'May it please your Majesty,' said Two, in a very humble tone, going
down on one knee as he spoke, 'we were trying--'

'I see!' said the Queen, who had meanwhile been examining the roses.
'Off with their heads!' and the procession moved on, three of the
soldiers remaining behind to execute the unfortunate gardeners, who ran
to Alice for protection.

'You shan't be beheaded!' said Alice, and she put them into a large
flower-pot that stood near. The three soldiers wandered about for a
minute or two, looking for them, and then quietly marched off after the
others.

'Are their heads off?' shouted the Queen.

'Their heads are gone, if it please your Majesty!' the soldiers shouted
in reply.

'That's right!' shouted the Queen. 'Can you play croquet?'

The soldiers were silent, and looked at Alice, as the question was
evidently meant for her.

'Yes!' shouted Alice.

'Come on, then!' roared the Queen, and Alice joined the procession,
wondering very much what would happen next.

'It's--it's a very fine day!' said a timid voice at her side. She was
walking by the White Rabbit, who was peeping anxiously into her face.

'Very,' said Alice: '--where's the Duchess?'

'Hush! Hush!' said the Rabbit in a low, hurried tone. He looked
anxiously over his shoulder as he spoke, and then raised himself upon
tiptoe, put his mouth close to her ear, and whispered 'She's under
sentence of execution.'

'What for?' said Alice.

'Did you say "What a pity!"?' the Rabbit asked.

'No, I didn't,' said Alice: 'I don't think it's at all a pity. I said
"What for?"'

'She boxed the Queen's ears--' the Rabbit began. Alice gave a little
scream of laughter. 'Oh, hush!' the Rabbit whispered in a frightened
tone. 'The Queen will hear you! You see, she came rather late, and the
Queen said--'

'Get to your places!' shouted the Queen in a voice of thunder, and
people began running about in all directions, tumbling up against each
other; however, they got settled down in a minute or two, and the game
began. Alice thought she had never seen such a curious croquet-ground in
her life; it was all ridges and furrows; the balls were live hedgehogs,
the mallets live flamingoes, and the soldiers had to double themselves
up and to stand on their hands and feet, to make the arches.

The chief difficulty Alice found at first was in managing her flamingo:
she succeeded in getting its body tucked away, comfortably enough, under
her arm, with its legs hanging down, but generally, just as she had got
its neck nicely straightened out, and was going to give the hedgehog a
blow with its head, it WOULD twist itself round and look up in her face,
with such a puzzled expression that she could not help bursting out
laughing: and when she had got its head down, and was going to begin
again, it was very provoking to find that the hedgehog had unrolled
itself, and was in the act of crawling away: besides all this, there was
generally a ridge or furrow in the way wherever she wanted to send the
hedgehog to, and, as the doubled-up soldiers were always getting up
and walking off to other parts of the ground, Alice soon came to the
conclusion that it was a very difficult game indeed.

The players all played at once without waiting for turns, quarrelling
all the while, and fighting for the hedgehogs; and in a very short
time the Queen was in a furious passion, and went stamping about, and
shouting 'Off with his head!' or 'Off with her head!' about once in a
minute.

Alice began to feel very uneasy: to be sure, she had not as yet had any
dispute with the Queen, but she knew that it might happen any minute,
'and then,' thought she, 'what would become of me? They're dreadfully
fond of beheading people here; the great wonder is, that there's any one
left alive!'

She was looking about for some way of escape, and wondering whether she
could get away without being seen, when she noticed a curious appearance
in the air: it puzzled her very much at first, but, after watching it
a minute or two, she made it out to be a grin, and she said to herself
'It's the Cheshire Cat: now I shall have somebody to talk to.'

'How are you getting on?' said the Cat, as soon as there was mouth
enough for it to speak with.

Alice waited till the eyes appeared, and then nodded. 'It's no use
speaking to it,' she thought, 'till its ears have come, or at least one
of them.' In another minute the whole head appeared, and then Alice put
down her flamingo, and began an account of the game, feeling very glad
she had someone to listen to her. The Cat seemed to think that there was
enough of it now in sight, and no more of it appeared.

'I don't think they play at all fairly,' Alice began, in rather a
complaining tone, 'and they all quarrel so dreadfully one can't hear
oneself speak--and they don't seem to have any rules in particular;
at least, if there are, nobody attends to them--and you've no idea how
confusing it is all the things being alive; for instance, there's the
arch I've got to go through next walking about at the other end of the
ground--and I should have croqueted the Queen's hedgehog just now, only
it ran away when it saw mine coming!'

'How do you like the Queen?' said the Cat in a low voice.

'Not at all,' said Alice: 'she's so extremely--' Just then she noticed
that the Queen was close behind her, listening: so she went on,
'--likely to win, that it's hardly worth while finishing the game.'

The Queen smiled and passed on.

'Who ARE you talking to?' said the King, going up to Alice, and looking
at the Cat's head with great curiosity.

'It's a friend of mine--a Cheshire Cat,' said Alice: 'allow me to
introduce it.'

'I don't like the look of it at all,' said the King: 'however, it may
kiss my hand if it likes.'

'I'd rather not,' the Cat remarked.

'Don't be impertinent,' said the King, 'and don't look at me like that!'
He got behind Alice as he spoke.

'A cat may look at a king,' said Alice. 'I've read that in some book,
but I don't remember where.'

'Well, it must be removed,' said the King very decidedly, and he called
the Queen, who was passing at the moment, 'My dear! I wish you would
have this cat removed!'

The Queen had only one way of settling all difficulties, great or small.
'Off with his head!' she said, without even looking round.

'I'll fetch the executioner myself,' said the King eagerly, and he
hurried off.

Alice thought she might as well go back, and see how the game was going
on, as she heard the Queen's voice in the distance, screaming with
passion. She had already heard her sentence three of the players to be
executed for having missed their turns, and she did not like the look
of things at all, as the game was in such confusion that she never knew
whether it was her turn or not. So she went in search of her hedgehog.

The hedgehog was engaged in a fight with another hedgehog, which seemed
to Alice an excellent opportunity for croqueting one of them with the
other: the only difficulty was, that her flamingo was gone across to the
other side of the garden, where Alice could see it trying in a helpless
sort of way to fly up into a tree.

By the time she had caught the flamingo and brought it back, the fight
was over, and both the hedgehogs were out of sight: 'but it doesn't
matter much,' thought Alice, 'as all the arches are gone from this side
of the ground.' So she tucked it away under her arm, that it might not
escape again, and went back for a little more conversation with her
friend.

When she got back to the Cheshire Cat, she was surprised to find quite a
large crowd collected round it: there was a dispute going on between
the executioner, the King, and the Queen, who were all talking at once,
while all the rest were quite silent, and looked very uncomfortable.

The moment Alice appeared, she was appealed to by all three to settle
the question, and they repeated their arguments to her, though, as they
all spoke at once, she found it very hard indeed to make out exactly
what they said.

The executioner's argument was, that you couldn't cut off a head unless
there was a body to cut it off from: that he had never had to do such a
thing before, and he wasn't going to begin at HIS time of life.

The King's argument was, that anything that had a head could be
beheaded, and that you weren't to talk nonsense.

The Queen's argument was, that if something wasn't done about it in less
than no time she'd have everybody executed, all round. (It was this last
remark that had made the whole party look so grave and anxious.)

Alice could think of nothing else to say but 'It belongs to the Duchess:
you'd better ask HER about it.'

'She's in prison,' the Queen said to the executioner: 'fetch her here.'
And the executioner went off like an arrow.

 The Cat's head began fading away the moment he was gone, and,
by the time he had come back with the Duchess, it had entirely
disappeared; so the King and the executioner ran wildly up and down
looking for it, while the rest of the party went back to the game.




CHAPTER IX. The Mock Turtle's Story

'You can't think how glad I am to see you again, you dear old thing!'
said the Duchess, as she tucked her arm affectionately into Alice's, and
they walked off together.

Alice was very glad to find her in such a pleasant temper, and thought
to herself that perhaps it was only the pepper that had made her so
savage when they met in the kitchen.

'When I'M a Duchess,' she said to herself, (not in a very hopeful tone
though), 'I won't have any pepper in my kitchen AT ALL. Soup does very
well without--Maybe it's always pepper that makes people hot-tempered,'
she went on, very much pleased at having found out a new kind of
rule, 'and vinegar that makes them sour--and camomile that makes
them bitter--and--and barley-sugar and such things that make children
sweet-tempered. I only wish people knew that: then they wouldn't be so
stingy about it, you know--'

She had quite forgotten the Duchess by this time, and was a little
startled when she heard her voice close to her ear. 'You're thinking
about something, my dear, and that makes you forget to talk. I can't
tell you just now what the moral of that is, but I shall remember it in
a bit.'

'Perhaps it hasn't one,' Alice ventured to remark.

'Tut, tut, child!' said the Duchess. 'Everything's got a moral, if only
you can find it.' And she squeezed herself up closer to Alice's side as
she spoke.

Alice did not much like keeping so close to her: first, because the
Duchess was VERY ugly; and secondly, because she was exactly the
right height to rest her chin upon Alice's shoulder, and it was an
uncomfortably sharp chin. However, she did not like to be rude, so she
bore it as well as she could.

'The game's going on rather better now,' she said, by way of keeping up
the conversation a little.

''Tis so,' said the Duchess: 'and the moral of that is--"Oh, 'tis love,
'tis love, that makes the world go round!"'

'Somebody said,' Alice whispered, 'that it's done by everybody minding
their own business!'

'Ah, well! It means much the same thing,' said the Duchess, digging her
sharp little chin into Alice's shoulder as she added, 'and the moral
of THAT is--"Take care of the sense, and the sounds will take care of
themselves."'

'How fond she is of finding morals in things!' Alice thought to herself.

'I dare say you're wondering why I don't put my arm round your waist,'
the Duchess said after a pause: 'the reason is, that I'm doubtful about
the temper of your flamingo. Shall I try the experiment?'

'HE might bite,' Alice cautiously replied, not feeling at all anxious to
have the experiment tried.

'Very true,' said the Duchess: 'flamingoes and mustard both bite. And
the moral of that is--"Birds of a feather flock together."'

'Only mustard isn't a bird,' Alice remarked.

'Right, as usual,' said the Duchess: 'what a clear way you have of
putting things!'

'It's a mineral, I THINK,' said Alice.

'Of course it is,' said the Duchess, who seemed ready to agree to
everything that Alice said; 'there's a large mustard-mine near here. And
the moral of that is--"The more there is of mine, the less there is of
yours."'

'Oh, I know!' exclaimed Alice, who had not attended to this last remark,
'it's a vegetable. It doesn't look like one, but it is.'

'I quite agree with you,' said the Duchess; 'and the moral of that
is--"Be what you would seem to be"--or if you'd like it put more
simply--"Never imagine yourself not to be otherwise than what it might
appear to others that what you were or might have been was not otherwise
than what you had been would have appeared to them to be otherwise."'

'I think I should understand that better,' Alice said very politely, 'if
I had it written down: but I can't quite follow it as you say it.'

'That's nothing to what I could say if I chose,' the Duchess replied, in
a pleased tone.

'Pray don't trouble yourself to say it any longer than that,' said
Alice.

'Oh, don't talk about trouble!' said the Duchess. 'I make you a present
of everything I've said as yet.'

'A cheap sort of present!' thought Alice. 'I'm glad they don't give
birthday presents like that!' But she did not venture to say it out
loud.

'Thinking again?' the Duchess asked, with another dig of her sharp
little chin.

'I've a right to think,' said Alice sharply, for she was beginning to
feel a little worried.

'Just about as much right,' said the Duchess, 'as pigs have to fly; and
the m--'

But here, to Alice's great surprise, the Duchess's voice died away, even
in the middle of her favourite word 'moral,' and the arm that was linked
into hers began to tremble. Alice looked up, and there stood the Queen
in front of them, with her arms folded, frowning like a thunderstorm.

'A fine day, your Majesty!' the Duchess began in a low, weak voice.

'Now, I give you fair warning,' shouted the Queen, stamping on the
ground as she spoke; 'either you or your head must be off, and that in
about half no time! Take your choice!'

The Duchess took her choice, and was gone in a moment.

'Let's go on with the game,' the Queen said to Alice; and Alice was
too much frightened to say a word, but slowly followed her back to the
croquet-ground.

The other guests had taken advantage of the Queen's absence, and were
resting in the shade: however, the moment they saw her, they hurried
back to the game, the Queen merely remarking that a moment's delay would
cost them their lives.

All the time they were playing the Queen never left off quarrelling with
the other players, and shouting 'Off with his head!' or 'Off with her
head!' Those whom she sentenced were taken into custody by the soldiers,
who of course had to leave off being arches to do this, so that by
the end of half an hour or so there were no arches left, and all the
players, except the King, the Queen, and Alice, were in custody and
under sentence of execution.

Then the Queen left off, quite out of breath, and said to Alice, 'Have
you seen the Mock Turtle yet?'

'No,' said Alice. 'I don't even know what a Mock Turtle is.'

'It's the thing Mock Turtle Soup is made from,' said the Queen.

'I never saw one, or heard of one,' said Alice.

'Come on, then,' said the Queen, 'and he shall tell you his history,'

As they walked off together, Alice heard the King say in a low voice,
to the company generally, 'You are all pardoned.' 'Come, THAT'S a good
thing!' she said to herself, for she had felt quite unhappy at the
number of executions the Queen had ordered.

They very soon came upon a Gryphon, lying fast asleep in the sun.
(IF you don't know what a Gryphon is, look at the picture.) 'Up, lazy
thing!' said the Queen, 'and take this young lady to see the Mock
Turtle, and to hear his history. I must go back and see after some
executions I have ordered'; and she walked off, leaving Alice alone with
the Gryphon. Alice did not quite like the look of the creature, but on
the whole she thought it would be quite as safe to stay with it as to go
after that savage Queen: so she waited.

The Gryphon sat up and rubbed its eyes: then it watched the Queen till
she was out of sight: then it chuckled. 'What fun!' said the Gryphon,
half to itself, half to Alice.

'What IS the fun?' said Alice.

'Why, SHE,' said the Gryphon. 'It's all her fancy, that: they never
executes nobody, you know. Come on!'

'Everybody says "come on!" here,' thought Alice, as she went slowly
after it: 'I never was so ordered about in all my life, never!'

They had not gone far before they saw the Mock Turtle in the distance,
sitting sad and lonely on a little ledge of rock, and, as they came
nearer, Alice could hear him sighing as if his heart would break. She
pitied him deeply. 'What is his sorrow?' she asked the Gryphon, and the
Gryphon answered, very nearly in the same words as before, 'It's all his
fancy, that: he hasn't got no sorrow, you know. Come on!'

So they went up to the Mock Turtle, who looked at them with large eyes
full of tears, but said nothing.

'This here young lady,' said the Gryphon, 'she wants for to know your
history, she do.'

'I'll tell it her,' said the Mock Turtle in a deep, hollow tone: 'sit
down, both of you, and don't speak a word till I've finished.'

So they sat down, and nobody spoke for some minutes. Alice thought to
herself, 'I don't see how he can EVEN finish, if he doesn't begin.' But
she waited patiently.

'Once,' said the Mock Turtle at last, with a deep sigh, 'I was a real
Turtle.'

These words were followed by a very long silence, broken only by an
occasional exclamation of 'Hjckrrh!' from the Gryphon, and the constant
heavy sobbing of the Mock Turtle. Alice was very nearly getting up and
saying, 'Thank you, sir, for your interesting story,' but she could
not help thinking there MUST be more to come, so she sat still and said
nothing.

'When we were little,' the Mock Turtle went on at last, more calmly,
though still sobbing a little now and then, 'we went to school in the
sea. The master was an old Turtle--we used to call him Tortoise--'

'Why did you call him Tortoise, if he wasn't one?' Alice asked.

'We called him Tortoise because he taught us,' said the Mock Turtle
angrily: 'really you are very dull!'

'You ought to be ashamed of yourself for asking such a simple question,'
added the Gryphon; and then they both sat silent and looked at poor
Alice, who felt ready to sink into the earth. At last the Gryphon said
to the Mock Turtle, 'Drive on, old fellow! Don't be all day about it!'
and he went on in these words:

'Yes, we went to school in the sea, though you mayn't believe it--'

'I never said I didn't!' interrupted Alice.

'You did,' said the Mock Turtle.

'Hold your tongue!' added the Gryphon, before Alice could speak again.
The Mock Turtle went on.

'We had the best of educations--in fact, we went to school every day--'

'I'VE been to a day-school, too,' said Alice; 'you needn't be so proud
as all that.'

'With extras?' asked the Mock Turtle a little anxiously.

'Yes,' said Alice, 'we learned French and music.'

'And washing?' said the Mock Turtle.

'Certainly not!' said Alice indignantly.

'Ah! then yours wasn't a really good school,' said the Mock Turtle in
a tone of great relief. 'Now at OURS they had at the end of the bill,
"French, music, AND WASHING--extra."'

'You couldn't have wanted it much,' said Alice; 'living at the bottom of
the sea.'

'I couldn't afford to learn it.' said the Mock Turtle with a sigh. 'I
only took the regular course.'

'What was that?' inquired Alice.

'Reeling and Writhing, of course, to begin with,' the Mock Turtle
replied; 'and then the different branches of Arithmetic--Ambition,
Distraction, Uglification, and Derision.'

'I never heard of "Uglification,"' Alice ventured to say. 'What is it?'

The Gryphon lifted up both its paws in surprise. 'What! Never heard of
uglifying!' it exclaimed. 'You know what to beautify is, I suppose?'

'Yes,' said Alice doubtfully: 'it means--to--make--anything--prettier.'

'Well, then,' the Gryphon went on, 'if you don't know what to uglify is,
you ARE a simpleton.'

Alice did not feel encouraged to ask any more questions about it, so she
turned to the Mock Turtle, and said 'What else had you to learn?'

'Well, there was Mystery,' the Mock Turtle replied, counting off
the subjects on his flappers, '--Mystery, ancient and modern, with
Seaography: then Drawling--the Drawling-master was an old conger-eel,
that used to come once a week: HE taught us Drawling, Stretching, and
Fainting in Coils.'

'What was THAT like?' said Alice.

'Well, I can't show it you myself,' the Mock Turtle said: 'I'm too
stiff. And the Gryphon never learnt it.'

'Hadn't time,' said the Gryphon: 'I went to the Classics master, though.
He was an old crab, HE was.'

'I never went to him,' the Mock Turtle said with a sigh: 'he taught
Laughing and Grief, they used to say.'

'So he did, so he did,' said the Gryphon, sighing in his turn; and both
creatures hid their faces in their paws.

'And how many hours a day did you do lessons?' said Alice, in a hurry to
change the subject.

'Ten hours the first day,' said the Mock Turtle: 'nine the next, and so
on.'

'What a curious plan!' exclaimed Alice.

'That's the reason they're called lessons,' the Gryphon remarked:
'because they lessen from day to day.'

This was quite a new idea to Alice, and she thought it over a little
before she made her next remark. 'Then the eleventh day must have been a
holiday?'

'Of course it was,' said the Mock Turtle.

'And how did you manage on the twelfth?' Alice went on eagerly.

'That's enough about lessons,' the Gryphon interrupted in a very decided
tone: 'tell her something about the games now.'




CHAPTER X. The Lobster Quadrille

The Mock Turtle sighed deeply, and drew the back of one flapper across
his eyes. He looked at Alice, and tried to speak, but for a minute or
two sobs choked his voice. 'Same as if he had a bone in his throat,'
said the Gryphon: and it set to work shaking him and punching him in
the back. At last the Mock Turtle recovered his voice, and, with tears
running down his cheeks, he went on again:--

'You may not have lived much under the sea--' ('I haven't,' said
Alice)--'and perhaps you were never even introduced to a lobster--'
(Alice began to say 'I once tasted--' but checked herself hastily, and
said 'No, never') '--so you can have no idea what a delightful thing a
Lobster Quadrille is!'

'No, indeed,' said Alice. 'What sort of a dance is it?'

'Why,' said the Gryphon, 'you first form into a line along the
sea-shore--'

'Two lines!' cried the Mock Turtle. 'Seals, turtles, salmon, and so on;
then, when you've cleared all the jelly-fish out of the way--'

'THAT generally takes some time,' interrupted the Gryphon.

'--you advance twice--'

'Each with a lobster as a partner!' cried the Gryphon.

'Of course,' the Mock Turtle said: 'advance twice, set to partners--'

'--change lobsters, and retire in same order,' continued the Gryphon.

'Then, you know,' the Mock Turtle went on, 'you throw the--'

'The lobsters!' shouted the Gryphon, with a bound into the air.

'--as far out to sea as you can--'

'Swim after them!' screamed the Gryphon.

'Turn a somersault in the sea!' cried the Mock Turtle, capering wildly
about.

'Change lobsters again!' yelled the Gryphon at the top of its voice.

'Back to land again, and that's all the first figure,' said the Mock
Turtle, suddenly dropping his voice; and the two creatures, who had been
jumping about like mad things all this time, sat down again very sadly
and quietly, and looked at Alice.

'It must be a very pretty dance,' said Alice timidly.

'Would you like to see a little of it?' said the Mock Turtle.

'Very much indeed,' said Alice.

'Come, let's try the first figure!' said the Mock Turtle to the Gryphon.
'We can do without lobsters, you know. Which shall sing?'

'Oh, YOU sing,' said the Gryphon. 'I've forgotten the words.'

So they began solemnly dancing round and round Alice, every now and
then treading on her toes when they passed too close, and waving their
forepaws to mark the time, while the Mock Turtle sang this, very slowly
and sadly:--

 '"Will you walk a little faster?" said a whiting to a snail.
 "There's a porpoise close behind us, and he's treading on my tail.

 See how eagerly the lobsters and the turtles all advance!
 They are waiting on the shingle--will you come and join the dance?

 Will you, won't you, will you, won't you, will you join the dance?
 Will you, won't you, will you, won't you, won't you join the dance?

 "You can really have no notion how delightful it will be
 When they take us up and throw us, with the lobsters, out to sea!"
 But the snail replied "Too far, too far!" and gave a look askance--
 Said he thanked the whiting kindly, but he would not join the dance.

 Would not, could not, would not, could not, would not join the dance.
 Would not, could not, would not, could not, could not join the dance.

 '"What matters it how far we go?" his scaly friend replied.
 "There is another shore, you know, upon the other side.
 The further off from England the nearer is to France--
 Then turn not pale, beloved snail, but come and join the dance.

 Will you, won't you, will you, won't you, will you join the dance?
 Will you, won't you, will you, won't you, won't you join the dance?"'

'Thank you, it's a very interesting dance to watch,' said Alice, feeling
very glad that it was over at last: 'and I do so like that curious song
about the whiting!'

'Oh, as to the whiting,' said the Mock Turtle, 'they--you've seen them,
of course?'

'Yes,' said Alice, 'I've often seen them at dinn--' she checked herself
hastily.

'I don't know where Dinn may be,' said the Mock Turtle, 'but if you've
seen them so often, of course you know what they're like.'

'I believe so,' Alice replied thoughtfully. 'They have their tails in
their mouths--and they're all over crumbs.'

'You're wrong about the crumbs,' said the Mock Turtle: 'crumbs would all
wash off in the sea. But they HAVE their tails in their mouths; and the
reason is--' here the Mock Turtle yawned and shut his eyes.--'Tell her
about the reason and all that,' he said to the Gryphon.

'The reason is,' said the Gryphon, 'that they WOULD go with the lobsters
to the dance. So they got thrown out to sea. So they had to fall a long
way. So they got their tails fast in their mouths. So they couldn't get
them out again. That's all.'

'Thank you,' said Alice, 'it's very interesting. I never knew so much
about a whiting before.'

'I can tell you more than that, if you like,' said the Gryphon. 'Do you
know why it's called a whiting?'

'I never thought about it,' said Alice. 'Why?'

'IT DOES THE BOOTS AND SHOES.' the Gryphon replied very solemnly.

Alice was thoroughly puzzled. 'Does the boots and shoes!' she repeated
in a wondering tone.

'Why, what are YOUR shoes done with?' said the Gryphon. 'I mean, what
makes them so shiny?'

Alice looked down at them, and considered a little before she gave her
answer. 'They're done with blacking, I believe.'

'Boots and shoes under the sea,' the Gryphon went on in a deep voice,
'are done with a whiting. Now you know.'

'And what are they made of?' Alice asked in a tone of great curiosity.

'Soles and eels, of course,' the Gryphon replied rather impatiently:
'any shrimp could have told you that.'

'If I'd been the whiting,' said Alice, whose thoughts were still running
on the song, 'I'd have said to the porpoise, "Keep back, please: we
don't want YOU with us!"'

'They were obliged to have him with them,' the Mock Turtle said: 'no
wise fish would go anywhere without a porpoise.'

'Wouldn't it really?' said Alice in a tone of great surprise.

'Of course not,' said the Mock Turtle: 'why, if a fish came to ME, and
told me he was going a journey, I should say "With what porpoise?"'

'Don't you mean "purpose"?' said Alice.

'I mean what I say,' the Mock Turtle replied in an offended tone. And
the Gryphon added 'Come, let's hear some of YOUR adventures.'

'I could tell you my adventures--beginning from this morning,' said
Alice a little timidly: 'but it's no use going back to yesterday,
because I was a different person then.'

'Explain all that,' said the Mock Turtle.

'No, no! The adventures first,' said the Gryphon in an impatient tone:
'explanations take such a dreadful time.'

So Alice began telling them her adventures from the time when she first
saw the White Rabbit. She was a little nervous about it just at first,
the two creatures got so close to her, one on each side, and opened
their eyes and mouths so VERY wide, but she gained courage as she went
on. Her listeners were perfectly quiet till she got to the part about
her repeating 'YOU ARE OLD, FATHER WILLIAM,' to the Caterpillar, and the
words all coming different, and then the Mock Turtle drew a long breath,
and said 'That's very curious.'

'It's all about as curious as it can be,' said the Gryphon.

'It all came different!' the Mock Turtle repeated thoughtfully. 'I
should like to hear her try and repeat something now. Tell her to
begin.' He looked at the Gryphon as if he thought it had some kind of
authority over Alice.

'Stand up and repeat "'TIS THE VOICE OF THE SLUGGARD,"' said the
Gryphon.

'How the creatures order one about, and make one repeat lessons!'
thought Alice; 'I might as well be at school at once.' However, she
got up, and began to repeat it, but her head was so full of the Lobster
Quadrille, that she hardly knew what she was saying, and the words came
very queer indeed:--

  ''Tis the voice of the Lobster; I heard him declare,
  "You have baked me too brown, I must sugar my hair."
  As a duck with its eyelids, so he with his nose
  Trims his belt and his buttons, and turns out his toes.'

       [later editions continued as follows
  When the sands are all dry, he is gay as a lark,
  And will talk in contemptuous tones of the Shark,
  But, when the tide rises and sharks are around,
  His voice has a timid and tremulous sound.]

'That's different from what I used to say when I was a child,' said the
Gryphon.

'Well, I never heard it before,' said the Mock Turtle; 'but it sounds
uncommon nonsense.'

Alice said nothing; she had sat down with her face in her hands,
wondering if anything would EVER happen in a natural way again.

'I should like to have it explained,' said the Mock Turtle.

'She can't explain it,' said the Gryphon hastily. 'Go on with the next
verse.'

'But about his toes?' the Mock Turtle persisted. 'How COULD he turn them
out with his nose, you know?'

'It's the first position in dancing.' Alice said; but was dreadfully
puzzled by the whole thing, and longed to change the subject.

'Go on with the next verse,' the Gryphon repeated impatiently: 'it
begins "I passed by his garden."'

Alice did not dare to disobey, though she felt sure it would all come
wrong, and she went on in a trembling voice:--

  'I passed by his garden, and marked, with one eye,
  How the Owl and the Panther were sharing a pie--'

    [later editions continued as follows
  The Panther took pie-crust, and gravy, and meat,
  While the Owl had the dish as its share of the treat.
  When the pie was all finished, the Owl, as a boon,
  Was kindly permitted to pocket the spoon:
  While the Panther received knife and fork with a growl,
  And concluded the banquet--]

'What IS the use of repeating all that stuff,' the Mock Turtle
interrupted, 'if you don't explain it as you go on? It's by far the most
confusing thing I ever heard!'

'Yes, I think you'd better leave off,' said the Gryphon: and Alice was
only too glad to do so.

'Shall we try another figure of the Lobster Quadrille?' the Gryphon went
on. 'Or would you like the Mock Turtle to sing you a song?'

'Oh, a song, please, if the Mock Turtle would be so kind,' Alice
replied, so eagerly that the Gryphon said, in a rather offended tone,
'Hm! No accounting for tastes! Sing her "Turtle Soup," will you, old
fellow?'

The Mock Turtle sighed deeply, and began, in a voice sometimes choked
with sobs, to sing this:--

   'Beautiful Soup, so rich and green,
   Waiting in a hot tureen!
   Who for such dainties would not stoop?
   Soup of the evening, beautiful Soup!
   Soup of the evening, beautiful Soup!
     Beau--ootiful Soo--oop!
     Beau--ootiful Soo--oop!
   Soo--oop of the e--e--evening,
     Beautiful, beautiful Soup!

   'Beautiful Soup! Who cares for fish,
   Game, or any other dish?
   Who would not give all else for two
   Pennyworth only of beautiful Soup?
   Pennyworth only of beautiful Soup?
     Beau--ootiful Soo--oop!
     Beau--ootiful Soo--oop!
   Soo--oop of the e--e--evening,
     Beautiful, beauti--FUL SOUP!'

'Chorus again!' cried the Gryphon, and the Mock Turtle had just begun
to repeat it, when a cry of 'The trial's beginning!' was heard in the
distance.

'Come on!' cried the Gryphon, and, taking Alice by the hand, it hurried
off, without waiting for the end of the song.

'What trial is it?' Alice panted as she ran; but the Gryphon only
answered 'Come on!' and ran the faster, while more and more faintly
came, carried on the breeze that followed them, the melancholy words:--

   'Soo--oop of the e--e--evening,
     Beautiful, beautiful Soup!'




CHAPTER XI. Who Stole the Tarts?

The King and Queen of Hearts were seated on their throne when they
arrived, with a great crowd assembled about them--all sorts of little
birds and beasts, as well as the whole pack of cards: the Knave was
standing before them, in chains, with a soldier on each side to guard
him; and near the King was the White Rabbit, with a trumpet in one hand,
and a scroll of parchment in the other. In the very middle of the court
was a table, with a large dish of tarts upon it: they looked so good,
that it made Alice quite hungry to look at them--'I wish they'd get the
trial done,' she thought, 'and hand round the refreshments!' But there
seemed to be no chance of this, so she began looking at everything about
her, to pass away the time.

Alice had never been in a court of justice before, but she had read
about them in books, and she was quite pleased to find that she knew
the name of nearly everything there. 'That's the judge,' she said to
herself, 'because of his great wig.'

The judge, by the way, was the King; and as he wore his crown over the
wig, (look at the frontispiece if you want to see how he did it,) he did
not look at all comfortable, and it was certainly not becoming.

'And that's the jury-box,' thought Alice, 'and those twelve creatures,'
(she was obliged to say 'creatures,' you see, because some of them were
animals, and some were birds,) 'I suppose they are the jurors.' She said
this last word two or three times over to herself, being rather proud of
it: for she thought, and rightly too, that very few little girls of her
age knew the meaning of it at all. However, 'jury-men' would have done
just as well.

The twelve jurors were all writing very busily on slates. 'What are they
doing?' Alice whispered to the Gryphon. 'They can't have anything to put
down yet, before the trial's begun.'

'They're putting down their names,' the Gryphon whispered in reply, 'for
fear they should forget them before the end of the trial.'

'Stupid things!' Alice began in a loud, indignant voice, but she stopped
hastily, for the White Rabbit cried out, 'Silence in the court!' and the
King put on his spectacles and looked anxiously round, to make out who
was talking.

Alice could see, as well as if she were looking over their shoulders,
that all the jurors were writing down 'stupid things!' on their slates,
and she could even make out that one of them didn't know how to spell
'stupid,' and that he had to ask his neighbour to tell him. 'A nice
muddle their slates'll be in before the trial's over!' thought Alice.

One of the jurors had a pencil that squeaked. This of course, Alice
could not stand, and she went round the court and got behind him, and
very soon found an opportunity of taking it away. She did it so quickly
that the poor little juror (it was Bill, the Lizard) could not make out
at all what had become of it; so, after hunting all about for it, he was
obliged to write with one finger for the rest of the day; and this was
of very little use, as it left no mark on the slate.

'Herald, read the accusation!' said the King.

On this the White Rabbit blew three blasts on the trumpet, and then
unrolled the parchment scroll, and read as follows:--

   'The Queen of Hearts, she made some tarts,
      All on a summer day:
    The Knave of Hearts, he stole those tarts,
      And took them quite away!'

'Consider your verdict,' the King said to the jury.

'Not yet, not yet!' the Rabbit hastily interrupted. 'There's a great
deal to come before that!'

'Call the first witness,' said the King; and the White Rabbit blew three
blasts on the trumpet, and called out, 'First witness!'

The first witness was the Hatter. He came in with a teacup in one
hand and a piece of bread-and-butter in the other. 'I beg pardon, your
Majesty,' he began, 'for bringing these in: but I hadn't quite finished
my tea when I was sent for.'

'You ought to have finished,' said the King. 'When did you begin?'

The Hatter looked at the March Hare, who had followed him into the
court, arm-in-arm with the Dormouse. 'Fourteenth of March, I think it
was,' he said.

'Fifteenth,' said the March Hare.

'Sixteenth,' added the Dormouse.

'Write that down,' the King said to the jury, and the jury eagerly
wrote down all three dates on their slates, and then added them up, and
reduced the answer to shillings and pence.

'Take off your hat,' the King said to the Hatter.

'It isn't mine,' said the Hatter.

'Stolen!' the King exclaimed, turning to the jury, who instantly made a
memorandum of the fact.

'I keep them to sell,' the Hatter added as an explanation; 'I've none of
my own. I'm a hatter.'

Here the Queen put on her spectacles, and began staring at the Hatter,
who turned pale and fidgeted.

'Give your evidence,' said the King; 'and don't be nervous, or I'll have
you executed on the spot.'

This did not seem to encourage the witness at all: he kept shifting
from one foot to the other, looking uneasily at the Queen, and in
his confusion he bit a large piece out of his teacup instead of the
bread-and-butter.

Just at this moment Alice felt a very curious sensation, which puzzled
her a good deal until she made out what it was: she was beginning to
grow larger again, and she thought at first she would get up and leave
the court; but on second thoughts she decided to remain where she was as
long as there was room for her.

'I wish you wouldn't squeeze so.' said the Dormouse, who was sitting
next to her. 'I can hardly breathe.'

'I can't help it,' said Alice very meekly: 'I'm growing.'

'You've no right to grow here,' said the Dormouse.

'Don't talk nonsense,' said Alice more boldly: 'you know you're growing
too.'

'Yes, but I grow at a reasonable pace,' said the Dormouse: 'not in that
ridiculous fashion.' And he got up very sulkily and crossed over to the
other side of the court.

All this time the Queen had never left off staring at the Hatter, and,
just as the Dormouse crossed the court, she said to one of the officers
of the court, 'Bring me the list of the singers in the last concert!' on
which the wretched Hatter trembled so, that he shook both his shoes off.

'Give your evidence,' the King repeated angrily, 'or I'll have you
executed, whether you're nervous or not.'

'I'm a poor man, your Majesty,' the Hatter began, in a trembling voice,
'--and I hadn't begun my tea--not above a week or so--and what with the
bread-and-butter getting so thin--and the twinkling of the tea--'

'The twinkling of the what?' said the King.

'It began with the tea,' the Hatter replied.

'Of course twinkling begins with a T!' said the King sharply. 'Do you
take me for a dunce? Go on!'

'I'm a poor man,' the Hatter went on, 'and most things twinkled after
that--only the March Hare said--'

'I didn't!' the March Hare interrupted in a great hurry.

'You did!' said the Hatter.

'I deny it!' said the March Hare.

'He denies it,' said the King: 'leave out that part.'

'Well, at any rate, the Dormouse said--' the Hatter went on, looking
anxiously round to see if he would deny it too: but the Dormouse denied
nothing, being fast asleep.

'After that,' continued the Hatter, 'I cut some more bread-and-butter--'

'But what did the Dormouse say?' one of the jury asked.

'That I can't remember,' said the Hatter.

'You MUST remember,' remarked the King, 'or I'll have you executed.'

The miserable Hatter dropped his teacup and bread-and-butter, and went
down on one knee. 'I'm a poor man, your Majesty,' he began.

'You're a very poor speaker,' said the King.

Here one of the guinea-pigs cheered, and was immediately suppressed by
the officers of the court. (As that is rather a hard word, I will just
explain to you how it was done. They had a large canvas bag, which tied
up at the mouth with strings: into this they slipped the guinea-pig,
head first, and then sat upon it.)

'I'm glad I've seen that done,' thought Alice. 'I've so often read
in the newspapers, at the end of trials, "There was some attempts
at applause, which was immediately suppressed by the officers of the
court," and I never understood what it meant till now.'

'If that's all you know about it, you may stand down,' continued the
King.

'I can't go no lower,' said the Hatter: 'I'm on the floor, as it is.'

'Then you may SIT down,' the King replied.

Here the other guinea-pig cheered, and was suppressed.

'Come, that finished the guinea-pigs!' thought Alice. 'Now we shall get
on better.'

'I'd rather finish my tea,' said the Hatter, with an anxious look at the
Queen, who was reading the list of singers.

'You may go,' said the King, and the Hatter hurriedly left the court,
without even waiting to put his shoes on.

'--and just take his head off outside,' the Queen added to one of the
officers: but the Hatter was out of sight before the officer could get
to the door.

'Call the next witness!' said the King.

The next witness was the Duchess's cook. She carried the pepper-box in
her hand, and Alice guessed who it was, even before she got into the
court, by the way the people near the door began sneezing all at once.

'Give your evidence,' said the King.

'Shan't,' said the cook.

The King looked anxiously at the White Rabbit, who said in a low voice,
'Your Majesty must cross-examine THIS witness.'

'Well, if I must, I must,' the King said, with a melancholy air, and,
after folding his arms and frowning at the cook till his eyes were
nearly out of sight, he said in a deep voice, 'What are tarts made of?'

'Pepper, mostly,' said the cook.

'Treacle,' said a sleepy voice behind her.

'Collar that Dormouse,' the Queen shrieked out. 'Behead that Dormouse!
Turn that Dormouse out of court! Suppress him! Pinch him! Off with his
whiskers!'

For some minutes the whole court was in confusion, getting the Dormouse
turned out, and, by the time they had settled down again, the cook had
disappeared.

'Never mind!' said the King, with an air of great relief. 'Call the next
witness.' And he added in an undertone to the Queen, 'Really, my dear,
YOU must cross-examine the next witness. It quite makes my forehead
ache!'

Alice watched the White Rabbit as he fumbled over the list, feeling very
curious to see what the next witness would be like, '--for they haven't
got much evidence YET,' she said to herself. Imagine her surprise, when
the White Rabbit read out, at the top of his shrill little voice, the
name 'Alice!'




CHAPTER XII. Alice's Evidence

'Here!' cried Alice, quite forgetting in the flurry of the moment how
large she had grown in the last few minutes, and she jumped up in such
a hurry that she tipped over the jury-box with the edge of her skirt,
upsetting all the jurymen on to the heads of the crowd below, and there
they lay sprawling about, reminding her very much of a globe of goldfish
she had accidentally upset the week before.

'Oh, I BEG your pardon!' she exclaimed in a tone of great dismay, and
began picking them up again as quickly as she could, for the accident of
the goldfish kept running in her head, and she had a vague sort of idea
that they must be collected at once and put back into the jury-box, or
they would die.

'The trial cannot proceed,' said the King in a very grave voice, 'until
all the jurymen are back in their proper places--ALL,' he repeated with
great emphasis, looking hard at Alice as he said do.

Alice looked at the jury-box, and saw that, in her haste, she had put
the Lizard in head downwards, and the poor little thing was waving its
tail about in a melancholy way, being quite unable to move. She soon got
it out again, and put it right; 'not that it signifies much,' she said
to herself; 'I should think it would be QUITE as much use in the trial
one way up as the other.'

As soon as the jury had a little recovered from the shock of being
upset, and their slates and pencils had been found and handed back to
them, they set to work very diligently to write out a history of the
accident, all except the Lizard, who seemed too much overcome to do
anything but sit with its mouth open, gazing up into the roof of the
court.

'What do you know about this business?' the King said to Alice.

'Nothing,' said Alice.

'Nothing WHATEVER?' persisted the King.

'Nothing whatever,' said Alice.

'That's very important,' the King said, turning to the jury. They were
just beginning to write this down on their slates, when the White Rabbit
interrupted: 'UNimportant, your Majesty means, of course,' he said in a
very respectful tone, but frowning and making faces at him as he spoke.

'UNimportant, of course, I meant,' the King hastily said, and went on
to himself in an undertone,

'important--unimportant--unimportant--important--' as if he were trying
which word sounded best.

Some of the jury wrote it down 'important,' and some 'unimportant.'
Alice could see this, as she was near enough to look over their slates;
'but it doesn't matter a bit,' she thought to herself.

At this moment the King, who had been for some time busily writing in
his note-book, cackled out 'Silence!' and read out from his book, 'Rule
Forty-two. ALL PERSONS MORE THAN A MILE HIGH TO LEAVE THE COURT.'

Everybody looked at Alice.

'I'M not a mile high,' said Alice.

'You are,' said the King.

'Nearly two miles high,' added the Queen.

'Well, I shan't go, at any rate,' said Alice: 'besides, that's not a
regular rule: you invented it just now.'

'It's the oldest rule in the book,' said the King.

'Then it ought to be Number One,' said Alice.

The King turned pale, and shut his note-book hastily. 'Consider your
verdict,' he said to the jury, in a low, trembling voice.

'There's more evidence to come yet, please your Majesty,' said the White
Rabbit, jumping up in a great hurry; 'this paper has just been picked
up.'

'What's in it?' said the Queen.

'I haven't opened it yet,' said the White Rabbit, 'but it seems to be a
letter, written by the prisoner to--to somebody.'

'It must have been that,' said the King, 'unless it was written to
nobody, which isn't usual, you know.'

'Who is it directed to?' said one of the jurymen.

'It isn't directed at all,' said the White Rabbit; 'in fact, there's
nothing written on the OUTSIDE.' He unfolded the paper as he spoke, and
added 'It isn't a letter, after all: it's a set of verses.'

'Are they in the prisoner's handwriting?' asked another of the jurymen.

'No, they're not,' said the White Rabbit, 'and that's the queerest thing
about it.' (The jury all looked puzzled.)

'He must have imitated somebody else's hand,' said the King. (The jury
all brightened up again.)

'Please your Majesty,' said the Knave, 'I didn't write it, and they
can't prove I did: there's no name signed at the end.'

'If you didn't sign it,' said the King, 'that only makes the matter
worse. You MUST have meant some mischief, or else you'd have signed your
name like an honest man.'

There was a general clapping of hands at this: it was the first really
clever thing the King had said that day.

'That PROVES his guilt,' said the Queen.

'It proves nothing of the sort!' said Alice. 'Why, you don't even know
what they're about!'

'Read them,' said the King.

The White Rabbit put on his spectacles. 'Where shall I begin, please
your Majesty?' he asked.

'Begin at the beginning,' the King said gravely, 'and go on till you
come to the end: then stop.'

These were the verses the White Rabbit read:--

   'They told me you had been to her,
    And mentioned me to him:
   She gave me a good character,
    But said I could not swim.

   He sent them word I had not gone
    (We know it to be true):
   If she should push the matter on,
    What would become of you?

   I gave her one, they gave him two,
    You gave us three or more;
   They all returned from him to you,
    Though they were mine before.

   If I or she should chance to be
    Involved in this affair,
   He trusts to you to set them free,
    Exactly as we were.

   My notion was that you had been
    (Before she had this fit)
   An obstacle that came between
    Him, and ourselves, and it.

   Don't let him know she liked them best,
    For this must ever be
   A secret, kept from all the rest,
    Between yourself and me.'

'That's the most important piece of evidence we've heard yet,' said the
King, rubbing his hands; 'so now let the jury--'

'If any one of them can explain it,' said Alice, (she had grown so large
in the last few minutes that she wasn't a bit afraid of interrupting
him,) 'I'll give him sixpence. _I_ don't believe there's an atom of
meaning in it.'

The jury all wrote down on their slates, 'SHE doesn't believe there's an
atom of meaning in it,' but none of them attempted to explain the paper.

'If there's no meaning in it,' said the King, 'that saves a world of
trouble, you know, as we needn't try to find any. And yet I don't know,'
he went on, spreading out the verses on his knee, and looking at them
with one eye; 'I seem to see some meaning in them, after all. "--SAID
I COULD NOT SWIM--" you can't swim, can you?' he added, turning to the
Knave.

The Knave shook his head sadly. 'Do I look like it?' he said. (Which he
certainly did NOT, being made entirely of cardboard.)

'All right, so far,' said the King, and he went on muttering over
the verses to himself: '"WE KNOW IT TO BE TRUE--" that's the jury, of
course--"I GAVE HER ONE, THEY GAVE HIM TWO--" why, that must be what he
did with the tarts, you know--'

'But, it goes on "THEY ALL RETURNED FROM HIM TO YOU,"' said Alice.

'Why, there they are!' said the King triumphantly, pointing to the tarts
on the table. 'Nothing can be clearer than THAT. Then again--"BEFORE SHE
HAD THIS FIT--" you never had fits, my dear, I think?' he said to the
Queen.

'Never!' said the Queen furiously, throwing an inkstand at the Lizard
as she spoke. (The unfortunate little Bill had left off writing on his
slate with one finger, as he found it made no mark; but he now hastily
began again, using the ink, that was trickling down his face, as long as
it lasted.)

'Then the words don't FIT you,' said the King, looking round the court
with a smile. There was a dead silence.

'It's a pun!' the King added in an offended tone, and everybody laughed,
'Let the jury consider their verdict,' the King said, for about the
twentieth time that day.

'No, no!' said the Queen. 'Sentence first--verdict afterwards.'

'Stuff and nonsense!' said Alice loudly. 'The idea of having the
sentence first!'

'Hold your tongue!' said the Queen, turning purple.

'I won't!' said Alice.

'Off with her head!' the Queen shouted at the top of her voice. Nobody
moved.

'Who cares for you?' said Alice, (she had grown to her full size by this
time.) 'You're nothing but a pack of cards!'

At this the whole pack rose up into the air, and came flying down upon
her: she gave a little scream, half of fright and half of anger, and
tried to beat them off, and found herself lying on the bank, with her
head in the lap of her sister, who was gently brushing away some dead
leaves that had fluttered down from the trees upon her face.

'Wake up, Alice dear!' said her sister; 'Why, what a long sleep you've
had!'

'Oh, I've had such a curious dream!' said Alice, and she told her
sister, as well as she could remember them, all these strange Adventures
of hers that you have just been reading about; and when she had
finished, her sister kissed her, and said, 'It WAS a curious dream,
dear, certainly: but now run in to your tea; it's getting late.' So
Alice got up and ran off, thinking while she ran, as well she might,
what a wonderful dream it had been.

But her sister sat still just as she left her, leaning her head on her
hand, watching the setting sun, and thinking of little Alice and all her
wonderful Adventures, till she too began dreaming after a fashion, and
this was her dream:--

First, she dreamed of little Alice herself, and once again the tiny
hands were clasped upon her knee, and the bright eager eyes were looking
up into hers--she could hear the very tones of her voice, and see that
queer little toss of her head to keep back the wandering hair that
WOULD always get into her eyes--and still as she listened, or seemed to
listen, the whole place around her became alive with the strange creatures
of her little sister's dream.

The long grass rustled at her feet as the White Rabbit hurried by--the
frightened Mouse splashed his way through the neighbouring pool--she
could hear the rattle of the teacups as the March Hare and his friends
shared their never-ending meal, and the shrill voice of the Queen
ordering off her unfortunate guests to execution--once more the pig-baby
was sneezing on the Duchess's knee, while plates and dishes crashed
around it--once more the shriek of the Gryphon, the squeaking of the
Lizard's slate-pencil, and the choking of the suppressed guinea-pigs,
filled the air, mixed up with the distant sobs of the miserable Mock
Turtle.

So she sat on, with closed eyes, and half believed herself in
Wonderland, though she knew she had but to open them again, and all
would change to dull reality--the grass would be only rustling in the
wind, and the pool rippling to the waving of the reeds--the rattling
teacups would change to tinkling sheep-bells, and the Queen's shrill
cries to the voice of the shepherd boy--and the sneeze of the baby, the
shriek of the Gryphon, and all the other queer noises, would change (she
knew) to the confused clamour of the busy farm-yard--while the lowing
of the cattle in the distance would take the place of the Mock Turtle's
heavy sobs.

Lastly, she pictured to herself how this same little sister of hers
would, in the after-time, be herself a grown woman; and how she would
keep, through all her riper years, the simple and loving heart of her
childhood: and how she would gather about her other little children, and
make THEIR eyes bright and eager with many a strange tale, perhaps even
with the dream of Wonderland of long ago: and how she would feel with
all their simple sorrows, and find a pleasure in all their simple joys,
remembering her own child-life, and the happy summer days.

              THE END
EOT;


































































































































































































































































































































































}
<?php


namespace Faker\Provider\en_US;


class Payment extends \Faker\Provider\Payment
{
public function bankAccountNumber()
{

 $length = self::numberBetween(0, 3) + self::numberBetween(0, 3) + self::numberBetween(0, 3) + self::numberBetween(0, 3) + 5;

return self::numerify(str_repeat('#', $length));
}

public function bankRoutingNumber()
{
$district = self::numberBetween(1, 12);
$type = self::randomElement(array(0, 0, 0, 0, 20, 20, 60));
$clearingCenter = self::randomDigitNotNull();
$state = self::randomDigit();
$institution = self::randomNumber(4, true);

$result = sprintf('%02d%01d%01d%04d', $district + $type, $clearingCenter, $state, $institution);

return $result . self::calculateRoutingNumberChecksum($result);
}

public static function calculateRoutingNumberChecksum($routing)
{
return (
7 * ($routing[0] + $routing[3] + $routing[6]) +
3 * ($routing[1] + $routing[4] + $routing[7]) +
9 * ($routing[2] + $routing[5])
) % 10;
}
}
<?php

namespace Faker\Provider\en_US;

class Address extends \Faker\Provider\Address
{
protected static $cityPrefix = array('North', 'East', 'West', 'South', 'New', 'Lake', 'Port');
protected static $citySuffix = array('town', 'ton', 'land', 'ville', 'berg', 'burgh', 'borough', 'bury', 'view', 'port', 'mouth', 'stad', 'furt', 'chester', 'mouth', 'fort', 'haven', 'side', 'shire');
protected static $buildingNumber = array('%####', '%###', '%##');
protected static $streetSuffix = array(
'Alley', 'Avenue', 'Branch', 'Bridge', 'Brook', 'Brooks', 'Burg', 'Burgs', 'Bypass', 'Camp', 'Canyon', 'Cape', 'Causeway', 'Center', 'Centers', 'Circle', 'Circles', 'Cliff', 'Cliffs', 'Club', 'Common', 'Corner', 'Corners', 'Course', 'Court', 'Courts', 'Cove', 'Coves', 'Creek', 'Crescent', 'Crest', 'Crossing', 'Crossroad', 'Curve', 'Dale', 'Dam', 'Divide', 'Drive', 'Drive', 'Drives', 'Estate', 'Estates', 'Expressway', 'Extension', 'Extensions', 'Fall', 'Falls', 'Ferry', 'Field', 'Fields', 'Flat', 'Flats', 'Ford', 'Fords', 'Forest', 'Forge', 'Forges', 'Fork', 'Forks', 'Fort', 'Freeway', 'Garden', 'Gardens', 'Gateway', 'Glen', 'Glens', 'Green', 'Greens', 'Grove', 'Groves', 'Harbor', 'Harbors', 'Haven', 'Heights', 'Highway', 'Hill', 'Hills', 'Hollow', 'Inlet', 'Inlet', 'Island', 'Island', 'Islands', 'Islands', 'Isle', 'Isle', 'Junction', 'Junctions', 'Key', 'Keys', 'Knoll', 'Knolls', 'Lake', 'Lakes', 'Land', 'Landing', 'Lane', 'Light', 'Lights', 'Loaf', 'Lock', 'Locks', 'Locks', 'Lodge', 'Lodge', 'Loop', 'Mall', 'Manor', 'Manors', 'Meadow', 'Meadows', 'Mews', 'Mill', 'Mills', 'Mission', 'Mission', 'Motorway', 'Mount', 'Mountain', 'Mountain', 'Mountains', 'Mountains', 'Neck', 'Orchard', 'Oval', 'Overpass', 'Park', 'Parks', 'Parkway', 'Parkways', 'Pass', 'Passage', 'Path', 'Pike', 'Pine', 'Pines', 'Place', 'Plain', 'Plains', 'Plains', 'Plaza', 'Plaza', 'Point', 'Points', 'Port', 'Port', 'Ports', 'Ports', 'Prairie', 'Prairie', 'Radial', 'Ramp', 'Ranch', 'Rapid', 'Rapids', 'Rest', 'Ridge', 'Ridges', 'River', 'Road', 'Road', 'Roads', 'Roads', 'Route', 'Row', 'Rue', 'Run', 'Shoal', 'Shoals', 'Shore', 'Shores', 'Skyway', 'Spring', 'Springs', 'Springs', 'Spur', 'Spurs', 'Square', 'Square', 'Squares', 'Squares', 'Station', 'Station', 'Stravenue', 'Stravenue', 'Stream', 'Stream', 'Street', 'Street', 'Streets', 'Summit', 'Summit', 'Terrace', 'Throughway', 'Trace', 'Track', 'Trafficway', 'Trail', 'Trail', 'Tunnel', 'Tunnel', 'Turnpike', 'Turnpike', 'Underpass', 'Union', 'Unions', 'Valley', 'Valleys', 'Via', 'Viaduct', 'View', 'Views', 'Village', 'Village', 'Villages', 'Ville', 'Vista', 'Vista', 'Walk', 'Walks', 'Wall', 'Way', 'Ways', 'Well', 'Wells'
);
protected static $postcode = array('#####', '#####-####');
protected static $state = array(
'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
);
protected static $stateAbbr = array(
'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA', 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY'
);
protected static $country = array(
'Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica (the territory South of 60 deg S)', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan',
'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Bouvet Island (Bouvetoya)', 'Brazil', 'British Indian Ocean Territory (Chagos Archipelago)', 'British Virgin Islands', 'Brunei Darussalam', 'Bulgaria', 'Burkina Faso', 'Burundi',
'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Cayman Islands', 'Central African Republic', 'Chad', 'Chile', 'China', 'Christmas Island', 'Cocos (Keeling) Islands', 'Colombia', 'Comoros', 'Congo', 'Cook Islands', 'Costa Rica', 'Cote d\'Ivoire', 'Croatia', 'Cuba', 'Cyprus', 'Czech Republic',
'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic',
'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia',
'Faroe Islands', 'Falkland Islands (Malvinas)', 'Fiji', 'Finland', 'France', 'French Guiana', 'French Polynesia', 'French Southern Territories',
'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea', 'Guinea-Bissau', 'Guyana',
'Haiti', 'Heard Island and McDonald Islands', 'Holy See (Vatican City State)', 'Honduras', 'Hong Kong', 'Hungary',
'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy',
'Jamaica', 'Japan', 'Jersey', 'Jordan',
'Kazakhstan', 'Kenya', 'Kiribati', 'Korea', 'Korea', 'Kuwait', 'Kyrgyz Republic',
'Lao People\'s Democratic Republic', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libyan Arab Jamahiriya', 'Liechtenstein', 'Lithuania', 'Luxembourg',
'Macao', 'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Martinique', 'Mauritania', 'Mauritius', 'Mayotte', 'Mexico', 'Micronesia', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Montserrat', 'Morocco', 'Mozambique', 'Myanmar',
'Namibia', 'Nauru', 'Nepal', 'Netherlands Antilles', 'Netherlands', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'Northern Mariana Islands', 'Norway',
'Oman',
'Pakistan', 'Palau', 'Palestinian Territories', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Pitcairn Islands', 'Poland', 'Portugal', 'Puerto Rico',
'Qatar',
'Reunion', 'Romania', 'Russian Federation', 'Rwanda',
'Saint Barthelemy', 'Saint Helena', 'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Martin', 'Saint Pierre and Miquelon', 'Saint Vincent and the Grenadines', 'Samoa', 'San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia (Slovak Republic)', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Georgia and the South Sandwich Islands', 'Spain', 'Sri Lanka', 'Sudan', 'Suriname', 'Svalbard & Jan Mayen Islands', 'Swaziland', 'Sweden', 'Switzerland', 'Syrian Arab Republic',
'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', 'Timor-Leste', 'Togo', 'Tokelau', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks and Caicos Islands', 'Tuvalu',
'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States of America', 'United States Minor Outlying Islands', 'United States Virgin Islands', 'Uruguay', 'Uzbekistan',
'Vanuatu', 'Venezuela', 'Vietnam',
'Wallis and Futuna', 'Western Sahara',
'Yemen',
'Zambia', 'Zimbabwe'
);
protected static $cityFormats = array(
'{{cityPrefix}} {{firstName}}{{citySuffix}}',
'{{cityPrefix}} {{firstName}}',
'{{firstName}}{{citySuffix}}',
'{{lastName}}{{citySuffix}}',
);
protected static $streetNameFormats = array(
'{{firstName}} {{streetSuffix}}',
'{{lastName}} {{streetSuffix}}'
);
protected static $streetAddressFormats = array(
'{{buildingNumber}} {{streetName}}',
'{{buildingNumber}} {{streetName}} {{secondaryAddress}}',
);
protected static $addressFormats = array(
"{{streetAddress}}\n{{city}}, {{stateAbbr}} {{postcode}}",
);
protected static $secondaryAddressFormats = array('Apt. ###', 'Suite ###');




public static function cityPrefix()
{
return static::randomElement(static::$cityPrefix);
}




public static function secondaryAddress()
{
return static::numerify(static::randomElement(static::$secondaryAddressFormats));
}




public static function state()
{
return static::randomElement(static::$state);
}




public static function stateAbbr()
{
return static::randomElement(static::$stateAbbr);
}
}
<?php

namespace Faker\Provider\en_US;

class PhoneNumber extends \Faker\Provider\PhoneNumber
{



protected static $formats = array(

 '+1-{{areaCode}}-{{exchangeCode}}-####',
'+1 ({{areaCode}}) {{exchangeCode}}-####',
'+1-{{areaCode}}-{{exchangeCode}}-####',
'+1.{{areaCode}}.{{exchangeCode}}.####',
'+1{{areaCode}}{{exchangeCode}}####',


 '{{areaCode}}-{{exchangeCode}}-####',
'({{areaCode}}) {{exchangeCode}}-####',
'1-{{areaCode}}-{{exchangeCode}}-####',
'{{areaCode}}.{{exchangeCode}}.####',

'{{areaCode}}-{{exchangeCode}}-####',
'({{areaCode}}) {{exchangeCode}}-####',
'1-{{areaCode}}-{{exchangeCode}}-####',
'{{areaCode}}.{{exchangeCode}}.####',


 '{{areaCode}}-{{exchangeCode}}-#### x###',
'({{areaCode}}) {{exchangeCode}}-#### x###',
'1-{{areaCode}}-{{exchangeCode}}-#### x###',
'{{areaCode}}.{{exchangeCode}}.#### x###',

'{{areaCode}}-{{exchangeCode}}-#### x####',
'({{areaCode}}) {{exchangeCode}}-#### x####',
'1-{{areaCode}}-{{exchangeCode}}-#### x####',
'{{areaCode}}.{{exchangeCode}}.#### x####',

'{{areaCode}}-{{exchangeCode}}-#### x#####',
'({{areaCode}}) {{exchangeCode}}-#### x#####',
'1-{{areaCode}}-{{exchangeCode}}-#### x#####',
'{{areaCode}}.{{exchangeCode}}.#### x#####'
);




protected static $tollFreeAreaCodes = array(
800, 844, 855, 866, 877, 888
);
protected static $tollFreeFormats = array(

 '{{tollFreeAreaCode}}-{{exchangeCode}}-####',
'({{tollFreeAreaCode}}) {{exchangeCode}}-####',
'1-{{tollFreeAreaCode}}-{{exchangeCode}}-####',
'{{tollFreeAreaCode}}.{{exchangeCode}}.####',
);

public function tollFreeAreaCode()
{
return self::randomElement(static::$tollFreeAreaCodes);
}

public function tollFreePhoneNumber()
{
$format = self::randomElement(static::$tollFreeFormats);

return self::numerify($this->generator->parse($format));
}








public static function areaCode()
{
$digits[] = self::numberBetween(2, 9);
$digits[] = self::randomDigit();
$digits[] = self::randomDigitNot($digits[1]);

return join('', $digits);
}








public static function exchangeCode()
{
$digits[] = self::numberBetween(2, 9);
$digits[] = self::randomDigit();

if ($digits[1] === 1) {
$digits[] = self::randomDigitNot(1);
} else {
$digits[] = self::randomDigit();
}

return join('', $digits);
}
}
<?php

namespace Faker\Provider;




class Color extends Base
{
protected static $safeColorNames = array(
'black', 'maroon', 'green', 'navy', 'olive',
'purple', 'teal', 'lime', 'blue', 'silver',
'gray', 'yellow', 'fuchsia', 'aqua', 'white'
);

protected static $allColorNames = array(
'AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine',
'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond',
'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue',
'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue',
'Cornsilk', 'Crimson', 'Cyan', 'DarkBlue', 'DarkCyan',
'DarkGoldenRod', 'DarkGray', 'DarkGreen', 'DarkKhaki',
'DarkMagenta', 'DarkOliveGreen', 'Darkorange', 'DarkOrchid',
'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue',
'DarkSlateGray', 'DarkTurquoise', 'DarkViolet', 'DeepPink',
'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick',
'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite',
'Gold', 'GoldenRod', 'Gray', 'Green', 'GreenYellow', 'HoneyDew',
'HotPink', 'IndianRed', 'Indigo', 'Ivory', 'Khaki', 'Lavender',
'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral',
'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGreen', 'LightPink',
'LightSalmon', 'LightSeaGreen', 'LightSkyBlue', 'LightSlateGray', 'LightSteelBlue',
'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon', 'MediumAquaMarine',
'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue',
'MediumSpringGreen', 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue',
'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive',
'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen',
'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum',
'PowderBlue', 'Purple', 'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon',
'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
'SlateGray', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato',
'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke', 'Yellow', 'YellowGreen'
);




public static function hexColor()
{
return '#' . str_pad(dechex(mt_rand(1, 16777215)), 6, '0', STR_PAD_LEFT);
}




public static function safeHexColor()
{
$color = str_pad(dechex(mt_rand(0, 255)), 3, '0', STR_PAD_LEFT);

return '#' . $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
}




public static function rgbColorAsArray()
{
$color = static::hexColor();

return array(
hexdec(substr($color, 1, 2)),
hexdec(substr($color, 3, 2)),
hexdec(substr($color, 5, 2))
);
}




public static function rgbColor()
{
return implode(',', static::rgbColorAsArray());
}




public static function rgbCssColor()
{
return 'rgb(' . static::rgbColor() . ')';
}




public static function rgbaCssColor()
{
return 'rgba(' . static::rgbColor() . ',' . static::randomFloat(1, 0, 1) . ')';
}




public static function safeColorName()
{
return static::randomElement(static::$safeColorNames);
}




public static function colorName()
{
return static::randomElement(static::$allColorNames);
}
}
<?php

namespace Faker\Provider;

abstract class Text extends Base
{
protected static $baseText = '';
protected static $separator = ' ';
protected static $separatorLen = 1;
protected $explodedText;
protected $consecutiveWords = array();
protected static $textStartsWithUppercase = true;
















public function realText($maxNbChars = 200, $indexSize = 2)
{
if ($maxNbChars < 10) {
throw new \InvalidArgumentException('maxNbChars must be at least 10');
}

if ($indexSize < 1) {
throw new \InvalidArgumentException('indexSize must be at least 1');
}

if ($indexSize > 5) {
throw new \InvalidArgumentException('indexSize must be at most 5');
}

$words = $this->getConsecutiveWords($indexSize);
$result = array();
$resultLength = 0;

 $next = static::randomKey($words);
while ($resultLength < $maxNbChars && isset($words[$next])) {

 $word = static::randomElement($words[$next]);


 $currentWords = static::explode($next);
$currentWords[] = $word;
array_shift($currentWords);
$next = static::implode($currentWords);


 if ($resultLength == 0 && !static::validStart($word)) {
continue;
}


 $result[] = $word;
$resultLength += static::strlen($word) + static::$separatorLen;
}


 array_pop($result);


 $result = static::implode($result);

return static::appendEnd($result);
}

protected function getConsecutiveWords($indexSize)
{
if (!isset($this->consecutiveWords[$indexSize])) {
$parts = $this->getExplodedText();
$words = array();
$index = array();
for ($i = 0; $i < $indexSize; $i++) {
$index[] = array_shift($parts);
}

for ($i = 0, $count = count($parts); $i < $count; $i++) {
$stringIndex = static::implode($index);
if (!isset($words[$stringIndex])) {
$words[$stringIndex] = array();
}
$word = $parts[$i];
$words[$stringIndex][] = $word;
array_shift($index);
$index[] = $word;
}

 $this->consecutiveWords[$indexSize] = $words;
}

return $this->consecutiveWords[$indexSize];
}

protected function getExplodedText()
{
if ($this->explodedText === null) {
$this->explodedText = static::explode(preg_replace('/\s+/u', ' ', static::$baseText));
}

return $this->explodedText;
}

protected static function explode($text)
{
return explode(static::$separator, $text);
}

protected static function implode($words)
{
return implode(static::$separator, $words);
}

protected static function strlen($text)
{
return function_exists('mb_strlen') ? mb_strlen($text, 'UTF-8') : strlen($text);
}

protected static function validStart($word)
{
$isValid = true;
if (static::$textStartsWithUppercase) {
$isValid = preg_match('/^\p{Lu}/u', $word);
}
return $isValid;
}

protected static function appendEnd($text)
{
return rtrim($text, ',— ').'.';
}
}
<?php

namespace Faker\Provider;





class Barcode extends Base
{
private function ean($length = 13)
{
$code = static::numerify(str_repeat('#', $length - 1));

return $code . static::eanChecksum($code);
}








protected static function eanChecksum($input)
{
$sequence = (strlen($input) + 1) === 8 ? array(3, 1) : array(1, 3);
$sums = 0;
foreach (str_split($input) as $n => $digit) {
$sums += $digit * $sequence[$n % 2];
}
return (10 - $sums % 10) % 10;
}










protected static function isbnChecksum($input)
{

 
 $length = 9;

if (strlen($input) !== $length) {
throw new \LengthException(sprintf('Input length should be equal to %d', $length));
}

$digits = str_split($input);
array_walk(
$digits,
function (&$digit, $position) {
$digit = (10 - $position) * $digit;
}
);
$result = (11 - array_sum($digits) % 11) % 11;


 return ($result < 10)?$result:'X';
}






public function ean13()
{
return $this->ean(13);
}






public function ean8()
{
return $this->ean(8);
}








public function isbn10()
{
$code = static::numerify(str_repeat('#', 9));

return $code . static::isbnChecksum($code);
}








public function isbn13()
{
$code = '97' . static::numberBetween(8, 9) . static::numerify(str_repeat('#', 9));

return $code . static::eanChecksum($code);
}
}
<?php

namespace Faker\Provider;

use Faker\Generator;
use Faker\DefaultGenerator;
use Faker\UniqueGenerator;
use Faker\ValidGenerator;

class Base
{



protected $generator;




protected $unique;




public function __construct(Generator $generator)
{
$this->generator = $generator;
}






public static function randomDigit()
{
return mt_rand(0, 9);
}






public static function randomDigitNotNull()
{
return mt_rand(1, 9);
}







public static function randomDigitNot($except)
{
$result = self::numberBetween(0, 8);
if ($result >= $except) {
$result++;
}
return $result;
}












public static function randomNumber($nbDigits = null, $strict = false)
{
if (!is_bool($strict)) {
throw new \InvalidArgumentException('randomNumber() generates numbers of fixed width. To generate numbers between two boundaries, use numberBetween() instead.');
}
if (null === $nbDigits) {
$nbDigits = static::randomDigitNotNull();
}
$max = pow(10, $nbDigits) - 1;
if ($max > mt_getrandmax()) {
throw new \InvalidArgumentException('randomNumber() can only generate numbers up to mt_getrandmax()');
}
if ($strict) {
return mt_rand(pow(10, $nbDigits - 1), $max);
}

return mt_rand(0, $max);
}











public static function randomFloat($nbMaxDecimals = null, $min = 0, $max = null)
{
if (null === $nbMaxDecimals) {
$nbMaxDecimals = static::randomDigit();
}

if (null === $max) {
$max = static::randomNumber();
if ($min > $max) {
$max = $min;
}
}

if ($min > $max) {
$tmp = $min;
$min = $max;
$max = $tmp;
}

return round($min + mt_rand() / mt_getrandmax() * ($max - $min), $nbMaxDecimals);
}










public static function numberBetween($int1 = 0, $int2 = 2147483647)
{
$min = $int1 < $int2 ? $int1 : $int2;
$max = $int1 < $int2 ? $int2 : $int1;
return mt_rand($min, $max);
}






public static function randomLetter()
{
return chr(mt_rand(97, 122));
}




public static function randomAscii()
{
return chr(mt_rand(33, 126));
}











public static function randomElements(array $array = array('a', 'b', 'c'), $count = 1, $allowDuplicates = false)
{
$allKeys = array_keys($array);
$numKeys = count($allKeys);

if (!$allowDuplicates && $numKeys < $count) {
throw new \LengthException(sprintf('Cannot get %d elements, only %d in array', $count, $numKeys));
}

$highKey = $numKeys - 1;
$keys = $elements = array();
$numElements = 0;

while ($numElements < $count) {
$num = mt_rand(0, $highKey);

if (!$allowDuplicates) {
if (isset($keys[$num])) {
continue;
}
$keys[$num] = true;
}

$elements[] = $array[$allKeys[$num]];
$numElements++;
}

return $elements;
}







public static function randomElement($array = array('a', 'b', 'c'))
{
if (!$array) {
return null;
}
$elements = static::randomElements($array, 1);

return $elements[0];
}







public static function randomKey($array = array())
{
if (!$array) {
return null;
}
$keys = array_keys($array);
$key = $keys[mt_rand(0, count($keys) - 1)];

return $key;
}















public static function shuffle($arg = '')
{
if (is_array($arg)) {
return static::shuffleArray($arg);
}
if (is_string($arg)) {
return static::shuffleString($arg);
}
throw new \InvalidArgumentException('shuffle() only supports strings or arrays');
}
















public static function shuffleArray($array = array())
{
$shuffledArray = array();
$i = 0;
reset($array);
foreach ($array as $key => $value) {
if ($i == 0) {
$j = 0;
} else {
$j = mt_rand(0, $i);
}
if ($j == $i) {
$shuffledArray[]= $value;
} else {
$shuffledArray[]= $shuffledArray[$j];
$shuffledArray[$j] = $value;
}
$i++;
}
return $shuffledArray;
}


















public static function shuffleString($string = '', $encoding = 'UTF-8')
{
if (function_exists('mb_strlen')) {

 $array = array();
$strlen = mb_strlen($string, $encoding);
for ($i = 0; $i < $strlen; $i++) {
$array []= mb_substr($string, $i, 1, $encoding);
}
} else {
$array = str_split($string, 1);
}
return implode('', static::shuffleArray($array));
}

private static function replaceWildcard($string, $wildcard = '#', $callback = 'static::randomDigit')
{
if (($pos = strpos($string, $wildcard)) === false) {
return $string;
}
for ($i = $pos, $last = strrpos($string, $wildcard, $pos) + 1; $i < $last; $i++) {
if ($string[$i] === $wildcard) {
$string[$i] = call_user_func($callback);
}
}
return $string;
}








public static function numerify($string = '###')
{

 
 $toReplace = array();
if (($pos = strpos($string, '#')) !== false) {
for ($i = $pos, $last = strrpos($string, '#', $pos) + 1; $i < $last; $i++) {
if ($string[$i] === '#') {
$toReplace[] = $i;
}
}
}
if ($nbReplacements = count($toReplace)) {
$maxAtOnce = strlen((string) mt_getrandmax()) - 1;
$numbers = '';
$i = 0;
while ($i < $nbReplacements) {
$size = min($nbReplacements - $i, $maxAtOnce);
$numbers .= str_pad(static::randomNumber($size), $size, '0', STR_PAD_LEFT);
$i += $size;
}
for ($i = 0; $i < $nbReplacements; $i++) {
$string[$toReplace[$i]] = $numbers[$i];
}
}
$string = self::replaceWildcard($string, '%', 'static::randomDigitNotNull');

return $string;
}







public static function lexify($string = '????')
{
return self::replaceWildcard($string, '?', 'static::randomLetter');
}








public static function bothify($string = '## ??')
{
$string = self::replaceWildcard($string, '*', function () {
return mt_rand(0, 1) ? '#' : '?';
});
return static::lexify(static::numerify($string));
}









public static function asciify($string = '****')
{
return preg_replace_callback('/\*/u', 'static::randomAscii', $string);
}



























public static function regexify($regex = '')
{

 $regex = preg_replace('/^\/?\^?/', '', $regex);
$regex = preg_replace('/\$?\/?$/', '', $regex);

 $regex = preg_replace('/\{(\d+)\}/', '{\1,\1}', $regex);

 $regex = preg_replace('/(?<!\\\)\?/', '{0,1}', $regex);
$regex = preg_replace('/(?<!\\\)\*/', '{0,' . static::randomDigitNotNull() . '}', $regex);
$regex = preg_replace('/(?<!\\\)\+/', '{1,' . static::randomDigitNotNull() . '}', $regex);

 $regex = preg_replace_callback('/(\[[^\]]+\])\{(\d+),(\d+)\}/', function ($matches) {
return str_repeat($matches[1], Base::randomElement(range($matches[2], $matches[3])));
}, $regex);

 $regex = preg_replace_callback('/(\([^\)]+\))\{(\d+),(\d+)\}/', function ($matches) {
return str_repeat($matches[1], Base::randomElement(range($matches[2], $matches[3])));
}, $regex);

 $regex = preg_replace_callback('/(\\\?.)\{(\d+),(\d+)\}/', function ($matches) {
return str_repeat($matches[1], Base::randomElement(range($matches[2], $matches[3])));
}, $regex);

 $regex = preg_replace_callback('/\((.*?)\)/', function ($matches) {
return Base::randomElement(explode('|', str_replace(array('(', ')'), '', $matches[1])));
}, $regex);

 $regex = preg_replace_callback('/\[([^\]]+)\]/', function ($matches) {
return '[' . preg_replace_callback('/(\w|\d)\-(\w|\d)/', function ($range) {
return implode(range($range[1], $range[2]), '');
}, $matches[1]) . ']';
}, $regex);

 $regex = preg_replace_callback('/\[([^\]]+)\]/', function ($matches) {
return Base::randomElement(str_split($matches[1]));
}, $regex);

 $regex = preg_replace_callback('/\\\w/', 'static::randomLetter', $regex);
$regex = preg_replace_callback('/\\\d/', 'static::randomDigit', $regex);
$regex = preg_replace_callback('/(?<!\\\)\./', 'static::randomAscii', $regex);

 $regex = str_replace('\\', '', $regex);

 return $regex;
}








public static function toLower($string = '')
{
return extension_loaded('mbstring') ? mb_strtolower($string, 'UTF-8') : strtolower($string);
}








public static function toUpper($string = '')
{
return extension_loaded('mbstring') ? mb_strtoupper($string, 'UTF-8') : strtoupper($string);
}










public function optional($weight = 0.5, $default = null)
{

 
 if ($weight > 0 && $weight < 1 && mt_rand() / mt_getrandmax() <= $weight) {
return $this->generator;
}


 if (is_int($weight) && mt_rand(1, 100) <= $weight) {
return $this->generator;
}

return new DefaultGenerator($default);
}
















public function unique($reset = false, $maxRetries = 10000)
{
if ($reset || !$this->unique) {
$this->unique = new UniqueGenerator($this->generator, $maxRetries);
}

return $this->unique;
}
























public function valid($validator = null, $maxRetries = 10000)
{
return new ValidGenerator($this->generator, $validator, $maxRetries);
}
}
<?php

namespace Faker\Provider;

class Lorem extends Base
{
protected static $wordList = array(
'alias', 'consequatur', 'aut', 'perferendis', 'sit', 'voluptatem',
'accusantium', 'doloremque', 'aperiam', 'eaque','ipsa', 'quae', 'ab',
'illo', 'inventore', 'veritatis', 'et', 'quasi', 'architecto',
'beatae', 'vitae', 'dicta', 'sunt', 'explicabo', 'aspernatur', 'aut',
'odit', 'aut', 'fugit', 'sed', 'quia', 'consequuntur', 'magni',
'dolores', 'eos', 'qui', 'ratione', 'voluptatem', 'sequi', 'nesciunt',
'neque', 'dolorem', 'ipsum', 'quia', 'dolor', 'sit', 'amet',
'consectetur', 'adipisci', 'velit', 'sed', 'quia', 'non', 'numquam',
'eius', 'modi', 'tempora', 'incidunt', 'ut', 'labore', 'et', 'dolore',
'magnam', 'aliquam', 'quaerat', 'voluptatem', 'ut', 'enim', 'ad',
'minima', 'veniam', 'quis', 'nostrum', 'exercitationem', 'ullam',
'corporis', 'nemo', 'enim', 'ipsam', 'voluptatem', 'quia', 'voluptas',
'sit', 'suscipit', 'laboriosam', 'nisi', 'ut', 'aliquid', 'ex', 'ea',
'commodi', 'consequatur', 'quis', 'autem', 'vel', 'eum', 'iure',
'reprehenderit', 'qui', 'in', 'ea', 'voluptate', 'velit', 'esse',
'quam', 'nihil', 'molestiae', 'et', 'iusto', 'odio', 'dignissimos',
'ducimus', 'qui', 'blanditiis', 'praesentium', 'laudantium', 'totam',
'rem', 'voluptatum', 'deleniti', 'atque', 'corrupti', 'quos',
'dolores', 'et', 'quas', 'molestias', 'excepturi', 'sint',
'occaecati', 'cupiditate', 'non', 'provident', 'sed', 'ut',
'perspiciatis', 'unde', 'omnis', 'iste', 'natus', 'error',
'similique', 'sunt', 'in', 'culpa', 'qui', 'officia', 'deserunt',
'mollitia', 'animi', 'id', 'est', 'laborum', 'et', 'dolorum', 'fuga',
'et', 'harum', 'quidem', 'rerum', 'facilis', 'est', 'et', 'expedita',
'distinctio', 'nam', 'libero', 'tempore', 'cum', 'soluta', 'nobis',
'est', 'eligendi', 'optio', 'cumque', 'nihil', 'impedit', 'quo',
'porro', 'quisquam', 'est', 'qui', 'minus', 'id', 'quod', 'maxime',
'placeat', 'facere', 'possimus', 'omnis', 'voluptas', 'assumenda',
'est', 'omnis', 'dolor', 'repellendus', 'temporibus', 'autem',
'quibusdam', 'et', 'aut', 'consequatur', 'vel', 'illum', 'qui',
'dolorem', 'eum', 'fugiat', 'quo', 'voluptas', 'nulla', 'pariatur',
'at', 'vero', 'eos', 'et', 'accusamus', 'officiis', 'debitis', 'aut',
'rerum', 'necessitatibus', 'saepe', 'eveniet', 'ut', 'et',
'voluptates', 'repudiandae', 'sint', 'et', 'molestiae', 'non',
'recusandae', 'itaque', 'earum', 'rerum', 'hic', 'tenetur', 'a',
'sapiente', 'delectus', 'ut', 'aut', 'reiciendis', 'voluptatibus',
'maiores', 'doloribus', 'asperiores', 'repellat'
);





public static function word()
{
return static::randomElement(static::$wordList);
}









public static function words($nb = 3, $asText = false)
{
$words = array();
for ($i=0; $i < $nb; $i++) {
$words []= static::word();
}

return $asText ? implode(' ', $words) : $words;
}










public static function sentence($nbWords = 6, $variableNbWords = true)
{
if ($nbWords <= 0) {
return '';
}
if ($variableNbWords) {
$nbWords = self::randomizeNbElements($nbWords);
}

$words = static::words($nbWords);
$words[0] = ucwords($words[0]);

return implode($words, ' ') . '.';
}









public static function sentences($nb = 3, $asText = false)
{
$sentences = array();
for ($i=0; $i < $nb; $i++) {
$sentences []= static::sentence();
}

return $asText ? implode(' ', $sentences) : $sentences;
}










public static function paragraph($nbSentences = 3, $variableNbSentences = true)
{
if ($nbSentences <= 0) {
return '';
}
if ($variableNbSentences) {
$nbSentences = self::randomizeNbElements($nbSentences);
}

return implode(static::sentences($nbSentences), ' ');
}









public static function paragraphs($nb = 3, $asText = false)
{
$paragraphs = array();
for ($i=0; $i < $nb; $i++) {
$paragraphs []= static::paragraph();
}

return $asText ? implode("\n\n", $paragraphs) : $paragraphs;
}











public static function text($maxNbChars = 200)
{
if ($maxNbChars < 5) {
throw new \InvalidArgumentException('text() can only generate text of at least 5 characters');
}

$type = ($maxNbChars < 25) ? 'word' : (($maxNbChars < 100) ? 'sentence' : 'paragraph');

$text = array();
while (empty($text)) {
$size = 0;


 while ($size < $maxNbChars) {
$word = ($size ? ' ' : '') . static::$type();
$text[] = $word;

$size += strlen($word);
}

array_pop($text);
}

if ($type === 'word') {

 $text[0] = ucwords($text[0]);


 $text[count($text) - 1] .= '.';
}

return implode($text, '');
}

protected static function randomizeNbElements($nbElements)
{
return (int) ($nbElements * mt_rand(60, 140) / 100) + 1;
}
}
<?php
namespace Faker\Provider;

class File extends Base
{







protected static $mimeTypes = array(
'application/atom+xml' => 'atom',
'application/ecmascript' => 'ecma',
'application/emma+xml' => 'emma',
'application/epub+zip' => 'epub',
'application/java-archive' => 'jar',
'application/java-vm' => 'class',
'application/javascript' => 'js',
'application/json' => 'json',
'application/jsonml+json' => 'jsonml',
'application/lost+xml' => 'lostxml',
'application/mathml+xml' => 'mathml',
'application/mets+xml' => 'mets',
'application/mods+xml' => 'mods',
'application/mp4' => 'mp4s',
'application/msword' => array('doc', 'dot'),
'application/octet-stream' => array(
'bin',
'dms',
'lrf',
'mar',
'so',
'dist',
'distz',
'pkg',
'bpk',
'dump',
'elc',
'deploy'
),
'application/ogg' => 'ogx',
'application/omdoc+xml' => 'omdoc',
'application/pdf' => 'pdf',
'application/pgp-encrypted' => 'pgp',
'application/pgp-signature' => array('asc', 'sig'),
'application/pkix-pkipath' => 'pkipath',
'application/pkixcmp' => 'pki',
'application/pls+xml' => 'pls',
'application/postscript' => array('ai', 'eps', 'ps'),
'application/pskc+xml' => 'pskcxml',
'application/rdf+xml' => 'rdf',
'application/reginfo+xml' => 'rif',
'application/rss+xml' => 'rss',
'application/rtf' => 'rtf',
'application/sbml+xml' => 'sbml',
'application/vnd.adobe.air-application-installer-package+zip' => 'air',
'application/vnd.adobe.xdp+xml' => 'xdp',
'application/vnd.adobe.xfdf' => 'xfdf',
'application/vnd.ahead.space' => 'ahead',
'application/vnd.dart' => 'dart',
'application/vnd.data-vision.rdz' => 'rdz',
'application/vnd.dece.data' => array('uvf', 'uvvf', 'uvd', 'uvvd'),
'application/vnd.dece.ttml+xml' => array('uvt', 'uvvt'),
'application/vnd.dece.unspecified' => array('uvx', 'uvvx'),
'application/vnd.dece.zip' => array('uvz', 'uvvz'),
'application/vnd.denovo.fcselayout-link' => 'fe_launch',
'application/vnd.dna' => 'dna',
'application/vnd.dolby.mlp' => 'mlp',
'application/vnd.dpgraph' => 'dpg',
'application/vnd.dreamfactory' => 'dfac',
'application/vnd.ds-keypoint' => 'kpxx',
'application/vnd.dvb.ait' => 'ait',
'application/vnd.dvb.service' => 'svc',
'application/vnd.dynageo' => 'geo',
'application/vnd.ecowin.chart' => 'mag',
'application/vnd.enliven' => 'nml',
'application/vnd.epson.esf' => 'esf',
'application/vnd.epson.msf' => 'msf',
'application/vnd.epson.quickanime' => 'qam',
'application/vnd.epson.salt' => 'slt',
'application/vnd.epson.ssf' => 'ssf',
'application/vnd.ezpix-album' => 'ez2',
'application/vnd.ezpix-package' => 'ez3',
'application/vnd.fdf' => 'fdf',
'application/vnd.fdsn.mseed' => 'mseed',
'application/vnd.fdsn.seed' => array('seed', 'dataless'),
'application/vnd.flographit' => 'gph',
'application/vnd.fluxtime.clip' => 'ftc',
'application/vnd.hal+xml' => 'hal',
'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx',
'application/vnd.ibm.minipay' => 'mpy',
'application/vnd.ibm.secure-container' => 'sc',
'application/vnd.iccprofile' => array('icc', 'icm'),
'application/vnd.igloader' => 'igl',
'application/vnd.immervision-ivp' => 'ivp',
'application/vnd.kde.karbon' => 'karbon',
'application/vnd.kde.kchart' => 'chrt',
'application/vnd.kde.kformula' => 'kfo',
'application/vnd.kde.kivio' => 'flw',
'application/vnd.kde.kontour' => 'kon',
'application/vnd.kde.kpresenter' => array('kpr', 'kpt'),
'application/vnd.kde.kspread' => 'ksp',
'application/vnd.kde.kword' => array('kwd', 'kwt'),
'application/vnd.kenameaapp' => 'htke',
'application/vnd.kidspiration' => 'kia',
'application/vnd.kinar' => array('kne', 'knp'),
'application/vnd.koan' => array('skp', 'skd', 'skt', 'skm'),
'application/vnd.kodak-descriptor' => 'sse',
'application/vnd.las.las+xml' => 'lasxml',
'application/vnd.llamagraphics.life-balance.desktop' => 'lbd',
'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe',
'application/vnd.lotus-1-2-3' => '123',
'application/vnd.lotus-approach' => 'apr',
'application/vnd.lotus-freelance' => 'pre',
'application/vnd.lotus-notes' => 'nsf',
'application/vnd.lotus-organizer' => 'org',
'application/vnd.lotus-screencam' => 'scm',
'application/vnd.mozilla.xul+xml' => 'xul',
'application/vnd.ms-artgalry' => 'cil',
'application/vnd.ms-cab-compressed' => 'cab',
'application/vnd.ms-excel' => array(
'xls',
'xlm',
'xla',
'xlc',
'xlt',
'xlw'
),
'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam',
'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb',
'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm',
'application/vnd.ms-excel.template.macroenabled.12' => 'xltm',
'application/vnd.ms-fontobject' => 'eot',
'application/vnd.ms-htmlhelp' => 'chm',
'application/vnd.ms-ims' => 'ims',
'application/vnd.ms-lrm' => 'lrm',
'application/vnd.ms-officetheme' => 'thmx',
'application/vnd.ms-pki.seccat' => 'cat',
'application/vnd.ms-pki.stl' => 'stl',
'application/vnd.ms-powerpoint' => array('ppt', 'pps', 'pot'),
'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam',
'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm',
'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm',
'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm',
'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm',
'application/vnd.ms-project' => array('mpp', 'mpt'),
'application/vnd.ms-word.document.macroenabled.12' => 'docm',
'application/vnd.ms-word.template.macroenabled.12' => 'dotm',
'application/vnd.ms-works' => array('wps', 'wks', 'wcm', 'wdb'),
'application/vnd.ms-wpl' => 'wpl',
'application/vnd.ms-xpsdocument' => 'xps',
'application/vnd.mseq' => 'mseq',
'application/vnd.musician' => 'mus',
'application/vnd.oasis.opendocument.chart' => 'odc',
'application/vnd.oasis.opendocument.chart-template' => 'otc',
'application/vnd.oasis.opendocument.database' => 'odb',
'application/vnd.oasis.opendocument.formula' => 'odf',
'application/vnd.oasis.opendocument.formula-template' => 'odft',
'application/vnd.oasis.opendocument.graphics' => 'odg',
'application/vnd.oasis.opendocument.graphics-template' => 'otg',
'application/vnd.oasis.opendocument.image' => 'odi',
'application/vnd.oasis.opendocument.image-template' => 'oti',
'application/vnd.oasis.opendocument.presentation' => 'odp',
'application/vnd.oasis.opendocument.presentation-template' => 'otp',
'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots',
'application/vnd.oasis.opendocument.text' => 'odt',
'application/vnd.oasis.opendocument.text-master' => 'odm',
'application/vnd.oasis.opendocument.text-template' => 'ott',
'application/vnd.oasis.opendocument.text-web' => 'oth',
'application/vnd.olpc-sugar' => 'xo',
'application/vnd.oma.dd2+xml' => 'dd2',
'application/vnd.openofficeorg.extension' => 'oxt',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx',
'application/vnd.pvi.ptid1' => 'ptid',
'application/vnd.quark.quarkxpress' => array(
'qxd',
'qxt',
'qwd',
'qwt',
'qxl',
'qxb'
),
'application/vnd.realvnc.bed' => 'bed',
'application/vnd.recordare.musicxml' => 'mxl',
'application/vnd.recordare.musicxml+xml' => 'musicxml',
'application/vnd.rig.cryptonote' => 'cryptonote',
'application/vnd.rim.cod' => 'cod',
'application/vnd.rn-realmedia' => 'rm',
'application/vnd.rn-realmedia-vbr' => 'rmvb',
'application/vnd.route66.link66+xml' => 'link66',
'application/vnd.sailingtracker.track' => 'st',
'application/vnd.seemail' => 'see',
'application/vnd.sema' => 'sema',
'application/vnd.semd' => 'semd',
'application/vnd.semf' => 'semf',
'application/vnd.shana.informed.formdata' => 'ifm',
'application/vnd.shana.informed.formtemplate' => 'itp',
'application/vnd.shana.informed.interchange' => 'iif',
'application/vnd.shana.informed.package' => 'ipk',
'application/vnd.simtech-mindmapper' => array('twd', 'twds'),
'application/vnd.smaf' => 'mmf',
'application/vnd.stepmania.stepchart' => 'sm',
'application/vnd.sun.xml.calc' => 'sxc',
'application/vnd.sun.xml.calc.template' => 'stc',
'application/vnd.sun.xml.draw' => 'sxd',
'application/vnd.sun.xml.draw.template' => 'std',
'application/vnd.sun.xml.impress' => 'sxi',
'application/vnd.sun.xml.impress.template' => 'sti',
'application/vnd.sun.xml.math' => 'sxm',
'application/vnd.sun.xml.writer' => 'sxw',
'application/vnd.sun.xml.writer.global' => 'sxg',
'application/vnd.sun.xml.writer.template' => 'stw',
'application/vnd.sus-calendar' => array('sus', 'susp'),
'application/vnd.svd' => 'svd',
'application/vnd.symbian.install' => array('sis', 'sisx'),
'application/vnd.syncml+xml' => 'xsm',
'application/vnd.syncml.dm+wbxml' => 'bdm',
'application/vnd.syncml.dm+xml' => 'xdm',
'application/vnd.tao.intent-module-archive' => 'tao',
'application/vnd.tcpdump.pcap' => array('pcap', 'cap', 'dmp'),
'application/vnd.tmobile-livetv' => 'tmo',
'application/vnd.trid.tpt' => 'tpt',
'application/vnd.triscape.mxs' => 'mxs',
'application/vnd.trueapp' => 'tra',
'application/vnd.ufdl' => array('ufd', 'ufdl'),
'application/vnd.uiq.theme' => 'utz',
'application/vnd.umajin' => 'umj',
'application/vnd.unity' => 'unityweb',
'application/vnd.uoml+xml' => 'uoml',
'application/vnd.vcx' => 'vcx',
'application/vnd.visio' => array('vsd', 'vst', 'vss', 'vsw'),
'application/vnd.visionary' => 'vis',
'application/vnd.vsf' => 'vsf',
'application/vnd.wap.wbxml' => 'wbxml',
'application/vnd.wap.wmlc' => 'wmlc',
'application/vnd.wap.wmlscriptc' => 'wmlsc',
'application/vnd.webturbo' => 'wtb',
'application/vnd.wolfram.player' => 'nbp',
'application/vnd.wordperfect' => 'wpd',
'application/vnd.wqd' => 'wqd',
'application/vnd.wt.stf' => 'stf',
'application/vnd.xara' => 'xar',
'application/vnd.xfdl' => 'xfdl',
'application/voicexml+xml' => 'vxml',
'application/widget' => 'wgt',
'application/winhlp' => 'hlp',
'application/wsdl+xml' => 'wsdl',
'application/wspolicy+xml' => 'wspolicy',
'application/x-7z-compressed' => '7z',
'application/x-bittorrent' => 'torrent',
'application/x-blorb' => array('blb', 'blorb'),
'application/x-bzip' => 'bz',
'application/x-cdlink' => 'vcd',
'application/x-cfs-compressed' => 'cfs',
'application/x-chat' => 'chat',
'application/x-chess-pgn' => 'pgn',
'application/x-conference' => 'nsc',
'application/x-cpio' => 'cpio',
'application/x-csh' => 'csh',
'application/x-debian-package' => array('deb', 'udeb'),
'application/x-dgc-compressed' => 'dgc',
'application/x-director' => array(
'dir',
'dcr',
'dxr',
'cst',
'cct',
'cxt',
'w3d',
'fgd',
'swa'
),
'application/x-font-ttf' => array('ttf', 'ttc'),
'application/x-font-type1' => array('pfa', 'pfb', 'pfm', 'afm'),
'application/x-font-woff' => 'woff',
'application/x-freearc' => 'arc',
'application/x-futuresplash' => 'spl',
'application/x-gca-compressed' => 'gca',
'application/x-glulx' => 'ulx',
'application/x-gnumeric' => 'gnumeric',
'application/x-gramps-xml' => 'gramps',
'application/x-gtar' => 'gtar',
'application/x-hdf' => 'hdf',
'application/x-install-instructions' => 'install',
'application/x-iso9660-image' => 'iso',
'application/x-java-jnlp-file' => 'jnlp',
'application/x-latex' => 'latex',
'application/x-lzh-compressed' => array('lzh', 'lha'),
'application/x-mie' => 'mie',
'application/x-mobipocket-ebook' => array('prc', 'mobi'),
'application/x-ms-application' => 'application',
'application/x-ms-shortcut' => 'lnk',
'application/x-ms-wmd' => 'wmd',
'application/x-ms-wmz' => 'wmz',
'application/x-ms-xbap' => 'xbap',
'application/x-msaccess' => 'mdb',
'application/x-msbinder' => 'obd',
'application/x-mscardfile' => 'crd',
'application/x-msclip' => 'clp',
'application/x-msdownload' => array('exe', 'dll', 'com', 'bat', 'msi'),
'application/x-msmediaview' => array(
'mvb',
'm13',
'm14'
),
'application/x-msmetafile' => array('wmf', 'wmz', 'emf', 'emz'),
'application/x-rar-compressed' => 'rar',
'application/x-research-info-systems' => 'ris',
'application/x-sh' => 'sh',
'application/x-shar' => 'shar',
'application/x-shockwave-flash' => 'swf',
'application/x-silverlight-app' => 'xap',
'application/x-sql' => 'sql',
'application/x-stuffit' => 'sit',
'application/x-stuffitx' => 'sitx',
'application/x-subrip' => 'srt',
'application/x-sv4cpio' => 'sv4cpio',
'application/x-sv4crc' => 'sv4crc',
'application/x-t3vm-image' => 't3',
'application/x-tads' => 'gam',
'application/x-tar' => 'tar',
'application/x-tcl' => 'tcl',
'application/x-tex' => 'tex',
'application/x-tex-tfm' => 'tfm',
'application/x-texinfo' => array('texinfo', 'texi'),
'application/x-tgif' => 'obj',
'application/x-ustar' => 'ustar',
'application/x-wais-source' => 'src',
'application/x-x509-ca-cert' => array('der', 'crt'),
'application/x-xfig' => 'fig',
'application/x-xliff+xml' => 'xlf',
'application/x-xpinstall' => 'xpi',
'application/x-xz' => 'xz',
'application/x-zmachine' => 'z1',
'application/xaml+xml' => 'xaml',
'application/xcap-diff+xml' => 'xdf',
'application/xenc+xml' => 'xenc',
'application/xhtml+xml' => array('xhtml', 'xht'),
'application/xml' => array('xml', 'xsl'),
'application/xml-dtd' => 'dtd',
'application/xop+xml' => 'xop',
'application/xproc+xml' => 'xpl',
'application/xslt+xml' => 'xslt',
'application/xspf+xml' => 'xspf',
'application/xv+xml' => array('mxml', 'xhvml', 'xvml', 'xvm'),
'application/yang' => 'yang',
'application/yin+xml' => 'yin',
'application/zip' => 'zip',
'audio/adpcm' => 'adp',
'audio/basic' => array('au', 'snd'),
'audio/midi' => array('mid', 'midi', 'kar', 'rmi'),
'audio/mp4' => 'mp4a',
'audio/mpeg' => array(
'mpga',
'mp2',
'mp2a',
'mp3',
'm2a',
'm3a'
),
'audio/ogg' => array('oga', 'ogg', 'spx'),
'audio/vnd.dece.audio' => array('uva', 'uvva'),
'audio/vnd.rip' => 'rip',
'audio/webm' => 'weba',
'audio/x-aac' => 'aac',
'audio/x-aiff' => array('aif', 'aiff', 'aifc'),
'audio/x-caf' => 'caf',
'audio/x-flac' => 'flac',
'audio/x-matroska' => 'mka',
'audio/x-mpegurl' => 'm3u',
'audio/x-ms-wax' => 'wax',
'audio/x-ms-wma' => 'wma',
'audio/x-pn-realaudio' => array('ram', 'ra'),
'audio/x-pn-realaudio-plugin' => 'rmp',
'audio/x-wav' => 'wav',
'audio/xm' => 'xm',
'image/bmp' => 'bmp',
'image/cgm' => 'cgm',
'image/g3fax' => 'g3',
'image/gif' => 'gif',
'image/ief' => 'ief',
'image/jpeg' => array('jpeg', 'jpg', 'jpe'),
'image/ktx' => 'ktx',
'image/png' => 'png',
'image/prs.btif' => 'btif',
'image/sgi' => 'sgi',
'image/svg+xml' => array('svg', 'svgz'),
'image/tiff' => array('tiff', 'tif'),
'image/vnd.adobe.photoshop' => 'psd',
'image/vnd.dece.graphic' => array('uvi', 'uvvi', 'uvg', 'uvvg'),
'image/vnd.dvb.subtitle' => 'sub',
'image/vnd.djvu' => array('djvu', 'djv'),
'image/vnd.dwg' => 'dwg',
'image/vnd.dxf' => 'dxf',
'image/vnd.fastbidsheet' => 'fbs',
'image/vnd.fpx' => 'fpx',
'image/vnd.fst' => 'fst',
'image/vnd.fujixerox.edmics-mmr' => 'mmr',
'image/vnd.fujixerox.edmics-rlc' => 'rlc',
'image/vnd.ms-modi' => 'mdi',
'image/vnd.ms-photo' => 'wdp',
'image/vnd.net-fpx' => 'npx',
'image/vnd.wap.wbmp' => 'wbmp',
'image/vnd.xiff' => 'xif',
'image/webp' => 'webp',
'image/x-3ds' => '3ds',
'image/x-cmu-raster' => 'ras',
'image/x-cmx' => 'cmx',
'image/x-freehand' => array('fh', 'fhc', 'fh4', 'fh5', 'fh7'),
'image/x-icon' => 'ico',
'image/x-mrsid-image' => 'sid',
'image/x-pcx' => 'pcx',
'image/x-pict' => array('pic', 'pct'),
'image/x-portable-anymap' => 'pnm',
'image/x-portable-bitmap' => 'pbm',
'image/x-portable-graymap' => 'pgm',
'image/x-portable-pixmap' => 'ppm',
'image/x-rgb' => 'rgb',
'image/x-tga' => 'tga',
'image/x-xbitmap' => 'xbm',
'image/x-xpixmap' => 'xpm',
'image/x-xwindowdump' => 'xwd',
'message/rfc822' => array('eml', 'mime'),
'model/iges' => array('igs', 'iges'),
'model/mesh' => array('msh', 'mesh', 'silo'),
'model/vnd.collada+xml' => 'dae',
'model/vnd.dwf' => 'dwf',
'model/vnd.gdl' => 'gdl',
'model/vnd.gtw' => 'gtw',
'model/vnd.mts' => 'mts',
'model/vnd.vtu' => 'vtu',
'model/vrml' => array('wrl', 'vrml'),
'model/x3d+binary' => 'x3db',
'model/x3d+vrml' => 'x3dv',
'model/x3d+xml' => 'x3d',
'text/cache-manifest' => 'appcache',
'text/calendar' => array('ics', 'ifb'),
'text/css' => 'css',
'text/csv' => 'csv',
'text/html' => array('html', 'htm'),
'text/n3' => 'n3',
'text/plain' => array(
'txt',
'text',
'conf',
'def',
'list',
'log',
'in'
),
'text/prs.lines.tag' => 'dsc',
'text/richtext' => 'rtx',
'text/sgml' => array('sgml', 'sgm'),
'text/tab-separated-values' => 'tsv',
'text/troff' => array(
't',
'tr',
'roff',
'man',
'me',
'ms'
),
'text/turtle' => 'ttl',
'text/uri-list' => array('uri', 'uris', 'urls'),
'text/vcard' => 'vcard',
'text/vnd.curl' => 'curl',
'text/vnd.curl.dcurl' => 'dcurl',
'text/vnd.curl.scurl' => 'scurl',
'text/vnd.curl.mcurl' => 'mcurl',
'text/vnd.dvb.subtitle' => 'sub',
'text/vnd.fly' => 'fly',
'text/vnd.fmi.flexstor' => 'flx',
'text/vnd.graphviz' => 'gv',
'text/vnd.in3d.3dml' => '3dml',
'text/vnd.in3d.spot' => 'spot',
'text/vnd.sun.j2me.app-descriptor' => 'jad',
'text/vnd.wap.wml' => 'wml',
'text/vnd.wap.wmlscript' => 'wmls',
'text/x-asm' => array('s', 'asm'),
'text/x-fortran' => array('f', 'for', 'f77', 'f90'),
'text/x-java-source' => 'java',
'text/x-opml' => 'opml',
'text/x-pascal' => array('p', 'pas'),
'text/x-nfo' => 'nfo',
'text/x-setext' => 'etx',
'text/x-sfv' => 'sfv',
'text/x-uuencode' => 'uu',
'text/x-vcalendar' => 'vcs',
'text/x-vcard' => 'vcf',
'video/3gpp' => '3gp',
'video/3gpp2' => '3g2',
'video/h261' => 'h261',
'video/h263' => 'h263',
'video/h264' => 'h264',
'video/jpeg' => 'jpgv',
'video/jpm' => array('jpm', 'jpgm'),
'video/mj2' => 'mj2',
'video/mp4' => 'mp4',
'video/mpeg' => array('mpeg', 'mpg', 'mpe', 'm1v', 'm2v'),
'video/ogg' => 'ogv',
'video/quicktime' => array('qt', 'mov'),
'video/vnd.dece.hd' => array('uvh', 'uvvh'),
'video/vnd.dece.mobile' => array('uvm', 'uvvm'),
'video/vnd.dece.pd' => array('uvp', 'uvvp'),
'video/vnd.dece.sd' => array('uvs', 'uvvs'),
'video/vnd.dece.video' => array('uvv', 'uvvv'),
'video/vnd.dvb.file' => 'dvb',
'video/vnd.fvt' => 'fvt',
'video/vnd.mpegurl' => array('mxu', 'm4u'),
'video/vnd.ms-playready.media.pyv' => 'pyv',
'video/vnd.uvvu.mp4' => array('uvu', 'uvvu'),
'video/vnd.vivo' => 'viv',
'video/webm' => 'webm',
'video/x-f4v' => 'f4v',
'video/x-fli' => 'fli',
'video/x-flv' => 'flv',
'video/x-m4v' => 'm4v',
'video/x-matroska' => array('mkv', 'mk3d', 'mks'),
'video/x-mng' => 'mng',
'video/x-ms-asf' => array('asf', 'asx'),
'video/x-ms-vob' => 'vob',
'video/x-ms-wm' => 'wm',
'video/x-ms-wmv' => 'wmv',
'video/x-ms-wmx' => 'wmx',
'video/x-ms-wvx' => 'wvx',
'video/x-msvideo' => 'avi',
'video/x-sgi-movie' => 'movie',
);







public static function mimeType()
{
return static::randomElement(array_keys(static::$mimeTypes));
}







public static function fileExtension()
{
$random_extension = static::randomElement(array_values(static::$mimeTypes));

return is_array($random_extension) ? static::randomElement($random_extension) : $random_extension;
}









public static function file($sourceDirectory = '/tmp', $targetDirectory = '/tmp', $fullPath = true)
{
if (!is_dir($sourceDirectory)) {
throw new \InvalidArgumentException(sprintf('Source directory %s does not exist or is not a directory.', $sourceDirectory));
}

if (!is_dir($targetDirectory)) {
throw new \InvalidArgumentException(sprintf('Target directory %s does not exist or is not a directory.', $targetDirectory));
}

if ($sourceDirectory == $targetDirectory) {
throw new \InvalidArgumentException('Source and target directories must differ.');
}


 $files = array_filter(array_values(array_diff(scandir($sourceDirectory), array('.', '..'))), function ($file) use ($sourceDirectory) {
return is_file($sourceDirectory . DIRECTORY_SEPARATOR . $file) && is_readable($sourceDirectory . DIRECTORY_SEPARATOR . $file);
});

if (empty($files)) {
throw new \InvalidArgumentException(sprintf('Source directory %s is empty.', $sourceDirectory));
}

$sourceFullPath = $sourceDirectory . DIRECTORY_SEPARATOR . static::randomElement($files);

$destinationFile = Uuid::uuid() . '.' . pathinfo($sourceFullPath, PATHINFO_EXTENSION);
$destinationFullPath = $targetDirectory . DIRECTORY_SEPARATOR . $destinationFile;

if (false === copy($sourceFullPath, $destinationFullPath)) {
return false;
}

return $fullPath ? $destinationFullPath : $destinationFile;
}
}
<?php

namespace Faker\Provider;

class Uuid extends Base
{




public static function uuid()
{

 $seed = mt_rand(0, 2147483647) . '#' . mt_rand(0, 2147483647);


 $val = md5($seed, true);
$byte = array_values(unpack('C16', $val));


 $tLo = ($byte[0] << 24) | ($byte[1] << 16) | ($byte[2] << 8) | $byte[3];
$tMi = ($byte[4] << 8) | $byte[5];
$tHi = ($byte[6] << 8) | $byte[7];
$csLo = $byte[9];
$csHi = $byte[8] & 0x3f | (1 << 7);


 if (pack('L', 0x6162797A) == pack('N', 0x6162797A)) {
$tLo = (($tLo & 0x000000ff) << 24) | (($tLo & 0x0000ff00) << 8)
| (($tLo & 0x00ff0000) >> 8) | (($tLo & 0xff000000) >> 24);
$tMi = (($tMi & 0x00ff) << 8) | (($tMi & 0xff00) >> 8);
$tHi = (($tHi & 0x00ff) << 8) | (($tHi & 0xff00) >> 8);
}


 $tHi &= 0x0fff;
$tHi |= (3 << 12);


 $uuid = sprintf(
'%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x',
$tLo,
$tMi,
$tHi,
$csHi,
$csLo,
$byte[10],
$byte[11],
$byte[12],
$byte[13],
$byte[14],
$byte[15]
);

return $uuid;
}
}
<?php

namespace Faker\Provider;

class Internet extends Base
{
protected static $freeEmailDomain = array('gmail.com', 'yahoo.com', 'hotmail.com');
protected static $tld = array('com', 'com', 'com', 'com', 'com', 'com', 'biz', 'info', 'net', 'org');

protected static $userNameFormats = array(
'{{lastName}}.{{firstName}}',
'{{firstName}}.{{lastName}}',
'{{firstName}}##',
'?{{lastName}}',
);
protected static $emailFormats = array(
'{{userName}}@{{domainName}}',
'{{userName}}@{{freeEmailDomain}}',
);
protected static $urlFormats = array(
'http://www.{{domainName}}/',
'http://{{domainName}}/',
'http://www.{{domainName}}/{{slug}}',
'http://www.{{domainName}}/{{slug}}',
'https://www.{{domainName}}/{{slug}}',
'http://www.{{domainName}}/{{slug}}.html',
'http://{{domainName}}/{{slug}}',
'http://{{domainName}}/{{slug}}',
'http://{{domainName}}/{{slug}}.html',
'https://{{domainName}}/{{slug}}.html',
);




public function email()
{
$format = static::randomElement(static::$emailFormats);

return $this->generator->parse($format);
}




final public function safeEmail()
{
return preg_replace('/\s/u', '', $this->userName() . '@' . static::safeEmailDomain());
}




public function freeEmail()
{
return preg_replace('/\s/u', '', $this->userName() . '@' . static::freeEmailDomain());
}




public function companyEmail()
{
return preg_replace('/\s/u', '', $this->userName() . '@' . $this->domainName());
}




public static function freeEmailDomain()
{
return static::randomElement(static::$freeEmailDomain);
}




final public static function safeEmailDomain()
{
$domains = array(
'example.com',
'example.org',
'example.net'
);

return static::randomElement($domains);
}



public function userName()
{
$format = static::randomElement(static::$userNameFormats);
$username = static::bothify($this->generator->parse($format));

$username = strtolower(static::transliterate($username));


 if (trim($username, '._') === '') {
throw new \Exception('userName failed with the selected locale. Try a different locale or activate the "intl" PHP extension.');
}


 $username = str_replace('..', '.', $username);
$username = rtrim($username, '.');

return $username;
}



public function password($minLength = 6, $maxLength = 20)
{
$pattern = str_repeat('*', $this->numberBetween($minLength, $maxLength));

return $this->asciify($pattern);
}




public function domainName()
{
return $this->domainWord() . '.' . $this->tld();
}




public function domainWord()
{
$lastName = $this->generator->format('lastName');

$lastName = strtolower(static::transliterate($lastName));


 if (trim($lastName, '._') === '') {
throw new \Exception('domainWord failed with the selected locale. Try a different locale or activate the "intl" PHP extension.');
}


 $lastName = rtrim($lastName, '.');

return $lastName;
}




public function tld()
{
return static::randomElement(static::$tld);
}




public function url()
{
$format = static::randomElement(static::$urlFormats);

return $this->generator->parse($format);
}




public function slug($nbWords = 6, $variableNbWords = true)
{
if ($nbWords <= 0) {
return '';
}
if ($variableNbWords) {
$nbWords = (int) ($nbWords * mt_rand(60, 140) / 100) + 1;
}
$words = $this->generator->words($nbWords);

return join($words, '-');
}




public function ipv4()
{
return long2ip(mt_rand(0, 1) == 0 ? mt_rand(-2147483648, -2) : mt_rand(16777216, 2147483647));
}




public function ipv6()
{
$res = array();
for ($i=0; $i < 8; $i++) {
$res []= dechex(mt_rand(0, "65535"));
}

return join(':', $res);
}




public static function localIpv4()
{
if (static::numberBetween(0, 1) === 0) {

 return long2ip(static::numberBetween(ip2long("10.0.0.0"), ip2long("10.255.255.255")));
}


 return long2ip(static::numberBetween(ip2long("192.168.0.0"), ip2long("192.168.255.255")));
}




public static function macAddress()
{
for ($i=0; $i<6; $i++) {
$mac[] = sprintf('%02X', static::numberBetween(0, 0xff));
}
$mac = implode(':', $mac);

return $mac;
}

protected static function transliterate($string)
{
if (0 === preg_match('/[^A-Za-z0-9_.]/', $string)) {
return $string;
}

$transId = 'Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC;';
if (class_exists('Transliterator') && $transliterator = \Transliterator::create($transId)) {
$transString = $transliterator->transliterate($string);
} else {
$transString = static::toAscii($string);
}

return preg_replace('/[^A-Za-z0-9_.]/u', '', $transString);
}

protected static function toAscii($string)
{
static $arrayFrom, $arrayTo;

if (empty($arrayFrom)) {
$transliterationTable = array(
'IJ'=>'I', 'Ö'=>'O', 'Œ'=>'O', 'Ü'=>'U', 'ä'=>'a', 'æ'=>'a',
'ij'=>'i', 'ö'=>'o', 'œ'=>'o', 'ü'=>'u', 'ß'=>'s', 'ſ'=>'s',
'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A',
'Æ'=>'A', 'Ā'=>'A', 'Ą'=>'A', 'Ă'=>'A', 'Ç'=>'C', 'Ć'=>'C',
'Č'=>'C', 'Ĉ'=>'C', 'Ċ'=>'C', 'Ď'=>'D', 'Đ'=>'D', 'È'=>'E',
'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ē'=>'E', 'Ę'=>'E', 'Ě'=>'E',
'Ĕ'=>'E', 'Ė'=>'E', 'Ĝ'=>'G', 'Ğ'=>'G', 'Ġ'=>'G', 'Ģ'=>'G',
'Ĥ'=>'H', 'Ħ'=>'H', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I',
'Ī'=>'I', 'Ĩ'=>'I', 'Ĭ'=>'I', 'Į'=>'I', 'İ'=>'I', 'Ĵ'=>'J',
'Ķ'=>'K', 'Ľ'=>'K', 'Ĺ'=>'K', 'Ļ'=>'K', 'Ŀ'=>'K', 'Ł'=>'L',
'Ñ'=>'N', 'Ń'=>'N', 'Ň'=>'N', 'Ņ'=>'N', 'Ŋ'=>'N', 'Ò'=>'O',
'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ø'=>'O', 'Ō'=>'O', 'Ő'=>'O',
'Ŏ'=>'O', 'Ŕ'=>'R', 'Ř'=>'R', 'Ŗ'=>'R', 'Ś'=>'S', 'Ş'=>'S',
'Ŝ'=>'S', 'Ș'=>'S', 'Š'=>'S', 'Ť'=>'T', 'Ţ'=>'T', 'Ŧ'=>'T',
'Ț'=>'T', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ū'=>'U', 'Ů'=>'U',
'Ű'=>'U', 'Ŭ'=>'U', 'Ũ'=>'U', 'Ų'=>'U', 'Ŵ'=>'W', 'Ŷ'=>'Y',
'Ÿ'=>'Y', 'Ý'=>'Y', 'Ź'=>'Z', 'Ż'=>'Z', 'Ž'=>'Z', 'à'=>'a',
'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ā'=>'a', 'ą'=>'a', 'ă'=>'a',
'å'=>'a', 'ç'=>'c', 'ć'=>'c', 'č'=>'c', 'ĉ'=>'c', 'ċ'=>'c',
'ď'=>'d', 'đ'=>'d', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e',
'ē'=>'e', 'ę'=>'e', 'ě'=>'e', 'ĕ'=>'e', 'ė'=>'e', 'ƒ'=>'f',
'ĝ'=>'g', 'ğ'=>'g', 'ġ'=>'g', 'ģ'=>'g', 'ĥ'=>'h', 'ħ'=>'h',
'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ī'=>'i', 'ĩ'=>'i',
'ĭ'=>'i', 'į'=>'i', 'ı'=>'i', 'ĵ'=>'j', 'ķ'=>'k', 'ĸ'=>'k',
'ł'=>'l', 'ľ'=>'l', 'ĺ'=>'l', 'ļ'=>'l', 'ŀ'=>'l', 'ñ'=>'n',
'ń'=>'n', 'ň'=>'n', 'ņ'=>'n', 'ʼn'=>'n', 'ŋ'=>'n', 'ò'=>'o',
'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ø'=>'o', 'ō'=>'o', 'ő'=>'o',
'ŏ'=>'o', 'ŕ'=>'r', 'ř'=>'r', 'ŗ'=>'r', 'ś'=>'s', 'š'=>'s',
'ť'=>'t', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ū'=>'u', 'ů'=>'u',
'ű'=>'u', 'ŭ'=>'u', 'ũ'=>'u', 'ų'=>'u', 'ŵ'=>'w', 'ÿ'=>'y',
'ý'=>'y', 'ŷ'=>'y', 'ż'=>'z', 'ź'=>'z', 'ž'=>'z', 'Α'=>'A',
'Ά'=>'A', 'Ἀ'=>'A', 'Ἁ'=>'A', 'Ἂ'=>'A', 'Ἃ'=>'A', 'Ἄ'=>'A',
'Ἅ'=>'A', 'Ἆ'=>'A', 'Ἇ'=>'A', 'ᾈ'=>'A', 'ᾉ'=>'A', 'ᾊ'=>'A',
'ᾋ'=>'A', 'ᾌ'=>'A', 'ᾍ'=>'A', 'ᾎ'=>'A', 'ᾏ'=>'A', 'Ᾰ'=>'A',
'Ᾱ'=>'A', 'Ὰ'=>'A', 'ᾼ'=>'A', 'Β'=>'B', 'Γ'=>'G', 'Δ'=>'D',
'Ε'=>'E', 'Έ'=>'E', 'Ἐ'=>'E', 'Ἑ'=>'E', 'Ἒ'=>'E', 'Ἓ'=>'E',
'Ἔ'=>'E', 'Ἕ'=>'E', 'Ὲ'=>'E', 'Ζ'=>'Z', 'Η'=>'I', 'Ή'=>'I',
'Ἠ'=>'I', 'Ἡ'=>'I', 'Ἢ'=>'I', 'Ἣ'=>'I', 'Ἤ'=>'I', 'Ἥ'=>'I',
'Ἦ'=>'I', 'Ἧ'=>'I', 'ᾘ'=>'I', 'ᾙ'=>'I', 'ᾚ'=>'I', 'ᾛ'=>'I',
'ᾜ'=>'I', 'ᾝ'=>'I', 'ᾞ'=>'I', 'ᾟ'=>'I', 'Ὴ'=>'I', 'ῌ'=>'I',
'Θ'=>'T', 'Ι'=>'I', 'Ί'=>'I', 'Ϊ'=>'I', 'Ἰ'=>'I', 'Ἱ'=>'I',
'Ἲ'=>'I', 'Ἳ'=>'I', 'Ἴ'=>'I', 'Ἵ'=>'I', 'Ἶ'=>'I', 'Ἷ'=>'I',
'Ῐ'=>'I', 'Ῑ'=>'I', 'Ὶ'=>'I', 'Κ'=>'K', 'Λ'=>'L', 'Μ'=>'M',
'Ν'=>'N', 'Ξ'=>'K', 'Ο'=>'O', 'Ό'=>'O', 'Ὀ'=>'O', 'Ὁ'=>'O',
'Ὂ'=>'O', 'Ὃ'=>'O', 'Ὄ'=>'O', 'Ὅ'=>'O', 'Ὸ'=>'O', 'Π'=>'P',
'Ρ'=>'R', 'Ῥ'=>'R', 'Σ'=>'S', 'Τ'=>'T', 'Υ'=>'Y', 'Ύ'=>'Y',
'Ϋ'=>'Y', 'Ὑ'=>'Y', 'Ὓ'=>'Y', 'Ὕ'=>'Y', 'Ὗ'=>'Y', 'Ῠ'=>'Y',
'Ῡ'=>'Y', 'Ὺ'=>'Y', 'Φ'=>'F', 'Χ'=>'X', 'Ψ'=>'P', 'Ω'=>'O',
'Ώ'=>'O', 'Ὠ'=>'O', 'Ὡ'=>'O', 'Ὢ'=>'O', 'Ὣ'=>'O', 'Ὤ'=>'O',
'Ὥ'=>'O', 'Ὦ'=>'O', 'Ὧ'=>'O', 'ᾨ'=>'O', 'ᾩ'=>'O', 'ᾪ'=>'O',
'ᾫ'=>'O', 'ᾬ'=>'O', 'ᾭ'=>'O', 'ᾮ'=>'O', 'ᾯ'=>'O', 'Ὼ'=>'O',
'ῼ'=>'O', 'α'=>'a', 'ά'=>'a', 'ἀ'=>'a', 'ἁ'=>'a', 'ἂ'=>'a',
'ἃ'=>'a', 'ἄ'=>'a', 'ἅ'=>'a', 'ἆ'=>'a', 'ἇ'=>'a', 'ᾀ'=>'a',
'ᾁ'=>'a', 'ᾂ'=>'a', 'ᾃ'=>'a', 'ᾄ'=>'a', 'ᾅ'=>'a', 'ᾆ'=>'a',
'ᾇ'=>'a', 'ὰ'=>'a', 'ᾰ'=>'a', 'ᾱ'=>'a', 'ᾲ'=>'a', 'ᾳ'=>'a',
'ᾴ'=>'a', 'ᾶ'=>'a', 'ᾷ'=>'a', 'β'=>'b', 'γ'=>'g', 'δ'=>'d',
'ε'=>'e', 'έ'=>'e', 'ἐ'=>'e', 'ἑ'=>'e', 'ἒ'=>'e', 'ἓ'=>'e',
'ἔ'=>'e', 'ἕ'=>'e', 'ὲ'=>'e', 'ζ'=>'z', 'η'=>'i', 'ή'=>'i',
'ἠ'=>'i', 'ἡ'=>'i', 'ἢ'=>'i', 'ἣ'=>'i', 'ἤ'=>'i', 'ἥ'=>'i',
'ἦ'=>'i', 'ἧ'=>'i', 'ᾐ'=>'i', 'ᾑ'=>'i', 'ᾒ'=>'i', 'ᾓ'=>'i',
'ᾔ'=>'i', 'ᾕ'=>'i', 'ᾖ'=>'i', 'ᾗ'=>'i', 'ὴ'=>'i', 'ῂ'=>'i',
'ῃ'=>'i', 'ῄ'=>'i', 'ῆ'=>'i', 'ῇ'=>'i', 'θ'=>'t', 'ι'=>'i',
'ί'=>'i', 'ϊ'=>'i', 'ΐ'=>'i', 'ἰ'=>'i', 'ἱ'=>'i', 'ἲ'=>'i',
'ἳ'=>'i', 'ἴ'=>'i', 'ἵ'=>'i', 'ἶ'=>'i', 'ἷ'=>'i', 'ὶ'=>'i',
'ῐ'=>'i', 'ῑ'=>'i', 'ῒ'=>'i', 'ῖ'=>'i', 'ῗ'=>'i', 'κ'=>'k',
'λ'=>'l', 'μ'=>'m', 'ν'=>'n', 'ξ'=>'k', 'ο'=>'o', 'ό'=>'o',
'ὀ'=>'o', 'ὁ'=>'o', 'ὂ'=>'o', 'ὃ'=>'o', 'ὄ'=>'o', 'ὅ'=>'o',
'ὸ'=>'o', 'π'=>'p', 'ρ'=>'r', 'ῤ'=>'r', 'ῥ'=>'r', 'σ'=>'s',
'ς'=>'s', 'τ'=>'t', 'υ'=>'y', 'ύ'=>'y', 'ϋ'=>'y', 'ΰ'=>'y',
'ὐ'=>'y', 'ὑ'=>'y', 'ὒ'=>'y', 'ὓ'=>'y', 'ὔ'=>'y', 'ὕ'=>'y',
'ὖ'=>'y', 'ὗ'=>'y', 'ὺ'=>'y', 'ῠ'=>'y', 'ῡ'=>'y', 'ῢ'=>'y',
'ῦ'=>'y', 'ῧ'=>'y', 'φ'=>'f', 'χ'=>'x', 'ψ'=>'p', 'ω'=>'o',
'ώ'=>'o', 'ὠ'=>'o', 'ὡ'=>'o', 'ὢ'=>'o', 'ὣ'=>'o', 'ὤ'=>'o',
'ὥ'=>'o', 'ὦ'=>'o', 'ὧ'=>'o', 'ᾠ'=>'o', 'ᾡ'=>'o', 'ᾢ'=>'o',
'ᾣ'=>'o', 'ᾤ'=>'o', 'ᾥ'=>'o', 'ᾦ'=>'o', 'ᾧ'=>'o', 'ὼ'=>'o',
'ῲ'=>'o', 'ῳ'=>'o', 'ῴ'=>'o', 'ῶ'=>'o', 'ῷ'=>'o', 'А'=>'A',
'Б'=>'B', 'В'=>'V', 'Г'=>'G', 'Д'=>'D', 'Е'=>'E', 'Ё'=>'E',
'Ж'=>'Z', 'З'=>'Z', 'И'=>'I', 'Й'=>'I', 'К'=>'K', 'Л'=>'L',
'М'=>'M', 'Н'=>'N', 'О'=>'O', 'П'=>'P', 'Р'=>'R', 'С'=>'S',
'Т'=>'T', 'У'=>'U', 'Ф'=>'F', 'Х'=>'K', 'Ц'=>'T', 'Ч'=>'C',
'Ш'=>'S', 'Щ'=>'S', 'Ы'=>'Y', 'Э'=>'E', 'Ю'=>'Y', 'Я'=>'Y',
'а'=>'A', 'б'=>'B', 'в'=>'V', 'г'=>'G', 'д'=>'D', 'е'=>'E',
'ё'=>'E', 'ж'=>'Z', 'з'=>'Z', 'и'=>'I', 'й'=>'I', 'к'=>'K',
'л'=>'L', 'м'=>'M', 'н'=>'N', 'о'=>'O', 'п'=>'P', 'р'=>'R',
'с'=>'S', 'т'=>'T', 'у'=>'U', 'ф'=>'F', 'х'=>'K', 'ц'=>'T',
'ч'=>'C', 'ш'=>'S', 'щ'=>'S', 'ы'=>'Y', 'э'=>'E', 'ю'=>'Y',
'я'=>'Y', 'ð'=>'d', 'Ð'=>'D', 'þ'=>'t', 'Þ'=>'T', 'ა'=>'a',
'ბ'=>'b', 'გ'=>'g', 'დ'=>'d', 'ე'=>'e', 'ვ'=>'v', 'ზ'=>'z',
'თ'=>'t', 'ი'=>'i', 'კ'=>'k', 'ლ'=>'l', 'მ'=>'m', 'ნ'=>'n',
'ო'=>'o', 'პ'=>'p', 'ჟ'=>'z', 'რ'=>'r', 'ს'=>'s', 'ტ'=>'t',
'უ'=>'u', 'ფ'=>'p', 'ქ'=>'k', 'ღ'=>'g', 'ყ'=>'q', 'შ'=>'s',
'ჩ'=>'c', 'ც'=>'t', 'ძ'=>'d', 'წ'=>'t', 'ჭ'=>'c', 'ხ'=>'k',
'ჯ'=>'j', 'ჰ'=>'h', 'ţ'=>'t', 'ʼ'=>"'", '̧'=>'', 'ḩ'=>'h',
'‘'=>"'", '’'=>"'", 'ừ'=>'u', '/'=>'', 'ế'=>'e', 'ả'=>'a',
'ị'=>'i', 'ậ'=>'a', 'ệ'=>'e', 'ỉ'=>'i', 'ồ'=>'o', 'ề'=>'e',
'ơ'=>'o', 'ạ'=>'a', 'ẵ'=>'a', 'ư'=>'u', 'ằ'=>'a', 'ầ'=>'a',
'ḑ'=>'d', 'Ḩ'=>'H', 'Ḑ'=>'D', 'ș'=>'s', 'ț'=>'t', 'ộ'=>'o',
'ắ'=>'a', 'ş'=>'s', "'"=>'', 'ու'=>'u', 'ա'=>'a', 'բ'=>'b',
'գ'=>'g', 'դ'=>'d', 'ե'=>'e', 'զ'=>'z', 'է'=>'e', 'ը'=>'y',
'թ'=>'t', 'ժ'=>'zh', 'ի'=>'i', 'լ'=>'l', 'խ'=>'kh', 'ծ'=>'ts',
'կ'=>'k', 'հ'=>'h', 'ձ'=>'dz', 'ղ'=>'gh', 'ճ'=>'ch', 'մ'=>'m',
'յ'=>'y', 'ն'=>'n', 'շ'=>'sh', 'ո'=>'o', 'չ'=>'ch', 'պ'=>'p',
'ջ'=>'j', 'ռ'=>'r', 'ս'=>'s', 'վ'=>'v', 'տ'=>'t', 'ր'=>'r',
'ց'=>'ts', 'փ'=>'p', 'ք'=>'q', 'և'=>'ev', 'օ'=>'o', 'ֆ'=>'f',
);
$arrayFrom = array_keys($transliterationTable);
$arrayTo = array_values($transliterationTable);
}

return str_replace($arrayFrom, $arrayTo, $string);
}
}
<?php

namespace Faker\Provider;




class Image extends Base
{
protected static $categories = array(
'abstract', 'animals', 'business', 'cats', 'city', 'food', 'nightlife',
'fashion', 'people', 'nature', 'sports', 'technics', 'transport'
);

















public static function imageUrl($width = 640, $height = 480, $category = null, $randomize = true, $word = null, $gray = false)
{
$baseUrl = "https://lorempixel.com/";
$url = "{$width}/{$height}/";

if ($gray) {
$url = "gray/" . $url;
}

if ($category) {
if (!in_array($category, static::$categories)) {
throw new \InvalidArgumentException(sprintf('Unknown image category "%s"', $category));
}
$url .= "{$category}/";
if ($word) {
$url .= "{$word}/";
}
}

if ($randomize) {
$url .= '?' . static::randomNumber(5, true);
}

return $baseUrl . $url;
}








public static function image($dir = null, $width = 640, $height = 480, $category = null, $fullPath = true, $randomize = true, $word = null)
{
$dir = is_null($dir) ? sys_get_temp_dir() : $dir; 
 
 if (!is_dir($dir) || !is_writable($dir)) {
throw new \InvalidArgumentException(sprintf('Cannot write to directory "%s"', $dir));
}


 
 $name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));
$filename = $name .'.jpg';
$filepath = $dir . DIRECTORY_SEPARATOR . $filename;

$url = static::imageUrl($width, $height, $category, $randomize, $word);


 if (function_exists('curl_exec')) {

 $fp = fopen($filepath, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;

if ($success) {
fclose($fp);
} else {
unlink($filepath);
}

curl_close($ch);
} elseif (ini_get('allow_url_fopen')) {

 $success = copy($url, $filepath);
} else {
return new \RuntimeException('The image formatter downloads an image from a remote HTTP server. Therefore, it requires that PHP can request remote hosts, either via cURL or fopen()');
}

if (!$success) {

 return false;
}

return $fullPath ? $filepath : $filename;
}
}
<?php

namespace Faker\Provider;

use Faker\Calculator\Iban;
use Faker\Calculator\Luhn;

class Payment extends Base
{
public static $expirationDateFormat = "m/y";

protected static $cardVendors = array(
'Visa', 'Visa', 'Visa', 'Visa', 'Visa',
'MasterCard', 'MasterCard', 'MasterCard', 'MasterCard', 'MasterCard',
'American Express', 'Discover Card'
);






protected static $cardParams = array(
'Visa' => array(
"4539########",
"4539###########",
"4556########",
"4556###########",
"4916########",
"4916###########",
"4532########",
"4532###########",
"4929########",
"4929###########",
"40240071####",
"40240071#######",
"4485########",
"4485###########",
"4716########",
"4716###########",
"4###########",
"4##############"
),
'MasterCard' => array(
"2221###########",
"23#############",
"24#############",
"25#############",
"26#############",
"2720###########",
"51#############",
"52#############",
"53#############",
"54#############",
"55#############"
),
'American Express' => array(
"34############",
"37############"
),
'Discover Card' => array(
"6011###########"
),
);




protected static $ibanFormats = array(
'AD' => array(array('n', 4), array('n', 4), array('c', 12)),
'AE' => array(array('n', 3), array('n', 16)),
'AL' => array(array('n', 8), array('c', 16)),
'AT' => array(array('n', 5), array('n', 11)),
'AZ' => array(array('a', 4), array('c', 20)),
'BA' => array(array('n', 3), array('n', 3), array('n', 8), array('n', 2)),
'BE' => array(array('n', 3), array('n', 7), array('n', 2)),
'BG' => array(array('a', 4), array('n', 4), array('n', 2), array('c', 8)),
'BH' => array(array('a', 4), array('c', 14)),
'BR' => array(array('n', 8), array('n', 5), array('n', 10), array('a', 1), array('c', 1)),
'CH' => array(array('n', 5), array('c', 12)),
'CR' => array(array('n', 3), array('n', 14)),
'CY' => array(array('n', 3), array('n', 5), array('c', 16)),
'CZ' => array(array('n', 4), array('n', 6), array('n', 10)),
'DE' => array(array('n', 8), array('n', 10)),
'DK' => array(array('n', 4), array('n', 9), array('n', 1)),
'DO' => array(array('c', 4), array('n', 20)),
'EE' => array(array('n', 2), array('n', 2), array('n', 11), array('n', 1)),
'ES' => array(array('n', 4), array('n', 4), array('n', 1), array('n', 1), array('n', 10)),
'FI' => array(array('n', 6), array('n', 7), array('n', 1)),
'FR' => array(array('n', 5), array('n', 5), array('c', 11), array('n', 2)),
'GB' => array(array('a', 4), array('n', 6), array('n', 8)),
'GE' => array(array('a', 2), array('n', 16)),
'GI' => array(array('a', 4), array('c', 15)),
'GR' => array(array('n', 3), array('n', 4), array('c', 16)),
'GT' => array(array('c', 4), array('c', 20)),
'HR' => array(array('n', 7), array('n', 10)),
'HU' => array(array('n', 3), array('n', 4), array('n', 1), array('n', 15), array('n', 1)),
'IE' => array(array('a', 4), array('n', 6), array('n', 8)),
'IL' => array(array('n', 3), array('n', 3), array('n', 13)),
'IS' => array(array('n', 4), array('n', 2), array('n', 6), array('n', 10)),
'IT' => array(array('a', 1), array('n', 5), array('n', 5), array('c', 12)),
'KW' => array(array('a', 4), array('n', 22)),
'KZ' => array(array('n', 3), array('c', 13)),
'LB' => array(array('n', 4), array('c', 20)),
'LI' => array(array('n', 5), array('c', 12)),
'LT' => array(array('n', 5), array('n', 11)),
'LU' => array(array('n', 3), array('c', 13)),
'LV' => array(array('a', 4), array('c', 13)),
'MC' => array(array('n', 5), array('n', 5), array('c', 11), array('n', 2)),
'MD' => array(array('c', 2), array('c', 18)),
'ME' => array(array('n', 3), array('n', 13), array('n', 2)),
'MK' => array(array('n', 3), array('c', 10), array('n', 2)),
'MR' => array(array('n', 5), array('n', 5), array('n', 11), array('n', 2)),
'MT' => array(array('a', 4), array('n', 5), array('c', 18)),
'MU' => array(array('a', 4), array('n', 2), array('n', 2), array('n', 12), array('n', 3), array('a', 3)),
'NL' => array(array('a', 4), array('n', 10)),
'NO' => array(array('n', 4), array('n', 6), array('n', 1)),
'PK' => array(array('a', 4), array('c', 16)),
'PL' => array(array('n', 8), array('n', 16)),
'PS' => array(array('a', 4), array('c', 21)),
'PT' => array(array('n', 4), array('n', 4), array('n', 11), array('n', 2)),
'RO' => array(array('a', 4), array('c', 16)),
'RS' => array(array('n', 3), array('n', 13), array('n', 2)),
'SA' => array(array('n', 2), array('c', 18)),
'SE' => array(array('n', 3), array('n', 16), array('n', 1)),
'SI' => array(array('n', 5), array('n', 8), array('n', 2)),
'SK' => array(array('n', 4), array('n', 6), array('n', 10)),
'SM' => array(array('a', 1), array('n', 5), array('n', 5), array('c', 12)),
'TN' => array(array('n', 2), array('n', 3), array('n', 13), array('n', 2)),
'TR' => array(array('n', 5), array('n', 1), array('c', 16)),
'VG' => array(array('a', 4), array('n', 16)),
);






public static function creditCardType()
{
return static::randomElement(static::$cardVendors);
}











public static function creditCardNumber($type = null, $formatted = false, $separator = '-')
{
if (is_null($type)) {
$type = static::creditCardType();
}
$mask = static::randomElement(static::$cardParams[$type]);

$number = static::numerify($mask);
$number .= Luhn::computeCheckDigit($number);

if ($formatted) {
$p1 = substr($number, 0, 4);
$p2 = substr($number, 4, 4);
$p3 = substr($number, 8, 4);
$p4 = substr($number, 12);
$number = $p1 . $separator . $p2 . $separator . $p3 . $separator . $p4;
}

return $number;
}






public function creditCardExpirationDate($valid = true)
{
if ($valid) {
return $this->generator->dateTimeBetween('now', '36 months');
}

return $this->generator->dateTimeBetween('-36 months', '36 months');
}







public function creditCardExpirationDateString($valid = true, $expirationDateFormat = null)
{
return $this->creditCardExpirationDate($valid)->format(is_null($expirationDateFormat) ? static::$expirationDateFormat : $expirationDateFormat);
}





public function creditCardDetails($valid = true)
{
$type = static::creditCardType();

return array(
'type' => $type,
'number' => static::creditCardNumber($type),
'name' => $this->generator->name(),
'expirationDate' => $this->creditCardExpirationDateString($valid)
);
}










public static function iban($countryCode, $prefix = '', $length = null)
{
$countryCode = is_null($countryCode) ? self::randomKey(self::$ibanFormats) : strtoupper($countryCode);

$format = !isset(static::$ibanFormats[$countryCode]) ? null : static::$ibanFormats[$countryCode];
if ($length === null) {
if ($format === null) {
$length = 24;
} else {
$length = 0;
foreach ($format as $part) {
list($class, $groupCount) = $part;
$length += $groupCount;
}
}
}
if ($format === null) {
$format = array(array('n', $length));
}

$expandedFormat = '';
foreach ($format as $item) {
list($class, $length) = $item;
$expandedFormat .= str_repeat($class, $length);
}

$result = $prefix;
$expandedFormat = substr($expandedFormat, strlen($result));
foreach (str_split($expandedFormat) as $class) {
switch ($class) {
default:
case 'c':
$result .= mt_rand(0, 100) <= 50 ? static::randomDigit() : strtoupper(static::randomLetter());
break;
case 'a':
$result .= strtoupper(static::randomLetter());
break;
case 'n':
$result .= static::randomDigit();
break;
}
}

$checksum = Iban::checksum($countryCode . '00' . $result);

return $countryCode . $checksum . $result;
}








public static function swiftBicNumber()
{
return self::regexify("^([A-Z]){4}([A-Z]){2}([0-9A-Z]){2}([0-9A-Z]{3})?$");
}
}
<?php

namespace Faker\Provider;

class Address extends Base
{
protected static $citySuffix = array('Ville');
protected static $streetSuffix = array('Street');
protected static $cityFormats = array(
'{{firstName}}{{citySuffix}}',
);
protected static $streetNameFormats = array(
'{{lastName}} {{streetSuffix}}'
);
protected static $streetAddressFormats = array(
'{{buildingNumber}} {{streetName}}'
);
protected static $addressFormats = array(
'{{streetAddress}} {{postcode}} {{city}}',
);

protected static $buildingNumber = array('%#');
protected static $postcode = array('#####');
protected static $country = array();




public static function citySuffix()
{
return static::randomElement(static::$citySuffix);
}




public static function streetSuffix()
{
return static::randomElement(static::$streetSuffix);
}




public static function buildingNumber()
{
return static::numerify(static::randomElement(static::$buildingNumber));
}




public function city()
{
$format = static::randomElement(static::$cityFormats);

return $this->generator->parse($format);
}




public function streetName()
{
$format = static::randomElement(static::$streetNameFormats);

return $this->generator->parse($format);
}




public function streetAddress()
{
$format = static::randomElement(static::$streetAddressFormats);

return $this->generator->parse($format);
}




public static function postcode()
{
return static::toUpper(static::bothify(static::randomElement(static::$postcode)));
}




public function address()
{
$format = static::randomElement(static::$addressFormats);

return $this->generator->parse($format);
}




public static function country()
{
return static::randomElement(static::$country);
}







public static function latitude($min = -90, $max = 90)
{
return static::randomFloat(6, $min, $max);
}







public static function longitude($min = -180, $max = 180)
{
return static::randomFloat(6, $min, $max);
}





public static function localCoordinates()
{
return array(
'latitude' => static::latitude(),
'longitude' => static::longitude()
);
}
}
<?php

namespace Faker\Provider;

use Faker\Calculator\Luhn;

class PhoneNumber extends Base
{
protected static $formats = array('###-###-###');




public function phoneNumber()
{
return static::numerify($this->generator->parse(static::randomElement(static::$formats)));
}





public function e164PhoneNumber()
{
$formats = array('+%############');
return static::numerify($this->generator->parse(static::randomElement($formats)));
}









public function imei()
{
$imei = (string) static::numerify('##############');
$imei .= Luhn::computeCheckDigit($imei);
return $imei;
}
}
<?php

namespace Faker\Provider;

use Faker\Generator;
use Faker\UniqueGenerator;

class HtmlLorem extends Base
{

const HTML_TAG = "html";
const HEAD_TAG = "head";
const BODY_TAG = "body";
const DIV_TAG = "div";
const P_TAG = "p";
const A_TAG = "a";
const SPAN_TAG = "span";
const TABLE_TAG = "table";
const THEAD_TAG = "thead";
const TBODY_TAG = "tbody";
const TR_TAG = "tr";
const TD_TAG = "td";
const TH_TAG = "th";
const UL_TAG = "ul";
const LI_TAG = "li";
const H_TAG = "h";
const B_TAG = "b";
const I_TAG = "i";
const TITLE_TAG = "title";
const FORM_TAG = "form";
const INPUT_TAG = "input";
const LABEL_TAG = "label";

private $idGenerator;

public function __construct(Generator $generator)
{
parent::__construct($generator);
$generator->addProvider(new Lorem($generator));
$generator->addProvider(new Internet($generator));
}







public function randomHtml($maxDepth = 4, $maxWidth = 4)
{
$document = new \DOMDocument();
$this->idGenerator = new UniqueGenerator($this->generator);

$head = $document->createElement("head");
$this->addRandomTitle($head);

$body = $document->createElement("body");
$this->addLoginForm($body);
$this->addRandomSubTree($body, $maxDepth, $maxWidth);

$html = $document->createElement("html");
$html->appendChild($head);
$html->appendChild($body);

$document->appendChild($html);
return $document->saveHTML();
}

private function addRandomSubTree(\DOMElement $root, $maxDepth, $maxWidth)
{
$maxDepth--;
if ($maxDepth <= 0) {
return $root;
}

$siblings = mt_rand(1, $maxWidth);
for ($i = 0; $i < $siblings; $i++) {
if ($maxDepth == 1) {
$this->addRandomLeaf($root);
} else {
$sibling = $root->ownerDocument->createElement("div");
$root->appendChild($sibling);
$this->addRandomAttribute($sibling);
$this->addRandomSubTree($sibling, mt_rand(0, $maxDepth), $maxWidth);
}
};
return $root;
}

private function addRandomLeaf(\DOMElement $node)
{
$rand = mt_rand(1, 10);
switch($rand){
case 1:
$this->addRandomP($node);
break;
case 2:
$this->addRandomA($node);
break;
case 3:
$this->addRandomSpan($node);
break;
case 4:
$this->addRandomUL($node);
break;
case 5:
$this->addRandomH($node);
break;
case 6:
$this->addRandomB($node);
break;
case 7:
$this->addRandomI($node);
break;
case 8:
$this->addRandomTable($node);
break;
default:
$this->addRandomText($node);
break;
}
}

private function addRandomAttribute(\DOMElement $node)
{
$rand = mt_rand(1, 2);
switch ($rand) {
case 1:
$node->setAttribute("class", $this->generator->word);
break;
case 2:
$node->setAttribute("id", (string)$this->idGenerator->randomNumber(5));
break;
}
}

private function addRandomP(\DOMElement $element, $maxLength = 10)
{

$node = $element->ownerDocument->createElement(static::P_TAG);
$node->textContent = $this->generator->sentence(mt_rand(1, $maxLength));
$element->appendChild($node);
}

private function addRandomText(\DOMElement $element, $maxLength = 10)
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$element->appendChild($text);
}

private function addRandomA(\DOMElement $element, $maxLength = 10)
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::A_TAG);
$node->setAttribute("href", $this->generator->safeEmailDomain);
$node->appendChild($text);
$element->appendChild($node);
}

private function addRandomTitle(\DOMElement $element, $maxLength = 10)
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::TITLE_TAG);
$node->appendChild($text);
$element->appendChild($node);
}

private function addRandomH(\DOMElement $element, $maxLength = 10)
{
$h = static::H_TAG . (string)mt_rand(1, 3);
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$node = $element->ownerDocument->createElement($h);
$node->appendChild($text);
$element->appendChild($node);

}

private function addRandomB(\DOMElement $element, $maxLength = 10)
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::B_TAG);
$node->appendChild($text);
$element->appendChild($node);
}

private function addRandomI(\DOMElement $element, $maxLength = 10)
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::I_TAG);
$node->appendChild($text);
$element->appendChild($node);
}

private function addRandomSpan(\DOMElement $element, $maxLength = 10)
{
$text = $element->ownerDocument->createTextNode($this->generator->sentence(mt_rand(1, $maxLength)));
$node = $element->ownerDocument->createElement(static::SPAN_TAG);
$node->appendChild($text);
$element->appendChild($node);
}

private function addLoginForm(\DOMElement $element)
{

$textInput = $element->ownerDocument->createElement(static::INPUT_TAG);
$textInput->setAttribute("type", "text");
$textInput->setAttribute("id", "username");

$textLabel = $element->ownerDocument->createElement(static::LABEL_TAG);
$textLabel->setAttribute("for", "username");
$textLabel->textContent = $this->generator->word;

$passwordInput = $element->ownerDocument->createElement(static::INPUT_TAG);
$passwordInput->setAttribute("type", "password");
$passwordInput->setAttribute("id", "password");

$passwordLabel = $element->ownerDocument->createElement(static::LABEL_TAG);
$passwordLabel->setAttribute("for", "password");
$passwordLabel->textContent = $this->generator->word;

$submit = $element->ownerDocument->createElement(static::INPUT_TAG);
$submit->setAttribute("type", "submit");
$submit->setAttribute("value", $this->generator->word);

$submit = $element->ownerDocument->createElement(static::FORM_TAG);
$submit->setAttribute("action", $this->generator->safeEmailDomain);
$submit->setAttribute("method", "POST");
$submit->appendChild($textLabel);
$submit->appendChild($textInput);
$submit->appendChild($passwordLabel);
$submit->appendChild($passwordInput);
$element->appendChild($submit);
}

private function addRandomTable(\DOMElement $element, $maxRows = 10, $maxCols = 6, $maxTitle = 4, $maxLength = 10)
{
$rows = mt_rand(1, $maxRows);
$cols = mt_rand(1, $maxCols);

$table = $element->ownerDocument->createElement(static::TABLE_TAG);
$thead = $element->ownerDocument->createElement(static::THEAD_TAG);
$tbody = $element->ownerDocument->createElement(static::TBODY_TAG);

$table->appendChild($thead);
$table->appendChild($tbody);

$tr = $element->ownerDocument->createElement(static::TR_TAG);
$thead->appendChild($tr);
for ($i = 0; $i < $cols; $i++) {
$th = $element->ownerDocument->createElement(static::TH_TAG);
$th->textContent = $this->generator->sentence(mt_rand(1, $maxTitle));
$tr->appendChild($th);
}
for ($i = 0; $i < $rows; $i++) {
$tr = $element->ownerDocument->createElement(static::TR_TAG);
$tbody->appendChild($tr);
for ($j = 0; $j < $cols; $j++) {
$th = $element->ownerDocument->createElement(static::TD_TAG);
$th->textContent = $this->generator->sentence(mt_rand(1, $maxLength));
$tr->appendChild($th);
}
}
$element->appendChild($table);
}

private function addRandomUL(\DOMElement $element, $maxItems = 11, $maxLength = 4)
{
$num = mt_rand(1, $maxItems);
$ul = $element->ownerDocument->createElement(static::UL_TAG);
for ($i = 0; $i < $num; $i++) {
$li = $element->ownerDocument->createElement(static::LI_TAG);
$li->textContent = $this->generator->sentence(mt_rand(1, $maxLength));
$ul->appendChild($li);
}
$element->appendChild($ul);
}
}
<?php

namespace Faker\Guesser;

use \Faker\Provider\Base;

class Name
{
protected $generator;




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}






public function guessFormat($name, $size = null)
{
$name = Base::toLower($name);
$generator = $this->generator;
if (preg_match('/^is[_A-Z]/', $name)) {
return function () use ($generator) {
return $generator->boolean;
};
}
if (preg_match('/(_a|A)t$/', $name)) {
return function () use ($generator) {
return $generator->dateTime;
};
}
switch (str_replace('_', '', $name)) {
case 'firstname':
return function () use ($generator) {
return $generator->firstName;
};
case 'lastname':
return function () use ($generator) {
return $generator->lastName;
};
case 'username':
case 'login':
return function () use ($generator) {
return $generator->userName;
};
case 'email':
case 'emailaddress':
return function () use ($generator) {
return $generator->email;
};
case 'phonenumber':
case 'phone':
case 'telephone':
case 'telnumber':
return function () use ($generator) {
return $generator->phoneNumber;
};
case 'address':
return function () use ($generator) {
return $generator->address;
};
case 'city':
case 'town':
return function () use ($generator) {
return $generator->city;
};
case 'streetaddress':
return function () use ($generator) {
return $generator->streetAddress;
};
case 'postcode':
case 'zipcode':
return function () use ($generator) {
return $generator->postcode;
};
case 'state':
return function () use ($generator) {
return $generator->state;
};
case 'county':
if ($this->generator->locale == 'en_US') {
return function () use ($generator) {
return sprintf('%s County', $generator->city);
};
}

return function () use ($generator) {
return $generator->state;
};
case 'country':
switch ($size) {
case 2:
return function () use ($generator) {
return $generator->countryCode;
};
case 3:
return function () use ($generator) {
return $generator->countryISOAlpha3;
};
case 5:
case 6:
return function () use ($generator) {
return $generator->locale;
};
default:
return function () use ($generator) {
return $generator->country;
};
}
break;
case 'locale':
return function () use ($generator) {
return $generator->locale;
};
case 'currency':
case 'currencycode':
return function () use ($generator) {
return $generator->currencyCode;
};
case 'url':
case 'website':
return function () use ($generator) {
return $generator->url;
};
case 'company':
case 'companyname':
case 'employer':
return function () use ($generator) {
return $generator->company;
};
case 'title':
if ($size !== null && $size <= 10) {
return function () use ($generator) {
return $generator->title;
};
}

return function () use ($generator) {
return $generator->sentence;
};
case 'body':
case 'summary':
case 'article':
case 'description':
return function () use ($generator) {
return $generator->text;
};
}
}
}
<?php

namespace Faker\ORM\Mandango;

use Mandango\Mandango;
use Faker\Provider\Base;




class EntityPopulator
{
protected $class;
protected $columnFormatters = array();






public function __construct($class)
{
$this->class = $class;
}




public function getClass()
{
return $this->class;
}

public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}




public function getColumnFormatters()
{
return $this->columnFormatters;
}

public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}






public function guessColumnFormatters(\Faker\Generator $generator, Mandango $mandango)
{
$formatters = array();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Mandango\ColumnTypeGuesser($generator);

$metadata = $mandango->getMetadata($this->class);


 foreach ($metadata['fields'] as $fieldName => $field) {
if ($formatter = $nameGuesser->guessFormat($fieldName)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($field)) {
$formatters[$fieldName] = $formatter;
continue;
}
}


 foreach (array_merge($metadata['referencesOne'], $metadata['referencesMany']) as $referenceName => $reference) {
if (!isset($reference['class'])) {
continue;
}
$referenceClass = $reference['class'];

$formatters[$referenceName] = function ($insertedEntities) use ($referenceClass) {
if (isset($insertedEntities[$referenceClass])) {
return Base::randomElement($insertedEntities[$referenceClass]);
}
};
}

return $formatters;
}





public function execute(Mandango $mandango, $insertedEntities)
{
$metadata = $mandango->getMetadata($this->class);

$obj = $mandango->create($this->class);
foreach ($this->columnFormatters as $column => $format) {
if (null !== $format) {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;

if (isset($metadata['fields'][$column]) ||
isset($metadata['referencesOne'][$column])) {
$obj->set($column, $value);
}

if (isset($metadata['referencesMany'][$column])) {
$adder = 'add'.ucfirst($column);
$obj->$adder($value);
}
}
}
$mandango->persist($obj);

return $obj;
}
}
<?php

namespace Faker\ORM\Mandango;

class ColumnTypeGuesser
{
protected $generator;




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}




public function guessFormat($field)
{
$generator = $this->generator;
switch ($field['type']) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'integer':
return function () {
return mt_rand(0, intval('4294967295'));
};
case 'float':
return function () {
return mt_rand(0, intval('4294967295'))/mt_rand(1, intval('4294967295'));
};
case 'string':
return function () use ($generator) {
return $generator->text(255);
};
case 'date':
return function () use ($generator) {
return $generator->datetime;
};
default:

 return null;
}
}
}
<?php

namespace Faker\ORM\Mandango;

use Mandango\Mandango;





class Populator
{
protected $generator;
protected $mandango;
protected $entities = array();
protected $quantities = array();





public function __construct(\Faker\Generator $generator, Mandango $mandango)
{
$this->generator = $generator;
$this->mandango = $mandango;
}







public function addEntity($entity, $number, $customColumnFormatters = array())
{
if (!$entity instanceof \Faker\ORM\Mandango\EntityPopulator) {
$entity = new \Faker\ORM\Mandango\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator, $this->mandango));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}






public function execute()
{
$insertedEntities = array();
foreach ($this->quantities as $class => $number) {
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($this->mandango, $insertedEntities);
}
}
$this->mandango->flush();

return $insertedEntities;
}
}
<?php

namespace Faker\ORM\Spot;

use Faker\Generator;
use Faker\Guesser\Name;
use Spot\Locator;
use Spot\Mapper;
use Spot\Relation\BelongsTo;




class EntityPopulator
{



const RELATED_FETCH_COUNT = 10;




protected $mapper;




protected $locator;




protected $columnFormatters = array();



protected $modifiers = array();




protected $useExistingData = false;








public function __construct(Mapper $mapper, Locator $locator, $useExistingData = false)
{
$this->mapper = $mapper;
$this->locator = $locator;
$this->useExistingData = $useExistingData;
}




public function getMapper()
{
return $this->mapper;
}




public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}




public function getColumnFormatters()
{
return $this->columnFormatters;
}




public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}




public function setModifiers(array $modifiers)
{
$this->modifiers = $modifiers;
}




public function getModifiers()
{
return $this->modifiers;
}




public function mergeModifiersWith(array $modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}





public function guessColumnFormatters(Generator $generator)
{
$formatters = array();
$nameGuesser = new Name($generator);
$columnTypeGuesser = new ColumnTypeGuesser($generator);
$fields = $this->mapper->fields();
foreach ($fields as $fieldName => $field) {
if ($field['primary'] === true) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($fieldName)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($field)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
$entityName = $this->mapper->entity();
$entity = $this->mapper->build([]);
$relations = $entityName::relations($this->mapper, $entity);
foreach ($relations as $relation) {

 if ($relation instanceof BelongsTo) {

$fieldName = $relation->localKey();
$entityName = $relation->entityName();
$field = $fields[$fieldName];
$required = $field['required'];

$locator = $this->locator;

$formatters[$fieldName] = function ($inserted) use ($required, $entityName, $locator) {
if (!empty($inserted[$entityName])) {
return $inserted[$entityName][mt_rand(0, count($inserted[$entityName]) - 1)]->getId();
} else {
if ($required && $this->useExistingData) {

 
 $mapper = $this->locator->mapper($entityName);
$records = $mapper->all()->limit(self::RELATED_FETCH_COUNT)->toArray();
if (empty($records)) {
return null;
}
$id = $records[mt_rand(0, count($records) - 1)]['id'];

return $id;
} else {
return null;
}
}
};

}
}

return $formatters;
}







public function execute($insertedEntities)
{
$obj = $this->mapper->build([]);

$this->fillColumns($obj, $insertedEntities);
$this->callMethods($obj, $insertedEntities);

$this->mapper->insert($obj);


return $obj;
}





private function fillColumns($obj, $insertedEntities)
{
foreach ($this->columnFormatters as $field => $format) {
if (null !== $format) {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
$obj->set($field, $value);
}
}
}





private function callMethods($obj, $insertedEntities)
{
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
}
}
<?php

namespace Faker\ORM\Spot;

use Faker\Generator;

class ColumnTypeGuesser
{
protected $generator;






public function __construct(Generator $generator)
{
$this->generator = $generator;
}





public function guessFormat(array $field)
{
$generator = $this->generator;
$type = $field['type'];
switch ($type) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'decimal':
$size = isset($field['precision']) ? $field['precision'] : 2;

return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case 'smallint':
return function () use ($generator) {
return $generator->numberBetween(0, 65535);
};
case 'integer':
return function () use ($generator) {
return $generator->numberBetween(0, intval('2147483647'));
};
case 'bigint':
return function () use ($generator) {
return $generator->numberBetween(0, intval('18446744073709551615'));
};
case 'float':
return function () use ($generator) {
return $generator->randomFloat(null, 0, intval('4294967295'));
};
case 'string':
$size = isset($field['length']) ? $field['length'] : 255;

return function () use ($generator, $size) {
return $generator->text($size);
};
case 'text':
return function () use ($generator) {
return $generator->text;
};
case 'datetime':
case 'date':
case 'time':
return function () use ($generator) {
return $generator->datetime;
};
default:

 return null;
}
}
}
<?php


namespace Faker\ORM\Spot;

use Spot\Locator;




class Populator
{
protected $generator;
protected $locator;
protected $entities = array();
protected $quantities = array();






public function __construct(\Faker\Generator $generator, Locator $locator = null)
{
$this->generator = $generator;
$this->locator = $locator;
}










public function addEntity(
$entityName,
$number,
$customColumnFormatters = array(),
$customModifiers = array(),
$useExistingData = false
) {
$mapper = $this->locator->mapper($entityName);
if (null === $mapper) {
throw new \InvalidArgumentException("No mapper can be found for entity " . $entityName);
}
$entity = new EntityPopulator($mapper, $this->locator, $useExistingData);

$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->mergeModifiersWith($customModifiers);

$this->entities[$entityName] = $entity;
$this->quantities[$entityName] = $number;
}








public function execute($locator = null)
{
if (null === $locator) {
$locator = $this->locator;
}
if (null === $locator) {
throw new \InvalidArgumentException("No entity manager passed to Spot Populator.");
}

$insertedEntities = array();
foreach ($this->quantities as $entityName => $number) {
for ($i = 0; $i < $number; $i++) {
$insertedEntities[$entityName][] = $this->entities[$entityName]->execute(
$insertedEntities
);
}
}

return $insertedEntities;
}
}
<?php

namespace Faker\ORM\Propel;

use \Faker\Provider\Base;
use \ColumnMap;




class EntityPopulator
{
protected $class;
protected $columnFormatters = array();
protected $modifiers = array();






public function __construct($class)
{
$this->class = $class;
}




public function getClass()
{
return $this->class;
}

public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}




public function getColumnFormatters()
{
return $this->columnFormatters;
}

public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}





public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = array();
$class = $this->class;
$peerClass = $class::PEER;
$tableMap = $peerClass::getTableMap();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Propel\ColumnTypeGuesser($generator);
foreach ($tableMap->getColumns() as $columnMap) {

 if ($this->isColumnBehavior($columnMap)) {
continue;
}
if ($columnMap->isForeignKey()) {
$relatedClass = $columnMap->getRelation()->getForeignTable()->getClassname();
$formatters[$columnMap->getPhpName()] = function ($inserted) use ($relatedClass) {
return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null;
};
continue;
}
if ($columnMap->isPrimaryKey()) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName(), $columnMap->getSize())) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($columnMap)) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
}

return $formatters;
}





protected function isColumnBehavior(ColumnMap $columnMap)
{
foreach ($columnMap->getTable()->getBehaviors() as $name => $params) {
$columnName = Base::toLower($columnMap->getName());
switch ($name) {
case 'nested_set':
$columnNames = array($params['left_column'], $params['right_column'], $params['level_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
case 'timestampable':
$columnNames = array($params['create_column'], $params['update_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
}
}

return false;
}

public function setModifiers($modifiers)
{
$this->modifiers = $modifiers;
}




public function getModifiers()
{
return $this->modifiers;
}

public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}





public function guessModifiers(\Faker\Generator $generator)
{
$modifiers = array();
$class = $this->class;
$peerClass = $class::PEER;
$tableMap = $peerClass::getTableMap();
foreach ($tableMap->getBehaviors() as $name => $params) {
switch ($name) {
case 'nested_set':
$modifiers['nested_set'] = function ($obj, $inserted) use ($class, $generator) {
if (isset($inserted[$class])) {
$queryClass = $class . 'Query';
$parent = $queryClass::create()->findPk($generator->randomElement($inserted[$class]));
$obj->insertAsLastChildOf($parent);
} else {
$obj->makeRoot();
}
};
break;
case 'sortable':
$modifiers['sortable'] = function ($obj, $inserted) use ($class) {
$maxRank = isset($inserted[$class]) ? count($inserted[$class]) : 0;
$obj->insertAtRank(mt_rand(1, $maxRank + 1));
};
break;
}
}

return $modifiers;
}




public function execute($con, $insertedEntities)
{
$obj = new $this->class();
foreach ($this->getColumnFormatters() as $column => $format) {
if (null !== $format) {
$obj->setByName($column, is_callable($format) ? $format($insertedEntities, $obj) : $format);
}
}
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
$obj->save($con);

return $obj->getPrimaryKey();
}
}
<?php

namespace Faker\ORM\Propel;

use \PropelColumnTypes;
use \ColumnMap;

class ColumnTypeGuesser
{
protected $generator;




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}





public function guessFormat(ColumnMap $column)
{
$generator = $this->generator;
if ($column->isTemporal()) {
if ($column->isEpochTemporal()) {
return function () use ($generator) {
return $generator->dateTime;
};
} else {
return function () use ($generator) {
return $generator->dateTimeAD;
};
}
}
$type = $column->getType();
switch ($type) {
case PropelColumnTypes::BOOLEAN:
case PropelColumnTypes::BOOLEAN_EMU:
return function () use ($generator) {
return $generator->boolean;
};
case PropelColumnTypes::NUMERIC:
case PropelColumnTypes::DECIMAL:
$size = $column->getSize();

return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case PropelColumnTypes::TINYINT:
return function () {
return mt_rand(0, 127);
};
case PropelColumnTypes::SMALLINT:
return function () {
return mt_rand(0, 32767);
};
case PropelColumnTypes::INTEGER:
return function () {
return mt_rand(0, intval('2147483647'));
};
case PropelColumnTypes::BIGINT:
return function () {
return mt_rand(0, intval('9223372036854775807'));
};
case PropelColumnTypes::FLOAT:
return function () {
return mt_rand(0, intval('2147483647'))/mt_rand(1, intval('2147483647'));
};
case PropelColumnTypes::DOUBLE:
case PropelColumnTypes::REAL:
return function () {
return mt_rand(0, intval('9223372036854775807'))/mt_rand(1, intval('9223372036854775807'));
};
case PropelColumnTypes::CHAR:
case PropelColumnTypes::VARCHAR:
case PropelColumnTypes::BINARY:
case PropelColumnTypes::VARBINARY:
$size = $column->getSize();

return function () use ($generator, $size) {
return $generator->text($size);
};
case PropelColumnTypes::LONGVARCHAR:
case PropelColumnTypes::LONGVARBINARY:
case PropelColumnTypes::CLOB:
case PropelColumnTypes::CLOB_EMU:
case PropelColumnTypes::BLOB:
return function () use ($generator) {
return $generator->text;
};
case PropelColumnTypes::ENUM:
$valueSet = $column->getValueSet();

return function () use ($generator, $valueSet) {
return $generator->randomElement($valueSet);
};
case PropelColumnTypes::OBJECT:
case PropelColumnTypes::PHP_ARRAY:
default:

 return null;
}
}
}
<?php

namespace Faker\ORM\Propel;





class Populator
{
protected $generator;
protected $entities = array();
protected $quantities = array();




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}







public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array())
{
if (!$entity instanceof \Faker\ORM\Propel\EntityPopulator) {
$entity = new \Faker\ORM\Propel\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->setModifiers($entity->guessModifiers($this->generator));
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}








public function execute($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$isInstancePoolingEnabled = \Propel::isInstancePoolingEnabled();
\Propel::disableInstancePooling();
$insertedEntities = array();
$con->beginTransaction();
foreach ($this->quantities as $class => $number) {
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($con, $insertedEntities);
}
}
$con->commit();
if ($isInstancePoolingEnabled) {
\Propel::enableInstancePooling();
}

return $insertedEntities;
}

protected function getConnection()
{

 $class = key($this->entities);

if (!$class) {
throw new \RuntimeException('No class found from entities. Did you add entities to the Populator ?');
}

$peer = $class::PEER;

return \Propel::getConnection($peer::DATABASE_NAME, \Propel::CONNECTION_WRITE);
}
}
<?php

namespace Faker\ORM\Propel2;

use \Faker\Provider\Base;
use \Propel\Runtime\Map\ColumnMap;




class EntityPopulator
{
protected $class;
protected $columnFormatters = array();
protected $modifiers = array();






public function __construct($class)
{
$this->class = $class;
}




public function getClass()
{
return $this->class;
}

public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}




public function getColumnFormatters()
{
return $this->columnFormatters;
}

public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}





public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = array();
$class = $this->class;
$peerClass = $class::TABLE_MAP;
$tableMap = $peerClass::getTableMap();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Propel2\ColumnTypeGuesser($generator);
foreach ($tableMap->getColumns() as $columnMap) {

 if ($this->isColumnBehavior($columnMap)) {
continue;
}
if ($columnMap->isForeignKey()) {
$relatedClass = $columnMap->getRelation()->getForeignTable()->getClassname();
$formatters[$columnMap->getPhpName()] = function ($inserted) use ($relatedClass) {
$relatedClass = trim($relatedClass, "\\");
return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null;
};
continue;
}
if ($columnMap->isPrimaryKey()) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName(), $columnMap->getSize())) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($columnMap)) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
}

return $formatters;
}





protected function isColumnBehavior(ColumnMap $columnMap)
{
foreach ($columnMap->getTable()->getBehaviors() as $name => $params) {
$columnName = Base::toLower($columnMap->getName());
switch ($name) {
case 'nested_set':
$columnNames = array($params['left_column'], $params['right_column'], $params['level_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
case 'timestampable':
$columnNames = array($params['create_column'], $params['update_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
}
}

return false;
}

public function setModifiers($modifiers)
{
$this->modifiers = $modifiers;
}




public function getModifiers()
{
return $this->modifiers;
}

public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}





public function guessModifiers(\Faker\Generator $generator)
{
$modifiers = array();
$class = $this->class;
$peerClass = $class::TABLE_MAP;
$tableMap = $peerClass::getTableMap();
foreach ($tableMap->getBehaviors() as $name => $params) {
switch ($name) {
case 'nested_set':
$modifiers['nested_set'] = function ($obj, $inserted) use ($class, $generator) {
if (isset($inserted[$class])) {
$queryClass = $class . 'Query';
$parent = $queryClass::create()->findPk($generator->randomElement($inserted[$class]));
$obj->insertAsLastChildOf($parent);
} else {
$obj->makeRoot();
}
};
break;
case 'sortable':
$modifiers['sortable'] = function ($obj, $inserted) use ($class) {
$maxRank = isset($inserted[$class]) ? count($inserted[$class]) : 0;
$obj->insertAtRank(mt_rand(1, $maxRank + 1));
};
break;
}
}

return $modifiers;
}




public function execute($con, $insertedEntities)
{
$obj = new $this->class();
foreach ($this->getColumnFormatters() as $column => $format) {
if (null !== $format) {
$obj->setByName($column, is_callable($format) ? $format($insertedEntities, $obj) : $format);
}
}
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
$obj->save($con);

return $obj->getPrimaryKey();
}
}
<?php

namespace Faker\ORM\Propel2;

use \Propel\Generator\Model\PropelTypes;
use \Propel\Runtime\Map\ColumnMap;

class ColumnTypeGuesser
{
protected $generator;




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}





public function guessFormat(ColumnMap $column)
{
$generator = $this->generator;
if ($column->isTemporal()) {
if ($column->getType() == PropelTypes::BU_DATE || $column->getType() == PropelTypes::BU_TIMESTAMP) {
return function () use ($generator) {
return $generator->dateTime;
};
} else {
return function () use ($generator) {
return $generator->dateTimeAD;
};
}
}
$type = $column->getType();
switch ($type) {
case PropelTypes::BOOLEAN:
case PropelTypes::BOOLEAN_EMU:
return function () use ($generator) {
return $generator->boolean;
};
case PropelTypes::NUMERIC:
case PropelTypes::DECIMAL:
$size = $column->getSize();

return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case PropelTypes::TINYINT:
return function () {
return mt_rand(0, 127);
};
case PropelTypes::SMALLINT:
return function () {
return mt_rand(0, 32767);
};
case PropelTypes::INTEGER:
return function () {
return mt_rand(0, intval('2147483647'));
};
case PropelTypes::BIGINT:
return function () {
return mt_rand(0, intval('9223372036854775807'));
};
case PropelTypes::FLOAT:
return function () {
return mt_rand(0, intval('2147483647'))/mt_rand(1, intval('2147483647'));
};
case PropelTypes::DOUBLE:
case PropelTypes::REAL:
return function () {
return mt_rand(0, intval('9223372036854775807'))/mt_rand(1, intval('9223372036854775807'));
};
case PropelTypes::CHAR:
case PropelTypes::VARCHAR:
case PropelTypes::BINARY:
case PropelTypes::VARBINARY:
$size = $column->getSize();

return function () use ($generator, $size) {
return $generator->text($size);
};
case PropelTypes::LONGVARCHAR:
case PropelTypes::LONGVARBINARY:
case PropelTypes::CLOB:
case PropelTypes::CLOB_EMU:
case PropelTypes::BLOB:
return function () use ($generator) {
return $generator->text;
};
case PropelTypes::ENUM:
$valueSet = $column->getValueSet();

return function () use ($generator, $valueSet) {
return $generator->randomElement($valueSet);
};
case PropelTypes::OBJECT:
case PropelTypes::PHP_ARRAY:
default:

 return null;
}
}
}
<?php

namespace Faker\ORM\Propel2;

use Propel\Runtime\Propel;
use Propel\Runtime\ServiceContainer\ServiceContainerInterface;





class Populator
{
protected $generator;
protected $entities = array();
protected $quantities = array();




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}







public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array())
{
if (!$entity instanceof \Faker\ORM\Propel2\EntityPopulator) {
$entity = new \Faker\ORM\Propel2\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->setModifiers($entity->guessModifiers($this->generator));
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}








public function execute($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$isInstancePoolingEnabled = Propel::isInstancePoolingEnabled();
Propel::disableInstancePooling();
$insertedEntities = array();
$con->beginTransaction();
foreach ($this->quantities as $class => $number) {
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($con, $insertedEntities);
}
}
$con->commit();
if ($isInstancePoolingEnabled) {
Propel::enableInstancePooling();
}

return $insertedEntities;
}

protected function getConnection()
{

 $class = key($this->entities);

if (!$class) {
throw new \RuntimeException('No class found from entities. Did you add entities to the Populator ?');
}

$peer = $class::TABLE_MAP;

return Propel::getConnection($peer::DATABASE_NAME, ServiceContainerInterface::CONNECTION_WRITE);
}
}
<?php

namespace Faker\ORM\CakePHP;

use Cake\ORM\TableRegistry;

class EntityPopulator
{
protected $class;
protected $connectionName;
protected $columnFormatters = [];
protected $modifiers = [];

public function __construct($class)
{
$this->class = $class;
}




public function __get($name)
{
return $this->{$name};
}




public function __set($name, $value)
{
$this->{$name} = $value;
}

public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}

public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}




public function guessColumnFormatters($populator)
{
$formatters = [];
$class = $this->class;
$table = $this->getTable($class);
$schema = $table->schema();
$pk = $schema->primaryKey();
$guessers = $populator->getGuessers() + ['ColumnTypeGuesser' => new ColumnTypeGuesser($populator->getGenerator())];
$isForeignKey = function ($column) use ($table) {
foreach ($table->associations()->type('BelongsTo') as $assoc) {
if ($column == $assoc->foreignKey()) {
return true;
}
}
return false;
};


foreach ($schema->columns() as $column) {
if ($column == $pk[0] || $isForeignKey($column)) {
continue;
}

foreach ($guessers as $guesser) {
if ($formatter = $guesser->guessFormat($column, $table)) {
$formatters[$column] = $formatter;
break;
}
}
}

return $formatters;
}




public function guessModifiers()
{
$modifiers = [];
$table = $this->getTable($this->class);

$belongsTo = $table->associations()->type('BelongsTo');
foreach ($belongsTo as $assoc) {
$modifiers['belongsTo' . $assoc->name()] = function ($data, $insertedEntities) use ($assoc) {
$table = $assoc->target();
$foreignModel = $table->alias();

$foreignKeys = [];
if (!empty($insertedEntities[$foreignModel])) {
$foreignKeys = $insertedEntities[$foreignModel];
} else {
$foreignKeys = $table->find('all')
->select(['id'])
->map(function ($row) {
return $row->id;
})
->toArray();
}

if (empty($foreignKeys)) {
throw new \Exception(sprintf('%s belongsTo %s, which seems empty at this point.', $this->getTable($this->class)->table(), $assoc->table()));
}

$foreignKey = $foreignKeys[array_rand($foreignKeys)];
$data[$assoc->foreignKey()] = $foreignKey;
return $data;
};
}



return $modifiers;
}




public function execute($class, $insertedEntities, $options = [])
{
$table = $this->getTable($class);
$entity = $table->newEntity();

foreach ($this->columnFormatters as $column => $format) {
if (!is_null($format)) {
$entity->{$column} = is_callable($format) ? $format($insertedEntities, $table) : $format;
}
}

foreach ($this->modifiers as $modifier) {
$entity = $modifier($entity, $insertedEntities);
}

if (!$entity = $table->save($entity, $options)) {
throw new \RuntimeException("Failed saving $class record");
}

$pk = $table->primaryKey();
if (is_string($pk)) {
return $entity->{$pk};
}

return $entity->{$pk[0]};
}

public function setConnection($name)
{
$this->connectionName = $name;
}

protected function getTable($class)
{
$options = [];
if (!empty($this->connectionName)) {
$options['connection'] = $this->connectionName;
}
return TableRegistry::get($class, $options);
}
}
<?php

namespace Faker\ORM\CakePHP;

class ColumnTypeGuesser
{
protected $generator;

public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}




public function guessFormat($column, $table)
{
$generator = $this->generator;
$schema = $table->schema();

switch ($schema->columnType($column)) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'integer':
return function () {
return mt_rand(0, intval('2147483647'));
};
case 'biginteger':
return function () {
return mt_rand(0, intval('9223372036854775807'));
};
case 'decimal':
case 'float':
return function () use ($generator) {
return $generator->randomFloat();
};
case 'uuid':
return function () use ($generator) {
return $generator->uuid();
};
case 'string':
$columnData = $schema->column($column);
$length = $columnData['length'];
return function () use ($generator, $length) {
return $generator->text($length);
};
case 'text':
return function () use ($generator) {
return $generator->text();
};
case 'date':
case 'datetime':
case 'timestamp':
case 'time':
return function () use ($generator) {
return $generator->datetime();
};

case 'binary':
default:
return null;
}
}
}
<?php

namespace Faker\ORM\CakePHP;

class Populator
{

protected $generator;
protected $entities = [];
protected $quantities = [];
protected $guessers = [];




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}




public function getGenerator()
{
return $this->generator;
}




public function getGuessers()
{
return $this->guessers;
}




public function removeGuesser($name)
{
if ($this->guessers[$name]) {
unset($this->guessers[$name]);
}
return $this;
}





public function addGuesser($class)
{
if (!is_object($class)) {
$class = new $class($this->generator);
}

if (!method_exists($class, 'guessFormat')) {
throw new \Exception('Missing required custom guesser method: ' . get_class($class) . '::guessFormat()');
}

$this->guessers[get_class($class)] = $class;
return $this;
}






public function addEntity($entity, $number, $customColumnFormatters = [], $customModifiers = [])
{
if (!$entity instanceof EntityPopulator) {
$entity = new EntityPopulator($entity);
}

$entity->columnFormatters = $entity->guessColumnFormatters($this);
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}

$entity->modifiers = $entity->guessModifiers($this);
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}

$class = $entity->class;
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
return $this;
}





public function execute($options = [])
{
$insertedEntities = [];

foreach ($this->quantities as $class => $number) {
for ($i = 0; $i < $number; $i++) {
$insertedEntities[$class][] = $this->entities[$class]->execute($class, $insertedEntities, $options);
}
}

return $insertedEntities;
}
}
<?php

namespace Faker\ORM\Doctrine;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;




class EntityPopulator
{



protected $class;



protected $columnFormatters = array();



protected $modifiers = array();






public function __construct(ClassMetadata $class)
{
$this->class = $class;
}




public function getClass()
{
return $this->class->getName();
}




public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}




public function getColumnFormatters()
{
return $this->columnFormatters;
}

public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}




public function setModifiers(array $modifiers)
{
$this->modifiers = $modifiers;
}




public function getModifiers()
{
return $this->modifiers;
}




public function mergeModifiersWith(array $modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}





public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = array();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new ColumnTypeGuesser($generator);
foreach ($this->class->getFieldNames() as $fieldName) {
if ($this->class->isIdentifier($fieldName) || !$this->class->hasField($fieldName)) {
continue;
}

$size = isset($this->class->fieldMappings[$fieldName]['length']) ? $this->class->fieldMappings[$fieldName]['length'] : null;
if ($formatter = $nameGuesser->guessFormat($fieldName, $size)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($fieldName, $this->class)) {
$formatters[$fieldName] = $formatter;
continue;
}
}

foreach ($this->class->getAssociationNames() as $assocName) {
if ($this->class->isCollectionValuedAssociation($assocName)) {
continue;
}

$relatedClass = $this->class->getAssociationTargetClass($assocName);

$unique = $optional = false;
if ($this->class instanceof \Doctrine\ORM\Mapping\ClassMetadata) {
$mappings = $this->class->getAssociationMappings();
foreach ($mappings as $mapping) {
if ($mapping['targetEntity'] == $relatedClass) {
if ($mapping['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_ONE) {
$unique = true;
$optional = isset($mapping['joinColumns'][0]['nullable']) ? $mapping['joinColumns'][0]['nullable'] : false;
break;
}
}
}
} elseif ($this->class instanceof \Doctrine\ODM\MongoDB\Mapping\ClassMetadata) {
$mappings = $this->class->associationMappings;
foreach ($mappings as $mapping) {
if ($mapping['targetDocument'] == $relatedClass) {
if ($mapping['type'] == \Doctrine\ODM\MongoDB\Mapping\ClassMetadata::ONE && $mapping['association'] == \Doctrine\ODM\MongoDB\Mapping\ClassMetadata::REFERENCE_ONE) {
$unique = true;
$optional = isset($mapping['nullable']) ? $mapping['nullable'] : false;
break;
}
}
}
}

$index = 0;
$formatters[$assocName] = function ($inserted) use ($relatedClass, &$index, $unique, $optional) {

if (isset($inserted[$relatedClass])) {
if ($unique) {
$related = null;
if (isset($inserted[$relatedClass][$index]) || !$optional) {
$related = $inserted[$relatedClass][$index];
}

$index++;

return $related;
}

return $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)];
}

return null;
};
}

return $formatters;
}







public function execute(ObjectManager $manager, $insertedEntities, $generateId = false)
{
$obj = $this->class->newInstance();

$this->fillColumns($obj, $insertedEntities);
$this->callMethods($obj, $insertedEntities);

if ($generateId) {
$idsName = $this->class->getIdentifier();
foreach ($idsName as $idName) {
$id = $this->generateId($obj, $idName, $manager);
$this->class->reflFields[$idName]->setValue($obj, $id);
}
}

$manager->persist($obj);

return $obj;
}

private function fillColumns($obj, $insertedEntities)
{
foreach ($this->columnFormatters as $field => $format) {
if (null !== $format) {

 try {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
} catch (\InvalidArgumentException $ex) {
throw new \InvalidArgumentException(sprintf(
"Failed to generate a value for %s::%s: %s",
get_class($obj),
$field,
$ex->getMessage()
));
}

 $setter = sprintf("set%s", ucfirst($field));
if (method_exists($obj, $setter)) {
$obj->$setter($value);
} else {
$this->class->reflFields[$field]->setValue($obj, $value);
}
}
}
}

private function callMethods($obj, $insertedEntities)
{
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
}





private function generateId($obj, $column, ObjectManager $manager)
{

$repository = $manager->getRepository(get_class($obj));
$result = $repository->createQueryBuilder('e')
->select(sprintf('e.%s', $column))
->getQuery()
->execute();
$ids = array_map('current', $result->toArray());

$id = null;
do {
$id = mt_rand();
} while (in_array($id, $ids));

return $id;
}
}
<?php

namespace Faker\ORM\Doctrine;

use Doctrine\Common\Persistence\Mapping\ClassMetadata;

class ColumnTypeGuesser
{
protected $generator;




public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}





public function guessFormat($fieldName, ClassMetadata $class)
{
$generator = $this->generator;
$type = $class->getTypeOfField($fieldName);
switch ($type) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'decimal':
$size = isset($class->fieldMappings[$fieldName]['precision']) ? $class->fieldMappings[$fieldName]['precision'] : 2;

return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case 'smallint':
return function () {
return mt_rand(0, 65535);
};
case 'integer':
return function () {
return mt_rand(0, intval('2147483647'));
};
case 'bigint':
return function () {
return mt_rand(0, intval('18446744073709551615'));
};
case 'float':
return function () {
return mt_rand(0, intval('4294967295'))/mt_rand(1, intval('4294967295'));
};
case 'string':
$size = isset($class->fieldMappings[$fieldName]['length']) ? $class->fieldMappings[$fieldName]['length'] : 255;

return function () use ($generator, $size) {
return $generator->text($size);
};
case 'text':
return function () use ($generator) {
return $generator->text;
};
case 'datetime':
case 'date':
case 'time':
return function () use ($generator) {
return $generator->datetime;
};
default:

 return null;
}
}
}
<?php

namespace Faker\ORM\Doctrine;

use Doctrine\Common\Persistence\ObjectManager;





class Populator
{
protected $generator;
protected $manager;
protected $entities = array();
protected $quantities = array();
protected $generateId = array();





public function __construct(\Faker\Generator $generator, ObjectManager $manager = null)
{
$this->generator = $generator;
$this->manager = $manager;
}







public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array(), $generateId = false)
{
if (!$entity instanceof \Faker\ORM\Doctrine\EntityPopulator) {
if (null === $this->manager) {
throw new \InvalidArgumentException("No entity manager passed to Doctrine Populator.");
}
$entity = new \Faker\ORM\Doctrine\EntityPopulator($this->manager->getClassMetadata($entity));
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->mergeModifiersWith($customModifiers);
$this->generateId[$entity->getClass()] = $generateId;

$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}








public function execute($entityManager = null)
{
if (null === $entityManager) {
$entityManager = $this->manager;
}
if (null === $entityManager) {
throw new \InvalidArgumentException("No entity manager passed to Doctrine Populator.");
}

$insertedEntities = array();
foreach ($this->quantities as $class => $number) {
$generateId = $this->generateId[$class];
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($entityManager, $insertedEntities, $generateId);
}
$entityManager->flush();
}

return $insertedEntities;
}
}
<?php

namespace Faker;





class UniqueGenerator
{
protected $generator;
protected $maxRetries;
protected $uniques = array();





public function __construct(Generator $generator, $maxRetries = 10000)
{
$this->generator = $generator;
$this->maxRetries = $maxRetries;
}






public function __get($attribute)
{
return $this->__call($attribute, array());
}







public function __call($name, $arguments)
{
if (!isset($this->uniques[$name])) {
$this->uniques[$name] = array();
}
$i = 0;
do {
$res = call_user_func_array(array($this->generator, $name), $arguments);
$i++;
if ($i > $this->maxRetries) {
throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a unique value', $this->maxRetries));
}
} while (array_key_exists(serialize($res), $this->uniques[$name]));
$this->uniques[$name][serialize($res)]= null;

return $res;
}
}
<?php

namespace Faker\Calculator;

class Iban
{






public static function checksum($iban)
{

 $checkString = substr($iban, 4) . substr($iban, 0, 2) . '00';


 $checkString = preg_replace_callback('/[A-Z]/', array('self','alphaToNumberCallback'), $checkString);


 $checksum = 98 - self::mod97($checkString);

return str_pad($checksum, 2, '0', STR_PAD_LEFT);
}






private static function alphaToNumberCallback($match)
{
return self::alphaToNumber($match[0]);
}







public static function alphaToNumber($char)
{
return ord($char) - 55;
}







public static function mod97($number)
{
$checksum = (int)$number[0];
for ($i = 1, $size = strlen($number); $i < $size; $i++) {
$checksum = (10 * $checksum + (int) $number[$i]) % 97;
}
return $checksum;
}







public static function isValid($iban)
{
return self::checksum($iban) === substr($iban, 2, 2);
}
}
<?php

namespace Faker\Calculator;

use InvalidArgumentException;









class Luhn
{




private static function checksum($number)
{
$number = (string) $number;
$length = strlen($number);
$sum = 0;
for ($i = $length - 1; $i >= 0; $i -= 2) {
$sum += $number{$i};
}
for ($i = $length - 2; $i >= 0; $i -= 2) {
$sum += array_sum(str_split($number{$i} * 2));
}

return $sum % 10;
}





public static function computeCheckDigit($partialNumber)
{
$checkDigit = self::checksum($partialNumber . '0');
if ($checkDigit === 0) {
return 0;
}

return (string) (10 - $checkDigit);
}







public static function isValid($number)
{
return self::checksum($number) === 0;
}








public static function generateLuhnNumber($partialValue)
{
if (!preg_match('/^\d+$/', $partialValue)) {
throw new InvalidArgumentException('Argument should be an integer.');
}
return $partialValue . Luhn::computeCheckDigit($partialValue);
}
}
<?php
namespace Faker\Calculator;

class Inn
{








public static function checksum($inn)
{
$multipliers = array(1 => 2, 2 => 4, 3 => 10, 4 => 3, 5 => 5, 6 => 9, 7 => 4, 8 => 6, 9 => 8);
$sum = 0;
for ($i = 1; $i <= 9; $i++) {
$sum += intval(substr($inn, $i-1, 1)) * $multipliers[$i];
}
return strval(($sum % 11) % 10);
}







public static function isValid($inn)
{
return self::checksum(substr($inn, 0, -1)) === substr($inn, -1, 1);
}
}
<?php

namespace Faker;

class Documentor
{
protected $generator;




public function __construct(Generator $generator)
{
$this->generator = $generator;
}




public function getFormatters()
{
$formatters = array();
$providers = array_reverse($this->generator->getProviders());
$providers[]= new Provider\Base($this->generator);
foreach ($providers as $provider) {
$providerClass = get_class($provider);
$formatters[$providerClass] = array();
$refl = new \ReflectionObject($provider);
foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflmethod) {
if ($reflmethod->getDeclaringClass()->getName() == 'Faker\Provider\Base' && $providerClass != 'Faker\Provider\Base') {
continue;
}
$methodName = $reflmethod->name;
if ($reflmethod->isConstructor()) {
continue;
}
$parameters = array();
foreach ($reflmethod->getParameters() as $reflparameter) {
$parameter = '$'. $reflparameter->getName();
if ($reflparameter->isDefaultValueAvailable()) {
$parameter .= ' = ' . var_export($reflparameter->getDefaultValue(), true);
}
$parameters []= $parameter;
}
$parameters = $parameters ? '('. join(', ', $parameters) . ')' : '';
try {
$example = $this->generator->format($methodName);
} catch (\InvalidArgumentException $e) {
$example = '';
}
if (is_array($example)) {
$example = "array('". join("', '", $example) . "')";
} elseif ($example instanceof \DateTime) {
$example = "DateTime('" . $example->format('Y-m-d H:i:s') . "')";
} elseif ($example instanceof Generator || $example instanceof UniqueGenerator) { 
 $example = '';
} else {
$example = var_export($example, true);
}
$formatters[$providerClass][$methodName . $parameters] = $example;
}
}

return $formatters;
}
}
<?php

namespace Faker;





class DefaultGenerator
{
protected $default;

public function __construct($default = null)
{
$this->default = $default;
}






public function __get($attribute)
{
return $this->default;
}







public function __call($method, $attributes)
{
return $this->default;
}
}
<?php

namespace Faker;

class Factory
{
const DEFAULT_LOCALE = 'en_US';

protected static $defaultProviders = array('Address', 'Barcode', 'Biased', 'Color', 'Company', 'DateTime', 'File', 'HtmlLorem', 'Image', 'Internet', 'Lorem', 'Miscellaneous', 'Payment', 'Person', 'PhoneNumber', 'Text', 'UserAgent', 'Uuid');







public static function create($locale = self::DEFAULT_LOCALE)
{
$generator = new Generator();
foreach (static::$defaultProviders as $provider) {
$providerClassName = self::getProviderClassname($provider, $locale);
$generator->addProvider(new $providerClassName($generator));
}

return $generator;
}






protected static function getProviderClassname($provider, $locale = '')
{
if ($providerClass = self::findProviderClassname($provider, $locale)) {
return $providerClass;
}

 if ($providerClass = self::findProviderClassname($provider, static::DEFAULT_LOCALE)) {
return $providerClass;
}

 if ($providerClass = self::findProviderClassname($provider)) {
return $providerClass;
}
throw new \InvalidArgumentException(sprintf('Unable to find provider "%s" with locale "%s"', $provider, $locale));
}






protected static function findProviderClassname($provider, $locale = '')
{
$providerClass = 'Faker\\' . ($locale ? sprintf('Provider\%s\%s', $locale, $provider) : sprintf('Provider\%s', $provider));
if (class_exists($providerClass, true)) {
return $providerClass;
}
}
}
<?php

namespace Faker;





class ValidGenerator
{
protected $generator;
protected $validator;
protected $maxRetries;






public function __construct(Generator $generator, $validator = null, $maxRetries = 10000)
{
if (is_null($validator)) {
$validator = function () {
return true;
};
} elseif (!is_callable($validator)) {
throw new \InvalidArgumentException('valid() only accepts callables as first argument');
}
$this->generator = $generator;
$this->validator = $validator;
$this->maxRetries = $maxRetries;
}







public function __get($attribute)
{
return $this->__call($attribute, array());
}








public function __call($name, $arguments)
{
$i = 0;
do {
$res = call_user_func_array(array($this->generator, $name), $arguments);
$i++;
if ($i > $this->maxRetries) {
throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a valid value', $this->maxRetries));
}
} while (!call_user_func($this->validator, $res));

return $res;
}
}
<?php

namespace Faker;




























































































































































































class Generator
{
protected $providers = array();
protected $formatters = array();

public function addProvider($provider)
{
array_unshift($this->providers, $provider);
}

public function getProviders()
{
return $this->providers;
}

public function seed($seed = null)
{
if ($seed === null) {
mt_srand();
} else {
if (PHP_VERSION_ID < 70100) {
mt_srand((int) $seed);
} else {
mt_srand((int) $seed, MT_RAND_PHP);
}
}
}

public function format($formatter, $arguments = array())
{
return call_user_func_array($this->getFormatter($formatter), $arguments);
}






public function getFormatter($formatter)
{
if (isset($this->formatters[$formatter])) {
return $this->formatters[$formatter];
}
foreach ($this->providers as $provider) {
if (method_exists($provider, $formatter)) {
$this->formatters[$formatter] = array($provider, $formatter);

return $this->formatters[$formatter];
}
}
throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter));
}







public function parse($string)
{
return preg_replace_callback('/\{\{\s?(\w+)\s?\}\}/u', array($this, 'callFormatWithMatches'), $string);
}

protected function callFormatWithMatches($matches)
{
return $this->format($matches[1]);
}






public function __get($attribute)
{
return $this->format($attribute);
}







public function __call($method, $attributes)
{
return $this->format($method, $attributes);
}
}
<?php








spl_autoload_register(function ($className) {
$className = ltrim($className, '\\');
$fileName = '';
if ($lastNsPos = strripos($className, '\\')) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName = __DIR__ . DIRECTORY_SEPARATOR . $fileName . $className . '.php';
if (file_exists($fileName)) {
require $fileName;

return true;
}

return false;
});
<?php










namespace Symfony\Component\Yaml;









class Unescaper
{








const ENCODING = 'UTF-8';




const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';








public function unescapeSingleQuotedString($value)
{
return str_replace('\'\'', '\'', $value);
}








public function unescapeDoubleQuotedString($value)
{
$self = $this;
$callback = function ($match) use ($self) {
return $self->unescapeCharacter($match[0]);
};


 return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
}











public function unescapeCharacter($value)
{
switch ($value[1]) {
case '0':
return "\x0";
case 'a':
return "\x7";
case 'b':
return "\x8";
case 't':
return "\t";
case "\t":
return "\t";
case 'n':
return "\n";
case 'v':
return "\xB";
case 'f':
return "\xC";
case 'r':
return "\r";
case 'e':
return "\x1B";
case ' ':
return ' ';
case '"':
return '"';
case '/':
return '/';
case '\\':
return '\\';
case 'N':

 return "\xC2\x85";
case '_':

 return "\xC2\xA0";
case 'L':

 return "\xE2\x80\xA8";
case 'P':

 return "\xE2\x80\xA9";
case 'x':
return self::utf8chr(hexdec(substr($value, 2, 2)));
case 'u':
return self::utf8chr(hexdec(substr($value, 2, 4)));
case 'U':
return self::utf8chr(hexdec(substr($value, 2, 8)));
default:
@trigger_error('Not escaping a backslash in a double-quoted string is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', E_USER_DEPRECATED);

return $value;
}
}








private static function utf8chr($c)
{
if (0x80 > $c %= 0x200000) {
return chr($c);
}
if (0x800 > $c) {
return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
}
if (0x10000 > $c) {
return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
}

return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
}
}
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Exception\DumpException;






class Inline
{
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')';

private static $exceptionOnInvalidType = false;
private static $objectSupport = false;
private static $objectForMap = false;














public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
{
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
self::$objectSupport = $objectSupport;
self::$objectForMap = $objectForMap;

$value = trim($value);

if ('' === $value) {
return '';
}

if (2  & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}

$i = 0;
switch ($value[0]) {
case '[':
$result = self::parseSequence($value, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $i, $references);
++$i;
break;
default:
$result = self::parseScalar($value, null, array('"', "'"), $i, true, $references);
}


 if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
}

if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}

return $result;
}












public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
{
switch (true) {
case is_resource($value):
if ($exceptionOnInvalidType) {
throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
}

return 'null';
case is_object($value):
if ($objectSupport) {
return '!php/object:'.serialize($value);
}

if ($exceptionOnInvalidType) {
throw new DumpException('Object support when dumping a YAML file has been disabled.');
}

return 'null';
case is_array($value):
return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
case null === $value:
return 'null';
case true === $value:
return 'true';
case false === $value:
return 'false';
case ctype_digit($value):
return is_string($value) ? "'$value'" : (int) $value;
case is_numeric($value):
$locale = setlocale(LC_NUMERIC, 0);
if (false !== $locale) {
setlocale(LC_NUMERIC, 'C');
}
if (is_float($value)) {
$repr = (string) $value;
if (is_infinite($value)) {
$repr = str_ireplace('INF', '.Inf', $repr);
} elseif (floor($value) == $value && $repr == $value) {

 $repr = '!!float '.$repr;
}
} else {
$repr = is_string($value) ? "'$value'" : (string) $value;
}
if (false !== $locale) {
setlocale(LC_NUMERIC, $locale);
}

return $repr;
case '' == $value:
return "''";
case Escaper::requiresDoubleQuoting($value):
return Escaper::escapeWithDoubleQuotes($value);
case Escaper::requiresSingleQuoting($value):
case preg_match(self::getHexRegex(), $value):
case preg_match(self::getTimestampRegex(), $value):
return Escaper::escapeWithSingleQuotes($value);
default:
return $value;
}
}










public static function isHash(array $value)
{
$expectedKey = 0;

foreach ($value as $key => $val) {
if ($key !== $expectedKey++) {
return true;
}
}

return false;
}










private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
{

 if ($value && !self::isHash($value)) {
$output = array();
foreach ($value as $val) {
$output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
}

return sprintf('[%s]', implode(', ', $output));
}


 $output = array();
foreach ($value as $key => $val) {
$output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
}

return sprintf('{ %s }', implode(', ', $output));
}

















public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array())
{
if (in_array($scalar[$i], $stringDelimiters)) {

 $output = self::parseQuotedScalar($scalar, $i);

if (null !== $delimiters) {
$tmp = ltrim(substr($scalar, $i), ' ');
if (!in_array($tmp[0], $delimiters)) {
throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
}
}
} else {

 if (!$delimiters) {
$output = substr($scalar, $i);
$i += strlen($output);


 if (preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) {
$output = substr($output, 0, $match[0][1]);
}
} elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
$output = $match[1];
$i += strlen($output);
} else {
throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar));
}


 if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) {
@trigger_error(sprintf('Not quoting the scalar "%s" starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output, $output[0]), E_USER_DEPRECATED);


 
 }

if ($evaluate) {
$output = self::evaluateScalar($output, $references);
}
}

return $output;
}











private static function parseQuotedScalar($scalar, &$i)
{
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i)));
}

$output = substr($match[0], 1, strlen($match[0]) - 2);

$unescaper = new Unescaper();
if ('"' == $scalar[$i]) {
$output = $unescaper->unescapeDoubleQuotedString($output);
} else {
$output = $unescaper->unescapeSingleQuotedString($output);
}

$i += strlen($match[0]);

return $output;
}












private static function parseSequence($sequence, &$i = 0, $references = array())
{
$output = array();
$len = strlen($sequence);
++$i;


 while ($i < $len) {
switch ($sequence[$i]) {
case '[':

 $output[] = self::parseSequence($sequence, $i, $references);
break;
case '{':

 $output[] = self::parseMapping($sequence, $i, $references);
break;
case ']':
return $output;
case ',':
case ' ':
break;
default:
$isQuoted = in_array($sequence[$i], array('"', "'"));
$value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references);


 if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) {

 try {
$pos = 0;
$value = self::parseMapping('{'.$value.'}', $pos, $references);
} catch (\InvalidArgumentException $e) {

 }
}

$output[] = $value;

--$i;
}

++$i;
}

throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence));
}












private static function parseMapping($mapping, &$i = 0, $references = array())
{
$output = array();
$len = strlen($mapping);
++$i;


 while ($i < $len) {
switch ($mapping[$i]) {
case ' ':
case ',':
++$i;
continue 2;
case '}':
if (self::$objectForMap) {
return (object) $output;
}

return $output;
}


 $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);


 $done = false;

while ($i < $len) {
switch ($mapping[$i]) {
case '[':

 $value = self::parseSequence($mapping, $i, $references);

 
 
 if (!isset($output[$key])) {
$output[$key] = $value;
}
$done = true;
break;
case '{':

 $value = self::parseMapping($mapping, $i, $references);

 
 
 if (!isset($output[$key])) {
$output[$key] = $value;
}
$done = true;
break;
case ':':
case ' ':
break;
default:
$value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references);

 
 
 if (!isset($output[$key])) {
$output[$key] = $value;
}
$done = true;
--$i;
}

++$i;

if ($done) {
continue 2;
}
}
}

throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping));
}











private static function evaluateScalar($scalar, $references = array())
{
$scalar = trim($scalar);
$scalarLower = strtolower($scalar);

if (0 === strpos($scalar, '*')) {
if (false !== $pos = strpos($scalar, '#')) {
$value = substr($scalar, 1, $pos - 2);
} else {
$value = substr($scalar, 1);
}


 if (false === $value || '' === $value) {
throw new ParseException('A reference must contain at least one character.');
}

if (!array_key_exists($value, $references)) {
throw new ParseException(sprintf('Reference "%s" does not exist.', $value));
}

return $references[$value];
}

switch (true) {
case 'null' === $scalarLower:
case '' === $scalar:
case '~' === $scalar:
return;
case 'true' === $scalarLower:
return true;
case 'false' === $scalarLower:
return false;

 case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
switch (true) {
case 0 === strpos($scalar, '!str'):
return (string) substr($scalar, 5);
case 0 === strpos($scalar, '! '):
return (int) self::parseScalar(substr($scalar, 2));
case 0 === strpos($scalar, '!php/object:'):
if (self::$objectSupport) {
return unserialize(substr($scalar, 12));
}

if (self::$exceptionOnInvalidType) {
throw new ParseException('Object support when parsing a YAML file has been disabled.');
}

return;
case 0 === strpos($scalar, '!!php/object:'):
if (self::$objectSupport) {
return unserialize(substr($scalar, 13));
}

if (self::$exceptionOnInvalidType) {
throw new ParseException('Object support when parsing a YAML file has been disabled.');
}

return;
case 0 === strpos($scalar, '!!float '):
return (float) substr($scalar, 8);
case ctype_digit($scalar):
$raw = $scalar;
$cast = (int) $scalar;

return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
$raw = $scalar;
$cast = (int) $scalar;

return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
case is_numeric($scalar):
case preg_match(self::getHexRegex(), $scalar):
return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
case '.inf' === $scalarLower:
case '.nan' === $scalarLower:
return -log(0);
case '-.inf' === $scalarLower:
return log(0);
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
return (float) str_replace(',', '', $scalar);
case preg_match(self::getTimestampRegex(), $scalar):
$timeZone = date_default_timezone_get();
date_default_timezone_set('UTC');
$time = strtotime($scalar);
date_default_timezone_set($timeZone);

return $time;
}
default:
return (string) $scalar;
}
}








private static function getTimestampRegex()
{
return <<<EOF
        ~^
        (?P<year>[0-9][0-9][0-9][0-9])
        -(?P<month>[0-9][0-9]?)
        -(?P<day>[0-9][0-9]?)
        (?:(?:[Tt]|[ \t]+)
        (?P<hour>[0-9][0-9]?)
        :(?P<minute>[0-9][0-9])
        :(?P<second>[0-9][0-9])
        (?:\.(?P<fraction>[0-9]*))?
        (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
        (?::(?P<tz_minute>[0-9][0-9]))?))?)?
        $~x
EOF;
}






private static function getHexRegex()
{
return '~^0x[0-9a-f]++$~i';
}
}
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;






class Parser
{
const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';

 const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN;

private $offset = 0;
private $totalNumberOfLines;
private $lines = array();
private $currentLineNb = -1;
private $currentLine = '';
private $refs = array();
private $skippedLineNumbers = array();
private $locallySkippedLineNumbers = array();








public function __construct($offset = 0, $totalNumberOfLines = null, array $skippedLineNumbers = array())
{
$this->offset = $offset;
$this->totalNumberOfLines = $totalNumberOfLines;
$this->skippedLineNumbers = $skippedLineNumbers;
}













public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
{
if (!preg_match('//u', $value)) {
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
}
$this->currentLineNb = -1;
$this->currentLine = '';
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);

if (null === $this->totalNumberOfLines) {
$this->totalNumberOfLines = count($this->lines);
}

if (2  & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}

$data = array();
$context = null;
$allowOverwrite = false;
while ($this->moveToNextLine()) {
if ($this->isCurrentLineEmpty()) {
continue;
}


 if ("\t" === $this->currentLine[0]) {
throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}

$isRef = $mergeNode = false;
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
if ($context && 'mapping' == $context) {
throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
$context = 'sequence';

if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}


 if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
$data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
} else {
if (isset($values['leadspaces'])
&& preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
) {

 $block = $values['value'];
if ($this->isNextLineIndented()) {
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
}

$data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} else {
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
}
}
if ($isRef) {
$this->refs[$isRef] = end($data);
}
} elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
if ($context && 'sequence' == $context) {
throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
}
$context = 'mapping';


 Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
try {
$key = Inline::parseScalar($values['key']);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}


 if (is_float($key)) {
$key = (string) $key;
}

if ('<<' === $key) {
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
$refName = substr($values['value'], 1);
if (!array_key_exists($refName, $this->refs)) {
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
}

$refValue = $this->refs[$refName];

if (!is_array($refValue)) {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}

$data += $refValue; 
 } else {
if (isset($values['value']) && $values['value'] !== '') {
$value = $values['value'];
} else {
$value = $this->getNextEmbedBlock();
}
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $exceptionOnInvalidType, $objectSupport, $objectForMap);

if (!is_array($parsed)) {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}

if (isset($parsed[0])) {

 
 
 foreach ($parsed as $parsedItem) {
if (!is_array($parsedItem)) {
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
}

$data += $parsedItem; 
 }
} else {

 
 $data += $parsed; 
 }
}
} elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$values['value'] = $matches['value'];
}

if ($mergeNode) {

 } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {

 
 if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {

 
 if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = null;
}
} else {
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);

 
 if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value;
}
}
} else {
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);

 
 if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value;
}
}
if ($isRef) {
$this->refs[$isRef] = $data[$key];
}
} else {

 if ('---' === $this->currentLine) {
throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine);
}


 if (is_string($value) && $this->lines[0] === trim($value)) {
try {
$value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}

if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}

return $value;
}

switch (preg_last_error()) {
case PREG_INTERNAL_ERROR:
$error = 'Internal PCRE error.';
break;
case PREG_BACKTRACK_LIMIT_ERROR:
$error = 'pcre.backtrack_limit reached.';
break;
case PREG_RECURSION_LIMIT_ERROR:
$error = 'pcre.recursion_limit reached.';
break;
case PREG_BAD_UTF8_ERROR:
$error = 'Malformed UTF-8 data.';
break;
case PREG_BAD_UTF8_OFFSET_ERROR:
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
break;
default:
$error = 'Unable to parse.';
}

throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
}

if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}

if ($objectForMap && !is_object($data) && 'mapping' === $context) {
$object = new \stdClass();

foreach ($data as $key => $value) {
$object->$key = $value;
}

$data = $object;
}

return empty($data) ? null : $data;
}

private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap)
{
$skippedLineNumbers = $this->skippedLineNumbers;

foreach ($this->locallySkippedLineNumbers as $lineNumber) {
if ($lineNumber < $offset) {
continue;
}

$skippedLineNumbers[] = $lineNumber;
}

$parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers);
$parser->refs = &$this->refs;

return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap);
}






private function getRealCurrentLineNb()
{
$realCurrentLineNumber = $this->currentLineNb + $this->offset;

foreach ($this->skippedLineNumbers as $skippedLineNumber) {
if ($skippedLineNumber > $realCurrentLineNumber) {
break;
}

++$realCurrentLineNumber;
}

return $realCurrentLineNumber;
}






private function getCurrentLineIndentation()
{
return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
}











private function getNextEmbedBlock($indentation = null, $inSequence = false)
{
$oldLineIndentation = $this->getCurrentLineIndentation();
$blockScalarIndentations = array();

if ($this->isBlockScalarHeader()) {
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
}

if (!$this->moveToNextLine()) {
return;
}

if (null === $indentation) {
$newIndent = $this->getCurrentLineIndentation();

$unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();

if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
} else {
$newIndent = $indentation;
}

$data = array();
if ($this->getCurrentLineIndentation() >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent);
} else {
$this->moveToPreviousLine();

return;
}

if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {

 
 $this->moveToPreviousLine();

return;
}

$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();

if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
}

$previousLineIndentation = $this->getCurrentLineIndentation();

while ($this->moveToNextLine()) {
$indent = $this->getCurrentLineIndentation();


 if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) {
unset($blockScalarIndentations[$key]);
}
}
}

if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
}

$previousLineIndentation = $indent;

if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
$this->moveToPreviousLine();
break;
}

if ($this->isCurrentLineBlank()) {
$data[] = substr($this->currentLine, $newIndent);
continue;
}


 if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {

 
 
 
 
 
 $this->locallySkippedLineNumbers[] = $this->getRealCurrentLineNb();

continue;
}

if ($indent >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent);
} elseif (0 == $indent) {
$this->moveToPreviousLine();

break;
} else {
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
}

return implode("\n", $data);
}






private function moveToNextLine()
{
if ($this->currentLineNb >= count($this->lines) - 1) {
return false;
}

$this->currentLine = $this->lines[++$this->currentLineNb];

return true;
}






private function moveToPreviousLine()
{
if ($this->currentLineNb < 1) {
return false;
}

$this->currentLine = $this->lines[--$this->currentLineNb];

return true;
}














private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context)
{
if (0 === strpos($value, '*')) {
if (false !== $pos = strpos($value, '#')) {
$value = substr($value, 1, $pos - 2);
} else {
$value = substr($value, 1);
}

if (!array_key_exists($value, $this->refs)) {
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine);
}

return $this->refs[$value];
}

if (preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';

return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
}

try {
$parsedValue = Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);

if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
@trigger_error(sprintf('Using a colon in the unquoted mapping value "%s" in line %d is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $value, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);


 
 }

return $parsedValue;
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}
}










private function parseBlockScalar($style, $chomping = '', $indentation = 0)
{
$notEOF = $this->moveToNextLine();
if (!$notEOF) {
return '';
}

$isCurrentLineBlank = $this->isCurrentLineBlank();
$blockLines = array();


 while ($notEOF && $isCurrentLineBlank) {

 if ($notEOF = $this->moveToNextLine()) {
$blockLines[] = '';
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}


 if (0 === $indentation) {
if (preg_match('/^ +/', $this->currentLine, $matches)) {
$indentation = strlen($matches[0]);
}
}

if ($indentation > 0) {
$pattern = sprintf('/^ {%d}(.*)$/', $indentation);

while (
$notEOF && (
$isCurrentLineBlank ||
preg_match($pattern, $this->currentLine, $matches)
)
) {
if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) {
$blockLines[] = substr($this->currentLine, $indentation);
} elseif ($isCurrentLineBlank) {
$blockLines[] = '';
} else {
$blockLines[] = $matches[1];
}


 if ($notEOF = $this->moveToNextLine()) {
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
} elseif ($notEOF) {
$blockLines[] = '';
}

if ($notEOF) {
$blockLines[] = '';
$this->moveToPreviousLine();
} elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
$blockLines[] = '';
}


 if ('>' === $style) {
$text = '';
$previousLineIndented = false;
$previousLineBlank = false;

for ($i = 0, $blockLinesCount = count($blockLines); $i < $blockLinesCount; ++$i) {
if ('' === $blockLines[$i]) {
$text .= "\n";
$previousLineIndented = false;
$previousLineBlank = true;
} elseif (' ' === $blockLines[$i][0]) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = true;
$previousLineBlank = false;
} elseif ($previousLineIndented) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} elseif ($previousLineBlank || 0 === $i) {
$text .= $blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} else {
$text .= ' '.$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
}
}
} else {
$text = implode("\n", $blockLines);
}


 if ('' === $chomping) {
$text = preg_replace('/\n+$/', "\n", $text);
} elseif ('-' === $chomping) {
$text = preg_replace('/\n+$/', '', $text);
}

return $text;
}






private function isNextLineIndented()
{
$currentIndentation = $this->getCurrentLineIndentation();
$EOF = !$this->moveToNextLine();

while (!$EOF && $this->isCurrentLineEmpty()) {
$EOF = !$this->moveToNextLine();
}

if ($EOF) {
return false;
}

$ret = false;
if ($this->getCurrentLineIndentation() > $currentIndentation) {
$ret = true;
}

$this->moveToPreviousLine();

return $ret;
}






private function isCurrentLineEmpty()
{
return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
}






private function isCurrentLineBlank()
{
return '' == trim($this->currentLine, ' ');
}






private function isCurrentLineComment()
{

 $ltrimmedLine = ltrim($this->currentLine, ' ');

return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
}

private function isCurrentLineLastLineInDocument()
{
return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
}








private function cleanup($value)
{
$value = str_replace(array("\r\n", "\r"), "\n", $value);


 $count = 0;
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
$this->offset += $count;


 $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
if ($count == 1) {

 $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;
}


 $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
if ($count == 1) {

 $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;


 $value = preg_replace('#\.\.\.\s*$#', '', $value);
}

return $value;
}






private function isNextLineUnIndentedCollection()
{
$currentIndentation = $this->getCurrentLineIndentation();
$notEOF = $this->moveToNextLine();

while ($notEOF && $this->isCurrentLineEmpty()) {
$notEOF = $this->moveToNextLine();
}

if (false === $notEOF) {
return false;
}

$ret = false;
if (
$this->getCurrentLineIndentation() == $currentIndentation
&&
$this->isStringUnIndentedCollectionItem()
) {
$ret = true;
}

$this->moveToPreviousLine();

return $ret;
}






private function isStringUnIndentedCollectionItem()
{
return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
}






private function isBlockScalarHeader()
{
return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
}
}
<?php










namespace Symfony\Component\Yaml;






class Dumper
{





protected $indentation = 4;






public function setIndentation($num)
{
if ($num < 1) {
throw new \InvalidArgumentException('The indentation must be greater than zero.');
}

$this->indentation = (int) $num;
}












public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false)
{
$output = '';
$prefix = $indent ? str_repeat(' ', $indent) : '';

if ($inline <= 0 || !is_array($input) || empty($input)) {
$output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
} else {
$isAHash = Inline::isHash($input);

foreach ($input as $key => $value) {
$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);

$output .= sprintf('%s%s%s%s',
$prefix,
$isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-',
$willBeInlined ? ' ' : "\n",
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
).($willBeInlined ? "\n" : '');
}
}

return $output;
}
}
<?php










namespace Symfony\Component\Yaml;









class Escaper
{

 const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";


 
 
 
 private static $escapees = array('\\', '\\\\', '\\"', '"',
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
"\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9");
private static $escaped = array('\\\\', '\\"', '\\\\', '\\"',
'\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
'\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f',
'\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
'\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f',
'\\N', '\\_', '\\L', '\\P');








public static function requiresDoubleQuoting($value)
{
return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
}








public static function escapeWithDoubleQuotes($value)
{
return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
}








public static function requiresSingleQuoting($value)
{

 
 if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
return true;
}


 
 return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
}








public static function escapeWithSingleQuotes($value)
{
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
}
}
<?php










namespace Symfony\Component\Yaml\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Dumper;

class DumperTest extends TestCase
{
protected $parser;
protected $dumper;
protected $path;

protected $array = array(
'' => 'bar',
'foo' => '#bar',
'foo\'bar' => array(),
'bar' => array(1, 'foo'),
'foobar' => array(
'foo' => 'bar',
'bar' => array(1, 'foo'),
'foobar' => array(
'foo' => 'bar',
'bar' => array(1, 'foo'),
),
),
);

protected function setUp()
{
$this->parser = new Parser();
$this->dumper = new Dumper();
$this->path = __DIR__.'/Fixtures';
}

protected function tearDown()
{
$this->parser = null;
$this->dumper = null;
$this->path = null;
$this->array = null;
}

public function testSetIndentation()
{
$this->dumper->setIndentation(7);

$expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
       - 1
       - foo
foobar:
       foo: bar
       bar:
              - 1
              - foo
       foobar:
              foo: bar
              bar:
                     - 1
                     - foo

EOF;
$this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0));
}

public function testSpecifications()
{
$files = $this->parser->parse(file_get_contents($this->path.'/index.yml'));
foreach ($files as $file) {
$yamls = file_get_contents($this->path.'/'.$file.'.yml');


 foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
if (!$yaml) {
continue;
}

$test = $this->parser->parse($yaml);
if (isset($test['dump_skip']) && $test['dump_skip']) {
continue;
} elseif (isset($test['todo']) && $test['todo']) {

 } else {
eval('$expected = '.trim($test['php']).';');
$this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
}
}
}
}

public function testInlineLevel()
{
$expected = <<<'EOF'
{ '': bar, foo: '#bar', 'foo''bar': {  }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } }
EOF;
$this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument');
$this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument');

$expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar: [1, foo]
foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } }

EOF;
$this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument');

$expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
    - 1
    - foo
foobar:
    foo: bar
    bar: [1, foo]
    foobar: { foo: bar, bar: [1, foo] }

EOF;
$this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument');

$expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
    - 1
    - foo
foobar:
    foo: bar
    bar:
        - 1
        - foo
    foobar:
        foo: bar
        bar: [1, foo]

EOF;
$this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument');

$expected = <<<'EOF'
'': bar
foo: '#bar'
'foo''bar': {  }
bar:
    - 1
    - foo
foobar:
    foo: bar
    bar:
        - 1
        - foo
    foobar:
        foo: bar
        bar:
            - 1
            - foo

EOF;
$this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument');
$this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument');
}

public function testObjectSupportEnabled()
{
$dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true);

$this->assertEquals('{ foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects');
}

public function testObjectSupportDisabledButNoExceptions()
{
$dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1));

$this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled');
}




public function testObjectSupportDisabledWithExceptions()
{
$this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false);
}




public function testEscapedEscapeSequencesInQuotedScalar($input, $expected)
{
$this->assertEquals($expected, $this->dumper->dump($input));
}

public function getEscapeSequences()
{
return array(
'null' => array("\t\\0", '"\t\\\\0"'),
'bell' => array("\t\\a", '"\t\\\\a"'),
'backspace' => array("\t\\b", '"\t\\\\b"'),
'horizontal-tab' => array("\t\\t", '"\t\\\\t"'),
'line-feed' => array("\t\\n", '"\t\\\\n"'),
'vertical-tab' => array("\t\\v", '"\t\\\\v"'),
'form-feed' => array("\t\\f", '"\t\\\\f"'),
'carriage-return' => array("\t\\r", '"\t\\\\r"'),
'escape' => array("\t\\e", '"\t\\\\e"'),
'space' => array("\t\\ ", '"\t\\\\ "'),
'double-quote' => array("\t\\\"", '"\t\\\\\\""'),
'slash' => array("\t\\/", '"\t\\\\/"'),
'backslash' => array("\t\\\\", '"\t\\\\\\\\"'),
'next-line' => array("\t\\N", '"\t\\\\N"'),
'non-breaking-space' => array("\t\\�", '"\t\\\\�"'),
'line-separator' => array("\t\\L", '"\t\\\\L"'),
'paragraph-separator' => array("\t\\P", '"\t\\\\P"'),
);
}





public function testZeroIndentationThrowsException()
{
$this->dumper->setIndentation(0);
}





public function testNegativeIndentationThrowsException()
{
$this->dumper->setIndentation(-4);
}
}

class A
{
public $a = 'foo';
}
<?php










namespace Symfony\Component\Yaml\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Parser;

class ParserTest extends TestCase
{
protected $parser;

protected function setUp()
{
$this->parser = new Parser();
}

protected function tearDown()
{
$this->parser = null;
}




public function testSpecifications($file, $expected, $yaml, $comment)
{
$this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
}

public function getDataFormSpecifications()
{
$parser = new Parser();
$path = __DIR__.'/Fixtures';

$tests = array();
$files = $parser->parse(file_get_contents($path.'/index.yml'));
foreach ($files as $file) {
$yamls = file_get_contents($path.'/'.$file.'.yml');


 foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
if (!$yaml) {
continue;
}

$test = $parser->parse($yaml);
if (isset($test['todo']) && $test['todo']) {

 } else {
eval('$expected = '.trim($test['php']).';');

$tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']);
}
}
}

return $tests;
}

public function testTabsInYaml()
{

 $yamls = array(
"foo:\n	bar",
"foo:\n 	bar",
"foo:\n	 bar",
"foo:\n 	 bar",
);

foreach ($yamls as $yaml) {
try {
$content = $this->parser->parse($yaml);

$this->fail('YAML files must not contain tabs');
} catch (\Exception $e) {
$this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
$this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
}
}
}

public function testEndOfTheDocumentMarker()
{
$yaml = <<<'EOF'
--- %YAML:1.0
foo
...
EOF;

$this->assertEquals('foo', $this->parser->parse($yaml));
}

public function getBlockChompingTests()
{
$tests = array();

$yaml = <<<'EOF'
foo: |-
    one
    two
bar: |-
    one
    two

EOF;
$expected = array(
'foo' => "one\ntwo",
'bar' => "one\ntwo",
);
$tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |-
    one
    two

bar: |-
    one
    two


EOF;
$expected = array(
'foo' => "one\ntwo",
'bar' => "one\ntwo",
);
$tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml);

$yaml = <<<'EOF'
{}


EOF;
$expected = array();
$tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |-
    one
    two
bar: |-
    one
    two
EOF;
$expected = array(
'foo' => "one\ntwo",
'bar' => "one\ntwo",
);
$tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |
    one
    two
bar: |
    one
    two

EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo\n",
);
$tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |
    one
    two

bar: |
    one
    two


EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo\n",
);
$tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo:
- bar: |
    one

    two
EOF;
$expected = array(
'foo' => array(
array(
'bar' => "one\n\ntwo",
),
),
);
$tests['Literal block chomping clip with embedded blank line inside unindented collection'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |
    one
    two
bar: |
    one
    two
EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo",
);
$tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |+
    one
    two
bar: |+
    one
    two

EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo\n",
);
$tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |+
    one
    two

bar: |+
    one
    two


EOF;
$expected = array(
'foo' => "one\ntwo\n\n",
'bar' => "one\ntwo\n\n",
);
$tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: |+
    one
    two
bar: |+
    one
    two
EOF;
$expected = array(
'foo' => "one\ntwo\n",
'bar' => "one\ntwo",
);
$tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >-
    one
    two
bar: >-
    one
    two

EOF;
$expected = array(
'foo' => 'one two',
'bar' => 'one two',
);
$tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >-
    one
    two

bar: >-
    one
    two


EOF;
$expected = array(
'foo' => 'one two',
'bar' => 'one two',
);
$tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >-
    one
    two
bar: >-
    one
    two
EOF;
$expected = array(
'foo' => 'one two',
'bar' => 'one two',
);
$tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >
    one
    two
bar: >
    one
    two

EOF;
$expected = array(
'foo' => "one two\n",
'bar' => "one two\n",
);
$tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >
    one
    two

bar: >
    one
    two


EOF;
$expected = array(
'foo' => "one two\n",
'bar' => "one two\n",
);
$tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >
    one
    two
bar: >
    one
    two
EOF;
$expected = array(
'foo' => "one two\n",
'bar' => 'one two',
);
$tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >+
    one
    two
bar: >+
    one
    two

EOF;
$expected = array(
'foo' => "one two\n",
'bar' => "one two\n",
);
$tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >+
    one
    two

bar: >+
    one
    two


EOF;
$expected = array(
'foo' => "one two\n\n",
'bar' => "one two\n\n",
);
$tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml);

$yaml = <<<'EOF'
foo: >+
    one
    two
bar: >+
    one
    two
EOF;
$expected = array(
'foo' => "one two\n",
'bar' => 'one two',
);
$tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);

return $tests;
}




public function testBlockChomping($expected, $yaml)
{
$this->assertSame($expected, $this->parser->parse($yaml));
}






public function testBlockLiteralWithLeadingNewlines()
{
$yaml = <<<'EOF'
foo: |-


    bar

EOF;
$expected = array(
'foo' => "\n\nbar",
);

$this->assertSame($expected, $this->parser->parse($yaml));
}

public function testObjectSupportEnabled()
{
$input = <<<'EOF'
foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
$this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');

$input = <<<'EOF'
foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
$this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects');
}




public function testObjectSupportDisabledButNoExceptions($input)
{
$this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
}




public function testObjectForMap($yaml, $expected)
{
$this->assertEquals($expected, $this->parser->parse($yaml, false, false, true));
}

public function getObjectForMapTests()
{
$tests = array();

$yaml = <<<'EOF'
foo:
    fiz: [cat]
EOF;
$expected = new \stdClass();
$expected->foo = new \stdClass();
$expected->foo->fiz = array('cat');
$tests['mapping'] = array($yaml, $expected);

$yaml = '{ "foo": "bar", "fiz": "cat" }';
$expected = new \stdClass();
$expected->foo = 'bar';
$expected->fiz = 'cat';
$tests['inline-mapping'] = array($yaml, $expected);

$yaml = "foo: bar\nbaz: foobar";
$expected = new \stdClass();
$expected->foo = 'bar';
$expected->baz = 'foobar';
$tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected);

$yaml = <<<'EOT'
array:
  - key: one
  - key: two
EOT;
$expected = new \stdClass();
$expected->array = array();
$expected->array[0] = new \stdClass();
$expected->array[0]->key = 'one';
$expected->array[1] = new \stdClass();
$expected->array[1]->key = 'two';
$tests['nest-map-and-sequence'] = array($yaml, $expected);

$yaml = <<<'YAML'
map:
  1: one
  2: two
YAML;
$expected = new \stdClass();
$expected->map = new \stdClass();
$expected->map->{1} = 'one';
$expected->map->{2} = 'two';
$tests['numeric-keys'] = array($yaml, $expected);

$yaml = <<<'YAML'
map:
  0: one
  1: two
YAML;
$expected = new \stdClass();
$expected->map = new \stdClass();
$expected->map->{0} = 'one';
$expected->map->{1} = 'two';
$tests['zero-indexed-numeric-keys'] = array($yaml, $expected);

return $tests;
}





public function testObjectsSupportDisabledWithExceptions($yaml)
{
$this->parser->parse($yaml, true, false);
}

public function invalidDumpedObjectProvider()
{
$yamlTag = <<<'EOF'
foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;
$localTag = <<<'EOF'
foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
bar: 1
EOF;

return array(
'yaml-tag' => array($yamlTag),
'local-tag' => array($localTag),
);
}




public function testNonUtf8Exception()
{
$yamls = array(
iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"),
iconv('UTF-8', 'ISO-8859-15', "euro: '€'"),
iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"),
);

foreach ($yamls as $yaml) {
try {
$this->parser->parse($yaml);

$this->fail('charsets other than UTF-8 are rejected.');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
}
}
}




public function testUnindentedCollectionException()
{
$yaml = <<<'EOF'

collection:
-item1
-item2
-item3

EOF;

$this->parser->parse($yaml);
}




public function testShortcutKeyUnindentedCollectionException()
{
$yaml = <<<'EOF'

collection:
-  key: foo
  foo: bar

EOF;

$this->parser->parse($yaml);
}





public function testMultipleDocumentsNotSupportedException()
{
Yaml::parse(<<<'EOL'
# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey

# Team ranking
---
- Chicago Cubs
- St Louis Cardinals
EOL
);
}




public function testSequenceInAMapping()
{
Yaml::parse(<<<'EOF'
yaml:
  hash: me
  - array stuff
EOF
);
}

public function testSequenceInMappingStartedBySingleDashLine()
{
$yaml = <<<'EOT'
a:
-
  b:
  -
    bar: baz
- foo
d: e
EOT;
$expected = array(
'a' => array(
array(
'b' => array(
array(
'bar' => 'baz',
),
),
),
'foo',
),
'd' => 'e',
);

$this->assertSame($expected, $this->parser->parse($yaml));
}

public function testSequenceFollowedByCommentEmbeddedInMapping()
{
$yaml = <<<'EOT'
a:
    b:
        - c
# comment
    d: e
EOT;
$expected = array(
'a' => array(
'b' => array('c'),
'd' => 'e',
),
);

$this->assertSame($expected, $this->parser->parse($yaml));
}




public function testMappingInASequence()
{
Yaml::parse(<<<'EOF'
yaml:
  - array stuff
  hash: me
EOF
);
}





public function testScalarInSequence()
{
Yaml::parse(<<<'EOF'
foo:
    - bar
"missing colon"
    foo: bar
EOF
);
}











public function testMappingDuplicateKeyBlock()
{
$input = <<<'EOD'
parent:
    child: first
    child: duplicate
parent:
    child: duplicate
    child: duplicate
EOD;
$expected = array(
'parent' => array(
'child' => 'first',
),
);
$this->assertSame($expected, Yaml::parse($input));
}

public function testMappingDuplicateKeyFlow()
{
$input = <<<'EOD'
parent: { child: first, child: duplicate }
parent: { child: duplicate, child: duplicate }
EOD;
$expected = array(
'parent' => array(
'child' => 'first',
),
);
$this->assertSame($expected, Yaml::parse($input));
}

public function testEmptyValue()
{
$input = <<<'EOF'
hash:
EOF;

$this->assertEquals(array('hash' => null), Yaml::parse($input));
}

public function testCommentAtTheRootIndent()
{
$this->assertEquals(array(
'services' => array(
'app.foo_service' => array(
'class' => 'Foo',
),
'app/bar_service' => array(
'class' => 'Bar',
),
),
), Yaml::parse(<<<'EOF'
# comment 1
services:
# comment 2
    # comment 3
    app.foo_service:
        class: Foo
# comment 4
    # comment 5
    app/bar_service:
        class: Bar
EOF
));
}

public function testStringBlockWithComments()
{
$this->assertEquals(array('content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
), Yaml::parse(<<<'EOF'
content: |
    # comment 1
    header

        # comment 2
        <body>
            <h1>title</h1>
        </body>

    footer # comment3
EOF
));
}

public function testFoldedStringBlockWithComments()
{
$this->assertEquals(array(array('content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
)), Yaml::parse(<<<'EOF'
-
    content: |
        # comment 1
        header

            # comment 2
            <body>
                <h1>title</h1>
            </body>

        footer # comment3
EOF
));
}

public function testNestedFoldedStringBlockWithComments()
{
$this->assertEquals(array(array(
'title' => 'some title',
'content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
)), Yaml::parse(<<<'EOF'
-
    title: some title
    content: |
        # comment 1
        header

            # comment 2
            <body>
                <h1>title</h1>
            </body>

        footer # comment3
EOF
));
}

public function testReferenceResolvingInInlineStrings()
{
$this->assertEquals(array(
'var' => 'var-value',
'scalar' => 'var-value',
'list' => array('var-value'),
'list_in_list' => array(array('var-value')),
'map_in_list' => array(array('key' => 'var-value')),
'embedded_mapping' => array(array('key' => 'var-value')),
'map' => array('key' => 'var-value'),
'list_in_map' => array('key' => array('var-value')),
'map_in_map' => array('foo' => array('bar' => 'var-value')),
), Yaml::parse(<<<'EOF'
var:  &var var-value
scalar: *var
list: [ *var ]
list_in_list: [[ *var ]]
map_in_list: [ { key: *var } ]
embedded_mapping: [ key: *var ]
map: { key: *var }
list_in_map: { key: [*var] }
map_in_map: { foo: { bar: *var } }
EOF
));
}

public function testYamlDirective()
{
$yaml = <<<'EOF'
%YAML 1.2
---
foo: 1
bar: 2
EOF;
$this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml));
}

public function testFloatKeys()
{
$yaml = <<<'EOF'
foo:
    1.2: "bar"
    1.3: "baz"
EOF;

$expected = array(
'foo' => array(
'1.2' => 'bar',
'1.3' => 'baz',
),
);

$this->assertEquals($expected, $this->parser->parse($yaml));
}






public function testColonInMappingValueException()
{
$yaml = <<<'EOF'
foo: bar: baz
EOF;

$this->parser->parse($yaml);
}

public function testColonInMappingValueExceptionNotTriggeredByColonInComment()
{
$yaml = <<<'EOT'
foo:
    bar: foobar # Note: a comment after a colon
EOT;

$this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml));
}




public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
{
$this->assertSame($expectedParserResult, $this->parser->parse($yaml));
}

public function getCommentLikeStringInScalarBlockData()
{
$tests = array();

$yaml = <<<'EOT'
pages:
    -
        title: some title
        content: |
            # comment 1
            header

                # comment 2
                <body>
                    <h1>title</h1>
                </body>

            footer # comment3
EOT;
$expected = array(
'pages' => array(
array(
'title' => 'some title',
'content' => <<<'EOT'
# comment 1
header

    # comment 2
    <body>
        <h1>title</h1>
    </body>

footer # comment3
EOT
,
),
),
);
$tests[] = array($yaml, $expected);

$yaml = <<<'EOT'
test: |
    foo
    # bar
    baz
collection:
    - one: |
        foo
        # bar
        baz
    - two: |
        foo
        # bar
        baz
EOT;
$expected = array(
'test' => <<<'EOT'
foo
# bar
baz

EOT
,
'collection' => array(
array(
'one' => <<<'EOT'
foo
# bar
baz

EOT
,
),
array(
'two' => <<<'EOT'
foo
# bar
baz
EOT
,
),
),
);
$tests[] = array($yaml, $expected);

$yaml = <<<'EOT'
foo:
  bar:
    scalar-block: >
      line1
      line2>
  baz:
# comment
    foobar: ~
EOT;
$expected = array(
'foo' => array(
'bar' => array(
'scalar-block' => "line1 line2>\n",
),
'baz' => array(
'foobar' => null,
),
),
);
$tests[] = array($yaml, $expected);

$yaml = <<<'EOT'
a:
    b: hello
#    c: |
#        first row
#        second row
    d: hello
EOT;
$expected = array(
'a' => array(
'b' => 'hello',
'd' => 'hello',
),
);
$tests[] = array($yaml, $expected);

return $tests;
}

public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
{
$yaml = <<<'EOT'
test: >
    <h2>A heading</h2>

    <ul>
    <li>a list</li>
    <li>may be a good example</li>
    </ul>
EOT;

$this->assertSame(
array(
'test' => <<<'EOT'
<h2>A heading</h2>
<ul> <li>a list</li> <li>may be a good example</li> </ul>
EOT
,
),
$this->parser->parse($yaml)
);
}

public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
{
$yaml = <<<'EOT'
test: >
    <h2>A heading</h2>

    <ul>
      <li>a list</li>
      <li>may be a good example</li>
    </ul>
EOT;

$this->assertSame(
array(
'test' => <<<'EOT'
<h2>A heading</h2>
<ul>
  <li>a list</li>
  <li>may be a good example</li>
</ul>
EOT
,
),
$this->parser->parse($yaml)
);
}






public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml)
{
if (method_exists($this, 'expectException')) {
$this->expectException('\Symfony\Component\Yaml\Exception\ParseException');
$this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber));
} else {
$this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber));
}

$this->parser->parse($yaml);
}

public function parserThrowsExceptionWithCorrectLineNumberProvider()
{
return array(
array(
4,
<<<'YAML'
foo:
    -
        # bar
        bar: "123",
YAML
),
array(
5,
<<<'YAML'
foo:
    -
        # bar
        # bar
        bar: "123",
YAML
),
array(
8,
<<<'YAML'
foo:
    -
        # foobar
        baz: 123
bar:
    -
        # bar
        bar: "123",
YAML
),
array(
10,
<<<'YAML'
foo:
    -
        # foobar
        # foobar
        baz: 123
bar:
    -
        # bar
        # bar
        bar: "123",
YAML
),
);
}
}

class B
{
public $b = 'foo';
}
<?php










namespace Symfony\Component\Yaml\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Yaml;

class YamlTest extends TestCase
{
public function testParseAndDump()
{
$data = array('lorem' => 'ipsum', 'dolor' => 'sit');
$yml = Yaml::dump($data);
$parsed = Yaml::parse($yml);
$this->assertEquals($data, $parsed);
}




public function testLegacyParseFromFile()
{
$filename = __DIR__.'/Fixtures/index.yml';
$contents = file_get_contents($filename);
$parsedByFilename = Yaml::parse($filename);
$parsedByContents = Yaml::parse($contents);
$this->assertEquals($parsedByFilename, $parsedByContents);
}





public function testZeroIndentationThrowsException()
{
Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, 0);
}





public function testNegativeIndentationThrowsException()
{
Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, -4);
}
}
<?php










namespace Symfony\Component\Yaml\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Exception\ParseException;

class ParseExceptionTest extends TestCase
{
public function testGetMessage()
{
$exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml');
if (PHP_VERSION_ID >= 50400) {
$message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")';
} else {
$message = 'Error message in "\\/var\\/www\\/app\\/config.yml" at line 42 (near "foo: bar")';
}

$this->assertEquals($message, $exception->getMessage());
}

public function testGetMessageWithUnicodeInFilename()
{
$exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml');
if (PHP_VERSION_ID >= 50400) {
$message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")';
} else {
$message = 'Error message in "\u00e4\u00f6\u00fc.yml" at line 42 (near "foo: bar")';
}

$this->assertEquals($message, $exception->getMessage());
}
}
<?php










namespace Symfony\Component\Yaml\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Inline;

class InlineTest extends TestCase
{



public function testParse($yaml, $value)
{
$this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
}




public function testParseWithMapObjects($yaml, $value)
{
$actual = Inline::parse($yaml, false, false, true);

$this->assertSame(serialize($value), serialize($actual));
}




public function testDump($yaml, $value)
{
$this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));

$this->assertSame($value, Inline::parse(Inline::dump($value)), 'check consistency');
}

public function testDumpNumericValueWithLocale()
{
$locale = setlocale(LC_NUMERIC, 0);
if (false === $locale) {
$this->markTestSkipped('Your platform does not support locales.');
}

try {
$requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
if (false === setlocale(LC_NUMERIC, $requiredLocales)) {
$this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales));
}

$this->assertEquals('1.2', Inline::dump(1.2));
$this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
setlocale(LC_NUMERIC, $locale);
} catch (\Exception $e) {
setlocale(LC_NUMERIC, $locale);
throw $e;
}
}

public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()
{
$value = '686e444';

$this->assertSame($value, Inline::parse(Inline::dump($value)));
}





public function testParseScalarWithNonEscapedBlackslashShouldThrowException()
{
$this->assertSame('Foo\Var', Inline::parse('"Foo\Var"'));
}




public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException()
{
Inline::parse('"Foo\\"');
}




public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
{
$value = "'don't do somthin' like that'";
Inline::parse($value);
}




public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
{
$value = '"don"t do somthin" like that"';
Inline::parse($value);
}




public function testParseInvalidMappingKeyShouldThrowException()
{
$value = '{ "foo " bar": "bar" }';
Inline::parse($value);
}




public function testParseInvalidMappingShouldThrowException()
{
Inline::parse('[foo] bar');
}




public function testParseInvalidSequenceShouldThrowException()
{
Inline::parse('{ foo: bar } bar');
}

public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
{
$value = "'don''t do somthin'' like that'";
$expect = "don't do somthin' like that";

$this->assertSame($expect, Inline::parseScalar($value));
}




public function testParseReferences($yaml, $expected)
{
$this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value')));
}

public function getDataForParseReferences()
{
return array(
'scalar' => array('*var', 'var-value'),
'list' => array('[ *var ]', array('var-value')),
'list-in-list' => array('[[ *var ]]', array(array('var-value'))),
'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))),
'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))),
'map' => array('{ key: *var }', array('key' => 'var-value')),
'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))),
'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))),
);
}

public function testParseMapReferenceInSequence()
{
$foo = array(
'a' => 'Steve',
'b' => 'Clark',
'c' => 'Brian',
);
$this->assertSame(array($foo), Inline::parse('[*foo]', false, false, false, array('foo' => $foo)));
}





public function testParseUnquotedAsterisk()
{
Inline::parse('{ foo: * }');
}





public function testParseUnquotedAsteriskFollowedByAComment()
{
Inline::parse('{ foo: * #foo }');
}






public function testParseUnquotedScalarStartingWithReservedIndicator($indicator)
{
Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
}

public function getReservedIndicators()
{
return array(array('@'), array('`'));
}






public function testParseUnquotedScalarStartingWithScalarIndicator($indicator)
{
Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
}

public function getScalarIndicators()
{
return array(array('|'), array('>'));
}




public function testIsHash($array, $expected)
{
$this->assertSame($expected, Inline::isHash($array));
}

public function getDataForIsHash()
{
return array(
array(array(), false),
array(array(1, 2, 3), false),
array(array(2 => 1, 1 => 2, 0 => 3), true),
array(array('foo' => 1, 'bar' => 2), true),
);
}

public function getTestsForParse()
{
return array(
array('', ''),
array('null', null),
array('false', false),
array('true', true),
array('12', 12),
array('-12', -12),
array('"quoted string"', 'quoted string'),
array("'quoted string'", 'quoted string'),
array('12.30e+02', 12.30e+02),
array('0x4D2', 0x4D2),
array('02333', 02333),
array('.Inf', -log(0)),
array('-.Inf', log(0)),
array("'686e444'", '686e444'),
array('686e444', 646e444),
array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
array('"foo\r\nbar"', "foo\r\nbar"),
array("'foo#bar'", 'foo#bar'),
array("'foo # bar'", 'foo # bar'),
array("'#cfcfcf'", '#cfcfcf'),
array('::form_base.html.twig', '::form_base.html.twig'),


 array("'y'", 'y'),
array("'n'", 'n'),
array("'yes'", 'yes'),
array("'no'", 'no'),
array("'on'", 'on'),
array("'off'", 'off'),

array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),

array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),


 
 array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
array('[  foo  ,   bar , false  ,  null     ,  12  ]', array('foo', 'bar', false, null, 12)),
array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),


 array('{foo:bar,bar:foo,false:false,null:null,integer:12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
array('{ foo  : bar, bar : foo,  false  :   false,  null  :   null,  integer :  12  }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),


 array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),

array('[  foo, [  bar, foo  ]  ]', array('foo', array('bar', 'foo'))),

array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))),

array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),

array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),

array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))),
array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
);
}

public function getTestsForParseWithMapObjects()
{
return array(
array('', ''),
array('null', null),
array('false', false),
array('true', true),
array('12', 12),
array('-12', -12),
array('"quoted string"', 'quoted string'),
array("'quoted string'", 'quoted string'),
array('12.30e+02', 12.30e+02),
array('0x4D2', 0x4D2),
array('02333', 02333),
array('.Inf', -log(0)),
array('-.Inf', log(0)),
array("'686e444'", '686e444'),
array('686e444', 646e444),
array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
array('"foo\r\nbar"', "foo\r\nbar"),
array("'foo#bar'", 'foo#bar'),
array("'foo # bar'", 'foo # bar'),
array("'#cfcfcf'", '#cfcfcf'),
array('::form_base.html.twig', '::form_base.html.twig'),

array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),

array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),


 
 array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
array('[  foo  ,   bar , false  ,  null     ,  12  ]', array('foo', 'bar', false, null, 12)),
array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),


 array('{foo:bar,bar:foo,false:false,null:null,integer:12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
array('{ foo  : bar, bar : foo,  false  :   false,  null  :   null,  integer :  12  }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),


 array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))),
array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))),
array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))),

array('[  foo, [  bar, foo  ]  ]', array('foo', array('bar', 'foo'))),

array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))),

array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),

array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))),

array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))),
array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),

array('{}', new \stdClass()),
array('{ foo  : bar, bar : {}  }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
array('{ foo  : [], bar : {}  }', (object) array('foo' => array(), 'bar' => new \stdClass())),
array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')),

array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))),
array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))),
array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))),
array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))),
);
}

public function getTestsForDump()
{
return array(
array('null', null),
array('false', false),
array('true', true),
array('12', 12),
array("'quoted string'", 'quoted string'),
array('!!float 1230', 12.30e+02),
array('1234', 0x4D2),
array('1243', 02333),
array('.Inf', -log(0)),
array('-.Inf', log(0)),
array("'686e444'", '686e444'),
array('"foo\r\nbar"', "foo\r\nbar"),
array("'foo#bar'", 'foo#bar'),
array("'foo # bar'", 'foo # bar'),
array("'#cfcfcf'", '#cfcfcf'),

array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),

array("'-dash'", '-dash'),
array("'-'", '-'),


 array("'y'", 'y'),
array("'n'", 'n'),
array("'yes'", 'yes'),
array("'no'", 'no'),
array("'on'", 'on'),
array("'off'", 'off'),


 array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)),
array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),


 array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')),


 array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),

array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),

array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))),

array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))),

array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),

array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),

array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))),
);
}





public function testNotSupportedMissingValue()
{
Inline::parse('{this, is not, supported}');
}

public function testVeryLongQuotedStrings()
{
$longStringWithQuotes = str_repeat("x\r\n\\\"x\"x", 1000);

$yamlString = Inline::dump(array('longStringWithQuotes' => $longStringWithQuotes));
$arrayFromYaml = Inline::parse($yamlString);

$this->assertEquals($longStringWithQuotes, $arrayFromYaml['longStringWithQuotes']);
}

public function testBooleanMappingKeysAreConvertedToStrings()
{
$this->assertSame(array('false' => 'foo'), Inline::parse('{false: foo}'));
$this->assertSame(array('true' => 'foo'), Inline::parse('{true: foo}'));
}

public function testTheEmptyStringIsAValidMappingKey()
{
$this->assertSame(array('' => 'foo'), Inline::parse('{ "": foo }'));
}
}
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;






class Yaml
{
























public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
{

 $file = '';
if (strpos($input, "\n") === false && is_file($input)) {
@trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED);

if (false === is_readable($input)) {
throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
}

$file = $input;
$input = file_get_contents($file);
}

$yaml = new Parser();

try {
return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} catch (ParseException $e) {
if ($file) {
$e->setParsedFile($file);
}

throw $e;
}
}















public static function dump($input, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false)
{
if ($indent < 1) {
throw new \InvalidArgumentException('The indentation must be greater than zero.');
}

$yaml = new Dumper();
$yaml->setIndentation($indent);

return $yaml->dump($input, $inline, 0, $exceptionOnInvalidType, $objectSupport);
}
}
<?php










namespace Symfony\Component\Yaml\Exception;






interface ExceptionInterface
{
}
<?php










namespace Symfony\Component\Yaml\Exception;






class ParseException extends RuntimeException
{
private $parsedFile;
private $parsedLine;
private $snippet;
private $rawMessage;










public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null)
{
$this->parsedFile = $parsedFile;
$this->parsedLine = $parsedLine;
$this->snippet = $snippet;
$this->rawMessage = $message;

$this->updateRepr();

parent::__construct($this->message, 0, $previous);
}






public function getSnippet()
{
return $this->snippet;
}






public function setSnippet($snippet)
{
$this->snippet = $snippet;

$this->updateRepr();
}








public function getParsedFile()
{
return $this->parsedFile;
}






public function setParsedFile($parsedFile)
{
$this->parsedFile = $parsedFile;

$this->updateRepr();
}






public function getParsedLine()
{
return $this->parsedLine;
}






public function setParsedLine($parsedLine)
{
$this->parsedLine = $parsedLine;

$this->updateRepr();
}

private function updateRepr()
{
$this->message = $this->rawMessage;

$dot = false;
if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$dot = true;
}

if (null !== $this->parsedFile) {
if (PHP_VERSION_ID >= 50400) {
$jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
} else {
$jsonOptions = 0;
}
$this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions));
}

if ($this->parsedLine >= 0) {
$this->message .= sprintf(' at line %d', $this->parsedLine);
}

if ($this->snippet) {
$this->message .= sprintf(' (near "%s")', $this->snippet);
}

if ($dot) {
$this->message .= '.';
}
}
}
<?php










namespace Symfony\Component\Yaml\Exception;






class DumpException extends RuntimeException
{
}
<?php










namespace Symfony\Component\Yaml\Exception;






class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Debug;

use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\Exception\ContextErrorException;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;























class ErrorHandler
{



const TYPE_DEPRECATION = -100;

private $levels = array(
E_DEPRECATED => 'Deprecated',
E_USER_DEPRECATED => 'User Deprecated',
E_NOTICE => 'Notice',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice',
E_WARNING => 'Warning',
E_USER_WARNING => 'User Warning',
E_COMPILE_WARNING => 'Compile Warning',
E_CORE_WARNING => 'Core Warning',
E_USER_ERROR => 'User Error',
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
E_COMPILE_ERROR => 'Compile Error',
E_PARSE => 'Parse Error',
E_ERROR => 'Error',
E_CORE_ERROR => 'Core Error',
);

private $loggers = array(
E_DEPRECATED => array(null, LogLevel::INFO),
E_USER_DEPRECATED => array(null, LogLevel::INFO),
E_NOTICE => array(null, LogLevel::WARNING),
E_USER_NOTICE => array(null, LogLevel::WARNING),
E_STRICT => array(null, LogLevel::WARNING),
E_WARNING => array(null, LogLevel::WARNING),
E_USER_WARNING => array(null, LogLevel::WARNING),
E_COMPILE_WARNING => array(null, LogLevel::WARNING),
E_CORE_WARNING => array(null, LogLevel::WARNING),
E_USER_ERROR => array(null, LogLevel::CRITICAL),
E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL),
E_COMPILE_ERROR => array(null, LogLevel::CRITICAL),
E_PARSE => array(null, LogLevel::CRITICAL),
E_ERROR => array(null, LogLevel::CRITICAL),
E_CORE_ERROR => array(null, LogLevel::CRITICAL),
);

private $thrownErrors = 0x1FFF; 
 private $scopedErrors = 0x1FFF; 
 private $tracedErrors = 0x77FB; 
 private $screamedErrors = 0x55; 
 private $loggedErrors = 0;

private $loggedTraces = array();
private $isRecursive = 0;
private $isRoot = false;
private $exceptionHandler;
private $bootstrappingLogger;

private static $reservedMemory;
private static $stackedErrors = array();
private static $stackedErrorLevels = array();
private static $toStringException = null;






private $displayErrors = 0x1FFF;









public static function register($handler = null, $replace = true)
{
if (null === self::$reservedMemory) {
self::$reservedMemory = str_repeat('x', 10240);
register_shutdown_function(__CLASS__.'::handleFatalError');
}

$levels = -1;

if ($handlerIsNew = !$handler instanceof self) {

 if (null !== $handler) {
$levels = $replace ? $handler : 0;
$replace = true;
}
$handler = new static();
}

if (null === $prev = set_error_handler(array($handler, 'handleError'))) {
restore_error_handler();

 set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors);
$handler->isRoot = true;
}

if ($handlerIsNew && is_array($prev) && $prev[0] instanceof self) {
$handler = $prev[0];
$replace = false;
}
if ($replace || !$prev) {
$handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException')));
} else {
restore_error_handler();
}

$handler->throwAt($levels & $handler->thrownErrors, true);

return $handler;
}

public function __construct(BufferingLogger $bootstrappingLogger = null)
{
if ($bootstrappingLogger) {
$this->bootstrappingLogger = $bootstrappingLogger;
$this->setDefaultLogger($bootstrappingLogger);
}
}








public function setDefaultLogger(LoggerInterface $logger, $levels = null, $replace = false)
{
$loggers = array();

if (is_array($levels)) {
foreach ($levels as $type => $logLevel) {
if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {
$loggers[$type] = array($logger, $logLevel);
}
}
} else {
if (null === $levels) {
$levels = E_ALL | E_STRICT;
}
foreach ($this->loggers as $type => $log) {
if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) {
$log[0] = $logger;
$loggers[$type] = $log;
}
}
}

$this->setLoggers($loggers);
}










public function setLoggers(array $loggers)
{
$prevLogged = $this->loggedErrors;
$prev = $this->loggers;
$flush = array();

foreach ($loggers as $type => $log) {
if (!isset($prev[$type])) {
throw new \InvalidArgumentException('Unknown error type: '.$type);
}
if (!is_array($log)) {
$log = array($log);
} elseif (!array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
}
if (null === $log[0]) {
$this->loggedErrors &= ~$type;
} elseif ($log[0] instanceof LoggerInterface) {
$this->loggedErrors |= $type;
} else {
throw new \InvalidArgumentException('Invalid logger provided');
}
$this->loggers[$type] = $log + $prev[$type];

if ($this->bootstrappingLogger && $prev[$type][0] === $this->bootstrappingLogger) {
$flush[$type] = $type;
}
}
$this->reRegister($prevLogged | $this->thrownErrors);

if ($flush) {
foreach ($this->bootstrappingLogger->cleanLogs() as $log) {
$type = $log[2]['type'];
if (!isset($flush[$type])) {
$this->bootstrappingLogger->log($log[0], $log[1], $log[2]);
} elseif ($this->loggers[$type][0]) {
$this->loggers[$type][0]->log($this->loggers[$type][1], $log[1], $log[2]);
}
}
}

return $prev;
}










public function setExceptionHandler($handler)
{
if (null !== $handler && !is_callable($handler)) {
throw new \LogicException('The exception handler must be a valid PHP callable.');
}
$prev = $this->exceptionHandler;
$this->exceptionHandler = $handler;

return $prev;
}









public function throwAt($levels, $replace = false)
{
$prev = $this->thrownErrors;
$this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
if (!$replace) {
$this->thrownErrors |= $prev;
}
$this->reRegister($prev | $this->loggedErrors);


 $this->displayErrors = $this->thrownErrors;

return $prev;
}









public function scopeAt($levels, $replace = false)
{
$prev = $this->scopedErrors;
$this->scopedErrors = (int) $levels;
if (!$replace) {
$this->scopedErrors |= $prev;
}

return $prev;
}









public function traceAt($levels, $replace = false)
{
$prev = $this->tracedErrors;
$this->tracedErrors = (int) $levels;
if (!$replace) {
$this->tracedErrors |= $prev;
}

return $prev;
}









public function screamAt($levels, $replace = false)
{
$prev = $this->screamedErrors;
$this->screamedErrors = (int) $levels;
if (!$replace) {
$this->screamedErrors |= $prev;
}

return $prev;
}




private function reRegister($prev)
{
if ($prev !== $this->thrownErrors | $this->loggedErrors) {
$handler = set_error_handler('var_dump');
$handler = is_array($handler) ? $handler[0] : null;
restore_error_handler();
if ($handler === $this) {
restore_error_handler();
if ($this->isRoot) {
set_error_handler(array($this, 'handleError'), $this->thrownErrors | $this->loggedErrors);
} else {
set_error_handler(array($this, 'handleError'));
}
}
}
}















public function handleError($type, $message, $file, $line)
{
$level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
$log = $this->loggedErrors & $type;
$throw = $this->thrownErrors & $type & $level;
$type &= $level | $this->screamedErrors;

if (!$type || (!$log && !$throw)) {
return $type && $log;
}
$scope = $this->scopedErrors & $type;

if (4 < $numArgs = func_num_args()) {
$context = $scope ? (func_get_arg(4) ?: array()) : array();
$backtrace = 5 < $numArgs ? func_get_arg(5) : null; 
 } else {
$context = array();
$backtrace = null;
}

if (isset($context['GLOBALS']) && $scope) {
$e = $context; 
 unset($e['GLOBALS'], $context); 
 $context = $e;
}

if (null !== $backtrace && $type & E_ERROR) {

 
 
 $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace'));

return true;
}

if ($throw) {
if (null !== self::$toStringException) {
$throw = self::$toStringException;
self::$toStringException = null;
} elseif ($scope && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {

 $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
} else {
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
}

if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {

 
 

$throw->errorHandlerCanary = new ErrorHandlerCanary();
}

if (E_USER_ERROR & $type) {
$backtrace = $backtrace ?: $throw->getTrace();

for ($i = 1; isset($backtrace[$i]); ++$i) {
if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])
&& '__toString' === $backtrace[$i]['function']
&& '->' === $backtrace[$i]['type']
&& !isset($backtrace[$i - 1]['class'])
&& ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])
) {

 
 
 
 
 

foreach ($context as $e) {
if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) {
if (1 === $i) {

 $throw = $e;
break;
}
self::$toStringException = $e;

return true;
}
}

if (1 < $i) {

 $this->handleException($throw);


 return false;
}
}
}
}

throw $throw;
}


 $e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
$trace = true;

if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
$trace = false;
} else {
$this->loggedTraces[$e] = 1;
}

$e = compact('type', 'file', 'line', 'level');

if ($type & $level) {
if ($scope) {
$e['scope_vars'] = $context;
if ($trace) {
$e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
}
} elseif ($trace) {
if (null === $backtrace) {
$e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
} else {
foreach ($backtrace as &$frame) {
unset($frame['args'], $frame);
}
$e['stack'] = $backtrace;
}
}
}

if ($this->isRecursive) {
$log = 0;
} elseif (self::$stackedErrorLevels) {
self::$stackedErrors[] = array($this->loggers[$type][0], ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
} else {
try {
$this->isRecursive = true;
$this->loggers[$type][0]->log(($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
$this->isRecursive = false;
} catch (\Exception $e) {
$this->isRecursive = false;

throw $e;
} catch (\Throwable $e) {
$this->isRecursive = false;

throw $e;
}
}

return $type && $log;
}









public function handleException($exception, array $error = null)
{
if (!$exception instanceof \Exception) {
$exception = new FatalThrowableError($exception);
}
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;

if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
$e = array(
'type' => $type,
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'level' => error_reporting(),
'stack' => $exception->getTrace(),
);
if ($exception instanceof FatalErrorException) {
if ($exception instanceof FatalThrowableError) {
$error = array(
'type' => $type,
'message' => $message = $exception->getMessage(),
'file' => $e['file'],
'line' => $e['line'],
);
} else {
$message = 'Fatal '.$exception->getMessage();
}
} elseif ($exception instanceof \ErrorException) {
$message = 'Uncaught '.$exception->getMessage();
if ($exception instanceof ContextErrorException) {
$e['context'] = $exception->getContext();
}
} else {
$message = 'Uncaught Exception: '.$exception->getMessage();
}
}
if ($this->loggedErrors & $type) {
try {
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
} catch (\Exception $handlerException) {
} catch (\Throwable $handlerException) {
}
}
if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {
foreach ($this->getFatalErrorHandlers() as $handler) {
if ($e = $handler->handleError($error, $exception)) {
$exception = $e;
break;
}
}
}
if (empty($this->exceptionHandler)) {
throw $exception; 
 }
try {
call_user_func($this->exceptionHandler, $exception);
} catch (\Exception $handlerException) {
} catch (\Throwable $handlerException) {
}
if (isset($handlerException)) {
$this->exceptionHandler = null;
$this->handleException($handlerException);
}
}








public static function handleFatalError(array $error = null)
{
if (null === self::$reservedMemory) {
return;
}

self::$reservedMemory = null;

$handler = set_error_handler('var_dump');
$handler = is_array($handler) ? $handler[0] : null;
restore_error_handler();

if (!$handler instanceof self) {
return;
}

if (null === $error) {
$error = error_get_last();
}

try {
while (self::$stackedErrorLevels) {
static::unstackErrors();
}
} catch (\Exception $exception) {

 } catch (\Throwable $exception) {

 }

if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {

 $handler->throwAt(0, true);
$trace = isset($error['backtrace']) ? $error['backtrace'] : null;

if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
$exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false, $trace);
} else {
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);
}
} elseif (!isset($exception)) {
return;
}

try {
$handler->handleException($exception, $error);
} catch (FatalErrorException $e) {

 }
}












public static function stackErrors()
{
self::$stackedErrorLevels[] = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
}




public static function unstackErrors()
{
$level = array_pop(self::$stackedErrorLevels);

if (null !== $level) {
$e = error_reporting($level);
if ($e !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) {

 error_reporting($e);
}
}

if (empty(self::$stackedErrorLevels)) {
$errors = self::$stackedErrors;
self::$stackedErrors = array();

foreach ($errors as $e) {
$e[0]->log($e[1], $e[2], $e[3]);
}
}
}








protected function getFatalErrorHandlers()
{
return array(
new UndefinedFunctionFatalErrorHandler(),
new UndefinedMethodFatalErrorHandler(),
new ClassNotFoundFatalErrorHandler(),
);
}








public function setLevel($level)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);

$level = null === $level ? error_reporting() : $level;
$this->throwAt($level, true);
}








public function setDisplayErrors($displayErrors)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);

if ($displayErrors) {
$this->throwAt($this->displayErrors, true);
} else {
$displayErrors = $this->displayErrors;
$this->throwAt(0, true);
$this->displayErrors = $displayErrors;
}
}









public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
{
@trigger_error('The '.__METHOD__.' static method is deprecated since version 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED);

$handler = set_error_handler('var_dump');
$handler = is_array($handler) ? $handler[0] : null;
restore_error_handler();
if (!$handler instanceof self) {
return;
}
if ('deprecation' === $channel) {
$handler->setDefaultLogger($logger, E_DEPRECATED | E_USER_DEPRECATED, true);
$handler->screamAt(E_DEPRECATED | E_USER_DEPRECATED);
} elseif ('scream' === $channel) {
$handler->setDefaultLogger($logger, E_ALL | E_STRICT, false);
$handler->screamAt(E_ALL | E_STRICT);
} elseif ('emergency' === $channel) {
$handler->setDefaultLogger($logger, E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR, true);
$handler->screamAt(E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
}
}




public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
{
$this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array());

return $this->handleError($level, $message, $file, $line, (array) $context);
}






public function handleFatal()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED);

static::handleFatalError();
}
}








class ErrorHandlerCanary
{
private static $displayErrors = null;

public function __construct()
{
if (null === self::$displayErrors) {
self::$displayErrors = ini_set('display_errors', 1);
}
}

public function __destruct()
{
if (null !== self::$displayErrors) {
ini_set('display_errors', self::$displayErrors);
self::$displayErrors = null;
}
}
}
<?php










namespace Symfony\Component\Debug;












class DebugClassLoader
{
private $classLoader;
private $isFinder;
private $wasFinder;
private static $caseCheck;
private static $deprecated = array();
private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null');
private static $darwinCache = array('/' => array('/', array()));






public function __construct($classLoader)
{
$this->wasFinder = is_object($classLoader) && method_exists($classLoader, 'findFile');

if ($this->wasFinder) {
@trigger_error('The '.__METHOD__.' method will no longer support receiving an object into its $classLoader argument in 3.0.', E_USER_DEPRECATED);
$this->classLoader = array($classLoader, 'loadClass');
$this->isFinder = true;
} else {
$this->classLoader = $classLoader;
$this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile');
}

if (!isset(self::$caseCheck)) {
$file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), DIRECTORY_SEPARATOR);
$i = strrpos($file, DIRECTORY_SEPARATOR);
$dir = substr($file, 0, 1 + $i);
$file = substr($file, 1 + $i);
$test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
$test = realpath($dir.$test);

if (false === $test || false === $i) {

 self::$caseCheck = 0;
} elseif (substr($test, -strlen($file)) === $file) {

 self::$caseCheck = 1;
} elseif (false !== stripos(PHP_OS, 'darwin')) {

 self::$caseCheck = 2;
} else {

 self::$caseCheck = 0;
}
}
}






public function getClassLoader()
{
return $this->wasFinder ? $this->classLoader[0] : $this->classLoader;
}




public static function enable()
{

 class_exists('Symfony\Component\Debug\ErrorHandler');
class_exists('Psr\Log\LogLevel');

if (!is_array($functions = spl_autoload_functions())) {
return;
}

foreach ($functions as $function) {
spl_autoload_unregister($function);
}

foreach ($functions as $function) {
if (!is_array($function) || !$function[0] instanceof self) {
$function = array(new static($function), 'loadClass');
}

spl_autoload_register($function);
}
}




public static function disable()
{
if (!is_array($functions = spl_autoload_functions())) {
return;
}

foreach ($functions as $function) {
spl_autoload_unregister($function);
}

foreach ($functions as $function) {
if (is_array($function) && $function[0] instanceof self) {
$function = $function[0]->getClassLoader();
}

spl_autoload_register($function);
}
}










public function findFile($class)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);

if ($this->wasFinder) {
return $this->classLoader[0]->findFile($class);
}
}










public function loadClass($class)
{
ErrorHandler::stackErrors();

try {
if ($this->isFinder) {
if ($file = $this->classLoader[0]->findFile($class)) {
require_once $file;
}
} else {
call_user_func($this->classLoader, $class);
$file = false;
}
} catch (\Exception $e) {
ErrorHandler::unstackErrors();

throw $e;
} catch (\Throwable $e) {
ErrorHandler::unstackErrors();

throw $e;
}

ErrorHandler::unstackErrors();

$exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));

if ('\\' === $class[0]) {
$class = substr($class, 1);
}

if ($exists) {
$refl = new \ReflectionClass($class);
$name = $refl->getName();

if ($name !== $class && 0 === strcasecmp($name, $class)) {
throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: %s vs %s', $class, $name));
}

if (in_array(strtolower($refl->getShortName()), self::$php7Reserved)) {
@trigger_error(sprintf('%s uses a reserved class name (%s) that will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED);
} elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
} else {
if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
$len = 0;
$ns = '';
} else {
switch ($ns = substr($name, 0, $len)) {
case 'Symfony\Bridge\\':
case 'Symfony\Bundle\\':
case 'Symfony\Component\\':
$ns = 'Symfony\\';
$len = strlen($ns);
break;
}
}
$parent = get_parent_class($class);

if (!$parent || strncmp($ns, $parent, $len)) {
if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) {
@trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED);
}

$parentInterfaces = array();
$deprecatedInterfaces = array();
if ($parent) {
foreach (class_implements($parent) as $interface) {
$parentInterfaces[$interface] = 1;
}
}

foreach ($refl->getInterfaceNames() as $interface) {
if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) {
$deprecatedInterfaces[] = $interface;
}
foreach (class_implements($interface) as $interface) {
$parentInterfaces[$interface] = 1;
}
}

foreach ($deprecatedInterfaces as $interface) {
if (!isset($parentInterfaces[$interface])) {
@trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED);
}
}
}
}
}

if ($file) {
if (!$exists) {
if (false !== strpos($class, '/')) {
throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
}

throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
}
if (self::$caseCheck) {
$real = explode('\\', $class.strrchr($file, '.'));
$tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file));

$i = count($tail) - 1;
$j = count($real) - 1;

while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
--$i;
--$j;
}

array_splice($tail, 0, $i + 1);
}
if (self::$caseCheck && $tail) {
$tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail);
$tailLen = strlen($tail);
$real = $refl->getFileName();

if (2 === self::$caseCheck) {


$i = 1 + strrpos($real, '/');
$file = substr($real, $i);
$real = substr($real, 0, $i);

if (isset(self::$darwinCache[$real])) {
$kDir = $real;
} else {
$kDir = strtolower($real);

if (isset(self::$darwinCache[$kDir])) {
$real = self::$darwinCache[$kDir][0];
} else {
$dir = getcwd();
chdir($real);
$real = getcwd().'/';
chdir($dir);

$dir = $real;
$k = $kDir;
$i = strlen($dir) - 1;
while (!isset(self::$darwinCache[$k])) {
self::$darwinCache[$k] = array($dir, array());
self::$darwinCache[$dir] = &self::$darwinCache[$k];

while ('/' !== $dir[--$i]) {
}
$k = substr($k, 0, ++$i);
$dir = substr($dir, 0, $i--);
}
}
}

$dirFiles = self::$darwinCache[$kDir][1];

if (isset($dirFiles[$file])) {
$kFile = $file;
} else {
$kFile = strtolower($file);

if (!isset($dirFiles[$kFile])) {
foreach (scandir($real, 2) as $f) {
if ('.' !== $f[0]) {
$dirFiles[$f] = $f;
if ($f === $file) {
$kFile = $k = $file;
} elseif ($f !== $k = strtolower($f)) {
$dirFiles[$k] = $f;
}
}
}
self::$darwinCache[$kDir][1] = $dirFiles;
}
}

$real .= $dirFiles[$kFile];
}

if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
&& 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
) {
throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)));
}
}

return true;
}
}
}
<?php










namespace Symfony\Component\Debug;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\Debug\Exception\OutOfMemoryException;













class ExceptionHandler
{
private $debug;
private $charset;
private $handler;
private $caughtBuffer;
private $caughtLength;
private $fileLinkFormat;

public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
{
if (false !== strpos($charset, '%')) {
@trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since version 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED);


 $pivot = $fileLinkFormat;
$fileLinkFormat = $charset;
$charset = $pivot;
}
$this->debug = $debug;
$this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
}










public static function register($debug = true, $charset = null, $fileLinkFormat = null)
{
$handler = new static($debug, $charset, $fileLinkFormat);

$prev = set_exception_handler(array($handler, 'handle'));
if (is_array($prev) && $prev[0] instanceof ErrorHandler) {
restore_exception_handler();
$prev[0]->setExceptionHandler(array($handler, 'handle'));
}

return $handler;
}








public function setHandler($handler)
{
if (null !== $handler && !is_callable($handler)) {
throw new \LogicException('The exception handler must be a valid PHP callable.');
}
$old = $this->handler;
$this->handler = $handler;

return $old;
}








public function setFileLinkFormat($format)
{
$old = $this->fileLinkFormat;
$this->fileLinkFormat = $format;

return $old;
}









public function handle(\Exception $exception)
{
if (null === $this->handler || $exception instanceof OutOfMemoryException) {
$this->failSafeHandle($exception);

return;
}

$caughtLength = $this->caughtLength = 0;

ob_start(array($this, 'catchOutput'));
$this->failSafeHandle($exception);
while (null === $this->caughtBuffer && ob_end_flush()) {

 }
if (isset($this->caughtBuffer[0])) {
ob_start(array($this, 'cleanOutput'));
echo $this->caughtBuffer;
$caughtLength = ob_get_length();
}
$this->caughtBuffer = null;

try {
call_user_func($this->handler, $exception);
$this->caughtLength = $caughtLength;
} catch (\Exception $e) {
if (!$caughtLength) {

 throw $exception;
}
}
}










private function failSafeHandle(\Exception $exception)
{
if (class_exists('Symfony\Component\HttpFoundation\Response', false)
&& __CLASS__ !== get_class($this)
&& ($reflector = new \ReflectionMethod($this, 'createResponse'))
&& __CLASS__ !== $reflector->class
) {
$response = $this->createResponse($exception);
$response->sendHeaders();
$response->sendContent();
@trigger_error(sprintf("The %s::createResponse method is deprecated since 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED);

return;
}

$this->sendPhpResponse($exception);
}









public function sendPhpResponse($exception)
{
if (!$exception instanceof FlattenException) {
$exception = FlattenException::create($exception);
}

if (!headers_sent()) {
header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
foreach ($exception->getHeaders() as $name => $value) {
header($name.': '.$value, false);
}
header('Content-Type: text/html; charset='.$this->charset);
}

echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
}










public function createResponse($exception)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

if (!$exception instanceof FlattenException) {
$exception = FlattenException::create($exception);
}

return Response::create($this->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset($this->charset);
}








public function getHtml($exception)
{
if (!$exception instanceof FlattenException) {
$exception = FlattenException::create($exception);
}

return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
}








public function getContent(FlattenException $exception)
{
switch ($exception->getStatusCode()) {
case 404:
$title = 'Sorry, the page you are looking for could not be found.';
break;
default:
$title = 'Whoops, looks like something went wrong.';
}

$content = '';
if ($this->debug) {
try {
$count = count($exception->getAllPrevious());
$total = $count + 1;
foreach ($exception->toArray() as $position => $e) {
$ind = $count - $position + 1;
$class = $this->formatClass($e['class']);
$message = nl2br($this->escapeHtml($e['message']));
$content .= sprintf(<<<'EOF'
                        <h2 class="block_exception clear_fix">
                            <span class="exception_counter">%d/%d</span>
                            <span class="exception_title">%s%s:</span>
                            <span class="exception_message">%s</span>
                        </h2>
                        <div class="block">
                            <ol class="traces list_exception">

EOF
, $ind, $total, $class, $this->formatPath($e['trace'][0]['file'], $e['trace'][0]['line']), $message);
foreach ($e['trace'] as $trace) {
$content .= '       <li>';
if ($trace['function']) {
$content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
}
if (isset($trace['file']) && isset($trace['line'])) {
$content .= $this->formatPath($trace['file'], $trace['line']);
}
$content .= "</li>\n";
}

$content .= "    </ol>\n</div>\n";
}
} catch (\Exception $e) {

 if ($this->debug) {
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage()));
} else {
$title = 'Whoops, looks like something went wrong.';
}
}
}

return <<<EOF
            <div id="sf-resetcontent" class="sf-reset">
                <h1>$title</h1>
                $content
            </div>
EOF;
}








public function getStylesheet(FlattenException $exception)
{
return <<<'EOF'
            .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }
            .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }
            .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }
            .sf-reset .clear_fix { display:inline-block; }
            .sf-reset * html .clear_fix { height:1%; }
            .sf-reset .clear_fix { display:block; }
            .sf-reset, .sf-reset .block { margin: auto }
            .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
            .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
            .sf-reset strong { font-weight:bold; }
            .sf-reset a { color:#6c6159; cursor: default; }
            .sf-reset a img { border:none; }
            .sf-reset a:hover { text-decoration:underline; }
            .sf-reset em { font-style:italic; }
            .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
            .sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; }
            .sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; }
            .sf-reset .exception_message { margin-left: 3em; display: block; }
            .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
            .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
                -webkit-border-bottom-right-radius: 16px;
                -webkit-border-bottom-left-radius: 16px;
                -moz-border-radius-bottomright: 16px;
                -moz-border-radius-bottomleft: 16px;
                border-bottom-right-radius: 16px;
                border-bottom-left-radius: 16px;
                border-bottom:1px solid #ccc;
                border-right:1px solid #ccc;
                border-left:1px solid #ccc;
                word-wrap: break-word;
            }
            .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;
                -webkit-border-top-left-radius: 16px;
                -webkit-border-top-right-radius: 16px;
                -moz-border-radius-topleft: 16px;
                -moz-border-radius-topright: 16px;
                border-top-left-radius: 16px;
                border-top-right-radius: 16px;
                border-top:1px solid #ccc;
                border-right:1px solid #ccc;
                border-left:1px solid #ccc;
                overflow: hidden;
                word-wrap: break-word;
            }
            .sf-reset a { background:none; color:#868686; text-decoration:none; }
            .sf-reset a:hover { background:none; color:#313131; text-decoration:underline; }
            .sf-reset ol { padding: 10px 0; }
            .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
                -webkit-border-radius: 10px;
                -moz-border-radius: 10px;
                border-radius: 10px;
                border: 1px solid #ccc;
            }
EOF;
}

private function decorate($content, $css)
{
return <<<EOF
<!DOCTYPE html>
<html>
    <head>
        <meta charset="{$this->charset}" />
        <meta name="robots" content="noindex,nofollow" />
        <style>
            /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
            html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}

            html { background: #eee; padding: 10px }
            img { border: 0; }
            #sf-resetcontent { width:970px; margin:0 auto; }
            $css
        </style>
    </head>
    <body>
        $content
    </body>
</html>
EOF;
}

private function formatClass($class)
{
$parts = explode('\\', $class);

return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
}

private function formatPath($path, $line)
{
$path = $this->escapeHtml($path);
$file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path;

if ($linkFormat = $this->fileLinkFormat) {
$link = strtr($this->escapeHtml($linkFormat), array('%f' => $path, '%l' => (int) $line));

return sprintf(' in <a href="%s" title="Go to source">%s line %d</a>', $link, $file, $line);
}

return sprintf(' in <a title="%s line %3$d" ondblclick="var f=this.innerHTML;this.innerHTML=this.title;this.title=f;">%s line %d</a>', $path, $file, $line);
}








private function formatArgs(array $args)
{
$result = array();
foreach ($args as $key => $item) {
if ('object' === $item[0]) {
$formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
} elseif ('array' === $item[0]) {
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
} elseif ('string' === $item[0]) {
$formattedValue = sprintf("'%s'", $this->escapeHtml($item[1]));
} elseif ('null' === $item[0]) {
$formattedValue = '<em>null</em>';
} elseif ('boolean' === $item[0]) {
$formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
} elseif ('resource' === $item[0]) {
$formattedValue = '<em>resource</em>';
} else {
$formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true));
}

$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
}

return implode(', ', $result);
}






protected static function utf8Htmlize($str)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);

return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8');
}




private function escapeHtml($str)
{
return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset);
}




public function catchOutput($buffer)
{
$this->caughtBuffer = $buffer;

return '';
}




public function cleanOutput($buffer)
{
if ($this->caughtLength) {

 $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);
if (isset($cleanBuffer[0])) {
$buffer = $cleanBuffer;
}
}

return $buffer;
}
}
<?php










namespace Symfony\Component\Debug;

use Psr\Log\AbstractLogger;






class BufferingLogger extends AbstractLogger
{
private $logs = array();

public function log($level, $message, array $context = array())
{
$this->logs[] = array($level, $message, $context);
}

public function cleanLogs()
{
$logs = $this->logs;
$this->logs = array();

return $logs;
}
}
<?php










namespace Symfony\Component\Debug;






class Debug
{
private static $enabled = false;












public static function enable($errorReportingLevel = null, $displayErrors = true)
{
if (static::$enabled) {
return;
}

static::$enabled = true;

if (null !== $errorReportingLevel) {
error_reporting($errorReportingLevel);
} else {
error_reporting(-1);
}

if ('cli' !== PHP_SAPI) {
ini_set('display_errors', 0);
ExceptionHandler::register();
} elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) {

 ini_set('display_errors', 1);
}
if ($displayErrors) {
ErrorHandler::register(new ErrorHandler(new BufferingLogger()));
} else {
ErrorHandler::register()->throwAt(0, true);
}

DebugClassLoader::enable();
}
}
<?php










namespace Symfony\Component\Debug\Tests;

use PHPUnit\Framework\TestCase;
use Psr\Log\LogLevel;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\BufferingLogger;
use Symfony\Component\Debug\Exception\ContextErrorException;







class ErrorHandlerTest extends TestCase
{
public function testRegister()
{
$handler = ErrorHandler::register();

try {
$this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
$this->assertSame($handler, ErrorHandler::register());

$newHandler = new ErrorHandler();

$this->assertSame($newHandler, ErrorHandler::register($newHandler, false));
$h = set_error_handler('var_dump');
restore_error_handler();
$this->assertSame(array($handler, 'handleError'), $h);

try {
$this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
$h = set_error_handler('var_dump');
restore_error_handler();
$this->assertSame(array($newHandler, 'handleError'), $h);
} catch (\Exception $e) {
}

restore_error_handler();
restore_exception_handler();

if (isset($e)) {
throw $e;
}
} catch (\Exception $e) {
}

restore_error_handler();
restore_exception_handler();

if (isset($e)) {
throw $e;
}
}

public function testNotice()
{
ErrorHandler::register();

try {
self::triggerNotice($this);
$this->fail('ContextErrorException expected');
} catch (ContextErrorException $exception) {

 restore_error_handler();
restore_exception_handler();

$this->assertEquals(E_NOTICE, $exception->getSeverity());
$this->assertEquals(__FILE__, $exception->getFile());
$this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
$this->assertArrayHasKey('foobar', $exception->getContext());

$trace = $exception->getTrace();
$this->assertEquals(__FILE__, $trace[0]['file']);
$this->assertEquals('Symfony\Component\Debug\ErrorHandler', $trace[0]['class']);
$this->assertEquals('handleError', $trace[0]['function']);
$this->assertEquals('->', $trace[0]['type']);

$this->assertEquals(__FILE__, $trace[1]['file']);
$this->assertEquals(__CLASS__, $trace[1]['class']);
$this->assertEquals('triggerNotice', $trace[1]['function']);
$this->assertEquals('::', $trace[1]['type']);

$this->assertEquals(__FILE__, $trace[1]['file']);
$this->assertEquals(__CLASS__, $trace[2]['class']);
$this->assertEquals(__FUNCTION__, $trace[2]['function']);
$this->assertEquals('->', $trace[2]['type']);
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}


 private static function triggerNotice($that)
{

 $foobar = 123;
$that->assertSame('', $foo.$foo.$bar);
}

public function testConstruct()
{
try {
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
$this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}

public function testDefaultLogger()
{
try {
$handler = ErrorHandler::register();

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$handler->setDefaultLogger($logger, E_NOTICE);
$handler->setDefaultLogger($logger, array(E_USER_NOTICE => LogLevel::CRITICAL));

$loggers = array(
E_DEPRECATED => array(null, LogLevel::INFO),
E_USER_DEPRECATED => array(null, LogLevel::INFO),
E_NOTICE => array($logger, LogLevel::WARNING),
E_USER_NOTICE => array($logger, LogLevel::CRITICAL),
E_STRICT => array(null, LogLevel::WARNING),
E_WARNING => array(null, LogLevel::WARNING),
E_USER_WARNING => array(null, LogLevel::WARNING),
E_COMPILE_WARNING => array(null, LogLevel::WARNING),
E_CORE_WARNING => array(null, LogLevel::WARNING),
E_USER_ERROR => array(null, LogLevel::CRITICAL),
E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL),
E_COMPILE_ERROR => array(null, LogLevel::CRITICAL),
E_PARSE => array(null, LogLevel::CRITICAL),
E_ERROR => array(null, LogLevel::CRITICAL),
E_CORE_ERROR => array(null, LogLevel::CRITICAL),
);
$this->assertSame($loggers, $handler->setLoggers(array()));

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}

public function testHandleError()
{
try {
$handler = ErrorHandler::register();
$handler->throwAt(0, true);
$this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register();
$handler->throwAt(3, true);
$this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register();
$handler->throwAt(3, true);
try {
$handler->handleError(4, 'foo', 'foo.php', 12, array());
} catch (\ErrorException $e) {
$this->assertSame('Parse Error: foo', $e->getMessage());
$this->assertSame(4, $e->getSeverity());
$this->assertSame('foo.php', $e->getFile());
$this->assertSame(12, $e->getLine());
}

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register();
$handler->throwAt(E_USER_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$handler = ErrorHandler::register();
$handler->throwAt(E_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$that = $this;
$warnArgCheck = function ($logLevel, $message, $context) use ($that) {
$that->assertEquals('info', $logLevel);
$that->assertEquals('foo', $message);
$that->assertArrayHasKey('type', $context);
$that->assertEquals($context['type'], E_USER_DEPRECATED);
$that->assertArrayHasKey('stack', $context);
$that->assertInternalType('array', $context['stack']);
};

$logger
->expects($this->once())
->method('log')
->will($this->returnCallback($warnArgCheck))
;

$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_USER_DEPRECATED);
$this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$that = $this;
$logArgCheck = function ($level, $message, $context) use ($that) {
$that->assertEquals('Undefined variable: undefVar', $message);
$that->assertArrayHasKey('type', $context);
$that->assertEquals($context['type'], E_NOTICE);
};

$logger
->expects($this->once())
->method('log')
->will($this->returnCallback($logArgCheck))
;

$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->screamAt(E_NOTICE);
unset($undefVar);
@$undefVar++;

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}

public function testHandleUserError()
{
try {
$handler = ErrorHandler::register();
$handler->throwAt(0, true);

$e = null;
$x = new \Exception('Foo');

try {
$f = new Fixtures\ToStringThrower($x);
$f .= ''; 
 } catch (\Exception $e) {
}

$this->assertSame($x, $e);

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}

public function testHandleDeprecation()
{
$that = $this;
$logArgCheck = function ($level, $message, $context) use ($that) {
$that->assertEquals(LogLevel::INFO, $level);
$that->assertArrayHasKey('level', $context);
$that->assertEquals(E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED, $context['level']);
$that->assertArrayHasKey('stack', $context);
};

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger
->expects($this->once())
->method('log')
->will($this->returnCallback($logArgCheck))
;

$handler = new ErrorHandler();
$handler->setDefaultLogger($logger);
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, array());
}

public function testHandleException()
{
try {
$handler = ErrorHandler::register();

$exception = new \Exception('foo');

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$that = $this;
$logArgCheck = function ($level, $message, $context) use ($that) {
$that->assertEquals('Uncaught Exception: foo', $message);
$that->assertArrayHasKey('type', $context);
$that->assertEquals($context['type'], E_ERROR);
};

$logger
->expects($this->exactly(2))
->method('log')
->will($this->returnCallback($logArgCheck))
;

$handler->setDefaultLogger($logger, E_ERROR);

try {
$handler->handleException($exception);
$this->fail('Exception expected');
} catch (\Exception $e) {
$this->assertSame($exception, $e);
}

$that = $this;
$handler->setExceptionHandler(function ($e) use ($exception, $that) {
$that->assertSame($exception, $e);
});

$handler->handleException($exception);

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}

public function testErrorStacking()
{
try {
$handler = ErrorHandler::register();
$handler->screamAt(E_USER_WARNING);

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$logger
->expects($this->exactly(2))
->method('log')
->withConsecutive(
array($this->equalTo(LogLevel::WARNING), $this->equalTo('Dummy log')),
array($this->equalTo(LogLevel::DEBUG), $this->equalTo('Silenced warning'))
)
;

$handler->setDefaultLogger($logger, array(E_USER_WARNING => LogLevel::WARNING));

ErrorHandler::stackErrors();
@trigger_error('Silenced warning', E_USER_WARNING);
$logger->log(LogLevel::WARNING, 'Dummy log');
ErrorHandler::unstackErrors();

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}

public function testBootstrappingLogger()
{
$bootLogger = new BufferingLogger();
$handler = new ErrorHandler($bootLogger);

$loggers = array(
E_DEPRECATED => array($bootLogger, LogLevel::INFO),
E_USER_DEPRECATED => array($bootLogger, LogLevel::INFO),
E_NOTICE => array($bootLogger, LogLevel::WARNING),
E_USER_NOTICE => array($bootLogger, LogLevel::WARNING),
E_STRICT => array($bootLogger, LogLevel::WARNING),
E_WARNING => array($bootLogger, LogLevel::WARNING),
E_USER_WARNING => array($bootLogger, LogLevel::WARNING),
E_COMPILE_WARNING => array($bootLogger, LogLevel::WARNING),
E_CORE_WARNING => array($bootLogger, LogLevel::WARNING),
E_USER_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_RECOVERABLE_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_COMPILE_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_PARSE => array($bootLogger, LogLevel::CRITICAL),
E_ERROR => array($bootLogger, LogLevel::CRITICAL),
E_CORE_ERROR => array($bootLogger, LogLevel::CRITICAL),
);

$this->assertSame($loggers, $handler->setLoggers(array()));

$handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, array());
$expectedLog = array(LogLevel::INFO, 'Foo message', array('type' => E_DEPRECATED, 'file' => __FILE__, 'line' => 123, 'level' => error_reporting()));

$logs = $bootLogger->cleanLogs();
unset($logs[0][2]['stack']);

$this->assertSame(array($expectedLog), $logs);

$bootLogger->log($expectedLog[0], $expectedLog[1], $expectedLog[2]);

$mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$mockLogger->expects($this->once())
->method('log')
->with(LogLevel::WARNING, 'Foo message', $expectedLog[2]);

$handler->setLoggers(array(E_DEPRECATED => array($mockLogger, LogLevel::WARNING)));
}

public function testHandleFatalError()
{
try {
$handler = ErrorHandler::register();

$error = array(
'type' => E_PARSE,
'message' => 'foo',
'file' => 'bar',
'line' => 123,
);

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$that = $this;
$logArgCheck = function ($level, $message, $context) use ($that) {
$that->assertEquals('Fatal Parse Error: foo', $message);
$that->assertArrayHasKey('type', $context);
$that->assertEquals($context['type'], E_PARSE);
};

$logger
->expects($this->once())
->method('log')
->will($this->returnCallback($logArgCheck))
;

$handler->setDefaultLogger($logger, E_PARSE);

$handler->handleFatalError($error);

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}




public function testHandleErrorException()
{
$exception = new \Error("Class 'Foo' not found");

$handler = new ErrorHandler();
$handler->setExceptionHandler(function () use (&$args) {
$args = func_get_args();
});

$handler->handleException($exception);

$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
$this->assertStringStartsWith("Attempted to load class \"Foo\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
}

public function testHandleFatalErrorOnHHVM()
{
try {
$handler = ErrorHandler::register();

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger
->expects($this->once())
->method('log')
->with(
$this->equalTo(LogLevel::CRITICAL),
$this->equalTo('Fatal Error: foo'),
$this->equalTo(array(
'type' => 1,
'file' => 'bar',
'line' => 123,
'level' => -1,
'stack' => array(456),
))
)
;

$handler->setDefaultLogger($logger, E_ERROR);

$error = array(
'type' => E_ERROR + 0x1000000, 
 'message' => 'foo',
'file' => 'bar',
'line' => 123,
'context' => array(123),
'backtrace' => array(456),
);

call_user_func_array(array($handler, 'handleError'), $error);
$handler->handleFatalError($error);

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}




public function testLegacyInterface()
{
try {
$handler = ErrorHandler::register(0);
$this->assertFalse($handler->handle(0, 'foo', 'foo.php', 12, array()));

restore_error_handler();
restore_exception_handler();

$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

$that = $this;
$logArgCheck = function ($level, $message, $context) use ($that) {
$that->assertEquals('Undefined variable: undefVar', $message);
$that->assertArrayHasKey('type', $context);
$that->assertEquals($context['type'], E_NOTICE);
};

$logger
->expects($this->once())
->method('log')
->will($this->returnCallback($logArgCheck))
;

$handler = ErrorHandler::register(E_NOTICE);
@$handler->setLogger($logger, 'scream');
unset($undefVar);
@$undefVar++;

restore_error_handler();
restore_exception_handler();
} catch (\Exception $e) {
restore_error_handler();
restore_exception_handler();

throw $e;
}
}
}
<?php










namespace Symfony\Component\Debug\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;

require_once __DIR__.'/HeaderMock.php';

class ExceptionHandlerTest extends TestCase
{
protected function setUp()
{
testHeader();
}

protected function tearDown()
{
testHeader();
}

public function testDebug()
{
$handler = new ExceptionHandler(false);

ob_start();
$handler->sendPhpResponse(new \RuntimeException('Foo'));
$response = ob_get_clean();

$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response);
$this->assertNotContains('<h2 class="block_exception clear_fix">', $response);

$handler = new ExceptionHandler(true);

ob_start();
$handler->sendPhpResponse(new \RuntimeException('Foo'));
$response = ob_get_clean();

$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response);
$this->assertContains('<h2 class="block_exception clear_fix">', $response);
}

public function testStatusCode()
{
$handler = new ExceptionHandler(false, 'iso8859-1');

ob_start();
$handler->sendPhpResponse(new NotFoundHttpException('Foo'));
$response = ob_get_clean();

$this->assertContains('Sorry, the page you are looking for could not be found.', $response);

$expectedHeaders = array(
array('HTTP/1.0 404', true, null),
array('Content-Type: text/html; charset=iso8859-1', true, null),
);

$this->assertSame($expectedHeaders, testHeader());
}

public function testHeaders()
{
$handler = new ExceptionHandler(false, 'iso8859-1');

ob_start();
$handler->sendPhpResponse(new MethodNotAllowedHttpException(array('POST')));
$response = ob_get_clean();

$expectedHeaders = array(
array('HTTP/1.0 405', true, null),
array('Allow: POST', false, null),
array('Content-Type: text/html; charset=iso8859-1', true, null),
);

$this->assertSame($expectedHeaders, testHeader());
}

public function testNestedExceptions()
{
$handler = new ExceptionHandler(true);
ob_start();
$handler->sendPhpResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar')));
$response = ob_get_clean();

$this->assertStringMatchesFormat('%A<span class="exception_message">Foo</span>%A<span class="exception_message">Bar</span>%A', $response);
}

public function testHandle()
{
$exception = new \Exception('foo');

$handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(array('sendPhpResponse'))->getMock();
$handler
->expects($this->exactly(2))
->method('sendPhpResponse');

$handler->handle($exception);

$that = $this;
$handler->setHandler(function ($e) use ($exception, $that) {
$that->assertSame($exception, $e);
});

$handler->handle($exception);
}

public function testHandleOutOfMemoryException()
{
$exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__);

$handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(array('sendPhpResponse'))->getMock();
$handler
->expects($this->once())
->method('sendPhpResponse');

$that = $this;
$handler->setHandler(function ($e) use ($that) {
$that->fail('OutOfMemoryException should bypass the handler');
});

$handler->handle($exception);
}
}
<?php










namespace Symfony\Component\Debug;

function headers_sent()
{
return false;
}

function header($str, $replace = true, $status = null)
{
Tests\testHeader($str, $replace, $status);
}

namespace Symfony\Component\Debug\Tests;

function testHeader()
{
static $headers = array();

if (!$h = func_get_args()) {
$h = $headers;
$headers = array();

return $h;
}

$headers[] = func_get_args();
}
<?php










namespace Symfony\Component\Debug\Tests;

use Symfony\Component\Debug\ExceptionHandler;

class MockExceptionHandler extends ExceptionHandler
{
public $e;

public function handle(\Exception $e)
{
$this->e = $e;
}
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

class NotPSR0
{
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

class PSR4CaseMismatch
{
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;






class DeprecatedClass
{
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;






interface DeprecatedInterface
{
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

class CaseMismatch
{
}
<?php

class Symfony_Component_Debug_Tests_Fixtures_PEARClass
{
}
<?php

class_alias('Symfony\Component\Debug\Tests\Fixtures\NotPSR0bis', 'Symfony\Component\Debug\Tests\Fixtures\ClassAlias');
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

interface NonDeprecatedInterface extends DeprecatedInterface
{
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

class ToStringThrower
{
private $exception;

public function __construct(\Exception $e)
{
$this->exception = $e;
}

public function __toString()
{
try {
throw $this->exception;
} catch (\Exception $e) {

 
 return user_error($e, E_USER_ERROR);
}
}
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures;

class NotPSR0bis
{
}
<?php










namespace Symfony\Component\Debug\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\DebugClassLoader;
use Symfony\Component\Debug\ErrorHandler;

class DebugClassLoaderTest extends TestCase
{



private $errorReporting;

private $loader;

protected function setUp()
{
$this->errorReporting = error_reporting(E_ALL | E_STRICT);
$this->loader = new ClassLoader();
spl_autoload_register(array($this->loader, 'loadClass'), true, true);
DebugClassLoader::enable();
}

protected function tearDown()
{
DebugClassLoader::disable();
spl_autoload_unregister(array($this->loader, 'loadClass'));
error_reporting($this->errorReporting);
}

public function testIdempotence()
{
DebugClassLoader::enable();

$functions = spl_autoload_functions();
foreach ($functions as $function) {
if (is_array($function) && $function[0] instanceof DebugClassLoader) {
$reflClass = new \ReflectionClass($function[0]);
$reflProp = $reflClass->getProperty('classLoader');
$reflProp->setAccessible(true);

$this->assertNotInstanceOf('Symfony\Component\Debug\DebugClassLoader', $reflProp->getValue($function[0]));

return;
}
}

$this->fail('DebugClassLoader did not register');
}

public function testUnsilencing()
{
if (PHP_VERSION_ID >= 70000) {
$this->markTestSkipped('PHP7 throws exceptions, unsilencing is not required anymore.');
}
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('HHVM is not handled in this test case.');
}

ob_start();

$this->iniSet('log_errors', 0);
$this->iniSet('display_errors', 1);


 
 @class_exists(__NAMESPACE__.'\TestingUnsilencing', true);

$output = ob_get_clean();

$this->assertStringMatchesFormat('%aParse error%a', $output);
}

public function testStacking()
{

 
 if (class_exists('Symfony\Component\Debug\Exception\ContextErrorException', false)) {
$this->markTestSkipped('The ContextErrorException class is already loaded.');
}
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('HHVM is not handled in this test case.');
}

ErrorHandler::register();

try {

 
 
 

eval('
                namespace '.__NAMESPACE__.';
                class ChildTestingStacking extends TestingStacking { function foo($bar) {} }
            ');
$this->fail('ContextErrorException expected');
} catch (\ErrorException $exception) {

 restore_error_handler();
restore_exception_handler();
$this->assertStringStartsWith(__FILE__, $exception->getFile());
if (PHP_VERSION_ID < 70000) {
$this->assertRegExp('/^Runtime Notice: Declaration/', $exception->getMessage());
$this->assertEquals(E_STRICT, $exception->getSeverity());
} else {
$this->assertRegExp('/^Warning: Declaration/', $exception->getMessage());
$this->assertEquals(E_WARNING, $exception->getSeverity());
}
} catch (\Exception $exception) {
restore_error_handler();
restore_exception_handler();

throw $exception;
}
}




public function testNameCaseMismatch()
{
class_exists(__NAMESPACE__.'\TestingCaseMismatch', true);
}





public function testFileCaseMismatch()
{
if (!file_exists(__DIR__.'/Fixtures/CaseMismatch.php')) {
$this->markTestSkipped('Can only be run on case insensitive filesystems');
}

class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true);
}




public function testPsr4CaseMismatch()
{
class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true);
}

public function testNotPsr0()
{
$this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0', true));
}

public function testNotPsr0Bis()
{
$this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0bis', true));
}

public function testClassAlias()
{
$this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\ClassAlias', true));
}




public function testDeprecatedSuper($class, $super, $type)
{
set_error_handler(function () { return false; });
$e = error_reporting(0);
trigger_error('', E_USER_DEPRECATED);

class_exists('Test\\'.__NAMESPACE__.'\\'.$class, true);

error_reporting($e);
restore_error_handler();

$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);

$xError = array(
'type' => E_USER_DEPRECATED,
'message' => 'The Test\Symfony\Component\Debug\Tests\\'.$class.' class '.$type.' Symfony\Component\Debug\Tests\Fixtures\\'.$super.' that is deprecated but this is a test deprecation notice.',
);

$this->assertSame($xError, $lastError);
}

public function provideDeprecatedSuper()
{
return array(
array('DeprecatedInterfaceClass', 'DeprecatedInterface', 'implements'),
array('DeprecatedParentClass', 'DeprecatedClass', 'extends'),
);
}

public function testInterfaceExtendsDeprecatedInterface()
{
set_error_handler(function () { return false; });
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);

class_exists('Test\\'.__NAMESPACE__.'\\NonDeprecatedInterfaceClass', true);

error_reporting($e);
restore_error_handler();

$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);

$xError = array(
'type' => E_USER_NOTICE,
'message' => '',
);

$this->assertSame($xError, $lastError);
}

public function testDeprecatedSuperInSameNamespace()
{
set_error_handler(function () { return false; });
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);

class_exists('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent', true);

error_reporting($e);
restore_error_handler();

$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);

$xError = array(
'type' => E_USER_NOTICE,
'message' => '',
);

$this->assertSame($xError, $lastError);
}

public function testReservedForPhp7()
{
if (PHP_VERSION_ID >= 70000) {
$this->markTestSkipped('PHP7 already prevents using reserved names.');
}

set_error_handler(function () { return false; });
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);

class_exists('Test\\'.__NAMESPACE__.'\\Float', true);

error_reporting($e);
restore_error_handler();

$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);

$xError = array(
'type' => E_USER_DEPRECATED,
'message' => 'Test\Symfony\Component\Debug\Tests\Float uses a reserved class name (Float) that will break on PHP 7 and higher',
);

$this->assertSame($xError, $lastError);
}
}

class ClassLoader
{
public function loadClass($class)
{
}

public function getClassMap()
{
return array(__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php');
}

public function findFile($class)
{
$fixtureDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR;

if (__NAMESPACE__.'\TestingUnsilencing' === $class) {
eval('-- parse error --');
} elseif (__NAMESPACE__.'\TestingStacking' === $class) {
eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }');
} elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) {
eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');
} elseif (__NAMESPACE__.'\Fixtures\CaseMismatch' === $class) {
return $fixtureDir.'CaseMismatch.php';
} elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) {
return $fixtureDir.'psr4'.DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) {
return $fixtureDir.'reallyNotPsr0.php';
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) {
return $fixtureDir.'notPsr0Bis.php';
} elseif (__NAMESPACE__.'\Fixtures\DeprecatedInterface' === $class) {
return $fixtureDir.'DeprecatedInterface.php';
} elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) {
eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedInterfaceClass' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\DeprecatedInterface {}');
} elseif ('Test\\'.__NAMESPACE__.'\NonDeprecatedInterfaceClass' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
} elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
}
}
}
<?php

namespace Symfony\Component\Debug\Tests\Fixtures2;

class RequiredTwice
{
}
<?php










namespace Symfony\Component\Debug\Tests\FatalErrorHandler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;

class UndefinedFunctionFatalErrorHandlerTest extends TestCase
{



public function testUndefinedFunction($error, $translatedMessage)
{
$handler = new UndefinedFunctionFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));

$this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedFunctionException', $exception);

 $this->assertSame(strtolower($translatedMessage), strtolower($exception->getMessage()));
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
$this->assertSame($error['line'], $exception->getLine());
}

public function provideUndefinedFunctionData()
{
return array(
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function test_namespaced_function()',
),
"Attempted to call function \"test_namespaced_function\" from the global namespace.\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function Foo\\Bar\\Baz\\test_namespaced_function()',
),
"Attempted to call function \"test_namespaced_function\" from namespace \"Foo\\Bar\\Baz\".\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function foo()',
),
'Attempted to call function "foo" from the global namespace.',
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined function Foo\\Bar\\Baz\\foo()',
),
'Attempted to call function "foo" from namespace "Foo\Bar\Baz".',
),
);
}
}

function test_namespaced_function()
{
}
<?php










namespace Symfony\Component\Debug\Tests\FatalErrorHandler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
use Symfony\Component\Debug\DebugClassLoader;
use Composer\Autoload\ClassLoader as ComposerClassLoader;

class ClassNotFoundFatalErrorHandlerTest extends TestCase
{
public static function setUpBeforeClass()
{
foreach (spl_autoload_functions() as $function) {
if (!is_array($function)) {
continue;
}


 if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();
}

if ($function[0] instanceof ComposerClassLoader) {
$function[0]->add('Symfony_Component_Debug_Tests_Fixtures', dirname(dirname(dirname(dirname(dirname(__DIR__))))));
break;
}
}
}




public function testHandleClassNotFound($error, $translatedMessage, $autoloader = null)
{
if ($autoloader) {

 
 $autoloaders = spl_autoload_functions();
array_map('spl_autoload_unregister', $autoloaders);
spl_autoload_register($autoloader);
}

$handler = new ClassNotFoundFatalErrorHandler();

$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));

if ($autoloader) {
spl_autoload_unregister($autoloader);
array_map('spl_autoload_register', $autoloaders);
}

$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
$this->assertSame($error['line'], $exception->getLine());
}




public function testLegacyHandleClassNotFound()
{
$prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception'));
$symfonyUniversalClassLoader = new SymfonyUniversalClassLoader();
$symfonyUniversalClassLoader->registerPrefixes($prefixes);

$this->testHandleClassNotFound(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
array($symfonyUniversalClassLoader, 'loadClass')
);
}

public function provideClassNotFoundData()
{
$prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception'));

$symfonyAutoloader = new SymfonyClassLoader();
$symfonyAutoloader->addPrefixes($prefixes);

$debugClassLoader = new DebugClassLoader(array($symfonyAutoloader, 'loadClass'));

return array(
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'WhizBangFactory\' not found',
),
"Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\WhizBangFactory\' not found',
),
"Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'UndefinedFunctionException\' not found',
),
"Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'PEARClass\' not found',
),
"Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
array($symfonyAutoloader, 'loadClass'),
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
array($debugClassLoader, 'loadClass'),
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
),
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
function ($className) {  },
),
);
}

public function testCannotRedeclareClass()
{
if (!file_exists(__DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP')) {
$this->markTestSkipped('Can only be run on case insensitive filesystems');
}

require_once __DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP';

$error = array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Class \'Foo\\Bar\\RequiredTwice\' not found',
);

$handler = new ClassNotFoundFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));

$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
}
}
<?php










namespace Symfony\Component\Debug\Tests\FatalErrorHandler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;

class UndefinedMethodFatalErrorHandlerTest extends TestCase
{



public function testUndefinedMethod($error, $translatedMessage)
{
$handler = new UndefinedMethodFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));

$this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedMethodException', $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
$this->assertSame($error['line'], $exception->getLine());
}

public function provideUndefinedMethodData()
{
return array(
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::what()',
),
'Attempted to call an undefined method named "what" of class "SplObjectStorage".',
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::walid()',
),
"Attempted to call an undefined method named \"walid\" of class \"SplObjectStorage\".\nDid you mean to call \"valid\"?",
),
array(
array(
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::offsetFet()',
),
"Attempted to call an undefined method named \"offsetFet\" of class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?",
),
array(
array(
'type' => 1,
'message' => 'Call to undefined method class@anonymous::test()',
'file' => '/home/possum/work/symfony/test.php',
'line' => 11,
),
'Attempted to call an undefined method named "test" of class "class@anonymous".',
),
);
}
}
<?php










namespace Symfony\Component\Debug\Tests\Exception;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;

class FlattenExceptionTest extends TestCase
{
public function testStatusCode()
{
$flattened = FlattenException::create(new \RuntimeException(), 403);
$this->assertEquals('403', $flattened->getStatusCode());

$flattened = FlattenException::create(new \RuntimeException());
$this->assertEquals('500', $flattened->getStatusCode());

$flattened = FlattenException::create(new NotFoundHttpException());
$this->assertEquals('404', $flattened->getStatusCode());

$flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));
$this->assertEquals('401', $flattened->getStatusCode());

$flattened = FlattenException::create(new BadRequestHttpException());
$this->assertEquals('400', $flattened->getStatusCode());

$flattened = FlattenException::create(new NotAcceptableHttpException());
$this->assertEquals('406', $flattened->getStatusCode());

$flattened = FlattenException::create(new ConflictHttpException());
$this->assertEquals('409', $flattened->getStatusCode());

$flattened = FlattenException::create(new MethodNotAllowedHttpException(array('POST')));
$this->assertEquals('405', $flattened->getStatusCode());

$flattened = FlattenException::create(new AccessDeniedHttpException());
$this->assertEquals('403', $flattened->getStatusCode());

$flattened = FlattenException::create(new GoneHttpException());
$this->assertEquals('410', $flattened->getStatusCode());

$flattened = FlattenException::create(new LengthRequiredHttpException());
$this->assertEquals('411', $flattened->getStatusCode());

$flattened = FlattenException::create(new PreconditionFailedHttpException());
$this->assertEquals('412', $flattened->getStatusCode());

$flattened = FlattenException::create(new PreconditionRequiredHttpException());
$this->assertEquals('428', $flattened->getStatusCode());

$flattened = FlattenException::create(new ServiceUnavailableHttpException());
$this->assertEquals('503', $flattened->getStatusCode());

$flattened = FlattenException::create(new TooManyRequestsHttpException());
$this->assertEquals('429', $flattened->getStatusCode());

$flattened = FlattenException::create(new UnsupportedMediaTypeHttpException());
$this->assertEquals('415', $flattened->getStatusCode());
}

public function testHeadersForHttpException()
{
$flattened = FlattenException::create(new MethodNotAllowedHttpException(array('POST')));
$this->assertEquals(array('Allow' => 'POST'), $flattened->getHeaders());

$flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));
$this->assertEquals(array('WWW-Authenticate' => 'Basic realm="My Realm"'), $flattened->getHeaders());

$flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));
$this->assertEquals(array('Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'), $flattened->getHeaders());

$flattened = FlattenException::create(new ServiceUnavailableHttpException(120));
$this->assertEquals(array('Retry-After' => 120), $flattened->getHeaders());

$flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));
$this->assertEquals(array('Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'), $flattened->getHeaders());

$flattened = FlattenException::create(new TooManyRequestsHttpException(120));
$this->assertEquals(array('Retry-After' => 120), $flattened->getHeaders());
}




public function testFlattenHttpException(\Exception $exception, $statusCode)
{
$flattened = FlattenException::create($exception);
$flattened2 = FlattenException::create($exception);

$flattened->setPrevious($flattened2);

$this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.');
$this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.');
$this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');
}




public function testPrevious(\Exception $exception, $statusCode)
{
$flattened = FlattenException::create($exception);
$flattened2 = FlattenException::create($exception);

$flattened->setPrevious($flattened2);

$this->assertSame($flattened2, $flattened->getPrevious());

$this->assertSame(array($flattened2), $flattened->getAllPrevious());
}




public function testPreviousError()
{
$exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42));

$flattened = FlattenException::create($exception)->getPrevious();

$this->assertEquals($flattened->getMessage(), 'Parse error: Oh noes!', 'The message is copied from the original exception.');
$this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.');
$this->assertEquals($flattened->getClass(), 'Symfony\Component\Debug\Exception\FatalThrowableError', 'The class is set to the class of the original exception');
}




public function testLine(\Exception $exception)
{
$flattened = FlattenException::create($exception);
$this->assertSame($exception->getLine(), $flattened->getLine());
}




public function testFile(\Exception $exception)
{
$flattened = FlattenException::create($exception);
$this->assertSame($exception->getFile(), $flattened->getFile());
}




public function testToArray(\Exception $exception, $statusCode)
{
$flattened = FlattenException::create($exception);
$flattened->setTrace(array(), 'foo.php', 123);

$this->assertEquals(array(
array(
'message' => 'test',
'class' => 'Exception',
'trace' => array(array(
'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123,
'args' => array(),
)),
),
), $flattened->toArray());
}

public function flattenDataProvider()
{
return array(
array(new \Exception('test', 123), 500),
);
}

public function testRecursionInArguments()
{
$a = array('foo', array(2, &$a));
$exception = $this->createException($a);

$flattened = FlattenException::create($exception);
$trace = $flattened->getTrace();
$this->assertContains('*DEEP NESTED ARRAY*', serialize($trace));
}

public function testTooBigArray()
{
$a = array();
for ($i = 0; $i < 20; ++$i) {
for ($j = 0; $j < 50; ++$j) {
for ($k = 0; $k < 10; ++$k) {
$a[$i][$j][$k] = 'value';
}
}
}
$a[20] = 'value';
$a[21] = 'value1';
$exception = $this->createException($a);

$flattened = FlattenException::create($exception);
$trace = $flattened->getTrace();
$serializeTrace = serialize($trace);

$this->assertContains('*SKIPPED over 10000 entries*', $serializeTrace);
$this->assertNotContains('*value1*', $serializeTrace);
}

private function createException($foo)
{
return new \Exception();
}

public function testSetTraceIncompleteClass()
{
$flattened = FlattenException::create(new \Exception('test', 123));
$flattened->setTrace(
array(
array(
'file' => __FILE__,
'line' => 123,
'function' => 'test',
'args' => array(
unserialize('O:14:"BogusTestClass":0:{}'),
),
),
),
'foo.php', 123
);

$this->assertEquals(array(
array(
'message' => 'test',
'class' => 'Exception',
'trace' => array(
array(
'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '',
'file' => 'foo.php', 'line' => 123,
'args' => array(),
),
array(
'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => 'test',
'file' => __FILE__, 'line' => 123,
'args' => array(
array(
'incomplete-object', 'BogusTestClass',
),
),
),
),
),
), $flattened->toArray());
}
}
<?php










namespace Symfony\Component\Debug\FatalErrorHandler;

use Symfony\Component\Debug\Exception\UndefinedFunctionException;
use Symfony\Component\Debug\Exception\FatalErrorException;






class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
{



public function handleError(array $error, FatalErrorException $exception)
{
$messageLen = strlen($error['message']);
$notFoundSuffix = '()';
$notFoundSuffixLen = strlen($notFoundSuffix);
if ($notFoundSuffixLen > $messageLen) {
return;
}

if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
return;
}

$prefix = 'Call to undefined function ';
$prefixLen = strlen($prefix);
if (0 !== strpos($error['message'], $prefix)) {
return;
}

$fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) {
$functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1);
$namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex);
$message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix);
} else {
$functionName = $fullyQualifiedFunctionName;
$message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName);
}

$candidates = array();
foreach (get_defined_functions() as $type => $definedFunctionNames) {
foreach ($definedFunctionNames as $definedFunctionName) {
if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) {
$definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1);
} else {
$definedFunctionNameBasename = $definedFunctionName;
}

if ($definedFunctionNameBasename === $functionName) {
$candidates[] = '\\'.$definedFunctionName;
}
}
}

if ($candidates) {
sort($candidates);
$last = array_pop($candidates).'"?';
if ($candidates) {
$candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
} else {
$candidates = '"'.$last;
}
$message .= "\nDid you mean to call ".$candidates;
}

return new UndefinedFunctionException($message, $exception);
}
}
<?php










namespace Symfony\Component\Debug\FatalErrorHandler;

use Symfony\Component\Debug\Exception\ClassNotFoundException;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\DebugClassLoader;
use Composer\Autoload\ClassLoader as ComposerClassLoader;
use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;






class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
{



public function handleError(array $error, FatalErrorException $exception)
{
$messageLen = strlen($error['message']);
$notFoundSuffix = '\' not found';
$notFoundSuffixLen = strlen($notFoundSuffix);
if ($notFoundSuffixLen > $messageLen) {
return;
}

if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
return;
}

foreach (array('class', 'interface', 'trait') as $typeName) {
$prefix = ucfirst($typeName).' \'';
$prefixLen = strlen($prefix);
if (0 !== strpos($error['message'], $prefix)) {
continue;
}

$fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
$className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
$namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
$message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
$tail = ' for another namespace?';
} else {
$className = $fullyQualifiedClassName;
$message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
$tail = '?';
}

if ($candidates = $this->getClassCandidates($className)) {
$tail = array_pop($candidates).'"?';
if ($candidates) {
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
} else {
$tail = ' for "'.$tail;
}
}
$message .= "\nDid you forget a \"use\" statement".$tail;

return new ClassNotFoundException($message, $exception);
}
}











private function getClassCandidates($class)
{
if (!is_array($functions = spl_autoload_functions())) {
return array();
}


 $classes = array();

foreach ($functions as $function) {
if (!is_array($function)) {
continue;
}

 if ($function[0] instanceof DebugClassLoader) {
$function = $function[0]->getClassLoader();


 if (is_object($function)) {
$function = array($function);
}

if (!is_array($function)) {
continue;
}
}

if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) {
foreach ($function[0]->getPrefixes() as $prefix => $paths) {
foreach ($paths as $path) {
$classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
}
}
}
if ($function[0] instanceof ComposerClassLoader) {
foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {
foreach ($paths as $path) {
$classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
}
}
}
}

return array_unique($classes);
}








private function findClassInPath($path, $class, $prefix)
{
if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
return array();
}

$classes = array();
$filename = $class.'.php';
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
$classes[] = $class;
}
}

return $classes;
}








private function convertFileToClass($path, $file, $prefix)
{
$candidates = array(

 $namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),

 $prefix.$namespacedClass,

 $prefix.'\\'.$namespacedClass,

 str_replace('\\', '_', $namespacedClass),

 str_replace('\\', '_', $prefix.$namespacedClass),

 str_replace('\\', '_', $prefix.'\\'.$namespacedClass),
);

if ($prefix) {
$candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });
}


 
 
 foreach ($candidates as $candidate) {
if ($this->classExists($candidate)) {
return $candidate;
}
}

require_once $file;

foreach ($candidates as $candidate) {
if ($this->classExists($candidate)) {
return $candidate;
}
}
}






private function classExists($class)
{
return class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));
}
}
<?php










namespace Symfony\Component\Debug\FatalErrorHandler;

use Symfony\Component\Debug\Exception\FatalErrorException;






interface FatalErrorHandlerInterface
{








public function handleError(array $error, FatalErrorException $exception);
}
<?php










namespace Symfony\Component\Debug\FatalErrorHandler;

use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\UndefinedMethodException;






class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
{



public function handleError(array $error, FatalErrorException $exception)
{
preg_match('/^Call to undefined method (.*)::(.*)\(\)$/', $error['message'], $matches);
if (!$matches) {
return;
}

$className = $matches[1];
$methodName = $matches[2];

$message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className);

if (!class_exists($className) || null === $methods = get_class_methods($className)) {

 return new UndefinedMethodException($message, $exception);
}

$candidates = array();
foreach ($methods as $definedMethodName) {
$lev = levenshtein($methodName, $definedMethodName);
if ($lev <= strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
$candidates[] = $definedMethodName;
}
}

if ($candidates) {
sort($candidates);
$last = array_pop($candidates).'"?';
if ($candidates) {
$candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
} else {
$candidates = '"'.$last;
}

$message .= "\nDid you mean to call ".$candidates;
}

return new UndefinedMethodException($message, $exception);
}
}
<?php










namespace Symfony\Component\HttpKernel\Exception;

use Symfony\Component\Debug\Exception\FlattenException as DebugFlattenException;










class FlattenException
{
private $handler;

public static function __callStatic($method, $args)
{
if (!method_exists('Symfony\Component\Debug\Exception\FlattenException', $method)) {
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_called_class(), $method));
}

return call_user_func_array(array('Symfony\Component\Debug\Exception\FlattenException', $method), $args);
}

public function __call($method, $args)
{
if (!isset($this->handler)) {
$this->handler = new DebugFlattenException();
}

if (!method_exists($this->handler, $method)) {
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method));
}

return call_user_func_array(array($this->handler, $method), $args);
}
}

namespace Symfony\Component\Debug\Exception;

use Symfony\Component\HttpKernel\Exception\FlattenException as LegacyFlattenException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;








class FlattenException extends LegacyFlattenException
{
private $message;
private $code;
private $previous;
private $trace;
private $class;
private $statusCode;
private $headers;
private $file;
private $line;

public static function create(\Exception $exception, $statusCode = null, array $headers = array())
{
$e = new static();
$e->setMessage($exception->getMessage());
$e->setCode($exception->getCode());

if ($exception instanceof HttpExceptionInterface) {
$statusCode = $exception->getStatusCode();
$headers = array_merge($headers, $exception->getHeaders());
}

if (null === $statusCode) {
$statusCode = 500;
}

$e->setStatusCode($statusCode);
$e->setHeaders($headers);
$e->setTraceFromException($exception);
$e->setClass(get_class($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());

$previous = $exception->getPrevious();

if ($previous instanceof \Exception) {
$e->setPrevious(static::create($previous));
} elseif ($previous instanceof \Throwable) {
$e->setPrevious(static::create(new FatalThrowableError($previous)));
}

return $e;
}

public function toArray()
{
$exceptions = array();
foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) {
$exceptions[] = array(
'message' => $exception->getMessage(),
'class' => $exception->getClass(),
'trace' => $exception->getTrace(),
);
}

return $exceptions;
}

public function getStatusCode()
{
return $this->statusCode;
}

public function setStatusCode($code)
{
$this->statusCode = $code;
}

public function getHeaders()
{
return $this->headers;
}

public function setHeaders(array $headers)
{
$this->headers = $headers;
}

public function getClass()
{
return $this->class;
}

public function setClass($class)
{
$this->class = $class;
}

public function getFile()
{
return $this->file;
}

public function setFile($file)
{
$this->file = $file;
}

public function getLine()
{
return $this->line;
}

public function setLine($line)
{
$this->line = $line;
}

public function getMessage()
{
return $this->message;
}

public function setMessage($message)
{
$this->message = $message;
}

public function getCode()
{
return $this->code;
}

public function setCode($code)
{
$this->code = $code;
}

public function getPrevious()
{
return $this->previous;
}

public function setPrevious(FlattenException $previous)
{
$this->previous = $previous;
}

public function getAllPrevious()
{
$exceptions = array();
$e = $this;
while ($e = $e->getPrevious()) {
$exceptions[] = $e;
}

return $exceptions;
}

public function getTrace()
{
return $this->trace;
}

public function setTraceFromException(\Exception $exception)
{
$this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
}

public function setTrace($trace, $file, $line)
{
$this->trace = array();
$this->trace[] = array(
'namespace' => '',
'short_class' => '',
'class' => '',
'type' => '',
'function' => '',
'file' => $file,
'line' => $line,
'args' => array(),
);
foreach ($trace as $entry) {
$class = '';
$namespace = '';
if (isset($entry['class'])) {
$parts = explode('\\', $entry['class']);
$class = array_pop($parts);
$namespace = implode('\\', $parts);
}

$this->trace[] = array(
'namespace' => $namespace,
'short_class' => $class,
'class' => isset($entry['class']) ? $entry['class'] : '',
'type' => isset($entry['type']) ? $entry['type'] : '',
'function' => isset($entry['function']) ? $entry['function'] : null,
'file' => isset($entry['file']) ? $entry['file'] : null,
'line' => isset($entry['line']) ? $entry['line'] : null,
'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(),
);
}
}

private function flattenArgs($args, $level = 0, &$count = 0)
{
$result = array();
foreach ($args as $key => $value) {
if (++$count > 1e4) {
return array('array', '*SKIPPED over 10000 entries*');
}
if ($value instanceof \__PHP_Incomplete_Class) {

 $result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value));
} elseif (is_object($value)) {
$result[$key] = array('object', get_class($value));
} elseif (is_array($value)) {
if ($level > 10) {
$result[$key] = array('array', '*DEEP NESTED ARRAY*');
} else {
$result[$key] = array('array', $this->flattenArgs($value, $level + 1, $count));
}
} elseif (null === $value) {
$result[$key] = array('null', null);
} elseif (is_bool($value)) {
$result[$key] = array('boolean', $value);
} elseif (is_resource($value)) {
$result[$key] = array('resource', get_resource_type($value));
} else {
$result[$key] = array('string', (string) $value);
}
}

return $result;
}

private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
{
$array = new \ArrayObject($value);

return $array['__PHP_Incomplete_Class_Name'];
}
}
<?php










namespace Symfony\Component\HttpKernel\Exception;










class FatalErrorException extends \ErrorException
{
}

namespace Symfony\Component\Debug\Exception;

use Symfony\Component\HttpKernel\Exception\FatalErrorException as LegacyFatalErrorException;






class FatalErrorException extends LegacyFatalErrorException
{
public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null)
{
parent::__construct($message, $code, $severity, $filename, $lineno);

if (null !== $trace) {
if (!$traceArgs) {
foreach ($trace as &$frame) {
unset($frame['args'], $frame['this'], $frame);
}
}

$this->setTrace($trace);
} elseif (null !== $traceOffset) {
if (function_exists('xdebug_get_function_stack')) {
$trace = xdebug_get_function_stack();
if (0 < $traceOffset) {
array_splice($trace, -$traceOffset);
}

foreach ($trace as &$frame) {
if (!isset($frame['type'])) {

 if (isset($frame['class'])) {
$frame['type'] = '::';
}
} elseif ('dynamic' === $frame['type']) {
$frame['type'] = '->';
} elseif ('static' === $frame['type']) {
$frame['type'] = '::';
}


 if (!$traceArgs) {
unset($frame['params'], $frame['args']);
} elseif (isset($frame['params']) && !isset($frame['args'])) {
$frame['args'] = $frame['params'];
unset($frame['params']);
}
}

unset($frame);
$trace = array_reverse($trace);
} elseif (function_exists('symfony_debug_backtrace')) {
$trace = symfony_debug_backtrace();
if (0 < $traceOffset) {
array_splice($trace, 0, $traceOffset);
}
} else {
$trace = array();
}

$this->setTrace($trace);
}
}

protected function setTrace($trace)
{
$traceReflector = new \ReflectionProperty('Exception', 'trace');
$traceReflector->setAccessible(true);
$traceReflector->setValue($this, $trace);
}
}
<?php










namespace Symfony\Component\Debug\Exception;






class FatalThrowableError extends FatalErrorException
{
public function __construct(\Throwable $e)
{
if ($e instanceof \ParseError) {
$message = 'Parse error: '.$e->getMessage();
$severity = E_PARSE;
} elseif ($e instanceof \TypeError) {
$message = 'Type error: '.$e->getMessage();
$severity = E_RECOVERABLE_ERROR;
} else {
$message = $e->getMessage();
$severity = E_ERROR;
}

\ErrorException::__construct(
$message,
$e->getCode(),
$severity,
$e->getFile(),
$e->getLine()
);

$this->setTrace($e->getTrace());
}
}
<?php










namespace Symfony\Component\Debug\Exception;






class UndefinedMethodException extends FatalErrorException
{
public function __construct($message, \ErrorException $previous)
{
parent::__construct(
$message,
$previous->getCode(),
$previous->getSeverity(),
$previous->getFile(),
$previous->getLine(),
$previous->getPrevious()
);
$this->setTrace($previous->getTrace());
}
}
<?php










namespace Symfony\Component\Debug\Exception;






class OutOfMemoryException extends FatalErrorException
{
}
<?php










namespace Symfony\Component\Debug\Exception;






class ContextErrorException extends \ErrorException
{
private $context = array();

public function __construct($message, $code, $severity, $filename, $lineno, $context = array())
{
parent::__construct($message, $code, $severity, $filename, $lineno);
$this->context = $context;
}




public function getContext()
{
return $this->context;
}
}
<?php










namespace Symfony\Component\Debug\Exception;






class UndefinedFunctionException extends FatalErrorException
{
public function __construct($message, \ErrorException $previous)
{
parent::__construct(
$message,
$previous->getCode(),
$previous->getSeverity(),
$previous->getFile(),
$previous->getLine(),
$previous->getPrevious()
);
$this->setTrace($previous->getTrace());
}
}
<?php










namespace Symfony\Component\Debug\Exception;






class ClassNotFoundException extends FatalErrorException
{
public function __construct($message, \ErrorException $previous)
{
parent::__construct(
$message,
$previous->getCode(),
$previous->getSeverity(),
$previous->getFile(),
$previous->getLine(),
$previous->getPrevious()
);
$this->setTrace($previous->getTrace());
}
}
<?php










namespace Symfony\Component\Debug\Exception;

@trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);






class DummyException extends \ErrorException
{
}
<?php










namespace Symfony\Component\Config;








interface ConfigCacheFactoryInterface
{








public function cache($file, $callable);
}
<?php










namespace Symfony\Component\Config;










class ConfigCacheFactory implements ConfigCacheFactoryInterface
{



private $debug;




public function __construct($debug)
{
$this->debug = $debug;
}




public function cache($file, $callback)
{
if (!is_callable($callback)) {
throw new \InvalidArgumentException(sprintf('Invalid type for callback argument. Expected callable, but got "%s".', gettype($callback)));
}

$cache = new ConfigCache($file, $this->debug);
if (!$cache->isFresh()) {
call_user_func($callback, $cache);
}

return $cache;
}
}
<?php










namespace Symfony\Component\Config\Definition;

@trigger_error('The '.__NAMESPACE__.'\ReferenceDumper class is deprecated since version 2.4 and will be removed in 3.0. Use the Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper class instead.', E_USER_DEPRECATED);

use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;





class ReferenceDumper extends YamlReferenceDumper
{
}
<?php










namespace Symfony\Component\Config\Definition;






interface ConfigurationInterface
{





public function getConfigTreeBuilder();
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;









class VariableNode extends BaseNode implements PrototypeNodeInterface
{
protected $defaultValueSet = false;
protected $defaultValue;
protected $allowEmptyValue = true;




public function setDefaultValue($value)
{
$this->defaultValueSet = true;
$this->defaultValue = $value;
}




public function hasDefaultValue()
{
return $this->defaultValueSet;
}




public function getDefaultValue()
{
$v = $this->defaultValue;

return $v instanceof \Closure ? $v() : $v;
}






public function setAllowEmptyValue($boolean)
{
$this->allowEmptyValue = (bool) $boolean;
}




public function setName($name)
{
$this->name = $name;
}




protected function validateType($value)
{
}




protected function finalizeValue($value)
{
if (!$this->allowEmptyValue && $this->isValueEmpty($value)) {
$ex = new InvalidConfigurationException(sprintf(
'The path "%s" cannot contain an empty value, but got %s.',
$this->getPath(),
json_encode($value)
));
if ($hint = $this->getInfo()) {
$ex->addHint($hint);
}
$ex->setPath($this->getPath());

throw $ex;
}

return $value;
}




protected function normalizeValue($value)
{
return $value;
}




protected function mergeValues($leftSide, $rightSide)
{
return $rightSide;
}












protected function isValueEmpty($value)
{
return empty($value);
}
}
<?php










namespace Symfony\Component\Config\Definition;









interface NodeInterface
{





public function getName();






public function getPath();






public function isRequired();






public function hasDefaultValue();








public function getDefaultValue();








public function normalize($value);









public function merge($leftSide, $rightSide);








public function finalize($value);
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;






class BooleanNode extends ScalarNode
{



protected function validateType($value)
{
if (!is_bool($value)) {
$ex = new InvalidTypeException(sprintf(
'Invalid type for path "%s". Expected boolean, but got %s.',
$this->getPath(),
gettype($value)
));
if ($hint = $this->getInfo()) {
$ex->addHint($hint);
}
$ex->setPath($this->getPath());

throw $ex;
}
}




protected function isValueEmpty($value)
{

 return false;
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;






abstract class NodeDefinition implements NodeParentInterface
{
protected $name;
protected $normalization;
protected $validation;
protected $defaultValue;
protected $default = false;
protected $required = false;
protected $merge;
protected $allowEmptyValue = true;
protected $nullEquivalent;
protected $trueEquivalent = true;
protected $falseEquivalent = false;




protected $parent;
protected $attributes = array();







public function __construct($name, NodeParentInterface $parent = null)
{
$this->parent = $parent;
$this->name = $name;
}








public function setParent(NodeParentInterface $parent)
{
$this->parent = $parent;

return $this;
}








public function info($info)
{
return $this->attribute('info', $info);
}








public function example($example)
{
return $this->attribute('example', $example);
}









public function attribute($key, $value)
{
$this->attributes[$key] = $value;

return $this;
}






public function end()
{
return $this->parent;
}








public function getNode($forceRootNode = false)
{
if ($forceRootNode) {
$this->parent = null;
}

if (null !== $this->normalization) {
$this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before);
}

if (null !== $this->validation) {
$this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules);
}

$node = $this->createNode();
$node->setAttributes($this->attributes);

return $node;
}








public function defaultValue($value)
{
$this->default = true;
$this->defaultValue = $value;

return $this;
}






public function isRequired()
{
$this->required = true;

return $this;
}








public function treatNullLike($value)
{
$this->nullEquivalent = $value;

return $this;
}








public function treatTrueLike($value)
{
$this->trueEquivalent = $value;

return $this;
}








public function treatFalseLike($value)
{
$this->falseEquivalent = $value;

return $this;
}






public function defaultNull()
{
return $this->defaultValue(null);
}






public function defaultTrue()
{
return $this->defaultValue(true);
}






public function defaultFalse()
{
return $this->defaultValue(false);
}






public function beforeNormalization()
{
return $this->normalization()->before();
}






public function cannotBeEmpty()
{
$this->allowEmptyValue = false;

return $this;
}










public function validate()
{
return $this->validation()->rule();
}








public function cannotBeOverwritten($deny = true)
{
$this->merge()->denyOverwrite($deny);

return $this;
}






protected function validation()
{
if (null === $this->validation) {
$this->validation = new ValidationBuilder($this);
}

return $this->validation;
}






protected function merge()
{
if (null === $this->merge) {
$this->merge = new MergeBuilder($this);
}

return $this->merge;
}






protected function normalization()
{
if (null === $this->normalization) {
$this->normalization = new NormalizationBuilder($this);
}

return $this->normalization;
}








abstract protected function createNode();
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






interface NodeParentInterface
{
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;






class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
{
protected $performDeepMerging = true;
protected $ignoreExtraKeys = false;
protected $removeExtraKeys = true;
protected $children = array();
protected $prototype;
protected $atLeastOne = false;
protected $allowNewKeys = true;
protected $key;
protected $removeKeyItem;
protected $addDefaults = false;
protected $addDefaultChildren = false;
protected $nodeBuilder;
protected $normalizeKeys = true;




public function __construct($name, NodeParentInterface $parent = null)
{
parent::__construct($name, $parent);

$this->nullEquivalent = array();
$this->trueEquivalent = array();
}






public function setBuilder(NodeBuilder $builder)
{
$this->nodeBuilder = $builder;
}






public function children()
{
return $this->getNodeBuilder();
}








public function prototype($type)
{
return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
}










public function addDefaultsIfNotSet()
{
$this->addDefaults = true;

return $this;
}










public function addDefaultChildrenIfNoneSet($children = null)
{
$this->addDefaultChildren = $children;

return $this;
}








public function requiresAtLeastOneElement()
{
$this->atLeastOne = true;

return $this;
}








public function disallowNewKeysInSubsequentConfigs()
{
$this->allowNewKeys = false;

return $this;
}









public function fixXmlConfig($singular, $plural = null)
{
$this->normalization()->remap($singular, $plural);

return $this;
}





























public function useAttributeAsKey($name, $removeKeyItem = true)
{
$this->key = $name;
$this->removeKeyItem = $removeKeyItem;

return $this;
}








public function canBeUnset($allow = true)
{
$this->merge()->allowUnset($allow);

return $this;
}
















public function canBeEnabled()
{
$this
->addDefaultsIfNotSet()
->treatFalseLike(array('enabled' => false))
->treatTrueLike(array('enabled' => true))
->treatNullLike(array('enabled' => true))
->beforeNormalization()
->ifArray()
->then(function ($v) {
$v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;

return $v;
})
->end()
->children()
->booleanNode('enabled')
->defaultFalse()
;

return $this;
}








public function canBeDisabled()
{
$this
->addDefaultsIfNotSet()
->treatFalseLike(array('enabled' => false))
->treatTrueLike(array('enabled' => true))
->treatNullLike(array('enabled' => true))
->children()
->booleanNode('enabled')
->defaultTrue()
;

return $this;
}






public function performNoDeepMerging()
{
$this->performDeepMerging = false;

return $this;
}














public function ignoreExtraKeys($remove = true)
{
$this->ignoreExtraKeys = true;
$this->removeExtraKeys = $remove;

return $this;
}








public function normalizeKeys($bool)
{
$this->normalizeKeys = (bool) $bool;

return $this;
}
















public function append(NodeDefinition $node)
{
$this->children[$node->name] = $node->setParent($this);

return $this;
}






protected function getNodeBuilder()
{
if (null === $this->nodeBuilder) {
$this->nodeBuilder = new NodeBuilder();
}

return $this->nodeBuilder->setParent($this);
}




protected function createNode()
{
if (null === $this->prototype) {
$node = new ArrayNode($this->name, $this->parent);

$this->validateConcreteNode($node);

$node->setAddIfNotSet($this->addDefaults);

foreach ($this->children as $child) {
$child->parent = $node;
$node->addChild($child->getNode());
}
} else {
$node = new PrototypedArrayNode($this->name, $this->parent);

$this->validatePrototypeNode($node);

if (null !== $this->key) {
$node->setKeyAttribute($this->key, $this->removeKeyItem);
}

if (true === $this->atLeastOne) {
$node->setMinNumberOfElements(1);
}

if ($this->default) {
$node->setDefaultValue($this->defaultValue);
}

if (false !== $this->addDefaultChildren) {
$node->setAddChildrenIfNoneSet($this->addDefaultChildren);
if ($this->prototype instanceof static && null === $this->prototype->prototype) {
$this->prototype->addDefaultsIfNotSet();
}
}

$this->prototype->parent = $node;
$node->setPrototype($this->prototype->getNode());
}

$node->setAllowNewKeys($this->allowNewKeys);
$node->addEquivalentValue(null, $this->nullEquivalent);
$node->addEquivalentValue(true, $this->trueEquivalent);
$node->addEquivalentValue(false, $this->falseEquivalent);
$node->setPerformDeepMerging($this->performDeepMerging);
$node->setRequired($this->required);
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
$node->setNormalizeKeys($this->normalizeKeys);

if (null !== $this->normalization) {
$node->setNormalizationClosures($this->normalization->before);
$node->setXmlRemappings($this->normalization->remappings);
}

if (null !== $this->merge) {
$node->setAllowOverwrite($this->merge->allowOverwrite);
$node->setAllowFalse($this->merge->allowFalse);
}

if (null !== $this->validation) {
$node->setFinalValidationClosures($this->validation->rules);
}

return $node;
}








protected function validateConcreteNode(ArrayNode $node)
{
$path = $node->getPath();

if (null !== $this->key) {
throw new InvalidDefinitionException(
sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path)
);
}

if (true === $this->atLeastOne) {
throw new InvalidDefinitionException(
sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path)
);
}

if ($this->default) {
throw new InvalidDefinitionException(
sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path)
);
}

if (false !== $this->addDefaultChildren) {
throw new InvalidDefinitionException(
sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path)
);
}
}








protected function validatePrototypeNode(PrototypedArrayNode $node)
{
$path = $node->getPath();

if ($this->addDefaults) {
throw new InvalidDefinitionException(
sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s"', $path)
);
}

if (false !== $this->addDefaultChildren) {
if ($this->default) {
throw new InvalidDefinitionException(
sprintf('A default value and default children might not be used together at path "%s"', $path)
);
}

if (null !== $this->key && (null === $this->addDefaultChildren || is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
throw new InvalidDefinitionException(
sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
);
}

if (null === $this->key && (is_string($this->addDefaultChildren) || is_array($this->addDefaultChildren))) {
throw new InvalidDefinitionException(
sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path)
);
}
}
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\BooleanNode;






class BooleanNodeDefinition extends ScalarNodeDefinition
{



public function __construct($name, NodeParentInterface $parent = null)
{
parent::__construct($name, $parent);

$this->nullEquivalent = true;
}






public function cannotBeEmpty()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

return parent::cannotBeEmpty();
}






protected function instantiateNode()
{
return new BooleanNode($this->name, $this->parent);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






abstract class NumericNodeDefinition extends ScalarNodeDefinition
{
protected $min;
protected $max;










public function max($max)
{
if (isset($this->min) && $this->min > $max) {
throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s)', $max, $this->min));
}
$this->max = $max;

return $this;
}










public function min($min)
{
if (isset($this->max) && $this->max < $min) {
throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s)', $min, $this->max));
}
$this->min = $min;

return $this;
}






public function cannotBeEmpty()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

return parent::cannotBeEmpty();
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






class ValidationBuilder
{
protected $node;
public $rules = array();






public function __construct(NodeDefinition $node)
{
$this->node = $node;
}








public function rule(\Closure $closure = null)
{
if (null !== $closure) {
$this->rules[] = $closure;

return $this;
}

return $this->rules[] = new ExprBuilder($this->node);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\Exception\UnsetKeyException;







class ExprBuilder
{
protected $node;
public $ifPart;
public $thenPart;






public function __construct(NodeDefinition $node)
{
$this->node = $node;
}








public function always(\Closure $then = null)
{
$this->ifPart = function ($v) { return true; };

if (null !== $then) {
$this->thenPart = $then;
}

return $this;
}










public function ifTrue(\Closure $closure = null)
{
if (null === $closure) {
$closure = function ($v) { return true === $v; };
}

$this->ifPart = $closure;

return $this;
}






public function ifString()
{
$this->ifPart = function ($v) { return is_string($v); };

return $this;
}






public function ifNull()
{
$this->ifPart = function ($v) { return null === $v; };

return $this;
}






public function ifArray()
{
$this->ifPart = function ($v) { return is_array($v); };

return $this;
}








public function ifInArray(array $array)
{
$this->ifPart = function ($v) use ($array) { return in_array($v, $array, true); };

return $this;
}








public function ifNotInArray(array $array)
{
$this->ifPart = function ($v) use ($array) { return !in_array($v, $array, true); };

return $this;
}








public function then(\Closure $closure)
{
$this->thenPart = $closure;

return $this;
}






public function thenEmptyArray()
{
$this->thenPart = function ($v) { return array(); };

return $this;
}












public function thenInvalid($message)
{
$this->thenPart = function ($v) use ($message) {throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };

return $this;
}








public function thenUnset()
{
$this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); };

return $this;
}








public function end()
{
if (null === $this->ifPart) {
throw new \RuntimeException('You must specify an if part.');
}
if (null === $this->thenPart) {
throw new \RuntimeException('You must specify a then part.');
}

return $this->node;
}








public static function buildExpressions(array $expressions)
{
foreach ($expressions as $k => $expr) {
if ($expr instanceof self) {
$if = $expr->ifPart;
$then = $expr->thenPart;
$expressions[$k] = function ($v) use ($if, $then) {
return $if($v) ? $then($v) : $v;
};
}
}

return $expressions;
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\NodeInterface;






class TreeBuilder implements NodeParentInterface
{
protected $tree;
protected $root;
protected $builder;












public function root($name, $type = 'array', NodeBuilder $builder = null)
{
$builder = $builder ?: new NodeBuilder();

return $this->root = $builder->node($name, $type)->setParent($this);
}








public function buildTree()
{
if (null === $this->root) {
throw new \RuntimeException('The configuration tree has no root node.');
}
if (null !== $this->tree) {
return $this->tree;
}

return $this->tree = $this->root->getNode(true);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






class MergeBuilder
{
protected $node;
public $allowFalse = false;
public $allowOverwrite = true;






public function __construct(NodeDefinition $node)
{
$this->node = $node;
}








public function allowUnset($allow = true)
{
$this->allowFalse = $allow;

return $this;
}








public function denyOverwrite($deny = true)
{
$this->allowOverwrite = !$deny;

return $this;
}






public function end()
{
return $this->node;
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\IntegerNode;






class IntegerNodeDefinition extends NumericNodeDefinition
{





protected function instantiateNode()
{
return new IntegerNode($this->name, $this->parent, $this->min, $this->max);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






class NormalizationBuilder
{
protected $node;
public $before = array();
public $remappings = array();






public function __construct(NodeDefinition $node)
{
$this->node = $node;
}









public function remap($key, $plural = null)
{
$this->remappings[] = array($key, null === $plural ? $key.'s' : $plural);

return $this;
}








public function before(\Closure $closure = null)
{
if (null !== $closure) {
$this->before[] = $closure;

return $this;
}

return $this->before[] = new ExprBuilder($this->node);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






class NodeBuilder implements NodeParentInterface
{
protected $parent;
protected $nodeMapping;




public function __construct()
{
$this->nodeMapping = array(
'variable' => __NAMESPACE__.'\\VariableNodeDefinition',
'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
'integer' => __NAMESPACE__.'\\IntegerNodeDefinition',
'float' => __NAMESPACE__.'\\FloatNodeDefinition',
'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
);
}








public function setParent(ParentNodeDefinitionInterface $parent = null)
{
$this->parent = $parent;

return $this;
}








public function arrayNode($name)
{
return $this->node($name, 'array');
}








public function scalarNode($name)
{
return $this->node($name, 'scalar');
}








public function booleanNode($name)
{
return $this->node($name, 'boolean');
}








public function integerNode($name)
{
return $this->node($name, 'integer');
}








public function floatNode($name)
{
return $this->node($name, 'float');
}








public function enumNode($name)
{
return $this->node($name, 'enum');
}








public function variableNode($name)
{
return $this->node($name, 'variable');
}






public function end()
{
return $this->parent;
}












public function node($name, $type)
{
$class = $this->getNodeClass($type);

$node = new $class($name);

$this->append($node);

return $node;
}


















public function append(NodeDefinition $node)
{
if ($node instanceof ParentNodeDefinitionInterface) {
$builder = clone $this;
$builder->setParent(null);
$node->setBuilder($builder);
}

if (null !== $this->parent) {
$this->parent->append($node);

 $node->setParent($this);
}

return $this;
}









public function setNodeClass($type, $class)
{
$this->nodeMapping[strtolower($type)] = $class;

return $this;
}











protected function getNodeClass($type)
{
$type = strtolower($type);

if (!isset($this->nodeMapping[$type])) {
throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
}

$class = $this->nodeMapping[$type];

if (!class_exists($class)) {
throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
}

return $class;
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\EnumNode;






class EnumNodeDefinition extends ScalarNodeDefinition
{
private $values;






public function values(array $values)
{
$values = array_unique($values);

if (empty($values)) {
throw new \InvalidArgumentException('->values() must be called with at least one value.');
}

$this->values = $values;

return $this;
}








protected function instantiateNode()
{
if (null === $this->values) {
throw new \RuntimeException('You must call ->values() on enum nodes.');
}

return new EnumNode($this->name, $this->parent, $this->values);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\FloatNode;






class FloatNodeDefinition extends NumericNodeDefinition
{





protected function instantiateNode()
{
return new FloatNode($this->name, $this->parent, $this->min, $this->max);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\ScalarNode;






class ScalarNodeDefinition extends VariableNodeDefinition
{





protected function instantiateNode()
{
return new ScalarNode($this->name, $this->parent);
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;

use Symfony\Component\Config\Definition\VariableNode;






class VariableNodeDefinition extends NodeDefinition
{





protected function instantiateNode()
{
return new VariableNode($this->name, $this->parent);
}




protected function createNode()
{
$node = $this->instantiateNode();

if (null !== $this->normalization) {
$node->setNormalizationClosures($this->normalization->before);
}

if (null !== $this->merge) {
$node->setAllowOverwrite($this->merge->allowOverwrite);
}

if (true === $this->default) {
$node->setDefaultValue($this->defaultValue);
}

$node->setAllowEmptyValue($this->allowEmptyValue);
$node->addEquivalentValue(null, $this->nullEquivalent);
$node->addEquivalentValue(true, $this->trueEquivalent);
$node->addEquivalentValue(false, $this->falseEquivalent);
$node->setRequired($this->required);

if (null !== $this->validation) {
$node->setFinalValidationClosures($this->validation->rules);
}

return $node;
}
}
<?php










namespace Symfony\Component\Config\Definition\Builder;






interface ParentNodeDefinitionInterface
{
public function children();

public function append(NodeDefinition $node);

public function setBuilder(NodeBuilder $builder);
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;






class ArrayNode extends BaseNode implements PrototypeNodeInterface
{
protected $xmlRemappings = array();
protected $children = array();
protected $allowFalse = false;
protected $allowNewKeys = true;
protected $addIfNotSet = false;
protected $performDeepMerging = true;
protected $ignoreExtraKeys = false;
protected $removeExtraKeys = true;
protected $normalizeKeys = true;

public function setNormalizeKeys($normalizeKeys)
{
$this->normalizeKeys = (bool) $normalizeKeys;
}














protected function preNormalize($value)
{
if (!$this->normalizeKeys || !is_array($value)) {
return $value;
}

$normalized = array();

foreach ($value as $k => $v) {
if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
$normalized[$normalizedKey] = $v;
} else {
$normalized[$k] = $v;
}
}

return $normalized;
}






public function getChildren()
{
return $this->children;
}






public function setXmlRemappings(array $remappings)
{
$this->xmlRemappings = $remappings;
}






public function getXmlRemappings()
{
return $this->xmlRemappings;
}







public function setAddIfNotSet($boolean)
{
$this->addIfNotSet = (bool) $boolean;
}






public function setAllowFalse($allow)
{
$this->allowFalse = (bool) $allow;
}






public function setAllowNewKeys($allow)
{
$this->allowNewKeys = (bool) $allow;
}






public function setPerformDeepMerging($boolean)
{
$this->performDeepMerging = (bool) $boolean;
}







public function setIgnoreExtraKeys($boolean, $remove = true)
{
$this->ignoreExtraKeys = (bool) $boolean;
$this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
}






public function setName($name)
{
$this->name = $name;
}






public function hasDefaultValue()
{
return $this->addIfNotSet;
}








public function getDefaultValue()
{
if (!$this->hasDefaultValue()) {
throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
}

$defaults = array();
foreach ($this->children as $name => $child) {
if ($child->hasDefaultValue()) {
$defaults[$name] = $child->getDefaultValue();
}
}

return $defaults;
}









public function addChild(NodeInterface $node)
{
$name = $node->getName();
if (!strlen($name)) {
throw new \InvalidArgumentException('Child nodes must be named.');
}
if (isset($this->children[$name])) {
throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
}

$this->children[$name] = $node;
}











protected function finalizeValue($value)
{
if (false === $value) {
$msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
throw new UnsetKeyException($msg);
}

foreach ($this->children as $name => $child) {
if (!array_key_exists($name, $value)) {
if ($child->isRequired()) {
$msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());

throw $ex;
}

if ($child->hasDefaultValue()) {
$value[$name] = $child->getDefaultValue();
}

continue;
}

try {
$value[$name] = $child->finalize($value[$name]);
} catch (UnsetKeyException $e) {
unset($value[$name]);
}
}

return $value;
}








protected function validateType($value)
{
if (!is_array($value) && (!$this->allowFalse || false !== $value)) {
$ex = new InvalidTypeException(sprintf(
'Invalid type for path "%s". Expected array, but got %s',
$this->getPath(),
gettype($value)
));
if ($hint = $this->getInfo()) {
$ex->addHint($hint);
}
$ex->setPath($this->getPath());

throw $ex;
}
}










protected function normalizeValue($value)
{
if (false === $value) {
return $value;
}

$value = $this->remapXml($value);

$normalized = array();
foreach ($value as $name => $val) {
if (isset($this->children[$name])) {
$normalized[$name] = $this->children[$name]->normalize($val);
unset($value[$name]);
} elseif (!$this->removeExtraKeys) {
$normalized[$name] = $val;
}
}


 if (count($value) && !$this->ignoreExtraKeys) {
$msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());

throw $ex;
}

return $normalized;
}








protected function remapXml($value)
{
foreach ($this->xmlRemappings as $transformation) {
list($singular, $plural) = $transformation;

if (!isset($value[$singular])) {
continue;
}

$value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
unset($value[$singular]);
}

return $value;
}












protected function mergeValues($leftSide, $rightSide)
{
if (false === $rightSide) {

 
 return false;
}

if (false === $leftSide || !$this->performDeepMerging) {
return $rightSide;
}

foreach ($rightSide as $k => $v) {

 if (!array_key_exists($k, $leftSide)) {
if (!$this->allowNewKeys) {
$ex = new InvalidConfigurationException(sprintf(
'You are not allowed to define new elements for path "%s". '
.'Please define all elements for this path in one config file. '
.'If you are trying to overwrite an element, make sure you redefine it '
.'with the same name.',
$this->getPath()
));
$ex->setPath($this->getPath());

throw $ex;
}

$leftSide[$k] = $v;
continue;
}

if (!isset($this->children[$k])) {
throw new \RuntimeException('merge() expects a normalized config array.');
}

$leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
}

return $leftSide;
}
}
<?php










namespace Symfony\Component\Config\Definition;






class Processor
{








public function process(NodeInterface $configTree, array $configs)
{
$currentConfig = array();
foreach ($configs as $config) {
$config = $configTree->normalize($config);
$currentConfig = $configTree->merge($currentConfig, $config);
}

return $configTree->finalize($currentConfig);
}









public function processConfiguration(ConfigurationInterface $configuration, array $configs)
{
return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs);
}
























public static function normalizeConfig($config, $key, $plural = null)
{
if (null === $plural) {
$plural = $key.'s';
}

if (isset($config[$plural])) {
return $config[$plural];
}

if (isset($config[$key])) {
if (is_string($config[$key]) || !is_int(key($config[$key]))) {

 return array($config[$key]);
}

return $config[$key];
}

return array();
}
}
<?php










namespace Symfony\Component\Config\Definition\Dumper;

use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode;






class XmlReferenceDumper
{
private $reference;

public function dump(ConfigurationInterface $configuration, $namespace = null)
{
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
}

public function dumpNode(NodeInterface $node, $namespace = null)
{
$this->reference = '';
$this->writeNode($node, 0, true, $namespace);
$ref = $this->reference;
$this->reference = null;

return $ref;
}







private function writeNode(NodeInterface $node, $depth = 0, $root = false, $namespace = null)
{
$rootName = ($root ? 'config' : $node->getName());
$rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null));


 if ($node->getParent()) {
$remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) {
return $rootName === $mapping[1];
});

if (count($remapping)) {
list($singular) = current($remapping);
$rootName = $singular;
}
}
$rootName = str_replace('_', '-', $rootName);

$rootAttributes = array();
$rootAttributeComments = array();
$rootChildren = array();
$rootComments = array();

if ($node instanceof ArrayNode) {
$children = $node->getChildren();


 if ($rootInfo = $node->getInfo()) {
$rootComments[] = $rootInfo;
}

if ($rootNamespace) {
$rootComments[] = 'Namespace: '.$rootNamespace;
}


 if ($node instanceof PrototypedArrayNode) {
$prototype = $node->getPrototype();

$info = 'prototype';
if (null !== $prototype->getInfo()) {
$info .= ': '.$prototype->getInfo();
}
array_unshift($rootComments, $info);

if ($key = $node->getKeyAttribute()) {
$rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
}

if ($prototype instanceof ArrayNode) {
$children = $prototype->getChildren();
} else {
if ($prototype->hasDefaultValue()) {
$prototypeValue = $prototype->getDefaultValue();
} else {
switch (get_class($prototype)) {
case 'Symfony\Component\Config\Definition\ScalarNode':
$prototypeValue = 'scalar value';
break;

case 'Symfony\Component\Config\Definition\FloatNode':
case 'Symfony\Component\Config\Definition\IntegerNode':
$prototypeValue = 'numeric value';
break;

case 'Symfony\Component\Config\Definition\BooleanNode':
$prototypeValue = 'true|false';
break;

case 'Symfony\Component\Config\Definition\EnumNode':
$prototypeValue = implode('|', array_map('json_encode', $prototype->getValues()));
break;

default:
$prototypeValue = 'value';
}
}
}
}


 foreach ($children as $child) {
if (!$child instanceof ArrayNode) {



 $name = str_replace('_', '-', $child->getName());
$value = '%%%%not_defined%%%%'; 


 $comments = array();
if ($info = $child->getInfo()) {
$comments[] = $info;
}

if ($example = $child->getExample()) {
$comments[] = 'Example: '.$example;
}

if ($child->isRequired()) {
$comments[] = 'Required';
}

if ($child instanceof EnumNode) {
$comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
}

if (count($comments)) {
$rootAttributeComments[$name] = implode(";\n", $comments);
}


 if ($child->hasDefaultValue()) {
$value = $child->getDefaultValue();
}


 $rootAttributes[$name] = $value;
} else {

 $rootChildren[] = $child;
}
}
}




 if (count($rootComments)) {
foreach ($rootComments as $comment) {
$this->writeLine('<!-- '.$comment.' -->', $depth);
}
}


 if (count($rootAttributeComments)) {
foreach ($rootAttributeComments as $attrName => $comment) {
$commentDepth = $depth + 4 + strlen($attrName) + 2;
$commentLines = explode("\n", $comment);
$multiline = (count($commentLines) > 1);
$comment = implode(PHP_EOL.str_repeat(' ', $commentDepth), $commentLines);

if ($multiline) {
$this->writeLine('<!--', $depth);
$this->writeLine($attrName.': '.$comment, $depth + 4);
$this->writeLine('-->', $depth);
} else {
$this->writeLine('<!-- '.$attrName.': '.$comment.' -->', $depth);
}
}
}


 $rootIsVariablePrototype = isset($prototypeValue);
$rootIsEmptyTag = (0 === count($rootChildren) && !$rootIsVariablePrototype);
$rootOpenTag = '<'.$rootName;
if (1 >= ($attributesCount = count($rootAttributes))) {
if (1 === $attributesCount) {
$rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
}

$rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';

if ($rootIsVariablePrototype) {
$rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
}

$this->writeLine($rootOpenTag, $depth);
} else {
$this->writeLine($rootOpenTag, $depth);

$i = 1;

foreach ($rootAttributes as $attrName => $attrValue) {
$attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));

$this->writeLine($attr, $depth + 4);

if ($attributesCount === $i++) {
$this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth);

if ($rootIsVariablePrototype) {
$rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
}
}
}
}


 foreach ($rootChildren as $child) {
$this->writeLine('');
$this->writeNode($child, $depth + 4);
}


 if (!$rootIsEmptyTag && !$rootIsVariablePrototype) {
$this->writeLine('');

$rootEndTag = '</'.$rootName.'>';
$this->writeLine($rootEndTag, $depth);
}
}







private function writeLine($text, $indent = 0)
{
$indent = strlen($text) + $indent;
$format = '%'.$indent.'s';

$this->reference .= sprintf($format, $text).PHP_EOL;
}








private function writeValue($value)
{
if ('%%%%not_defined%%%%' === $value) {
return '';
}

if (is_string($value) || is_numeric($value)) {
return $value;
}

if (false === $value) {
return 'false';
}

if (true === $value) {
return 'true';
}

if (null === $value) {
return 'null';
}

if (empty($value)) {
return '';
}

if (is_array($value)) {
return implode(',', $value);
}
}
}
<?php










namespace Symfony\Component\Config\Definition\Dumper;

use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Yaml\Inline;






class YamlReferenceDumper
{
private $reference;

public function dump(ConfigurationInterface $configuration)
{
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
}

public function dumpNode(NodeInterface $node)
{
$this->reference = '';
$this->writeNode($node);
$ref = $this->reference;
$this->reference = null;

return $ref;
}





private function writeNode(NodeInterface $node, $depth = 0)
{
$comments = array();
$default = '';
$defaultArray = null;
$children = null;
$example = $node->getExample();


 if ($node instanceof ArrayNode) {
$children = $node->getChildren();

if ($node instanceof PrototypedArrayNode) {
$prototype = $node->getPrototype();

if ($prototype instanceof ArrayNode) {
$children = $prototype->getChildren();
}


 if ($key = $node->getKeyAttribute()) {
$keyNodeClass = 'Symfony\Component\Config\Definition\\'.($prototype instanceof ArrayNode ? 'ArrayNode' : 'ScalarNode');
$keyNode = new $keyNodeClass($key, $node);

$info = 'Prototype';
if (null !== $prototype->getInfo()) {
$info .= ': '.$prototype->getInfo();
}
$keyNode->setInfo($info);


 foreach ($children as $childNode) {
$keyNode->addChild($childNode);
}
$children = array($key => $keyNode);
}
}

if (!$children) {
if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) {
$default = '';
} elseif (!is_array($example)) {
$default = '[]';
}
}
} elseif ($node instanceof EnumNode) {
$comments[] = 'One of '.implode('; ', array_map('json_encode', $node->getValues()));
$default = $node->hasDefaultValue() ? Inline::dump($node->getDefaultValue()) : '~';
} else {
$default = '~';

if ($node->hasDefaultValue()) {
$default = $node->getDefaultValue();

if (is_array($default)) {
if (count($defaultArray = $node->getDefaultValue())) {
$default = '';
} elseif (!is_array($example)) {
$default = '[]';
}
} else {
$default = Inline::dump($default);
}
}
}


 if ($node->isRequired()) {
$comments[] = 'Required';
}


 if ($example && !is_array($example)) {
$comments[] = 'Example: '.$example;
}

$default = (string) $default != '' ? ' '.$default : '';
$comments = count($comments) ? '# '.implode(', ', $comments) : '';

$text = rtrim(sprintf('%-21s%s %s', $node->getName().':', $default, $comments), ' ');

if ($info = $node->getInfo()) {
$this->writeLine('');

 $info = str_replace("\n", sprintf("\n%".($depth * 4).'s# ', ' '), $info);
$this->writeLine('# '.$info, $depth * 4);
}

$this->writeLine($text, $depth * 4);


 if ($defaultArray) {
$this->writeLine('');

$message = count($defaultArray) > 1 ? 'Defaults' : 'Default';

$this->writeLine('# '.$message.':', $depth * 4 + 4);

$this->writeArray($defaultArray, $depth + 1);
}

if (is_array($example)) {
$this->writeLine('');

$message = count($example) > 1 ? 'Examples' : 'Example';

$this->writeLine('# '.$message.':', $depth * 4 + 4);

$this->writeArray($example, $depth + 1);
}

if ($children) {
foreach ($children as $childNode) {
$this->writeNode($childNode, $depth + 1);
}
}
}







private function writeLine($text, $indent = 0)
{
$indent = strlen($text) + $indent;
$format = '%'.$indent.'s';

$this->reference .= sprintf($format, $text)."\n";
}

private function writeArray(array $array, $depth)
{
$isIndexed = array_values($array) === $array;

foreach ($array as $key => $value) {
if (is_array($value)) {
$val = '';
} else {
$val = $value;
}

if ($isIndexed) {
$this->writeLine('- '.$val, $depth * 4);
} else {
$this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4);
}

if (is_array($value)) {
$this->writeArray($value, $depth + 1);
}
}
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;






class FloatNode extends NumericNode
{



protected function validateType($value)
{

 if (is_int($value)) {
$value = (float) $value;
}

if (!is_float($value)) {
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected float, but got %s.', $this->getPath(), gettype($value)));
if ($hint = $this->getInfo()) {
$ex->addHint($hint);
}
$ex->setPath($this->getPath());

throw $ex;
}
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;






class EnumNode extends ScalarNode
{
private $values;

public function __construct($name, NodeInterface $parent = null, array $values = array())
{
$values = array_unique($values);
if (empty($values)) {
throw new \InvalidArgumentException('$values must contain at least one element.');
}

parent::__construct($name, $parent);
$this->values = $values;
}

public function getValues()
{
return $this->values;
}

protected function finalizeValue($value)
{
$value = parent::finalizeValue($value);

if (!in_array($value, $this->values, true)) {
$ex = new InvalidConfigurationException(sprintf(
'The value %s is not allowed for path "%s". Permissible values: %s',
json_encode($value),
$this->getPath(),
implode(', ', array_map('json_encode', $this->values))));
$ex->setPath($this->getPath());

throw $ex;
}

return $value;
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
use Symfony\Component\Config\Definition\Exception\Exception;






class PrototypedArrayNode extends ArrayNode
{
protected $prototype;
protected $keyAttribute;
protected $removeKeyAttribute = false;
protected $minNumberOfElements = 0;
protected $defaultValue = array();
protected $defaultChildren;



private $valuePrototypes = array();







public function setMinNumberOfElements($number)
{
$this->minNumberOfElements = $number;
}

























public function setKeyAttribute($attribute, $remove = true)
{
$this->keyAttribute = $attribute;
$this->removeKeyAttribute = $remove;
}






public function getKeyAttribute()
{
return $this->keyAttribute;
}








public function setDefaultValue($value)
{
if (!is_array($value)) {
throw new \InvalidArgumentException($this->getPath().': the default value of an array node has to be an array.');
}

$this->defaultValue = $value;
}






public function hasDefaultValue()
{
return true;
}






public function setAddChildrenIfNoneSet($children = array('defaults'))
{
if (null === $children) {
$this->defaultChildren = array('defaults');
} else {
$this->defaultChildren = is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
}
}









public function getDefaultValue()
{
if (null !== $this->defaultChildren) {
$default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : array();
$defaults = array();
foreach (array_values($this->defaultChildren) as $i => $name) {
$defaults[null === $this->keyAttribute ? $i : $name] = $default;
}

return $defaults;
}

return $this->defaultValue;
}






public function setPrototype(PrototypeNodeInterface $node)
{
$this->prototype = $node;
}






public function getPrototype()
{
return $this->prototype;
}








public function addChild(NodeInterface $node)
{
throw new Exception('A prototyped array node can not have concrete children.');
}











protected function finalizeValue($value)
{
if (false === $value) {
$msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
throw new UnsetKeyException($msg);
}

foreach ($value as $k => $v) {
$prototype = $this->getPrototypeForChild($k);
try {
$value[$k] = $prototype->finalize($v);
} catch (UnsetKeyException $e) {
unset($value[$k]);
}
}

if (count($value) < $this->minNumberOfElements) {
$msg = sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements);
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());

throw $ex;
}

return $value;
}











protected function normalizeValue($value)
{
if (false === $value) {
return $value;
}

$value = $this->remapXml($value);

$isAssoc = array_keys($value) !== range(0, count($value) - 1);
$normalized = array();
foreach ($value as $k => $v) {
if (null !== $this->keyAttribute && is_array($v)) {
if (!isset($v[$this->keyAttribute]) && is_int($k) && !$isAssoc) {
$msg = sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath());
$ex = new InvalidConfigurationException($msg);
$ex->setPath($this->getPath());

throw $ex;
} elseif (isset($v[$this->keyAttribute])) {
$k = $v[$this->keyAttribute];


 if ($this->removeKeyAttribute) {
unset($v[$this->keyAttribute]);
}


 if (array_keys($v) === array('value')) {
$v = $v['value'];
if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && array_key_exists('value', $children)) {
$valuePrototype = current($this->valuePrototypes) ?: clone $children['value'];
$valuePrototype->parent = $this;
$originalClosures = $this->prototype->normalizationClosures;
if (is_array($originalClosures)) {
$valuePrototypeClosures = $valuePrototype->normalizationClosures;
$valuePrototype->normalizationClosures = is_array($valuePrototypeClosures) ? array_merge($originalClosures, $valuePrototypeClosures) : $originalClosures;
}
$this->valuePrototypes[$k] = $valuePrototype;
}
}
}

if (array_key_exists($k, $normalized)) {
$msg = sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath());
$ex = new DuplicateKeyException($msg);
$ex->setPath($this->getPath());

throw $ex;
}
}

$prototype = $this->getPrototypeForChild($k);
if (null !== $this->keyAttribute || $isAssoc) {
$normalized[$k] = $prototype->normalize($v);
} else {
$normalized[] = $prototype->normalize($v);
}
}

return $normalized;
}












protected function mergeValues($leftSide, $rightSide)
{
if (false === $rightSide) {

 
 return false;
}

if (false === $leftSide || !$this->performDeepMerging) {
return $rightSide;
}

foreach ($rightSide as $k => $v) {

 if (null === $this->keyAttribute) {
$leftSide[] = $v;
continue;
}


 if (!array_key_exists($k, $leftSide)) {
if (!$this->allowNewKeys) {
$ex = new InvalidConfigurationException(sprintf(
'You are not allowed to define new elements for path "%s". '.
'Please define all elements for this path in one config file.',
$this->getPath()
));
$ex->setPath($this->getPath());

throw $ex;
}

$leftSide[$k] = $v;
continue;
}

$prototype = $this->getPrototypeForChild($k);
$leftSide[$k] = $prototype->merge($leftSide[$k], $v);
}

return $leftSide;
}





































private function getPrototypeForChild($key)
{
$prototype = isset($this->valuePrototypes[$key]) ? $this->valuePrototypes[$key] : $this->prototype;
$prototype->setName($key);

return $prototype;
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;






class IntegerNode extends NumericNode
{



protected function validateType($value)
{
if (!is_int($value)) {
$ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected int, but got %s.', $this->getPath(), gettype($value)));
if ($hint = $this->getInfo()) {
$ex->addHint($hint);
}
$ex->setPath($this->getPath());

throw $ex;
}
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;






class NumericNode extends ScalarNode
{
protected $min;
protected $max;

public function __construct($name, NodeInterface $parent = null, $min = null, $max = null)
{
parent::__construct($name, $parent);
$this->min = $min;
$this->max = $max;
}




protected function finalizeValue($value)
{
$value = parent::finalizeValue($value);

$errorMsg = null;
if (isset($this->min) && $value < $this->min) {
$errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min);
}
if (isset($this->max) && $value > $this->max) {
$errorMsg = sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max);
}
if (isset($errorMsg)) {
$ex = new InvalidConfigurationException($errorMsg);
$ex->setPath($this->getPath());
throw $ex;
}

return $value;
}




protected function isValueEmpty($value)
{

 return false;
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;













class ScalarNode extends VariableNode
{



protected function validateType($value)
{
if (!is_scalar($value) && null !== $value) {
$ex = new InvalidTypeException(sprintf(
'Invalid type for path "%s". Expected scalar, but got %s.',
$this->getPath(),
gettype($value)
));
if ($hint = $this->getInfo()) {
$ex->addHint($hint);
}
$ex->setPath($this->getPath());

throw $ex;
}
}




protected function isValueEmpty($value)
{
return null === $value || '' === $value;
}
}
<?php










namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;






abstract class BaseNode implements NodeInterface
{
protected $name;
protected $parent;
protected $normalizationClosures = array();
protected $finalValidationClosures = array();
protected $allowOverwrite = true;
protected $required = false;
protected $equivalentValues = array();
protected $attributes = array();









public function __construct($name, NodeInterface $parent = null)
{
if (false !== strpos($name, '.')) {
throw new \InvalidArgumentException('The name must not contain ".".');
}

$this->name = $name;
$this->parent = $parent;
}

public function setAttribute($key, $value)
{
$this->attributes[$key] = $value;
}

public function getAttribute($key, $default = null)
{
return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
}

public function hasAttribute($key)
{
return isset($this->attributes[$key]);
}

public function getAttributes()
{
return $this->attributes;
}

public function setAttributes(array $attributes)
{
$this->attributes = $attributes;
}

public function removeAttribute($key)
{
unset($this->attributes[$key]);
}






public function setInfo($info)
{
$this->setAttribute('info', $info);
}






public function getInfo()
{
return $this->getAttribute('info');
}






public function setExample($example)
{
$this->setAttribute('example', $example);
}






public function getExample()
{
return $this->getAttribute('example');
}







public function addEquivalentValue($originalValue, $equivalentValue)
{
$this->equivalentValues[] = array($originalValue, $equivalentValue);
}






public function setRequired($boolean)
{
$this->required = (bool) $boolean;
}






public function setAllowOverwrite($allow)
{
$this->allowOverwrite = (bool) $allow;
}






public function setNormalizationClosures(array $closures)
{
$this->normalizationClosures = $closures;
}






public function setFinalValidationClosures(array $closures)
{
$this->finalValidationClosures = $closures;
}






public function isRequired()
{
return $this->required;
}






public function getName()
{
return $this->name;
}






public function getPath()
{
$path = $this->name;

if (null !== $this->parent) {
$path = $this->parent->getPath().'.'.$path;
}

return $path;
}











final public function merge($leftSide, $rightSide)
{
if (!$this->allowOverwrite) {
throw new ForbiddenOverwriteException(sprintf(
'Configuration path "%s" cannot be overwritten. You have to '
.'define all options for this path, and any of its sub-paths in '
.'one configuration section.',
$this->getPath()
));
}

$this->validateType($leftSide);
$this->validateType($rightSide);

return $this->mergeValues($leftSide, $rightSide);
}








final public function normalize($value)
{
$value = $this->preNormalize($value);


 foreach ($this->normalizationClosures as $closure) {
$value = $closure($value);
}


 foreach ($this->equivalentValues as $data) {
if ($data[0] === $value) {
$value = $data[1];
}
}


 $this->validateType($value);


 return $this->normalizeValue($value);
}








protected function preNormalize($value)
{
return $value;
}






public function getParent()
{
return $this->parent;
}











final public function finalize($value)
{
$this->validateType($value);

$value = $this->finalizeValue($value);


 
 foreach ($this->finalValidationClosures as $closure) {
try {
$value = $closure($value);
} catch (Exception $e) {
throw $e;
} catch (\Exception $e) {
throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": %s', $this->getPath(), $e->getMessage()), $e->getCode(), $e);
}
}

return $value;
}








abstract protected function validateType($value);








abstract protected function normalizeValue($value);









abstract protected function mergeValues($leftSide, $rightSide);








abstract protected function finalizeValue($value);
}
<?php










namespace Symfony\Component\Config\Definition\Exception;







class ForbiddenOverwriteException extends InvalidConfigurationException
{
}
<?php










namespace Symfony\Component\Config\Definition\Exception;






class InvalidDefinitionException extends Exception
{
}
<?php










namespace Symfony\Component\Config\Definition\Exception;







class DuplicateKeyException extends InvalidConfigurationException
{
}
<?php










namespace Symfony\Component\Config\Definition\Exception;







class InvalidConfigurationException extends Exception
{
private $path;
private $containsHints = false;

public function setPath($path)
{
$this->path = $path;
}

public function getPath()
{
return $this->path;
}






public function addHint($hint)
{
if (!$this->containsHints) {
$this->message .= "\nHint: ".$hint;
$this->containsHints = true;
} else {
$this->message .= ', '.$hint;
}
}
}
<?php










namespace Symfony\Component\Config\Definition\Exception;






class InvalidTypeException extends InvalidConfigurationException
{
}
<?php










namespace Symfony\Component\Config\Definition\Exception;






class Exception extends \RuntimeException
{
}
<?php










namespace Symfony\Component\Config\Definition\Exception;







class UnsetKeyException extends Exception
{
}
<?php










namespace Symfony\Component\Config\Definition;






interface PrototypeNodeInterface extends NodeInterface
{





public function setName($name);
}
<?php










namespace Symfony\Component\Config;







class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryInterface
{



private $resourceCheckers = array();




public function __construct(array $resourceCheckers = array())
{
$this->resourceCheckers = $resourceCheckers;
}




public function cache($file, $callback)
{
if (!is_callable($callback)) {
throw new \InvalidArgumentException(sprintf('Invalid type for callback argument. Expected callable, but got "%s".', gettype($callback)));
}

$cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers);
if (!$cache->isFresh()) {
call_user_func($callback, $cache);
}

return $cache;
}
}
<?php










namespace Symfony\Component\Config\Resource;







interface SelfCheckingResourceInterface extends ResourceInterface
{







public function isFresh($timestamp);
}
<?php










namespace Symfony\Component\Config\Resource;

use Symfony\Component\Config\ResourceCheckerInterface;









class SelfCheckingResourceChecker implements ResourceCheckerInterface
{
public function supports(ResourceInterface $metadata)
{
return $metadata instanceof SelfCheckingResourceInterface;
}

public function isFresh(ResourceInterface $resource, $timestamp)
{

return $resource->isFresh($timestamp);
}
}
<?php










namespace Symfony\Component\Config\Resource;









class FileExistenceResource implements SelfCheckingResourceInterface, \Serializable
{
private $resource;

private $exists;






public function __construct($resource)
{
$this->resource = (string) $resource;
$this->exists = file_exists($resource);
}




public function __toString()
{
return $this->resource;
}




public function getResource()
{
return $this->resource;
}




public function isFresh($timestamp)
{
return file_exists($this->resource) === $this->exists;
}




public function serialize()
{
return serialize(array($this->resource, $this->exists));
}




public function unserialize($serialized)
{
list($this->resource, $this->exists) = unserialize($serialized);
}
}
<?php










namespace Symfony\Component\Config\Resource;








class FileResource implements SelfCheckingResourceInterface, \Serializable
{



private $resource;






public function __construct($resource)
{
$this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false);
}




public function __toString()
{
return (string) $this->resource;
}




public function getResource()
{
return $this->resource;
}




public function isFresh($timestamp)
{
if (false === $this->resource || !file_exists($this->resource)) {
return false;
}

return filemtime($this->resource) <= $timestamp;
}

public function serialize()
{
return serialize($this->resource);
}

public function unserialize($serialized)
{
$this->resource = unserialize($serialized);
}
}
<?php










namespace Symfony\Component\Config\Resource;








class BCResourceInterfaceChecker extends SelfCheckingResourceChecker
{
public function supports(ResourceInterface $metadata)
{


return true;
}

public function isFresh(ResourceInterface $resource, $timestamp)
{
@trigger_error(sprintf('The class "%s" is performing resource checking through ResourceInterface::isFresh(), which is deprecated since 2.8 and will be removed in 3.0', get_class($resource)), E_USER_DEPRECATED);

return parent::isFresh($resource, $timestamp); 
 }
}
<?php










namespace Symfony\Component\Config\Resource;






class DirectoryResource implements SelfCheckingResourceInterface, \Serializable
{
private $resource;
private $pattern;







public function __construct($resource, $pattern = null)
{
$this->resource = $resource;
$this->pattern = $pattern;
}




public function __toString()
{
return md5(serialize(array($this->resource, $this->pattern)));
}




public function getResource()
{
return $this->resource;
}






public function getPattern()
{
return $this->pattern;
}




public function isFresh($timestamp)
{
if (!is_dir($this->resource)) {
return false;
}

if ($timestamp < filemtime($this->resource)) {
return false;
}

foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {

 if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
continue;
}


 
 if ($file->isDir() && '/..' === substr($file, -3)) {
continue;
}


 try {
$fileMTime = $file->getMTime();
} catch (\RuntimeException $e) {
continue;
}


 if ($timestamp < $fileMTime) {
return false;
}
}

return true;
}

public function serialize()
{
return serialize(array($this->resource, $this->pattern));
}

public function unserialize($serialized)
{
list($this->resource, $this->pattern) = unserialize($serialized);
}
}
<?php










namespace Symfony\Component\Config\Resource;






interface ResourceInterface
{











public function __toString();











public function isFresh($timestamp);












public function getResource();
}
<?php










namespace Symfony\Component\Config;






class FileLocator implements FileLocatorInterface
{
protected $paths;






public function __construct($paths = array())
{
$this->paths = (array) $paths;
}




public function locate($name, $currentPath = null, $first = true)
{
if ('' == $name) {
throw new \InvalidArgumentException('An empty file name is not valid to be located.');
}

if ($this->isAbsolutePath($name)) {
if (!file_exists($name)) {
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name));
}

return $name;
}

$paths = $this->paths;

if (null !== $currentPath) {
array_unshift($paths, $currentPath);
}

$paths = array_unique($paths);
$filepaths = array();

foreach ($paths as $path) {
if (@file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
if (true === $first) {
return $file;
}
$filepaths[] = $file;
}
}

if (!$filepaths) {
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s).', $name, implode(', ', $paths)));
}

return $filepaths;
}








private function isAbsolutePath($file)
{
if ($file[0] === '/' || $file[0] === '\\'
|| (strlen($file) > 3 && ctype_alpha($file[0])
&& $file[1] === ':'
&& ($file[2] === '\\' || $file[2] === '/')
)
|| null !== parse_url($file, PHP_URL_SCHEME)
) {
return true;
}

return false;
}
}
<?php










namespace Symfony\Component\Config;




interface FileLocatorInterface
{











public function locate($name, $currentPath = null, $first = true);
}
<?php










namespace Symfony\Component\Config\Loader;









class LoaderResolver implements LoaderResolverInterface
{



private $loaders = array();






public function __construct(array $loaders = array())
{
foreach ($loaders as $loader) {
$this->addLoader($loader);
}
}




public function resolve($resource, $type = null)
{
foreach ($this->loaders as $loader) {
if ($loader->supports($resource, $type)) {
return $loader;
}
}

return false;
}






public function addLoader(LoaderInterface $loader)
{
$this->loaders[] = $loader;
$loader->setResolver($this);
}






public function getLoaders()
{
return $this->loaders;
}
}
<?php










namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Config\Exception\FileLoaderLoadException;
use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;






abstract class FileLoader extends Loader
{



protected static $loading = array();




protected $locator;

private $currentDir;






public function __construct(FileLocatorInterface $locator)
{
$this->locator = $locator;
}






public function setCurrentDir($dir)
{
$this->currentDir = $dir;
}






public function getLocator()
{
return $this->locator;
}














public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
{
try {
$loader = $this->resolve($resource, $type);

if ($loader instanceof self && null !== $this->currentDir) {

 
 
 $locator = $loader->getLocator();
if (null === $locator) {
@trigger_error('Not calling the parent constructor in '.get_class($loader).' which extends '.__CLASS__.' is deprecated since version 2.7 and will not be supported anymore in 3.0.', E_USER_DEPRECATED);
$locator = $this->locator;
}

$resource = $locator->locate($resource, $this->currentDir, false);
}

$resources = is_array($resource) ? $resource : array($resource);
for ($i = 0; $i < $resourcesCount = count($resources); ++$i) {
if (isset(self::$loading[$resources[$i]])) {
if ($i == $resourcesCount - 1) {
throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
}
} else {
$resource = $resources[$i];
break;
}
}
self::$loading[$resource] = true;

try {
$ret = $loader->load($resource, $type);
} catch (\Exception $e) {
unset(self::$loading[$resource]);
throw $e;
} catch (\Throwable $e) {
unset(self::$loading[$resource]);
throw $e;
}

unset(self::$loading[$resource]);

return $ret;
} catch (FileLoaderImportCircularReferenceException $e) {
throw $e;
} catch (\Exception $e) {
if (!$ignoreErrors) {

 if ($e instanceof FileLoaderLoadException) {
throw $e;
}

throw new FileLoaderLoadException($resource, $sourceResource, null, $e);
}
}
}
}
<?php










namespace Symfony\Component\Config\Loader;






interface LoaderResolverInterface
{








public function resolve($resource, $type = null);
}
<?php










namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\FileLoaderLoadException;









class DelegatingLoader extends Loader
{





public function __construct(LoaderResolverInterface $resolver)
{
$this->resolver = $resolver;
}




public function load($resource, $type = null)
{
if (false === $loader = $this->resolver->resolve($resource, $type)) {
throw new FileLoaderLoadException($resource);
}

return $loader->load($resource, $type);
}




public function supports($resource, $type = null)
{
return false !== $this->resolver->resolve($resource, $type);
}
}
<?php










namespace Symfony\Component\Config\Loader;






interface LoaderInterface
{








public function load($resource, $type = null);









public function supports($resource, $type = null);






public function getResolver();






public function setResolver(LoaderResolverInterface $resolver);
}
<?php










namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\FileLoaderLoadException;






abstract class Loader implements LoaderInterface
{
protected $resolver;




public function getResolver()
{
return $this->resolver;
}




public function setResolver(LoaderResolverInterface $resolver)
{
$this->resolver = $resolver;
}









public function import($resource, $type = null)
{
return $this->resolve($resource, $type)->load($resource, $type);
}











public function resolve($resource, $type = null)
{
if ($this->supports($resource, $type)) {
return $this;
}

$loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);

if (false === $loader) {
throw new FileLoaderLoadException($resource);
}

return $loader;
}
}
<?php










namespace Symfony\Component\Config\Util;









class XmlUtils
{



private function __construct()
{
}











public static function loadFile($file, $schemaOrCallable = null)
{
$content = @file_get_contents($file);
if ('' === trim($content)) {
throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
}

$internalErrors = libxml_use_internal_errors(true);
$disableEntities = libxml_disable_entity_loader(true);
libxml_clear_errors();

$dom = new \DOMDocument();
$dom->validateOnParse = true;
if (!$dom->loadXML($content, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
libxml_disable_entity_loader($disableEntities);

throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors)));
}

$dom->normalizeDocument();

libxml_use_internal_errors($internalErrors);
libxml_disable_entity_loader($disableEntities);

foreach ($dom->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
throw new \InvalidArgumentException('Document types are not allowed.');
}
}

if (null !== $schemaOrCallable) {
$internalErrors = libxml_use_internal_errors(true);
libxml_clear_errors();

$e = null;
if (is_callable($schemaOrCallable)) {
try {
$valid = call_user_func($schemaOrCallable, $dom, $internalErrors);
} catch (\Exception $e) {
$valid = false;
}
} elseif (!is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) {
$schemaSource = file_get_contents((string) $schemaOrCallable);
$valid = @$dom->schemaValidateSource($schemaSource);
} else {
libxml_use_internal_errors($internalErrors);

throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
}

if (!$valid) {
$messages = static::getXmlErrors($internalErrors);
if (empty($messages)) {
$messages = array(sprintf('The XML file "%s" is not valid.', $file));
}
throw new \InvalidArgumentException(implode("\n", $messages), 0, $e);
}
}

libxml_clear_errors();
libxml_use_internal_errors($internalErrors);

return $dom;
}





















public static function convertDomElementToArray(\DOMElement $element, $checkPrefix = true)
{
$prefix = (string) $element->prefix;
$empty = true;
$config = array();
foreach ($element->attributes as $name => $node) {
if ($checkPrefix && !in_array((string) $node->prefix, array('', $prefix), true)) {
continue;
}
$config[$name] = static::phpize($node->value);
$empty = false;
}

$nodeValue = false;
foreach ($element->childNodes as $node) {
if ($node instanceof \DOMText) {
if ('' !== trim($node->nodeValue)) {
$nodeValue = trim($node->nodeValue);
$empty = false;
}
} elseif ($checkPrefix && $prefix != (string) $node->prefix) {
continue;
} elseif (!$node instanceof \DOMComment) {
$value = static::convertDomElementToArray($node, $checkPrefix);

$key = $node->localName;
if (isset($config[$key])) {
if (!is_array($config[$key]) || !is_int(key($config[$key]))) {
$config[$key] = array($config[$key]);
}
$config[$key][] = $value;
} else {
$config[$key] = $value;
}

$empty = false;
}
}

if (false !== $nodeValue) {
$value = static::phpize($nodeValue);
if (count($config)) {
$config['value'] = $value;
} else {
$config = $value;
}
}

return !$empty ? $config : null;
}








public static function phpize($value)
{
$value = (string) $value;
$lowercaseValue = strtolower($value);

switch (true) {
case 'null' === $lowercaseValue:
return;
case ctype_digit($value):
$raw = $value;
$cast = (int) $value;

return '0' == $value[0] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw);
case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)):
$raw = $value;
$cast = (int) $value;

return '0' == $value[1] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw);
case 'true' === $lowercaseValue:
return true;
case 'false' === $lowercaseValue:
return false;
case isset($value[1]) && '0b' == $value[0].$value[1]:
return bindec($value);
case is_numeric($value):
return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value;
case preg_match('/^0x[0-9a-f]++$/i', $value):
return hexdec($value);
case preg_match('/^(-|\+)?[0-9]+(\.[0-9]+)?$/', $value):
return (float) $value;
default:
return $value;
}
}

protected static function getXmlErrors($internalErrors)
{
$errors = array();
foreach (libxml_get_errors() as $error) {
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
$error->code,
trim($error->message),
$error->file ?: 'n/a',
$error->line,
$error->column
);
}

libxml_clear_errors();
libxml_use_internal_errors($internalErrors);

return $errors;
}
}
<?php










namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;












interface ResourceCheckerInterface
{








public function supports(ResourceInterface $metadata);









public function isFresh(ResourceInterface $resource, $timestamp);
}
<?php










namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Tests\Resource\ResourceStub;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\ResourceCheckerConfigCache;

class ResourceCheckerConfigCacheTest extends TestCase
{
private $cacheFile = null;

protected function setUp()
{
$this->cacheFile = tempnam(sys_get_temp_dir(), 'config_');
}

protected function tearDown()
{
$files = array($this->cacheFile, "{$this->cacheFile}.meta");

foreach ($files as $file) {
if (file_exists($file)) {
unlink($file);
}
}
}

public function testGetPath()
{
$cache = new ResourceCheckerConfigCache($this->cacheFile);

$this->assertSame($this->cacheFile, $cache->getPath());
}

public function testCacheIsNotFreshIfEmpty()
{
$checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock()
->expects($this->never())->method('supports');




unlink($this->cacheFile); 
 $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));

$this->assertFalse($cache->isFresh());
}

public function testCacheIsFreshIfNocheckerProvided()
{


$cache = new ResourceCheckerConfigCache($this->cacheFile);
$this->assertTrue($cache->isFresh());
}

public function testResourcesWithoutcheckersAreIgnoredAndConsideredFresh()
{

$cache = new ResourceCheckerConfigCache($this->cacheFile);
$cache->write('', array(new ResourceStub()));

$this->assertTrue($cache->isFresh()); 
 }

public function testIsFreshWithchecker()
{
$checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();

$checker->expects($this->once())
->method('supports')
->willReturn(true);

$checker->expects($this->once())
->method('isFresh')
->willReturn(true);

$cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
$cache->write('', array(new ResourceStub()));

$this->assertTrue($cache->isFresh());
}

public function testIsNotFreshWithchecker()
{
$checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();

$checker->expects($this->once())
->method('supports')
->willReturn(true);

$checker->expects($this->once())
->method('isFresh')
->willReturn(false);

$cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
$cache->write('', array(new ResourceStub()));

$this->assertFalse($cache->isFresh());
}

public function testCacheIsNotFreshWhenUnserializeFails()
{
$checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();
$cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
$cache->write('foo', array(new FileResource(__FILE__)));

$metaFile = "{$this->cacheFile}.meta";
file_put_contents($metaFile, str_replace('FileResource', 'ClassNotHere', file_get_contents($metaFile)));

$this->assertFalse($cache->isFresh());
}

public function testCacheKeepsContent()
{
$cache = new ResourceCheckerConfigCache($this->cacheFile);
$cache->write('FOOBAR');

$this->assertSame('FOOBAR', file_get_contents($cache->getPath()));
}

public function testCacheIsNotFreshIfNotExistsMetaFile()
{
$checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock();
$cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker));
$cache->write('foo', array(new FileResource(__FILE__)));

$metaFile = "{$this->cacheFile}.meta";
unlink($metaFile);

$this->assertFalse($cache->isFresh());
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class MergeTest extends TestCase
{



public function testForbiddenOverwrite()
{
$tb = new TreeBuilder();
$tree = $tb
->root('root', 'array')
->children()
->node('foo', 'scalar')
->cannotBeOverwritten()
->end()
->end()
->end()
->buildTree()
;

$a = array(
'foo' => 'bar',
);

$b = array(
'foo' => 'moo',
);

$tree->merge($a, $b);
}

public function testUnsetKey()
{
$tb = new TreeBuilder();
$tree = $tb
->root('root', 'array')
->children()
->node('foo', 'scalar')->end()
->node('bar', 'scalar')->end()
->node('unsettable', 'array')
->canBeUnset()
->children()
->node('foo', 'scalar')->end()
->node('bar', 'scalar')->end()
->end()
->end()
->node('unsetted', 'array')
->canBeUnset()
->prototype('scalar')->end()
->end()
->end()
->end()
->buildTree()
;

$a = array(
'foo' => 'bar',
'unsettable' => array(
'foo' => 'a',
'bar' => 'b',
),
'unsetted' => false,
);

$b = array(
'foo' => 'moo',
'bar' => 'b',
'unsettable' => false,
'unsetted' => array('a', 'b'),
);

$this->assertEquals(array(
'foo' => 'moo',
'bar' => 'b',
'unsettable' => false,
'unsetted' => array('a', 'b'),
), $tree->merge($a, $b));
}




public function testDoesNotAllowNewKeysInSubsequentConfigs()
{
$tb = new TreeBuilder();
$tree = $tb
->root('config', 'array')
->children()
->node('test', 'array')
->disallowNewKeysInSubsequentConfigs()
->useAttributeAsKey('key')
->prototype('array')
->children()
->node('value', 'scalar')->end()
->end()
->end()
->end()
->end()
->end()
->buildTree();

$a = array(
'test' => array(
'a' => array('value' => 'foo'),
),
);

$b = array(
'test' => array(
'b' => array('value' => 'foo'),
),
);

$tree->merge($a, $b);
}

public function testPerformsNoDeepMerging()
{
$tb = new TreeBuilder();

$tree = $tb
->root('config', 'array')
->children()
->node('no_deep_merging', 'array')
->performNoDeepMerging()
->children()
->node('foo', 'scalar')->end()
->node('bar', 'scalar')->end()
->end()
->end()
->end()
->end()
->buildTree()
;

$a = array(
'no_deep_merging' => array(
'foo' => 'a',
'bar' => 'b',
),
);

$b = array(
'no_deep_merging' => array(
'c' => 'd',
),
);

$this->assertEquals(array(
'no_deep_merging' => array(
'c' => 'd',
),
), $tree->merge($a, $b));
}

public function testPrototypeWithoutAKeyAttribute()
{
$tb = new TreeBuilder();

$tree = $tb
->root('config', 'array')
->children()
->arrayNode('append_elements')
->prototype('scalar')->end()
->end()
->end()
->end()
->buildTree()
;

$a = array(
'append_elements' => array('a', 'b'),
);

$b = array(
'append_elements' => array('c', 'd'),
);

$this->assertEquals(array('append_elements' => array('a', 'b', 'c', 'd')), $tree->merge($a, $b));
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\BooleanNode;

class BooleanNodeTest extends TestCase
{



public function testNormalize($value)
{
$node = new BooleanNode('test');
$this->assertSame($value, $node->normalize($value));
}






public function testValidNonEmptyValues($value)
{
$node = new BooleanNode('test');
$node->setAllowEmptyValue(false);

$this->assertSame($value, $node->finalize($value));
}

public function getValidValues()
{
return array(
array(false),
array(true),
);
}





public function testNormalizeThrowsExceptionOnInvalidValues($value)
{
$node = new BooleanNode('test');
$node->normalize($value);
}

public function getInvalidValues()
{
return array(
array(null),
array(''),
array('foo'),
array(0),
array(1),
array(0.0),
array(0.1),
array(array()),
array(array('foo' => 'bar')),
array(new \stdClass()),
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;

class ArrayNodeDefinitionTest extends TestCase
{
public function testAppendingSomeNode()
{
$parent = new ArrayNodeDefinition('root');
$child = new ScalarNodeDefinition('child');

$parent
->children()
->scalarNode('foo')->end()
->scalarNode('bar')->end()
->end()
->append($child);

$this->assertCount(3, $this->getField($parent, 'children'));
$this->assertTrue(in_array($child, $this->getField($parent, 'children')));
}





public function testPrototypeNodeSpecificOption($method, $args)
{
$node = new ArrayNodeDefinition('root');

call_user_func_array(array($node, $method), $args);

$node->getNode();
}

public function providePrototypeNodeSpecificCalls()
{
return array(
array('defaultValue', array(array())),
array('addDefaultChildrenIfNoneSet', array()),
array('requiresAtLeastOneElement', array()),
array('useAttributeAsKey', array('foo')),
);
}




public function testConcreteNodeSpecificOption()
{
$node = new ArrayNodeDefinition('root');
$node
->addDefaultsIfNotSet()
->prototype('array')
;
$node->getNode();
}




public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren()
{
$node = new ArrayNodeDefinition('root');
$node
->defaultValue(array())
->addDefaultChildrenIfNoneSet('foo')
->prototype('array')
;
$node->getNode();
}

public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
{
$node = new ArrayNodeDefinition('root');
$node
->addDefaultChildrenIfNoneSet()
->prototype('array')
;
$tree = $node->getNode();
$this->assertEquals(array(array()), $tree->getDefaultValue());
}




public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
{
$node = new ArrayNodeDefinition('root');
$node
->addDefaultChildrenIfNoneSet($args)
->prototype('array')
;

try {
$tree = $node->getNode();
$this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
$this->assertEquals($defaults, $tree->getDefaultValue());
} catch (InvalidDefinitionException $e) {
$this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
}

$node = new ArrayNodeDefinition('root');
$node
->useAttributeAsKey('attr')
->addDefaultChildrenIfNoneSet($args)
->prototype('array')
;

try {
$tree = $node->getNode();
$this->assertFalse($shouldThrowWhenUsingAttrAsKey);
$this->assertEquals($defaults, $tree->getDefaultValue());
} catch (InvalidDefinitionException $e) {
$this->assertTrue($shouldThrowWhenUsingAttrAsKey);
}
}

public function providePrototypedArrayNodeDefaults()
{
return array(
array(null, true, false, array(array())),
array(2, true, false, array(array(), array())),
array('2', false, true, array('2' => array())),
array('foo', false, true, array('foo' => array())),
array(array('foo'), false, true, array('foo' => array())),
array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
);
}

public function testNestedPrototypedArrayNodes()
{
$node = new ArrayNodeDefinition('root');
$node
->addDefaultChildrenIfNoneSet()
->prototype('array')
->prototype('array')
;
$node->getNode();
}

public function testEnabledNodeDefaults()
{
$node = new ArrayNodeDefinition('root');
$node
->canBeEnabled()
->children()
->scalarNode('foo')->defaultValue('bar')->end()
;

$this->assertEquals(array('enabled' => false, 'foo' => 'bar'), $node->getNode()->getDefaultValue());
}




public function testTrueEnableEnabledNode($expected, $config, $message)
{
$processor = new Processor();
$node = new ArrayNodeDefinition('root');
$node
->canBeEnabled()
->children()
->scalarNode('foo')->defaultValue('bar')->end()
;

$this->assertEquals(
$expected,
$processor->process($node->getNode(), $config),
$message
);
}

public function testCanBeDisabled()
{
$node = new ArrayNodeDefinition('root');
$node->canBeDisabled();

$this->assertTrue($this->getField($node, 'addDefaults'));
$this->assertEquals(array('enabled' => false), $this->getField($node, 'falseEquivalent'));
$this->assertEquals(array('enabled' => true), $this->getField($node, 'trueEquivalent'));
$this->assertEquals(array('enabled' => true), $this->getField($node, 'nullEquivalent'));

$nodeChildren = $this->getField($node, 'children');
$this->assertArrayHasKey('enabled', $nodeChildren);

$enabledNode = $nodeChildren['enabled'];
$this->assertTrue($this->getField($enabledNode, 'default'));
$this->assertTrue($this->getField($enabledNode, 'defaultValue'));
}

public function testIgnoreExtraKeys()
{
$node = new ArrayNodeDefinition('root');

$this->assertFalse($this->getField($node, 'ignoreExtraKeys'));

$result = $node->ignoreExtraKeys();

$this->assertEquals($node, $result);
$this->assertTrue($this->getField($node, 'ignoreExtraKeys'));
}

public function testNormalizeKeys()
{
$node = new ArrayNodeDefinition('root');

$this->assertTrue($this->getField($node, 'normalizeKeys'));

$result = $node->normalizeKeys(false);

$this->assertEquals($node, $result);
$this->assertFalse($this->getField($node, 'normalizeKeys'));
}

public function getEnableableNodeFixtures()
{
return array(
array(array('enabled' => true, 'foo' => 'bar'), array(true), 'true enables an enableable node'),
array(array('enabled' => true, 'foo' => 'bar'), array(null), 'null enables an enableable node'),
array(array('enabled' => true, 'foo' => 'bar'), array(array('enabled' => true)), 'An enableable node can be enabled'),
array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'),
array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'),
array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'),
);
}

protected function getField($object, $field)
{
$reflection = new \ReflectionProperty($object, $field);
$reflection->setAccessible(true);

return $reflection->getValue($object);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition;

class EnumNodeDefinitionTest extends TestCase
{
public function testWithOneValue()
{
$def = new EnumNodeDefinition('foo');
$def->values(array('foo'));

$node = $def->getNode();
$this->assertEquals(array('foo'), $node->getValues());
}

public function testWithOneDistinctValue()
{
$def = new EnumNodeDefinition('foo');
$def->values(array('foo', 'foo'));

$node = $def->getNode();
$this->assertEquals(array('foo'), $node->getValues());
}





public function testNoValuesPassed()
{
$def = new EnumNodeDefinition('foo');
$def->getNode();
}





public function testWithNoValues()
{
$def = new EnumNodeDefinition('foo');
$def->values(array());
}

public function testGetNode()
{
$def = new EnumNodeDefinition('foo');
$def->values(array('foo', 'bar'));

$node = $def->getNode();
$this->assertEquals(array('foo', 'bar'), $node->getValues());
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

require __DIR__.'/../../Fixtures/Builder/NodeBuilder.php';
require __DIR__.'/../../Fixtures/Builder/BarNodeDefinition.php';
require __DIR__.'/../../Fixtures/Builder/VariableNodeDefinition.php';

class TreeBuilderTest extends TestCase
{
public function testUsingACustomNodeBuilder()
{
$builder = new TreeBuilder();
$root = $builder->root('custom', 'array', new CustomNodeBuilder());

$nodeBuilder = $root->children();

$this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);

$nodeBuilder = $nodeBuilder->arrayNode('deeper')->children();

$this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);
}

public function testOverrideABuiltInNodeType()
{
$builder = new TreeBuilder();
$root = $builder->root('override', 'array', new CustomNodeBuilder());

$definition = $root->children()->variableNode('variable');

$this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition', $definition);
}

public function testAddANodeType()
{
$builder = new TreeBuilder();
$root = $builder->root('override', 'array', new CustomNodeBuilder());

$definition = $root->children()->barNode('variable');

$this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition', $definition);
}

public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
{
$builder = new TreeBuilder();
$root = $builder->root('builtin', 'array', new CustomNodeBuilder());

$definition = $root->children()->booleanNode('boolean');

$this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition);
}

public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
{
$builder = new TreeBuilder();
$root = $builder->root('override', 'array', new CustomNodeBuilder());

$root->prototype('bar')->end();
}

public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
{
$builder = new TreeBuilder();

$builder->root('propagation')
->children()
->setNodeClass('extended', 'Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition')
->node('foo', 'extended')->end()
->arrayNode('child')
->children()
->node('foo', 'extended')
->end()
->end()
->end()
->end();
}

public function testDefinitionInfoGetsTransferredToNode()
{
$builder = new TreeBuilder();

$builder->root('test')->info('root info')
->children()
->node('child', 'variable')->info('child info')->defaultValue('default')
->end()
->end();

$tree = $builder->buildTree();
$children = $tree->getChildren();

$this->assertEquals('root info', $tree->getInfo());
$this->assertEquals('child info', $children['child']->getInfo());
}

public function testDefinitionExampleGetsTransferredToNode()
{
$builder = new TreeBuilder();

$builder->root('test')
->example(array('key' => 'value'))
->children()
->node('child', 'variable')->info('child info')->defaultValue('default')->example('example')
->end()
->end();

$tree = $builder->buildTree();
$children = $tree->getChildren();

$this->assertInternalType('array', $tree->getExample());
$this->assertEquals('example', $children['child']->getExample());
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;

class NodeBuilderTest extends TestCase
{



public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType()
{
$builder = new BaseNodeBuilder();
$builder->node('', 'foobar');
}




public function testThrowsAnExceptionWhenTheNodeClassIsNotFound()
{
$builder = new BaseNodeBuilder();
$builder
->setNodeClass('noclasstype', '\\foo\\bar\\noclass')
->node('', 'noclasstype');
}

public function testAddingANewNodeType()
{
$class = __NAMESPACE__.'\\SomeNodeDefinition';

$builder = new BaseNodeBuilder();
$node = $builder
->setNodeClass('newtype', $class)
->node('', 'newtype');

$this->assertInstanceOf($class, $node);
}

public function testOverridingAnExistingNodeType()
{
$class = __NAMESPACE__.'\\SomeNodeDefinition';

$builder = new BaseNodeBuilder();
$node = $builder
->setNodeClass('variable', $class)
->node('', 'variable');

$this->assertInstanceOf($class, $node);
}

public function testNodeTypesAreNotCaseSensitive()
{
$builder = new BaseNodeBuilder();

$node1 = $builder->node('', 'VaRiAbLe');
$node2 = $builder->node('', 'variable');

$this->assertInstanceOf(get_class($node1), $node2);

$builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition');

$node1 = $builder->node('', 'CUSTOM');
$node2 = $builder->node('', 'custom');

$this->assertInstanceOf(get_class($node1), $node2);
}

public function testNumericNodeCreation()
{
$builder = new BaseNodeBuilder();

$node = $builder->integerNode('foo')->min(3)->max(5);
$this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', $node);

$node = $builder->floatNode('bar')->min(3.0)->max(5.0);
$this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', $node);
}
}

class SomeNodeDefinition extends BaseVariableNodeDefinition
{
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class ExprBuilderTest extends TestCase
{
public function testAlwaysExpression()
{
$test = $this->getTestBuilder()
->always($this->returnClosure('new_value'))
->end();

$this->assertFinalizedValueIs('new_value', $test);
}

public function testIfTrueExpression()
{
$test = $this->getTestBuilder()
->ifTrue()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test, array('key' => true));

$test = $this->getTestBuilder()
->ifTrue(function ($v) { return true; })
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test);

$test = $this->getTestBuilder()
->ifTrue(function ($v) { return false; })
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('value', $test);
}

public function testIfStringExpression()
{
$test = $this->getTestBuilder()
->ifString()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test);

$test = $this->getTestBuilder()
->ifString()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs(45, $test, array('key' => 45));
}

public function testIfNullExpression()
{
$test = $this->getTestBuilder()
->ifNull()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test, array('key' => null));

$test = $this->getTestBuilder()
->ifNull()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('value', $test);
}

public function testIfArrayExpression()
{
$test = $this->getTestBuilder()
->ifArray()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test, array('key' => array()));

$test = $this->getTestBuilder()
->ifArray()
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('value', $test);
}

public function testIfInArrayExpression()
{
$test = $this->getTestBuilder()
->ifInArray(array('foo', 'bar', 'value'))
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test);

$test = $this->getTestBuilder()
->ifInArray(array('foo', 'bar'))
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('value', $test);
}

public function testIfNotInArrayExpression()
{
$test = $this->getTestBuilder()
->ifNotInArray(array('foo', 'bar'))
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test);

$test = $this->getTestBuilder()
->ifNotInArray(array('foo', 'bar', 'value_from_config'))
->then($this->returnClosure('new_value'))
->end();
$this->assertFinalizedValueIs('new_value', $test);
}

public function testThenEmptyArrayExpression()
{
$test = $this->getTestBuilder()
->ifString()
->thenEmptyArray()
->end();
$this->assertFinalizedValueIs(array(), $test);
}




public function testThenInvalid()
{
$test = $this->getTestBuilder()
->ifString()
->thenInvalid('Invalid value')
->end();
$this->finalizeTestBuilder($test);
}

public function testThenUnsetExpression()
{
$test = $this->getTestBuilder()
->ifString()
->thenUnset()
->end();
$this->assertEquals(array(), $this->finalizeTestBuilder($test));
}





public function testEndIfPartNotSpecified()
{
$this->getTestBuilder()->end();
}





public function testEndThenPartNotSpecified()
{
$builder = $this->getTestBuilder();
$builder->ifPart = 'test';
$builder->end();
}






protected function getTestBuilder()
{
$builder = new TreeBuilder();

return $builder
->root('test')
->children()
->variableNode('key')
->validate()
;
}










protected function finalizeTestBuilder($testBuilder, $config = null)
{
return $testBuilder
->end()
->end()
->end()
->buildTree()
->finalize(null === $config ? array('key' => 'value') : $config)
;
}








protected function returnClosure($val)
{
return function ($v) use ($val) {
return $val;
};
}








protected function assertFinalizedValueIs($value, $treeBuilder, $config = null)
{
$this->assertEquals(array('key' => $value), $this->finalizeTestBuilder($treeBuilder, $config));
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition as NumericNodeDefinition;
use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition;
use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition;

class NumericNodeDefinitionTest extends TestCase
{




public function testIncoherentMinAssertion()
{
$def = new NumericNodeDefinition('foo');
$def->max(3)->min(4);
}





public function testIncoherentMaxAssertion()
{
$node = new NumericNodeDefinition('foo');
$node->min(3)->max(2);
}





public function testIntegerMinAssertion()
{
$def = new IntegerNodeDefinition('foo');
$def->min(5)->getNode()->finalize(4);
}





public function testIntegerMaxAssertion()
{
$def = new IntegerNodeDefinition('foo');
$def->max(3)->getNode()->finalize(4);
}

public function testIntegerValidMinMaxAssertion()
{
$def = new IntegerNodeDefinition('foo');
$node = $def->min(3)->max(7)->getNode();
$this->assertEquals(4, $node->finalize(4));
}





public function testFloatMinAssertion()
{
$def = new FloatNodeDefinition('foo');
$def->min(5E2)->getNode()->finalize(4e2);
}





public function testFloatMaxAssertion()
{
$def = new FloatNodeDefinition('foo');
$def->max(0.3)->getNode()->finalize(4.3);
}

public function testFloatValidMinMaxAssertion()
{
$def = new FloatNodeDefinition('foo');
$node = $def->min(3.0)->max(7e2)->getNode();
$this->assertEquals(4.5, $node->finalize(4.5));
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\ScalarNode;

class ArrayNodeTest extends TestCase
{



public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
{
$node = new ArrayNode('root');
$node->normalize(false);
}





public function testExceptionThrownOnUnrecognizedChild()
{
$node = new ArrayNode('root');
$node->normalize(array('foo' => 'bar'));
}

public function ignoreAndRemoveMatrixProvider()
{
$unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"');

return array(
array(true, true, array(), 'no exception is thrown for an unrecognized child if the ignoreExtraKeys option is set to true'),
array(true, false, array('foo' => 'bar'), 'extra keys are not removed when ignoreExtraKeys second option is set to false'),
array(false, true, $unrecognizedOptionException),
array(false, false, $unrecognizedOptionException),
);
}




public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '')
{
if ($expected instanceof \Exception) {
if (method_exists($this, 'expectException')) {
$this->expectException(get_class($expected));
$this->expectExceptionMessage($expected->getMessage());
} else {
$this->setExpectedException(get_class($expected), $expected->getMessage());
}
}
$node = new ArrayNode('root');
$node->setIgnoreExtraKeys($ignore, $remove);
$result = $node->normalize(array('foo' => 'bar'));
$this->assertSame($expected, $result, $message);
}




public function testPreNormalize($denormalized, $normalized)
{
$node = new ArrayNode('foo');

$r = new \ReflectionMethod($node, 'preNormalize');
$r->setAccessible(true);

$this->assertSame($normalized, $r->invoke($node, $denormalized));
}

public function getPreNormalizationTests()
{
return array(
array(
array('foo-bar' => 'foo'),
array('foo_bar' => 'foo'),
),
array(
array('foo-bar_moo' => 'foo'),
array('foo-bar_moo' => 'foo'),
),
array(
array('anything-with-dash-and-no-underscore' => 'first', 'no_dash' => 'second'),
array('anything_with_dash_and_no_underscore' => 'first', 'no_dash' => 'second'),
),
array(
array('foo-bar' => null, 'foo_bar' => 'foo'),
array('foo-bar' => null, 'foo_bar' => 'foo'),
),
);
}




public function testNodeNameCanBeZero($denormalized, $normalized)
{
$zeroNode = new ArrayNode(0);
$zeroNode->addChild(new ScalarNode('name'));
$fiveNode = new ArrayNode(5);
$fiveNode->addChild(new ScalarNode(0));
$fiveNode->addChild(new ScalarNode('new_key'));
$rootNode = new ArrayNode('root');
$rootNode->addChild($zeroNode);
$rootNode->addChild($fiveNode);
$rootNode->addChild(new ScalarNode('string_key'));
$r = new \ReflectionMethod($rootNode, 'normalizeValue');
$r->setAccessible(true);

$this->assertSame($normalized, $r->invoke($rootNode, $denormalized));
}

public function getZeroNamedNodeExamplesData()
{
return array(
array(
array(
0 => array(
'name' => 'something',
),
5 => array(
0 => 'this won\'t work too',
'new_key' => 'some other value',
),
'string_key' => 'just value',
),
array(
0 => array(
'name' => 'something',
),
5 => array(
0 => 'this won\'t work too',
'new_key' => 'some other value',
),
'string_key' => 'just value',
),
),
);
}




public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized)
{
$scalar1 = new ScalarNode('1');
$scalar2 = new ScalarNode('2');
$scalar3 = new ScalarNode('3');
$node = new ArrayNode('foo');
$node->addChild($scalar1);
$node->addChild($scalar3);
$node->addChild($scalar2);

$r = new \ReflectionMethod($node, 'normalizeValue');
$r->setAccessible(true);

$this->assertSame($normalized, $r->invoke($node, $prenormalized));
}

public function getPreNormalizedNormalizedOrderedData()
{
return array(
array(
array('2' => 'two', '1' => 'one', '3' => 'three'),
array('2' => 'two', '1' => 'one', '3' => 'three'),
),
);
}





public function testAddChildEmptyName()
{
$node = new ArrayNode('root');

$childNode = new ArrayNode('');
$node->addChild($childNode);
}





public function testAddChildNameAlreadyExists()
{
$node = new ArrayNode('root');

$childNode = new ArrayNode('foo');
$node->addChild($childNode);

$childNodeWithSameName = new ArrayNode('foo');
$node->addChild($childNodeWithSameName);
}





public function testGetDefaultValueWithoutDefaultValue()
{
$node = new ArrayNode('foo');
$node->getDefaultValue();
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\ScalarNode;

class ScalarNodeTest extends TestCase
{



public function testNormalize($value)
{
$node = new ScalarNode('test');
$this->assertSame($value, $node->normalize($value));
}

public function getValidValues()
{
return array(
array(false),
array(true),
array(null),
array(''),
array('foo'),
array(0),
array(1),
array(0.0),
array(0.1),
);
}





public function testNormalizeThrowsExceptionOnInvalidValues($value)
{
$node = new ScalarNode('test');
$node->normalize($value);
}

public function getInvalidValues()
{
return array(
array(array()),
array(array('foo' => 'bar')),
array(new \stdClass()),
);
}

public function testNormalizeThrowsExceptionWithoutHint()
{
$node = new ScalarNode('test');

if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException');
$this->expectExceptionMessage('Invalid type for path "test". Expected scalar, but got array.');
} else {
$this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', 'Invalid type for path "test". Expected scalar, but got array.');
}

$node->normalize(array());
}

public function testNormalizeThrowsExceptionWithErrorMessage()
{
$node = new ScalarNode('test');
$node->setInfo('"the test value"');

if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException');
$this->expectExceptionMessage("Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\"");
} else {
$this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', "Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\"");
}

$node->normalize(array());
}






public function testValidNonEmptyValues($value)
{
$node = new ScalarNode('test');
$node->setAllowEmptyValue(false);

$this->assertSame($value, $node->finalize($value));
}

public function getValidNonEmptyValues()
{
return array(
array(false),
array(true),
array('foo'),
array(0),
array(1),
array(0.0),
array(0.1),
);
}







public function testNotAllowedEmptyValuesThrowException($value)
{
$node = new ScalarNode('test');
$node->setAllowEmptyValue(false);
$node->finalize($value);
}

public function getEmptyValues()
{
return array(
array(null),
array(''),
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\NodeInterface;

class FinalizationTest extends TestCase
{
public function testUnsetKeyWithDeepHierarchy()
{
$tb = new TreeBuilder();
$tree = $tb
->root('config', 'array')
->children()
->node('level1', 'array')
->canBeUnset()
->children()
->node('level2', 'array')
->canBeUnset()
->children()
->node('somevalue', 'scalar')->end()
->node('anothervalue', 'scalar')->end()
->end()
->end()
->node('level1_scalar', 'scalar')->end()
->end()
->end()
->end()
->end()
->buildTree()
;

$a = array(
'level1' => array(
'level2' => array(
'somevalue' => 'foo',
'anothervalue' => 'bar',
),
'level1_scalar' => 'foo',
),
);

$b = array(
'level1' => array(
'level2' => false,
),
);

$this->assertEquals(array(
'level1' => array(
'level1_scalar' => 'foo',
),
), $this->process($tree, array($a, $b)));
}

protected function process(NodeInterface $tree, array $configs)
{
$processor = new Processor();

return $processor->process($tree, $configs);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;

class YamlReferenceDumperTest extends TestCase
{
public function testDumper()
{
$configuration = new ExampleConfiguration();

$dumper = new YamlReferenceDumper();

$this->assertContains($this->getConfigurationAsString(), $dumper->dump($configuration));
$this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays');
}

private function getConfigurationAsString()
{
return <<<'EOL'
acme_root:
    boolean:              true
    scalar_empty:         ~
    scalar_null:          null
    scalar_true:          true
    scalar_false:         false
    scalar_default:       default
    scalar_array_empty:   []
    scalar_array_defaults:

        # Defaults:
        - elem1
        - elem2
    scalar_required:      ~ # Required
    node_with_a_looong_name: ~
    enum_with_default:    this # One of "this"; "that"
    enum:                 ~ # One of "this"; "that"

    # some info
    array:
        child1:               ~
        child2:               ~

        # this is a long
        # multi-line info text
        # which should be indented
        child3:               ~ # Example: example setting
    parameters:

        # Prototype: Parameter name
        name:                 ~
EOL;
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper;
use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;

class XmlReferenceDumperTest extends TestCase
{
public function testDumper()
{
$configuration = new ExampleConfiguration();

$dumper = new XmlReferenceDumper();
$this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
}

public function testNamespaceDumper()
{
$configuration = new ExampleConfiguration();

$dumper = new XmlReferenceDumper();
$this->assertEquals(str_replace('http://example.org/schema/dic/acme_root', 'http://symfony.com/schema/dic/symfony', $this->getConfigurationAsString()), $dumper->dump($configuration, 'http://symfony.com/schema/dic/symfony'));
}

private function getConfigurationAsString()
{
return str_replace("\n", PHP_EOL, <<<'EOL'
<!-- Namespace: http://example.org/schema/dic/acme_root -->
<!-- scalar-required: Required -->
<!-- enum-with-default: One of "this"; "that" -->
<!-- enum: One of "this"; "that" -->
<config
    boolean="true"
    scalar-empty=""
    scalar-null="null"
    scalar-true="true"
    scalar-false="false"
    scalar-default="default"
    scalar-array-empty=""
    scalar-array-defaults="elem1,elem2"
    scalar-required=""
    node-with-a-looong-name=""
    enum-with-default="this"
    enum=""
>

    <!-- some info -->
    <!--
        child3: this is a long
                multi-line info text
                which should be indented;
                Example: example setting
    -->
    <array
        child1=""
        child2=""
        child3=""
    />

    <!-- prototype: Parameter name -->
    <parameter name="parameter name">scalar value</parameter>

    <!-- prototype -->
    <connection
        user=""
        pass=""
    />

</config>

EOL
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\FloatNode;

class FloatNodeTest extends TestCase
{



public function testNormalize($value)
{
$node = new FloatNode('test');
$this->assertSame($value, $node->normalize($value));
}






public function testValidNonEmptyValues($value)
{
$node = new FloatNode('test');
$node->setAllowEmptyValue(false);

$this->assertSame($value, $node->finalize($value));
}

public function getValidValues()
{
return array(
array(1798.0),
array(-678.987),
array(12.56E45),
array(0.0),

 array(17),
array(-10),
array(0),
);
}





public function testNormalizeThrowsExceptionOnInvalidValues($value)
{
$node = new FloatNode('test');
$node->normalize($value);
}

public function getInvalidValues()
{
return array(
array(null),
array(''),
array('foo'),
array(true),
array(false),
array(array()),
array(array('foo' => 'bar')),
array(new \stdClass()),
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

class NormalizationTest extends TestCase
{



public function testNormalizeEncoders($denormalized)
{
$tb = new TreeBuilder();
$tree = $tb
->root('root_name', 'array')
->fixXmlConfig('encoder')
->children()
->node('encoders', 'array')
->useAttributeAsKey('class')
->prototype('array')
->beforeNormalization()->ifString()->then(function ($v) { return array('algorithm' => $v); })->end()
->children()
->node('algorithm', 'scalar')->end()
->end()
->end()
->end()
->end()
->end()
->buildTree()
;

$normalized = array(
'encoders' => array(
'foo' => array('algorithm' => 'plaintext'),
),
);

$this->assertNormalized($tree, $denormalized, $normalized);
}

public function getEncoderTests()
{
$configs = array();


 $configs[] = array(
'encoder' => array(
array('class' => 'foo', 'algorithm' => 'plaintext'),
),
);


 $configs[] = array(
'encoder' => array('class' => 'foo', 'algorithm' => 'plaintext'),
);


 $configs[] = array(
'encoders' => array(
array('class' => 'foo', 'algorithm' => 'plaintext'),
),
);


 $configs[] = array(
'encoders' => array(
'foo' => 'plaintext',
),
);


 $configs[] = array(
'encoders' => array(
'foo' => array('algorithm' => 'plaintext'),
),
);

return array_map(function ($v) {
return array($v);
}, $configs);
}




public function testAnonymousKeysArray($denormalized)
{
$tb = new TreeBuilder();
$tree = $tb
->root('root', 'array')
->children()
->node('logout', 'array')
->fixXmlConfig('handler')
->children()
->node('handlers', 'array')
->prototype('scalar')->end()
->end()
->end()
->end()
->end()
->end()
->buildTree()
;

$normalized = array('logout' => array('handlers' => array('a', 'b', 'c')));

$this->assertNormalized($tree, $denormalized, $normalized);
}

public function getAnonymousKeysTests()
{
$configs = array();

$configs[] = array(
'logout' => array(
'handlers' => array('a', 'b', 'c'),
),
);

$configs[] = array(
'logout' => array(
'handler' => array('a', 'b', 'c'),
),
);

return array_map(function ($v) { return array($v); }, $configs);
}




public function testNumericKeysAsAttributes($denormalized)
{
$normalized = array(
'thing' => array(42 => array('foo', 'bar'), 1337 => array('baz', 'qux')),
);

$this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized);
}

public function getNumericKeysTests()
{
$configs = array();

$configs[] = array(
'thing' => array(
42 => array('foo', 'bar'), 1337 => array('baz', 'qux'),
),
);

$configs[] = array(
'thing' => array(
array('foo', 'bar', 'id' => 42), array('baz', 'qux', 'id' => 1337),
),
);

return array_map(function ($v) { return array($v); }, $configs);
}





public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet()
{
$denormalized = array(
'thing' => array(
array('foo', 'bar'), array('baz', 'qux'),
),
);

$this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, array());
}

public function testAssociativeArrayPreserveKeys()
{
$tb = new TreeBuilder();
$tree = $tb
->root('root', 'array')
->prototype('array')
->children()
->node('foo', 'scalar')->end()
->end()
->end()
->end()
->buildTree()
;

$data = array('first' => array('foo' => 'bar'));

$this->assertNormalized($tree, $data, $data);
}

public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
{
self::assertSame($normalized, $tree->normalize($denormalized));
}

private function getNumericKeysTestTree()
{
$tb = new TreeBuilder();
$tree = $tb
->root('root', 'array')
->children()
->node('thing', 'array')
->useAttributeAsKey('id')
->prototype('array')
->prototype('scalar')->end()
->end()
->end()
->end()
->end()
->buildTree()
;

return $tree;
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\IntegerNode;

class IntegerNodeTest extends TestCase
{



public function testNormalize($value)
{
$node = new IntegerNode('test');
$this->assertSame($value, $node->normalize($value));
}






public function testValidNonEmptyValues($value)
{
$node = new IntegerNode('test');
$node->setAllowEmptyValue(false);

$this->assertSame($value, $node->finalize($value));
}

public function getValidValues()
{
return array(
array(1798),
array(-678),
array(0),
);
}





public function testNormalizeThrowsExceptionOnInvalidValues($value)
{
$node = new IntegerNode('test');
$node->normalize($value);
}

public function getInvalidValues()
{
return array(
array(null),
array(''),
array('foo'),
array(true),
array(false),
array(0.0),
array(0.1),
array(array()),
array(array('foo' => 'bar')),
array(new \stdClass()),
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Config\Definition\VariableNode;

class PrototypedArrayNodeTest extends TestCase
{
public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
{
$node = new PrototypedArrayNode('root');
$prototype = new ArrayNode(null, $node);
$node->setPrototype($prototype);
$this->assertEmpty($node->getDefaultValue());
}

public function testGetDefaultValueReturnsDefaultValueForPrototypes()
{
$node = new PrototypedArrayNode('root');
$prototype = new ArrayNode(null, $node);
$node->setPrototype($prototype);
$node->setDefaultValue(array('test'));
$this->assertEquals(array('test'), $node->getDefaultValue());
}


 public function testRemappedKeysAreUnset()
{
$node = new ArrayNode('root');
$mappingsNode = new PrototypedArrayNode('mappings');
$node->addChild($mappingsNode);


 $prototype = new ScalarNode(null, $mappingsNode);
$mappingsNode->setPrototype($prototype);

$remappings = array();
$remappings[] = array('mapping', 'mappings');
$node->setXmlRemappings($remappings);

$normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
$this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
}



















public function testMappedAttributeKeyIsRemoved()
{
$node = new PrototypedArrayNode('root');
$node->setKeyAttribute('id', true);


 $prototype = new ArrayNode(null, $node);
$prototype->addChild(new ScalarNode('foo'));
$node->setPrototype($prototype);

$children = array();
$children[] = array('id' => 'item_name', 'foo' => 'bar');
$normalized = $node->normalize($children);

$expected = array();
$expected['item_name'] = array('foo' => 'bar');
$this->assertEquals($expected, $normalized);
}





public function testMappedAttributeKeyNotRemoved()
{
$node = new PrototypedArrayNode('root');
$node->setKeyAttribute('id', false);


 $prototype = new ArrayNode(null, $node);
$prototype->addChild(new ScalarNode('foo'));
$prototype->addChild(new ScalarNode('id')); 
 $node->setPrototype($prototype);

$children = array();
$children[] = array('id' => 'item_name', 'foo' => 'bar');
$normalized = $node->normalize($children);

$expected = array();
$expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar');
$this->assertEquals($expected, $normalized);
}

public function testAddDefaultChildren()
{
$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setAddChildrenIfNoneSet();
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());

$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setKeyAttribute('foobar');
$node->setAddChildrenIfNoneSet();
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue());

$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setKeyAttribute('foobar');
$node->setAddChildrenIfNoneSet('defaultkey');
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());

$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setKeyAttribute('foobar');
$node->setAddChildrenIfNoneSet(array('defaultkey'));
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());

$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setKeyAttribute('foobar');
$node->setAddChildrenIfNoneSet(array('dk1', 'dk2'));
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue());

$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setAddChildrenIfNoneSet(array(5, 6));
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue());

$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setAddChildrenIfNoneSet(2);
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue());
}

public function testDefaultChildrenWinsOverDefaultValue()
{
$node = $this->getPrototypeNodeWithDefaultChildren();
$node->setAddChildrenIfNoneSet();
$node->setDefaultValue(array('bar' => 'foo'));
$this->assertTrue($node->hasDefaultValue());
$this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
}

protected function getPrototypeNodeWithDefaultChildren()
{
$node = new PrototypedArrayNode('root');
$prototype = new ArrayNode(null, $node);
$child = new ScalarNode('foo');
$child->setDefaultValue('bar');
$prototype->addChild($child);
$prototype->setAddIfNotSet(true);
$node->setPrototype($prototype);

return $node;
}






















































































public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected)
{
$node = new PrototypedArrayNode('root');
$node->setKeyAttribute('id', true);


 $prototype = new ArrayNode(null, $node);
$prototype->addChild(new ScalarNode('id'));
$prototype->addChild(new ScalarNode('foo'));
$prototype->addChild($value);
$node->setPrototype($prototype);

$normalized = $node->normalize($children);
$this->assertEquals($expected, $normalized);
}

public function getDataForKeyRemovedLeftValueOnly()
{
$scalarValue = new ScalarNode('value');

$arrayValue = new ArrayNode('value');
$arrayValue->addChild(new ScalarNode('foo'));
$arrayValue->addChild(new ScalarNode('bar'));

$variableValue = new VariableNode('value');

return array(
array(
$scalarValue,
array(
array('id' => 'option1', 'value' => 'value1'),
),
array('option1' => 'value1'),
),

array(
$scalarValue,
array(
array('id' => 'option1', 'value' => 'value1'),
array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2'),
),
array(
'option1' => 'value1',
'option2' => array('value' => 'value2', 'foo' => 'foo2'),
),
),

array(
$arrayValue,
array(
array(
'id' => 'option1',
'value' => array('foo' => 'foo1', 'bar' => 'bar1'),
),
),
array(
'option1' => array('foo' => 'foo1', 'bar' => 'bar1'),
),
),

array($variableValue,
array(
array(
'id' => 'option1', 'value' => array('foo' => 'foo1', 'bar' => 'bar1'),
),
array('id' => 'option2', 'value' => 'value2'),
),
array(
'option1' => array('foo' => 'foo1', 'bar' => 'bar1'),
'option2' => 'value2',
),
),
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\EnumNode;

class EnumNodeTest extends TestCase
{
public function testFinalizeValue()
{
$node = new EnumNode('foo', null, array('foo', 'bar'));
$this->assertSame('foo', $node->finalize('foo'));
}





public function testConstructionWithNoValues()
{
new EnumNode('foo', null, array());
}

public function testConstructionWithOneValue()
{
$node = new EnumNode('foo', null, array('foo'));
$this->assertSame('foo', $node->finalize('foo'));
}

public function testConstructionWithOneDistinctValue()
{
$node = new EnumNode('foo', null, array('foo', 'foo'));
$this->assertSame('foo', $node->finalize('foo'));
}





public function testFinalizeWithInvalidValue()
{
$node = new EnumNode('foo', null, array('foo', 'bar'));
$node->finalize('foobar');
}
}
<?php










namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\FileResource;

class FileResourceTest extends TestCase
{
protected $resource;
protected $file;
protected $time;

protected function setUp()
{
$this->file = realpath(sys_get_temp_dir()).'/tmp.xml';
$this->time = time();
touch($this->file, $this->time);
$this->resource = new FileResource($this->file);
}

protected function tearDown()
{
unlink($this->file);
}

public function testGetResource()
{
$this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource');
}

public function testToString()
{
$this->assertSame(realpath($this->file), (string) $this->resource);
}

public function testIsFresh()
{
$this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second');
$this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
$this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');

$resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999));
$this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
}

public function testSerializeUnserialize()
{
$unserialized = unserialize(serialize($this->resource));

$this->assertSame(realpath($this->file), $this->resource->getResource());
}
}
<?php










namespace Symfony\Component\Config\Tests\Resource;

use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;

class ResourceStub implements SelfCheckingResourceInterface
{
private $fresh = true;

public function setFresh($isFresh)
{
$this->fresh = $isFresh;
}

public function __toString()
{
return 'stub';
}

public function isFresh($timestamp)
{
return $this->fresh;
}

public function getResource()
{
return 'stub';
}
}
<?php










namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\DirectoryResource;

class DirectoryResourceTest extends TestCase
{
protected $directory;

protected function setUp()
{
$this->directory = sys_get_temp_dir().DIRECTORY_SEPARATOR.'symfonyDirectoryIterator';
if (!file_exists($this->directory)) {
mkdir($this->directory);
}
touch($this->directory.'/tmp.xml');
}

protected function tearDown()
{
if (!is_dir($this->directory)) {
return;
}
$this->removeDirectory($this->directory);
}

protected function removeDirectory($directory)
{
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $path) {
if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
continue;
}
if ($path->isDir()) {
rmdir($path->__toString());
} else {
unlink($path->__toString());
}
}
rmdir($directory);
}

public function testGetResource()
{
$resource = new DirectoryResource($this->directory);
$this->assertSame($this->directory, $resource->getResource(), '->getResource() returns the path to the resource');
}

public function testGetPattern()
{
$resource = new DirectoryResource('foo', 'bar');
$this->assertEquals('bar', $resource->getPattern());
}

public function testIsFresh()
{
$resource = new DirectoryResource($this->directory);
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
$this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');

$resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999));
$this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
}

public function testIsFreshUpdateFile()
{
$resource = new DirectoryResource($this->directory);
touch($this->directory.'/tmp.xml', time() + 20);
$this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified');
}

public function testIsFreshNewFile()
{
$resource = new DirectoryResource($this->directory);
touch($this->directory.'/new.xml', time() + 20);
$this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added');
}

public function testIsFreshNewFileWithDifferentPattern()
{
$resource = new DirectoryResource($this->directory, '/.xml$/');
touch($this->directory.'/new.yaml', time() + 20);
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file with a non-matching pattern is added');
}

public function testIsFreshDeleteFile()
{
$resource = new DirectoryResource($this->directory);
$time = time();
sleep(1);
unlink($this->directory.'/tmp.xml');
$this->assertFalse($resource->isFresh($time), '->isFresh() returns false if an existing file is removed');
}

public function testIsFreshDeleteDirectory()
{
$resource = new DirectoryResource($this->directory);
$this->removeDirectory($this->directory);
$this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed');
}

public function testIsFreshCreateFileInSubdirectory()
{
$subdirectory = $this->directory.'/subdirectory';
mkdir($subdirectory);

$resource = new DirectoryResource($this->directory);
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists');

touch($subdirectory.'/newfile.xml', time() + 20);
$this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added');
}

public function testIsFreshModifySubdirectory()
{
$resource = new DirectoryResource($this->directory);

$subdirectory = $this->directory.'/subdirectory';
mkdir($subdirectory);
touch($subdirectory, time() + 20);

$this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)');
}

public function testFilterRegexListNoMatch()
{
$resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');

touch($this->directory.'/new.bar', time() + 20);
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created');
}

public function testFilterRegexListMatch()
{
$resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');

touch($this->directory.'/new.xml', time() + 20);
$this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created ');
}

public function testSerializeUnserialize()
{
$resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');

$unserialized = unserialize(serialize($resource));

$this->assertSame($this->directory, $resource->getResource());
$this->assertSame('/\.(foo|xml)$/', $resource->getPattern());
}

public function testResourcesWithDifferentPatternsAreDifferent()
{
$resourceA = new DirectoryResource($this->directory, '/.xml$/');
$resourceB = new DirectoryResource($this->directory, '/.yaml$/');

$this->assertEquals(2, count(array_unique(array($resourceA, $resourceB))));
}
}
<?php










namespace Symfony\Component\Config\Tests\Resource;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\FileExistenceResource;

class FileExistenceResourceTest extends TestCase
{
protected $resource;
protected $file;
protected $time;

protected function setUp()
{
$this->file = realpath(sys_get_temp_dir()).'/tmp.xml';
$this->time = time();
$this->resource = new FileExistenceResource($this->file);
}

protected function tearDown()
{
if (file_exists($this->file)) {
unlink($this->file);
}
}

public function testToString()
{
$this->assertSame($this->file, (string) $this->resource);
}

public function testGetResource()
{
$this->assertSame($this->file, $this->resource->getResource(), '->getResource() returns the path to the resource');
}

public function testIsFreshWithExistingResource()
{
touch($this->file, $this->time);
$serialized = serialize(new FileExistenceResource($this->file));

$resource = unserialize($serialized);
$this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still present');

unlink($this->file);
$resource = unserialize($serialized);
$this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been deleted');
}

public function testIsFreshWithAbsentResource()
{
$serialized = serialize(new FileExistenceResource($this->file));

$resource = unserialize($serialized);
$this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still absent');

touch($this->file, $this->time);
$resource = unserialize($serialized);
$this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been created');
}
}
<?php










namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\ConfigCacheFactory;

class ConfigCacheFactoryTest extends TestCase
{




public function testCachWithInvalidCallback()
{
$cacheFactory = new ConfigCacheFactory(true);

$cacheFactory->cache('file', new \stdClass());
}
}
<?php










namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\Loader;

class LoaderTest extends TestCase
{
public function testGetSetResolver()
{
$resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();

$loader = new ProjectLoader1();
$loader->setResolver($resolver);

$this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
}

public function testResolve()
{
$resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();

$resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
$resolver->expects($this->once())
->method('resolve')
->with('foo.xml')
->will($this->returnValue($resolvedLoader));

$loader = new ProjectLoader1();
$loader->setResolver($resolver);

$this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader');
$this->assertSame($resolvedLoader, $loader->resolve('foo.xml'), '->resolve() finds a loader');
}




public function testResolveWhenResolverCannotFindLoader()
{
$resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
$resolver->expects($this->once())
->method('resolve')
->with('FOOBAR')
->will($this->returnValue(false));

$loader = new ProjectLoader1();
$loader->setResolver($resolver);

$loader->resolve('FOOBAR');
}

public function testImport()
{
$resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$resolvedLoader->expects($this->once())
->method('load')
->with('foo')
->will($this->returnValue('yes'));

$resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
$resolver->expects($this->once())
->method('resolve')
->with('foo')
->will($this->returnValue($resolvedLoader));

$loader = new ProjectLoader1();
$loader->setResolver($resolver);

$this->assertEquals('yes', $loader->import('foo'));
}

public function testImportWithType()
{
$resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$resolvedLoader->expects($this->once())
->method('load')
->with('foo', 'bar')
->will($this->returnValue('yes'));

$resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock();
$resolver->expects($this->once())
->method('resolve')
->with('foo', 'bar')
->will($this->returnValue($resolvedLoader));

$loader = new ProjectLoader1();
$loader->setResolver($resolver);

$this->assertEquals('yes', $loader->import('foo', 'bar'));
}
}

class ProjectLoader1 extends Loader
{
public function load($resource, $type = null)
{
}

public function supports($resource, $type = null)
{
return is_string($resource) && 'foo' === pathinfo($resource, PATHINFO_EXTENSION);
}

public function getType()
{
}
}
<?php










namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\Loader\DelegatingLoader;

class DelegatingLoaderTest extends TestCase
{
public function testConstructor()
{
$loader = new DelegatingLoader($resolver = new LoaderResolver());
$this->assertTrue(true, '__construct() takes a loader resolver as its first argument');
}

public function testGetSetResolver()
{
$resolver = new LoaderResolver();
$loader = new DelegatingLoader($resolver);
$this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader');
$loader->setResolver($resolver = new LoaderResolver());
$this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
}

public function testSupports()
{
$loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$loader1->expects($this->once())->method('supports')->will($this->returnValue(true));
$loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
$this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');

$loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$loader1->expects($this->once())->method('supports')->will($this->returnValue(false));
$loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable');
}

public function testLoad()
{
$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$loader->expects($this->once())->method('supports')->will($this->returnValue(true));
$loader->expects($this->once())->method('load');
$resolver = new LoaderResolver(array($loader));
$loader = new DelegatingLoader($resolver);

$loader->load('foo');
}




public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded()
{
$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$loader->expects($this->once())->method('supports')->will($this->returnValue(false));
$resolver = new LoaderResolver(array($loader));
$loader = new DelegatingLoader($resolver);

$loader->load('foo');
}
}
<?php










namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\LoaderResolver;

class LoaderResolverTest extends TestCase
{
public function testConstructor()
{
$resolver = new LoaderResolver(array(
$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(),
));

$this->assertEquals(array($loader), $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument');
}

public function testResolve()
{
$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$resolver = new LoaderResolver(array($loader));
$this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource');

$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
$loader->expects($this->once())->method('supports')->will($this->returnValue(true));
$resolver = new LoaderResolver(array($loader));
$this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource');
}

public function testLoaders()
{
$resolver = new LoaderResolver();
$resolver->addLoader($loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock());

$this->assertEquals(array($loader), $resolver->getLoaders(), 'addLoader() adds a loader');
}
}
<?php










namespace Symfony\Component\Config\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;

class FileLoaderTest extends TestCase
{
public function testImportWithFileLocatorDelegation()
{
$locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();

$locatorMockForAdditionalLoader = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
$locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls(
array('path/to/file1'), 
 array('path/to/file1', 'path/to/file2'), 
 array('path/to/file1', 'path/to/file2'), 
 array('path/to/file1'), 
 array('path/to/file1', 'path/to/file2') 
 ));

$fileLoader = new TestFileLoader($locatorMock);
$fileLoader->setSupports(false);
$fileLoader->setCurrentDir('.');

$additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader);
$additionalLoader->setCurrentDir('.');

$fileLoader->setResolver($loaderResolver = new LoaderResolver(array($fileLoader, $additionalLoader)));


 $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));


 $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));


 $fileLoader->addLoading('path/to/file1');
$this->assertSame('path/to/file2', $fileLoader->import('my_resource'));


 try {
$fileLoader->import('my_resource');
$this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
}


 try {
$fileLoader->addLoading('path/to/file2');
$fileLoader->import('my_resource');
$this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
}
}
}

class TestFileLoader extends FileLoader
{
private $supports = true;

public function load($resource, $type = null)
{
return $resource;
}

public function supports($resource, $type = null)
{
return $this->supports;
}

public function addLoading($resource)
{
self::$loading[$resource] = true;
}

public function removeLoading($resource)
{
unset(self::$loading[$resource]);
}

public function clearLoading()
{
self::$loading = array();
}

public function setSupports($supports)
{
$this->supports = $supports;
}
}
<?php










namespace Symfony\Component\Config\Tests\Util;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Util\XmlUtils;

class XmlUtilsTest extends TestCase
{
public function testLoadFile()
{
$fixtures = __DIR__.'/../Fixtures/Util/';

try {
XmlUtils::loadFile($fixtures.'invalid.xml');
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertContains('ERROR 77', $e->getMessage());
}

try {
XmlUtils::loadFile($fixtures.'document_type.xml');
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertContains('Document types are not allowed', $e->getMessage());
}

try {
XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd');
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertContains('ERROR 1845', $e->getMessage());
}

try {
XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file');
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertContains('XSD file or callable', $e->getMessage());
}

$mock = $this->getMockBuilder(__NAMESPACE__.'\Validator')->getMock();
$mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true));

try {
XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertContains('is not valid', $e->getMessage());
}

$this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
$this->assertSame(array(), libxml_get_errors());
}

public function testLoadFileWithInternalErrorsEnabled()
{
$internalErrors = libxml_use_internal_errors(true);

$this->assertSame(array(), libxml_get_errors());
$this->assertInstanceOf('DOMDocument', XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/invalid_schema.xml'));
$this->assertSame(array(), libxml_get_errors());

libxml_clear_errors();
libxml_use_internal_errors($internalErrors);
}




public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true)
{
$dom = new \DOMDocument();
$dom->loadXML($root ? $xml : '<root>'.$xml.'</root>');

$this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix));
}

public function getDataForConvertDomToArray()
{
return array(
array(null, ''),
array('bar', 'bar'),
array(array('bar' => 'foobar'), '<foo bar="foobar" />', true),
array(array('foo' => null), '<foo />'),
array(array('foo' => 'bar'), '<foo>bar</foo>'),
array(array('foo' => array('foo' => 'bar')), '<foo foo="bar"/>'),
array(array('foo' => array('foo' => 0)), '<foo><foo>0</foo></foo>'),
array(array('foo' => array('foo' => 'bar')), '<foo><foo>bar</foo></foo>'),
array(array('foo' => array('foo' => 'bar', 'value' => 'text')), '<foo foo="bar">text</foo>'),
array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), '<foo attr="bar"><foo>text</foo></foo>'),
array(array('foo' => array('bar', 'text')), '<foo>bar</foo><foo>text</foo>'),
array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), '<foo foo="bar"/><foo foo="text" />'),
array(array('foo' => array('foo' => array('bar', 'text'))), '<foo foo="bar"><foo>text</foo></foo>'),
array(array('foo' => 'bar'), '<foo><!-- Comment -->bar</foo>'),
array(array('foo' => 'text'), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>'),
array(array('foo' => array('bar' => 'bar', 'value' => 'text')), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>', false, false),
array(array('attr' => 1, 'b' => 'hello'), '<foo:a xmlns:foo="http://www.example.org/foo" xmlns:h="http://www.example.org/bar" attr="1" h:bar="bar"><foo:b>hello</foo:b><h:c>2</h:c></foo:a>', true),
);
}




public function testPhpize($expected, $value)
{
$this->assertSame($expected, XmlUtils::phpize($value));
}

public function getDataForPhpize()
{
return array(
array('', ''),
array(null, 'null'),
array(true, 'true'),
array(false, 'false'),
array(null, 'Null'),
array(true, 'True'),
array(false, 'False'),
array(0, '0'),
array(1, '1'),
array(-1, '-1'),
array(0777, '0777'),
array(255, '0xFF'),
array(100.0, '1e2'),
array(-120.0, '-1.2E2'),
array(-10100.1, '-10100.1'),
array('-10,100.1', '-10,100.1'),
array('1234 5678 9101 1121 3141', '1234 5678 9101 1121 3141'),
array('1,2,3,4', '1,2,3,4'),
array('11,22,33,44', '11,22,33,44'),
array('11,222,333,4', '11,222,333,4'),
array('1,222,333,444', '1,222,333,444'),
array('11,222,333,444', '11,222,333,444'),
array('111,222,333,444', '111,222,333,444'),
array('1111,2222,3333,4444,5555', '1111,2222,3333,4444,5555'),
array('foo', 'foo'),
array(6, '0b0110'),
);
}

public function testLoadEmptyXmlFile()
{
$file = __DIR__.'/../Fixtures/foo.xml';

if (method_exists($this, 'expectException')) {
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage(sprintf('File %s does not contain valid XML, it is empty.', $file));
} else {
$this->setExpectedException('InvalidArgumentException', sprintf('File %s does not contain valid XML, it is empty.', $file));
}

XmlUtils::loadFile($file);
}


 public function testLoadWrongEmptyXMLWithErrorHandler()
{
$originalDisableEntities = libxml_disable_entity_loader(false);
$errorReporting = error_reporting(-1);

set_error_handler(function ($errno, $errstr) {
throw new \Exception($errstr, $errno);
});

$file = __DIR__.'/../Fixtures/foo.xml';
try {
try {
XmlUtils::loadFile($file);
$this->fail('An exception should have been raised');
} catch (\InvalidArgumentException $e) {
$this->assertEquals(sprintf('File %s does not contain valid XML, it is empty.', $file), $e->getMessage());
}
} catch (\Exception $e) {
restore_error_handler();
error_reporting($errorReporting);

throw $e;
}

restore_error_handler();
error_reporting($errorReporting);

$disableEntities = libxml_disable_entity_loader(true);
libxml_disable_entity_loader($disableEntities);

libxml_disable_entity_loader($originalDisableEntities);

$this->assertFalse($disableEntities);


 XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/valid.xml', __DIR__.'/../Fixtures/Util/schema.xsd');
}
}

interface Validator
{
public function validate();
}
<?php










namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\Tests\Resource\ResourceStub;

class ConfigCacheTest extends TestCase
{
private $cacheFile = null;

protected function setUp()
{
$this->cacheFile = tempnam(sys_get_temp_dir(), 'config_');
}

protected function tearDown()
{
$files = array($this->cacheFile, $this->cacheFile.'.meta');

foreach ($files as $file) {
if (file_exists($file)) {
unlink($file);
}
}
}




public function testCacheIsNotValidIfNothingHasBeenCached($debug)
{
unlink($this->cacheFile); 
 $cache = new ConfigCache($this->cacheFile, $debug);

$this->assertFalse($cache->isFresh());
}

public function testIsAlwaysFreshInProduction()
{
$staleResource = new ResourceStub();
$staleResource->setFresh(false);

$cache = new ConfigCache($this->cacheFile, false);
$cache->write('', array($staleResource));

$this->assertTrue($cache->isFresh());
}




public function testIsFreshWhenNoResourceProvided($debug)
{
$cache = new ConfigCache($this->cacheFile, $debug);
$cache->write('', array());
$this->assertTrue($cache->isFresh());
}

public function testFreshResourceInDebug()
{
$freshResource = new ResourceStub();
$freshResource->setFresh(true);

$cache = new ConfigCache($this->cacheFile, true);
$cache->write('', array($freshResource));

$this->assertTrue($cache->isFresh());
}

public function testStaleResourceInDebug()
{
$staleResource = new ResourceStub();
$staleResource->setFresh(false);

$cache = new ConfigCache($this->cacheFile, true);
$cache->write('', array($staleResource));

$this->assertFalse($cache->isFresh());
}

public function debugModes()
{
return array(
array(true),
array(false),
);
}
}
<?php










namespace Symfony\Component\Config\Tests\Fixtures\Configuration;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class ExampleConfiguration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_root');

$rootNode
->fixXmlConfig('parameter')
->fixXmlConfig('connection')
->children()
->booleanNode('boolean')->defaultTrue()->end()
->scalarNode('scalar_empty')->end()
->scalarNode('scalar_null')->defaultNull()->end()
->scalarNode('scalar_true')->defaultTrue()->end()
->scalarNode('scalar_false')->defaultFalse()->end()
->scalarNode('scalar_default')->defaultValue('default')->end()
->scalarNode('scalar_array_empty')->defaultValue(array())->end()
->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end()
->scalarNode('scalar_required')->isRequired()->end()
->scalarNode('node_with_a_looong_name')->end()
->enumNode('enum_with_default')->values(array('this', 'that'))->defaultValue('this')->end()
->enumNode('enum')->values(array('this', 'that'))->end()
->arrayNode('array')
->info('some info')
->canBeUnset()
->children()
->scalarNode('child1')->end()
->scalarNode('child2')->end()
->scalarNode('child3')
->info(
"this is a long\n".
"multi-line info text\n".
'which should be indented'
)
->example('example setting')
->end()
->end()
->end()
->arrayNode('parameters')
->useAttributeAsKey('name')
->prototype('scalar')->info('Parameter name')->end()
->end()
->arrayNode('connections')
->prototype('array')
->children()
->scalarNode('user')->end()
->scalarNode('pass')->end()
->end()
->end()
->end()
->end()
;

return $treeBuilder;
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use Symfony\Component\Config\Definition\Builder\NodeDefinition;

class BarNodeDefinition extends NodeDefinition
{
protected function createNode()
{
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;

class NodeBuilder extends BaseNodeBuilder
{
public function barNode($name)
{
return $this->node($name, 'bar');
}

protected function getNodeClass($type)
{
switch ($type) {
case 'variable':
return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
case 'bar':
return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
default:
return parent::getNodeClass($type);
}
}
}
<?php










namespace Symfony\Component\Config\Tests\Definition\Builder;

use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;

class VariableNodeDefinition extends BaseVariableNodeDefinition
{
}
<?php










namespace Symfony\Component\Config\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;

class FileLocatorTest extends TestCase
{



public function testIsAbsolutePath($path)
{
$loader = new FileLocator(array());
$r = new \ReflectionObject($loader);
$m = $r->getMethod('isAbsolutePath');
$m->setAccessible(true);

$this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path');
}

public function getIsAbsolutePathTests()
{
return array(
array('/foo.xml'),
array('c:\\\\foo.xml'),
array('c:/foo.xml'),
array('\\server\\foo.xml'),
array('https://server/foo.xml'),
array('phar://server/foo.xml'),
);
}

public function testLocate()
{
$loader = new FileLocator(__DIR__.'/Fixtures');

$this->assertEquals(
__DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php',
$loader->locate('FileLocatorTest.php', __DIR__),
'->locate() returns the absolute filename if the file exists in the given path'
);

$this->assertEquals(
__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
$loader->locate('foo.xml', __DIR__),
'->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
);

$this->assertEquals(
__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
$loader->locate(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__),
'->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
);

$loader = new FileLocator(array(__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again'));

$this->assertEquals(
array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
$loader->locate('foo.xml', __DIR__, false),
'->locate() returns an array of absolute filenames'
);

$this->assertEquals(
array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
$loader->locate('foo.xml', __DIR__.'/Fixtures', false),
'->locate() returns an array of absolute filenames'
);

$loader = new FileLocator(__DIR__.'/Fixtures/Again');

$this->assertEquals(
array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
$loader->locate('foo.xml', __DIR__.'/Fixtures', false),
'->locate() returns an array of absolute filenames'
);
}





public function testLocateThrowsAnExceptionIfTheFileDoesNotExists()
{
$loader = new FileLocator(array(__DIR__.'/Fixtures'));

$loader->locate('foobar.xml', __DIR__);
}




public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath()
{
$loader = new FileLocator(array(__DIR__.'/Fixtures'));

$loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__);
}





public function testLocateEmpty()
{
$loader = new FileLocator(array(__DIR__.'/Fixtures'));

$loader->locate(null, __DIR__);
}
}
<?php










namespace Symfony\Component\Config\Tests\Exception;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Exception\FileLoaderLoadException;

class FileLoaderLoadExceptionTest extends TestCase
{
public function testMessageCannotLoadResource()
{
$exception = new FileLoaderLoadException('resource', null);
$this->assertEquals('Cannot load resource "resource".', $exception->getMessage());
}

public function testMessageCannotImportResourceFromSource()
{
$exception = new FileLoaderLoadException('resource', 'sourceResource');
$this->assertEquals('Cannot import resource "resource" from "sourceResource".', $exception->getMessage());
}

public function testMessageCannotImportBundleResource()
{
$exception = new FileLoaderLoadException('@resource', 'sourceResource');
$this->assertEquals(
'Cannot import resource "@resource" from "sourceResource". '.
'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '.
'If the bundle is registered, make sure the bundle path "@resource" is not empty.',
$exception->getMessage()
);
}

public function testMessageHasPreviousErrorWithDotAndUnableToLoad()
{
$exception = new FileLoaderLoadException(
'resource',
null,
null,
new \Exception('There was a previous error with an ending dot.')
);
$this->assertEquals(
'There was a previous error with an ending dot in resource (which is loaded in resource "resource").',
$exception->getMessage()
);
}

public function testMessageHasPreviousErrorWithoutDotAndUnableToLoad()
{
$exception = new FileLoaderLoadException(
'resource',
null,
null,
new \Exception('There was a previous error with no ending dot')
);
$this->assertEquals(
'There was a previous error with no ending dot in resource (which is loaded in resource "resource").',
$exception->getMessage()
);
}

public function testMessageHasPreviousErrorAndUnableToLoadBundle()
{
$exception = new FileLoaderLoadException(
'@resource',
null,
null,
new \Exception('There was a previous error with an ending dot.')
);
$this->assertEquals(
'There was a previous error with an ending dot in @resource '.
'(which is loaded in resource "@resource"). '.
'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '.
'If the bundle is registered, make sure the bundle path "@resource" is not empty.',
$exception->getMessage()
);
}
}
<?php










namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\BCResourceInterfaceChecker;
use Symfony\Component\Config\Resource\SelfCheckingResourceChecker;
















class ConfigCache extends ResourceCheckerConfigCache
{
private $debug;





public function __construct($file, $debug)
{
parent::__construct($file, array(
new SelfCheckingResourceChecker(),
new BCResourceInterfaceChecker(),
));
$this->debug = (bool) $debug;
}








public function __toString()
{
@trigger_error('ConfigCache::__toString() is deprecated since version 2.7 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED);

return $this->getPath();
}









public function isFresh()
{
if (!$this->debug && is_file($this->getPath())) {
return true;
}

return parent::isFresh();
}
}
<?php










namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;







class ResourceCheckerConfigCache implements ConfigCacheInterface
{



private $file;




private $resourceCheckers;





public function __construct($file, array $resourceCheckers = array())
{
$this->file = $file;
$this->resourceCheckers = $resourceCheckers;
}




public function getPath()
{
return $this->file;
}












public function isFresh()
{
if (!is_file($this->file)) {
return false;
}

if (!$this->resourceCheckers) {
return true; 
 }

$metadata = $this->getMetaFile();
if (!is_file($metadata)) {
return false;
}

$e = null;
$meta = false;
$time = filemtime($this->file);
$signalingException = new \UnexpectedValueException();
$prevUnserializeHandler = ini_set('unserialize_callback_func', '');
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context) use (&$prevErrorHandler, $signalingException) {
if (E_WARNING === $type && 'Class __PHP_Incomplete_Class has no unserializer' === $msg) {
throw $signalingException;
}

return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
});

try {
$meta = unserialize(file_get_contents($metadata));
} catch (\Error $e) {
} catch (\Exception $e) {
}
restore_error_handler();
ini_set('unserialize_callback_func', $prevUnserializeHandler);
if (null !== $e && $e !== $signalingException) {
throw $e;
}
if (false === $meta) {
return false;
}

foreach ($meta as $resource) {

foreach ($this->resourceCheckers as $checker) {
if (!$checker->supports($resource)) {
continue; 
 }
if ($checker->isFresh($resource, $time)) {
break; 
 }

return false; 
 }

 }

return true;
}









public function write($content, array $metadata = null)
{
$mode = 0666;
$umask = umask();
$filesystem = new Filesystem();
$filesystem->dumpFile($this->file, $content, null);
try {
$filesystem->chmod($this->file, $mode, $umask);
} catch (IOException $e) {

 }

if (null !== $metadata) {
$filesystem->dumpFile($this->getMetaFile(), serialize($metadata), null);
try {
$filesystem->chmod($this->getMetaFile(), $mode, $umask);
} catch (IOException $e) {

 }
}
}






private function getMetaFile()
{
return $this->file.'.meta';
}
}
<?php










namespace Symfony\Component\Config\Exception;






class FileLoaderLoadException extends \Exception
{






public function __construct($resource, $sourceResource = null, $code = null, $previous = null)
{
$message = '';
if ($previous) {



 if ('.' === substr($previous->getMessage(), -1)) {
$trimmedMessage = substr($previous->getMessage(), 0, -1);
$message .= sprintf('%s', $trimmedMessage).' in ';
} else {
$message .= sprintf('%s', $previous->getMessage()).' in ';
}
$message .= $resource.' ';


 if (null === $sourceResource) {
$message .= sprintf('(which is loaded in resource "%s")', $this->varToString($resource));
} else {
$message .= sprintf('(which is being imported from "%s")', $this->varToString($sourceResource));
}
$message .= '.';


 } elseif (null === $sourceResource) {
$message .= sprintf('Cannot load resource "%s".', $this->varToString($resource));
} else {
$message .= sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource));
}


 if ('@' === $resource[0]) {
$parts = explode(DIRECTORY_SEPARATOR, $resource);
$bundle = substr($parts[0], 1);
$message .= sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
$message .= sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource);
}

parent::__construct($message, $code, $previous);
}

protected function varToString($var)
{
if (is_object($var)) {
return sprintf('Object(%s)', get_class($var));
}

if (is_array($var)) {
$a = array();
foreach ($var as $k => $v) {
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
}

return sprintf('Array(%s)', implode(', ', $a));
}

if (is_resource($var)) {
return sprintf('Resource(%s)', get_resource_type($var));
}

if (null === $var) {
return 'null';
}

if (false === $var) {
return 'false';
}

if (true === $var) {
return 'true';
}

return (string) $var;
}
}
<?php










namespace Symfony\Component\Config\Exception;






class FileLoaderImportCircularReferenceException extends FileLoaderLoadException
{
public function __construct(array $resources, $code = null, $previous = null)
{
$message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);

\Exception::__construct($message, $code, $previous);
}
}
<?php










namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;






interface ConfigCacheInterface
{





public function getPath();








public function isFresh();










public function write($content, array $metadata = null);
}
<?php










namespace Symfony\Component\Filesystem;

use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;






class Filesystem
{














public function copy($originFile, $targetFile, $overwriteNewerFiles = false)
{
if (stream_is_local($originFile) && !is_file($originFile)) {
throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
}

$this->mkdir(dirname($targetFile));

$doCopy = true;
if (!$overwriteNewerFiles && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) {
$doCopy = filemtime($originFile) > filemtime($targetFile);
}

if ($doCopy) {

 if (false === $source = @fopen($originFile, 'r')) {
throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading.', $originFile, $targetFile), 0, null, $originFile);
}


 if (false === $target = @fopen($targetFile, 'w', null, stream_context_create(array('ftp' => array('overwrite' => true))))) {
throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing.', $originFile, $targetFile), 0, null, $originFile);
}

$bytesCopied = stream_copy_to_stream($source, $target);
fclose($source);
fclose($target);
unset($source, $target);

if (!is_file($targetFile)) {
throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
}


 @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));

if (stream_is_local($originFile) && $bytesCopied !== ($bytesOrigin = filesize($originFile))) {
throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
}
}
}









public function mkdir($dirs, $mode = 0777)
{
foreach ($this->toIterator($dirs) as $dir) {
if (is_dir($dir)) {
continue;
}

if (true !== @mkdir($dir, $mode, true)) {
$error = error_get_last();
if (!is_dir($dir)) {

 if ($error) {
throw new IOException(sprintf('Failed to create "%s": %s.', $dir, $error['message']), 0, null, $dir);
}
throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir);
}
}
}
}








public function exists($files)
{
foreach ($this->toIterator($files) as $file) {
if ('\\' === DIRECTORY_SEPARATOR && strlen($file) > 258) {
throw new IOException('Could not check if file exist because path length exceeds 258 characters.', 0, null, $file);
}

if (!file_exists($file)) {
return false;
}
}

return true;
}










public function touch($files, $time = null, $atime = null)
{
foreach ($this->toIterator($files) as $file) {
$touch = $time ? @touch($file, $time, $atime) : @touch($file);
if (true !== $touch) {
throw new IOException(sprintf('Failed to touch "%s".', $file), 0, null, $file);
}
}
}








public function remove($files)
{
if ($files instanceof \Traversable) {
$files = iterator_to_array($files, false);
} elseif (!is_array($files)) {
$files = array($files);
}
$files = array_reverse($files);
foreach ($files as $file) {
if (is_link($file)) {

 if (!@(unlink($file) || '\\' !== DIRECTORY_SEPARATOR || rmdir($file)) && file_exists($file)) {
$error = error_get_last();
throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, $error['message']));
}
} elseif (is_dir($file)) {
$this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));

if (!@rmdir($file) && file_exists($file)) {
$error = error_get_last();
throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, $error['message']));
}
} elseif (!@unlink($file) && file_exists($file)) {
$error = error_get_last();
throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, $error['message']));
}
}
}











public function chmod($files, $mode, $umask = 0000, $recursive = false)
{
foreach ($this->toIterator($files) as $file) {
if (true !== @chmod($file, $mode & ~$umask)) {
throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file);
}
if ($recursive && is_dir($file) && !is_link($file)) {
$this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
}
}
}










public function chown($files, $user, $recursive = false)
{
foreach ($this->toIterator($files) as $file) {
if ($recursive && is_dir($file) && !is_link($file)) {
$this->chown(new \FilesystemIterator($file), $user, true);
}
if (is_link($file) && function_exists('lchown')) {
if (true !== @lchown($file, $user)) {
throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
}
} else {
if (true !== @chown($file, $user)) {
throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
}
}
}
}










public function chgrp($files, $group, $recursive = false)
{
foreach ($this->toIterator($files) as $file) {
if ($recursive && is_dir($file) && !is_link($file)) {
$this->chgrp(new \FilesystemIterator($file), $group, true);
}
if (is_link($file) && function_exists('lchgrp')) {
if (true !== @lchgrp($file, $group) || (defined('HHVM_VERSION') && !posix_getgrnam($group))) {
throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
}
} else {
if (true !== @chgrp($file, $group)) {
throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
}
}
}
}











public function rename($origin, $target, $overwrite = false)
{

 if (!$overwrite && $this->isReadable($target)) {
throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
}

if (true !== @rename($origin, $target)) {
throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target);
}
}










private function isReadable($filename)
{
if ('\\' === DIRECTORY_SEPARATOR && strlen($filename) > 258) {
throw new IOException('Could not check if file is readable because path length exceeds 258 characters.', 0, null, $filename);
}

return is_readable($filename);
}










public function symlink($originDir, $targetDir, $copyOnWindows = false)
{
if ('\\' === DIRECTORY_SEPARATOR) {
$originDir = strtr($originDir, '/', '\\');
$targetDir = strtr($targetDir, '/', '\\');

if ($copyOnWindows) {
$this->mirror($originDir, $targetDir);

return;
}
}

$this->mkdir(dirname($targetDir));

$ok = false;
if (is_link($targetDir)) {
if (readlink($targetDir) != $originDir) {
$this->remove($targetDir);
} else {
$ok = true;
}
}

if (!$ok && true !== @symlink($originDir, $targetDir)) {
$report = error_get_last();
if (is_array($report)) {
if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) {
throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir);
}
}
throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
}
}









public function makePathRelative($endPath, $startPath)
{

 if ('\\' === DIRECTORY_SEPARATOR) {
$endPath = str_replace('\\', '/', $endPath);
$startPath = str_replace('\\', '/', $startPath);
}


 $startPathArr = explode('/', trim($startPath, '/'));
$endPathArr = explode('/', trim($endPath, '/'));


 $index = 0;
while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
++$index;
}


 if (count($startPathArr) === 1 && $startPathArr[0] === '') {
$depth = 0;
} else {
$depth = count($startPathArr) - $index;
}


 if ('/' === $startPath[0] && 0 === $index && 0 === $depth) {
$traverser = '';
} else {

 $traverser = str_repeat('../', $depth);
}

$endPathRemainder = implode('/', array_slice($endPathArr, $index));


 $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');

return '' === $relativePath ? './' : $relativePath;
}















public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
{
$targetDir = rtrim($targetDir, '/\\');
$originDir = rtrim($originDir, '/\\');


 if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
$deleteIterator = $iterator;
if (null === $deleteIterator) {
$flags = \FilesystemIterator::SKIP_DOTS;
$deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
}
foreach ($deleteIterator as $file) {
$origin = str_replace($targetDir, $originDir, $file->getPathname());
if (!$this->exists($origin)) {
$this->remove($file);
}
}
}

$copyOnWindows = false;
if (isset($options['copy_on_windows'])) {
$copyOnWindows = $options['copy_on_windows'];
}

if (null === $iterator) {
$flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
}

if ($this->exists($originDir)) {
$this->mkdir($targetDir);
}

foreach ($iterator as $file) {
$target = str_replace($originDir, $targetDir, $file->getPathname());

if ($copyOnWindows) {
if (is_file($file)) {
$this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
} elseif (is_dir($file)) {
$this->mkdir($target);
} else {
throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
}
} else {
if (is_link($file)) {
$this->symlink($file->getLinkTarget(), $target);
} elseif (is_dir($file)) {
$this->mkdir($target);
} elseif (is_file($file)) {
$this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
} else {
throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
}
}
}
}








public function isAbsolutePath($file)
{
return strspn($file, '/\\', 0, 1)
|| (strlen($file) > 3 && ctype_alpha($file[0])
&& substr($file, 1, 1) === ':'
&& strspn($file, '/\\', 2, 1)
)
|| null !== parse_url($file, PHP_URL_SCHEME)
;
}










public function tempnam($dir, $prefix)
{
list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir);


 if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) {
$tmpFile = @tempnam($hierarchy, $prefix);


 if (false !== $tmpFile) {
if (null !== $scheme && 'gs' !== $scheme) {
return $scheme.'://'.$tmpFile;
}

return $tmpFile;
}

throw new IOException('A temporary file could not be created.');
}


 for ($i = 0; $i < 10; ++$i) {

 $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true);


 
 $handle = @fopen($tmpFile, 'x+');


 if (false === $handle) {
continue;
}


 @fclose($handle);

return $tmpFile;
}

throw new IOException('A temporary file could not be created.');
}











public function dumpFile($filename, $content, $mode = 0666)
{
$dir = dirname($filename);

if (!is_dir($dir)) {
$this->mkdir($dir);
}

if (!is_writable($dir)) {
throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
}

$tmpFile = $this->tempnam($dir, basename($filename));

if (false === @file_put_contents($tmpFile, $content)) {
throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
}

if (null !== $mode) {
if (func_num_args() > 2) {
@trigger_error('Support for modifying file permissions is deprecated since version 2.3.12 and will be removed in 3.0.', E_USER_DEPRECATED);
}

$this->chmod($tmpFile, $mode);
}
$this->rename($tmpFile, $filename, true);
}






private function toIterator($files)
{
if (!$files instanceof \Traversable) {
$files = new \ArrayObject(is_array($files) ? $files : array($files));
}

return $files;
}








private function getSchemeAndHierarchy($filename)
{
$components = explode('://', $filename, 2);

return 2 === count($components) ? array($components[0], $components[1]) : array(null, $components[0]);
}
}
<?php










namespace Symfony\Component\Filesystem;

use Symfony\Component\Filesystem\Exception\IOException;














class LockHandler
{
private $file;
private $handle;







public function __construct($name, $lockPath = null)
{
$lockPath = $lockPath ?: sys_get_temp_dir();

if (!is_dir($lockPath)) {
$fs = new Filesystem();
$fs->mkdir($lockPath);
}

if (!is_writable($lockPath)) {
throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath);
}

$this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name));
}










public function lock($blocking = false)
{
if ($this->handle) {
return true;
}


 set_error_handler(function () {});

if (!$this->handle = fopen($this->file, 'r')) {
if ($this->handle = fopen($this->file, 'x')) {
chmod($this->file, 0444);
} elseif (!$this->handle = fopen($this->file, 'r')) {
usleep(100); 
 $this->handle = fopen($this->file, 'r');
}
}
restore_error_handler();

if (!$this->handle) {
$error = error_get_last();
throw new IOException($error['message'], 0, null, $this->file);
}


 
 if (!flock($this->handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
fclose($this->handle);
$this->handle = null;

return false;
}

return true;
}




public function release()
{
if ($this->handle) {
flock($this->handle, LOCK_UN | LOCK_NB);
fclose($this->handle);
$this->handle = null;
}
}
}
<?php










namespace Symfony\Component\Filesystem\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\LockHandler;

class LockHandlerTest extends TestCase
{




public function testConstructWhenRepositoryDoesNotExist()
{
if (!getenv('USER') || 'root' === getenv('USER')) {
$this->markTestSkipped('This test will fail if run under superuser');
}
new LockHandler('lock', '/a/b/c/d/e');
}





public function testConstructWhenRepositoryIsNotWriteable()
{
if (!getenv('USER') || 'root' === getenv('USER')) {
$this->markTestSkipped('This test will fail if run under superuser');
}
new LockHandler('lock', '/');
}

public function testConstructSanitizeName()
{
$lock = new LockHandler('<?php echo "% hello word ! %" ?>');

$file = sprintf('%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', sys_get_temp_dir());

 @unlink($file);

$lock->lock();

$this->assertFileExists($file);

$lock->release();
}

public function testLockRelease()
{
$name = 'symfony-test-filesystem.lock';

$l1 = new LockHandler($name);
$l2 = new LockHandler($name);

$this->assertTrue($l1->lock());
$this->assertFalse($l2->lock());

$l1->release();

$this->assertTrue($l2->lock());
$l2->release();
}

public function testLockTwice()
{
$name = 'symfony-test-filesystem.lock';

$lockHandler = new LockHandler($name);

$this->assertTrue($lockHandler->lock());
$this->assertTrue($lockHandler->lock());

$lockHandler->release();
}

public function testLockIsReleased()
{
$name = 'symfony-test-filesystem.lock';

$l1 = new LockHandler($name);
$l2 = new LockHandler($name);

$this->assertTrue($l1->lock());
$this->assertFalse($l2->lock());

$l1 = null;

$this->assertTrue($l2->lock());
$l2->release();
}
}
<?php










namespace Symfony\Component\Filesystem\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Filesystem;

class FilesystemTestCase extends TestCase
{
private $umask;

protected $longPathNamesWindows = array();




protected $filesystem = null;




protected $workspace = null;

private static $symlinkOnWindows = null;

public static function setUpBeforeClass()
{
if ('\\' === DIRECTORY_SEPARATOR && null === self::$symlinkOnWindows) {
$target = tempnam(sys_get_temp_dir(), 'sl');
$link = sys_get_temp_dir().'/sl'.microtime(true).mt_rand();
self::$symlinkOnWindows = @symlink($target, $link) && is_link($link);
@unlink($link);
unlink($target);
}
}

protected function setUp()
{
$this->umask = umask(0);
$this->filesystem = new Filesystem();
$this->workspace = sys_get_temp_dir().'/'.microtime(true).'.'.mt_rand();
mkdir($this->workspace, 0777, true);
$this->workspace = realpath($this->workspace);
}

protected function tearDown()
{
if (!empty($this->longPathNamesWindows)) {
foreach ($this->longPathNamesWindows as $path) {
exec('DEL '.$path);
}
$this->longPathNamesWindows = array();
}

$this->filesystem->remove($this->workspace);
umask($this->umask);
}





protected function assertFilePermissions($expectedFilePerms, $filePath)
{
$actualFilePerms = (int) substr(sprintf('%o', fileperms($filePath)), -3);
$this->assertEquals(
$expectedFilePerms,
$actualFilePerms,
sprintf('File permissions for %s must be %s. Actual %s', $filePath, $expectedFilePerms, $actualFilePerms)
);
}

protected function getFileOwner($filepath)
{
$this->markAsSkippedIfPosixIsMissing();

$infos = stat($filepath);
if ($datas = posix_getpwuid($infos['uid'])) {
return $datas['name'];
}
}

protected function getFileGroup($filepath)
{
$this->markAsSkippedIfPosixIsMissing();

$infos = stat($filepath);
if ($datas = posix_getgrgid($infos['gid'])) {
return $datas['name'];
}

$this->markTestSkipped('Unable to retrieve file group name');
}

protected function markAsSkippedIfSymlinkIsMissing($relative = false)
{
if ('\\' === DIRECTORY_SEPARATOR && false === self::$symlinkOnWindows) {
$this->markTestSkipped('symlink requires "Create symbolic links" privilege on Windows');
}


 if ($relative && '\\' === DIRECTORY_SEPARATOR && 1 === PHP_ZTS) {
$this->markTestSkipped('symlink does not support relative paths on thread safe Windows PHP versions');
}
}

protected function markAsSkippedIfChmodIsMissing()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('chmod is not supported on Windows');
}
}

protected function markAsSkippedIfPosixIsMissing()
{
if (!function_exists('posix_isatty')) {
$this->markTestSkipped('Function posix_isatty is required.');
}
}
}
<?php










namespace Symfony\Component\Filesystem\Tests\Fixtures\MockStream;





class MockStream
{











public function stream_open($path, $mode, $options, &$opened_path)
{
return true;
}







public function url_stat($path, $flags)
{
return array();
}
}
<?php










namespace Symfony\Component\Filesystem\Tests;




class FilesystemTest extends FilesystemTestCase
{
public function testCopyCreatesNewFile()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');

$this->filesystem->copy($sourceFilePath, $targetFilePath);

$this->assertFileExists($targetFilePath);
$this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
}




public function testCopyFails()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

$this->filesystem->copy($sourceFilePath, $targetFilePath);
}




public function testCopyUnreadableFileFails()
{

 if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test cannot run on Windows.');
}

$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');


 $this->filesystem->chmod($sourceFilePath, 0222);

$this->filesystem->copy($sourceFilePath, $targetFilePath);
}

public function testCopyOverridesExistingFileIfModified()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');
file_put_contents($targetFilePath, 'TARGET FILE');
touch($targetFilePath, time() - 1000);

$this->filesystem->copy($sourceFilePath, $targetFilePath);

$this->assertFileExists($targetFilePath);
$this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
}

public function testCopyDoesNotOverrideExistingFileByDefault()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');
file_put_contents($targetFilePath, 'TARGET FILE');


 $modificationTime = time() - 1000;
touch($sourceFilePath, $modificationTime);
touch($targetFilePath, $modificationTime);

$this->filesystem->copy($sourceFilePath, $targetFilePath);

$this->assertFileExists($targetFilePath);
$this->assertEquals('TARGET FILE', file_get_contents($targetFilePath));
}

public function testCopyOverridesExistingFileIfForced()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');
file_put_contents($targetFilePath, 'TARGET FILE');


 $modificationTime = time() - 1000;
touch($sourceFilePath, $modificationTime);
touch($targetFilePath, $modificationTime);

$this->filesystem->copy($sourceFilePath, $targetFilePath, true);

$this->assertFileExists($targetFilePath);
$this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
}




public function testCopyWithOverrideWithReadOnlyTargetFails()
{

 if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test cannot run on Windows.');
}

$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');
file_put_contents($targetFilePath, 'TARGET FILE');


 $modificationTime = time() - 1000;
touch($sourceFilePath, $modificationTime);
touch($targetFilePath, $modificationTime);


 $this->filesystem->chmod($targetFilePath, 0444);

$this->filesystem->copy($sourceFilePath, $targetFilePath, true);
}

public function testCopyCreatesTargetDirectoryIfItDoesNotExist()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
$targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');

$this->filesystem->copy($sourceFilePath, $targetFilePath);

$this->assertTrue(is_dir($targetFileDirectory));
$this->assertFileExists($targetFilePath);
$this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
}

public function testCopyForOriginUrlsAndExistingLocalFileDefaultsToCopy()
{
$sourceFilePath = 'http://symfony.com/images/common/logo/logo_symfony_header.png';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($targetFilePath, 'TARGET FILE');

$this->filesystem->copy($sourceFilePath, $targetFilePath, false);

$this->assertFileExists($targetFilePath);
$this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath));
}

public function testMkdirCreatesDirectoriesRecursively()
{
$directory = $this->workspace
.DIRECTORY_SEPARATOR.'directory'
.DIRECTORY_SEPARATOR.'sub_directory';

$this->filesystem->mkdir($directory);

$this->assertTrue(is_dir($directory));
}

public function testMkdirCreatesDirectoriesFromArray()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;
$directories = array(
$basePath.'1', $basePath.'2', $basePath.'3',
);

$this->filesystem->mkdir($directories);

$this->assertTrue(is_dir($basePath.'1'));
$this->assertTrue(is_dir($basePath.'2'));
$this->assertTrue(is_dir($basePath.'3'));
}

public function testMkdirCreatesDirectoriesFromTraversableObject()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;
$directories = new \ArrayObject(array(
$basePath.'1', $basePath.'2', $basePath.'3',
));

$this->filesystem->mkdir($directories);

$this->assertTrue(is_dir($basePath.'1'));
$this->assertTrue(is_dir($basePath.'2'));
$this->assertTrue(is_dir($basePath.'3'));
}




public function testMkdirCreatesDirectoriesFails()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;
$dir = $basePath.'2';

file_put_contents($dir, '');

$this->filesystem->mkdir($dir);
}

public function testTouchCreatesEmptyFile()
{
$file = $this->workspace.DIRECTORY_SEPARATOR.'1';

$this->filesystem->touch($file);

$this->assertFileExists($file);
}




public function testTouchFails()
{
$file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2';

$this->filesystem->touch($file);
}

public function testTouchCreatesEmptyFilesFromArray()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;
$files = array(
$basePath.'1', $basePath.'2', $basePath.'3',
);

$this->filesystem->touch($files);

$this->assertFileExists($basePath.'1');
$this->assertFileExists($basePath.'2');
$this->assertFileExists($basePath.'3');
}

public function testTouchCreatesEmptyFilesFromTraversableObject()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;
$files = new \ArrayObject(array(
$basePath.'1', $basePath.'2', $basePath.'3',
));

$this->filesystem->touch($files);

$this->assertFileExists($basePath.'1');
$this->assertFileExists($basePath.'2');
$this->assertFileExists($basePath.'3');
}

public function testRemoveCleansFilesAndDirectoriesIteratively()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

mkdir($basePath);
mkdir($basePath.'dir');
touch($basePath.'file');

$this->filesystem->remove($basePath);

$this->assertFileNotExists($basePath);
}

public function testRemoveCleansArrayOfFilesAndDirectories()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;

mkdir($basePath.'dir');
touch($basePath.'file');

$files = array(
$basePath.'dir', $basePath.'file',
);

$this->filesystem->remove($files);

$this->assertFileNotExists($basePath.'dir');
$this->assertFileNotExists($basePath.'file');
}

public function testRemoveCleansTraversableObjectOfFilesAndDirectories()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;

mkdir($basePath.'dir');
touch($basePath.'file');

$files = new \ArrayObject(array(
$basePath.'dir', $basePath.'file',
));

$this->filesystem->remove($files);

$this->assertFileNotExists($basePath.'dir');
$this->assertFileNotExists($basePath.'file');
}

public function testRemoveIgnoresNonExistingFiles()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;

mkdir($basePath.'dir');

$files = array(
$basePath.'dir', $basePath.'file',
);

$this->filesystem->remove($files);

$this->assertFileNotExists($basePath.'dir');
}

public function testRemoveCleansInvalidLinks()
{
$this->markAsSkippedIfSymlinkIsMissing();

$basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

mkdir($basePath);
mkdir($basePath.'dir');

 @symlink($basePath.'file', $basePath.'file-link');


 $this->filesystem->symlink($basePath.'dir/', $basePath.'dir-link');
$this->assertTrue(is_dir($basePath.'dir-link'));


 rmdir($basePath.'dir');
$this->assertFalse('\\' === DIRECTORY_SEPARATOR ? @readlink($basePath.'dir-link') : is_dir($basePath.'dir-link'));

$this->filesystem->remove($basePath);

$this->assertFileNotExists($basePath);
}

public function testFilesExists()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

mkdir($basePath);
touch($basePath.'file1');
mkdir($basePath.'folder');

$this->assertTrue($this->filesystem->exists($basePath.'file1'));
$this->assertTrue($this->filesystem->exists($basePath.'folder'));
}




public function testFilesExistsFails()
{
if ('\\' !== DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Test covers edge case on Windows only.');
}

$basePath = $this->workspace.'\\directory\\';

$oldPath = getcwd();
mkdir($basePath);
chdir($basePath);
$file = str_repeat('T', 259 - strlen($basePath));
$path = $basePath.$file;
exec('TYPE NUL >>'.$file); 
 $this->longPathNamesWindows[] = $path; 
 chdir($oldPath);
$this->filesystem->exists($path);
}

public function testFilesExistsTraversableObjectOfFilesAndDirectories()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;

mkdir($basePath.'dir');
touch($basePath.'file');

$files = new \ArrayObject(array(
$basePath.'dir', $basePath.'file',
));

$this->assertTrue($this->filesystem->exists($files));
}

public function testFilesNotExistsTraversableObjectOfFilesAndDirectories()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR;

mkdir($basePath.'dir');
touch($basePath.'file');
touch($basePath.'file2');

$files = new \ArrayObject(array(
$basePath.'dir', $basePath.'file', $basePath.'file2',
));

unlink($basePath.'file');

$this->assertFalse($this->filesystem->exists($files));
}

public function testInvalidFileNotExists()
{
$basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;

$this->assertFalse($this->filesystem->exists($basePath.time()));
}

public function testChmodChangesFileMode()
{
$this->markAsSkippedIfChmodIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);
$file = $dir.DIRECTORY_SEPARATOR.'file';
touch($file);

$this->filesystem->chmod($file, 0400);
$this->filesystem->chmod($dir, 0753);

$this->assertFilePermissions(753, $dir);
$this->assertFilePermissions(400, $file);
}

public function testChmodWrongMod()
{
$this->markAsSkippedIfChmodIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'file';
touch($dir);

$this->filesystem->chmod($dir, 'Wrongmode');
}

public function testChmodRecursive()
{
$this->markAsSkippedIfChmodIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);
$file = $dir.DIRECTORY_SEPARATOR.'file';
touch($file);

$this->filesystem->chmod($file, 0400, 0000, true);
$this->filesystem->chmod($dir, 0753, 0000, true);

$this->assertFilePermissions(753, $dir);
$this->assertFilePermissions(753, $file);
}

public function testChmodAppliesUmask()
{
$this->markAsSkippedIfChmodIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
touch($file);

$this->filesystem->chmod($file, 0770, 0022);
$this->assertFilePermissions(750, $file);
}

public function testChmodChangesModeOfArrayOfFiles()
{
$this->markAsSkippedIfChmodIsMissing();

$directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$files = array($directory, $file);

mkdir($directory);
touch($file);

$this->filesystem->chmod($files, 0753);

$this->assertFilePermissions(753, $file);
$this->assertFilePermissions(753, $directory);
}

public function testChmodChangesModeOfTraversableFileObject()
{
$this->markAsSkippedIfChmodIsMissing();

$directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$files = new \ArrayObject(array($directory, $file));

mkdir($directory);
touch($file);

$this->filesystem->chmod($files, 0753);

$this->assertFilePermissions(753, $file);
$this->assertFilePermissions(753, $directory);
}

public function testChmodChangesZeroModeOnSubdirectoriesOnRecursive()
{
$this->markAsSkippedIfChmodIsMissing();

$directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
$subdirectory = $directory.DIRECTORY_SEPARATOR.'subdirectory';

mkdir($directory);
mkdir($subdirectory);
chmod($subdirectory, 0000);

$this->filesystem->chmod($directory, 0753, 0000, true);

$this->assertFilePermissions(753, $subdirectory);
}

public function testChown()
{
$this->markAsSkippedIfPosixIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);

$this->filesystem->chown($dir, $this->getFileOwner($dir));
}

public function testChownRecursive()
{
$this->markAsSkippedIfPosixIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);
$file = $dir.DIRECTORY_SEPARATOR.'file';
touch($file);

$this->filesystem->chown($dir, $this->getFileOwner($dir), true);
}

public function testChownSymlink()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

touch($file);

$this->filesystem->symlink($file, $link);

$this->filesystem->chown($link, $this->getFileOwner($link));
}




public function testChownSymlinkFails()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

touch($file);

$this->filesystem->symlink($file, $link);

$this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
}




public function testChownFail()
{
$this->markAsSkippedIfPosixIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);

$this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999));
}

public function testChgrp()
{
$this->markAsSkippedIfPosixIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);

$this->filesystem->chgrp($dir, $this->getFileGroup($dir));
}

public function testChgrpRecursive()
{
$this->markAsSkippedIfPosixIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);
$file = $dir.DIRECTORY_SEPARATOR.'file';
touch($file);

$this->filesystem->chgrp($dir, $this->getFileGroup($dir), true);
}

public function testChgrpSymlink()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

touch($file);

$this->filesystem->symlink($file, $link);

$this->filesystem->chgrp($link, $this->getFileGroup($link));
}




public function testChgrpSymlinkFails()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

touch($file);

$this->filesystem->symlink($file, $link);

$this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
}




public function testChgrpFail()
{
$this->markAsSkippedIfPosixIsMissing();

$dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
mkdir($dir);

$this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999));
}

public function testRename()
{
$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
touch($file);

$this->filesystem->rename($file, $newPath);

$this->assertFileNotExists($file);
$this->assertFileExists($newPath);
}




public function testRenameThrowsExceptionIfTargetAlreadyExists()
{
$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';

touch($file);
touch($newPath);

$this->filesystem->rename($file, $newPath);
}

public function testRenameOverwritesTheTargetIfItAlreadyExists()
{
$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';

touch($file);
touch($newPath);

$this->filesystem->rename($file, $newPath, true);

$this->assertFileNotExists($file);
$this->assertFileExists($newPath);
}




public function testRenameThrowsExceptionOnError()
{
$file = $this->workspace.DIRECTORY_SEPARATOR.uniqid('fs_test_', true);
$newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';

$this->filesystem->rename($file, $newPath);
}

public function testSymlink()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support creating "broken" symlinks');
}

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';


 $this->filesystem->symlink($file, $link);

$this->assertTrue(is_link($link));


 touch($file);

$this->assertEquals($file, readlink($link));
}




public function testRemoveSymlink()
{
$this->markAsSkippedIfSymlinkIsMissing();

$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

$this->filesystem->remove($link);

$this->assertTrue(!is_link($link));
$this->assertTrue(!is_file($link));
$this->assertTrue(!is_dir($link));
}

public function testSymlinkIsOverwrittenIfPointsToDifferentTarget()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

touch($file);
symlink($this->workspace, $link);

$this->filesystem->symlink($file, $link);

$this->assertTrue(is_link($link));
$this->assertEquals($file, readlink($link));
}

public function testSymlinkIsNotOverwrittenIfAlreadyCreated()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';

touch($file);
symlink($file, $link);

$this->filesystem->symlink($file, $link);

$this->assertTrue(is_link($link));
$this->assertEquals($file, readlink($link));
}

public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist()
{
$this->markAsSkippedIfSymlinkIsMissing();

$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link';
$link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link';

touch($file);

$this->filesystem->symlink($file, $link1);
$this->filesystem->symlink($file, $link2);

$this->assertTrue(is_link($link1));
$this->assertEquals($file, readlink($link1));
$this->assertTrue(is_link($link2));
$this->assertEquals($file, readlink($link2));
}




public function testMakePathRelative($endPath, $startPath, $expectedPath)
{
$path = $this->filesystem->makePathRelative($endPath, $startPath);

$this->assertEquals($expectedPath, $path);
}




public function providePathsForMakePathRelative()
{
$paths = array(
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'),
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
array('/aa/bb', '/aa/bb', './'),
array('/aa/bb', '/aa/bb/', './'),
array('/aa/bb/', '/aa/bb', './'),
array('/aa/bb/', '/aa/bb/', './'),
array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
array('/aa/bb/cc', '/aa', 'bb/cc/'),
array('/aa/bb/cc', '/aa/', 'bb/cc/'),
array('/aa/bb/cc/', '/aa', 'bb/cc/'),
array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
array('/a/aab/bb', '/a/aa', '../aab/bb/'),
array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
array('/a/aab/bb/', '/', 'a/aab/bb/'),
array('/a/aab/bb/', '/b/aab', '../../a/aab/bb/'),
array('/aab/bb', '/aa', '../aab/bb/'),
array('/aab', '/aa', '../aab/'),
);

if ('\\' === DIRECTORY_SEPARATOR) {
$paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
}

return $paths;
}

public function testMirrorCopiesFilesAndDirectoriesRecursively()
{
$sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
$directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR;
$file1 = $directory.'file1';
$file2 = $sourcePath.'file2';

mkdir($sourcePath);
mkdir($directory);
file_put_contents($file1, 'FILE1');
file_put_contents($file2, 'FILE2');

$targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

$this->filesystem->mirror($sourcePath, $targetPath);

$this->assertTrue(is_dir($targetPath));
$this->assertTrue(is_dir($targetPath.'directory'));
$this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1');
$this->assertFileEquals($file2, $targetPath.'file2');

$this->filesystem->remove($file1);

$this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false));
$this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));

$this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
$this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));

file_put_contents($file1, 'FILE1');

$this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
$this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));

$this->filesystem->remove($directory);
$this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
$this->assertFalse($this->filesystem->exists($targetPath.'directory'));
$this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
}

public function testMirrorCreatesEmptyDirectory()
{
$sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;

mkdir($sourcePath);

$targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

$this->filesystem->mirror($sourcePath, $targetPath);

$this->assertTrue(is_dir($targetPath));

$this->filesystem->remove($sourcePath);
}

public function testMirrorCopiesLinks()
{
$this->markAsSkippedIfSymlinkIsMissing();

$sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;

mkdir($sourcePath);
file_put_contents($sourcePath.'file1', 'FILE1');
symlink($sourcePath.'file1', $sourcePath.'link1');

$targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

$this->filesystem->mirror($sourcePath, $targetPath);

$this->assertTrue(is_dir($targetPath));
$this->assertFileEquals($sourcePath.'file1', $targetPath.'link1');
$this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
}

public function testMirrorCopiesLinkedDirectoryContents()
{
$this->markAsSkippedIfSymlinkIsMissing(true);

$sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;

mkdir($sourcePath.'nested/', 0777, true);
file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');

 symlink($sourcePath.'nested', $sourcePath.'link1');

$targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

$this->filesystem->mirror($sourcePath, $targetPath);

$this->assertTrue(is_dir($targetPath));
$this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt');
$this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
}

public function testMirrorCopiesRelativeLinkedContents()
{
$this->markAsSkippedIfSymlinkIsMissing(true);

$sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
$oldPath = getcwd();

mkdir($sourcePath.'nested/', 0777, true);
file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');

 chdir($sourcePath);
symlink('nested', 'link1');

chdir($oldPath);

$targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;

$this->filesystem->mirror($sourcePath, $targetPath);

$this->assertTrue(is_dir($targetPath));
$this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt');
$this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
$this->assertEquals('\\' === DIRECTORY_SEPARATOR ? realpath($sourcePath.'\nested') : 'nested', readlink($targetPath.DIRECTORY_SEPARATOR.'link1'));
}




public function testIsAbsolutePath($path, $expectedResult)
{
$result = $this->filesystem->isAbsolutePath($path);

$this->assertEquals($expectedResult, $result);
}




public function providePathsForIsAbsolutePath()
{
return array(
array('/var/lib', true),
array('c:\\\\var\\lib', true),
array('\\var\\lib', true),
array('var/lib', false),
array('../var/lib', false),
array('', false),
array(null, false),
);
}

public function testTempnam()
{
$dirname = $this->workspace;

$filename = $this->filesystem->tempnam($dirname, 'foo');

$this->assertFileExists($filename);
}

public function testTempnamWithFileScheme()
{
$scheme = 'file://';
$dirname = $scheme.$this->workspace;

$filename = $this->filesystem->tempnam($dirname, 'foo');

$this->assertStringStartsWith($scheme, $filename);
$this->assertFileExists($filename);
}

public function testTempnamWithMockScheme()
{
stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream');

$scheme = 'mock://';
$dirname = $scheme.$this->workspace;

$filename = $this->filesystem->tempnam($dirname, 'foo');

$this->assertStringStartsWith($scheme, $filename);
$this->assertFileExists($filename);
}




public function testTempnamWithZlibSchemeFails()
{
$scheme = 'compress.zlib://';
$dirname = $scheme.$this->workspace;


 $this->filesystem->tempnam($dirname, 'bar');
}

public function testTempnamWithPHPTempSchemeFails()
{
$scheme = 'php://temp';
$dirname = $scheme;

$filename = $this->filesystem->tempnam($dirname, 'bar');

$this->assertStringStartsWith($scheme, $filename);


 $this->assertFileNotExists($filename);
}




public function testTempnamWithPharSchemeFails()
{

 if (!\Phar::canWrite()) {
$this->markTestSkipped('This test cannot run when phar.readonly is 1.');
}

$scheme = 'phar://';
$dirname = $scheme.$this->workspace;
$pharname = 'foo.phar';

new \Phar($this->workspace.'/'.$pharname, 0, $pharname);

 $this->filesystem->tempnam($dirname, $pharname.'/bar');
}




public function testTempnamWithHTTPSchemeFails()
{
$scheme = 'http://';
$dirname = $scheme.$this->workspace;


 $this->filesystem->tempnam($dirname, 'bar');
}

public function testTempnamOnUnwritableFallsBackToSysTmp()
{
$scheme = 'file://';
$dirname = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'does_not_exist';

$filename = $this->filesystem->tempnam($dirname, 'bar');
$realTempDir = realpath(sys_get_temp_dir());
$this->assertStringStartsWith(rtrim($scheme.$realTempDir, DIRECTORY_SEPARATOR), $filename);
$this->assertFileExists($filename);


 @unlink($filename);
}

public function testDumpFile()
{
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

$this->filesystem->dumpFile($filename, 'bar');

$this->assertFileExists($filename);
$this->assertSame('bar', file_get_contents($filename));
}




public function testDumpFileAndSetPermissions()
{
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

$this->filesystem->dumpFile($filename, 'bar', 0753);

$this->assertFileExists($filename);
$this->assertSame('bar', file_get_contents($filename));


 if ('\\' !== DIRECTORY_SEPARATOR) {
$this->assertFilePermissions(753, $filename);
}
}

public function testDumpFileWithNullMode()
{
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

$this->filesystem->dumpFile($filename, 'bar', null);

$this->assertFileExists($filename);
$this->assertSame('bar', file_get_contents($filename));


 if ('\\' !== DIRECTORY_SEPARATOR) {
$this->assertFilePermissions(600, $filename);
}
}

public function testDumpFileOverwritesAnExistingFile()
{
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
file_put_contents($filename, 'FOO BAR');

$this->filesystem->dumpFile($filename, 'bar');

$this->assertFileExists($filename);
$this->assertSame('bar', file_get_contents($filename));
}

public function testDumpFileWithFileScheme()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('HHVM does not handle the file:// scheme correctly');
}

$scheme = 'file://';
$filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

$this->filesystem->dumpFile($filename, 'bar', null);

$this->assertFileExists($filename);
$this->assertSame('bar', file_get_contents($filename));
}

public function testDumpFileWithZlibScheme()
{
$scheme = 'compress.zlib://';
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';

$this->filesystem->dumpFile($filename, 'bar', null);


 $this->assertFileExists(str_replace($scheme, '', $filename));
$this->assertSame('bar', file_get_contents($filename));
}

public function testCopyShouldKeepExecutionPermission()
{
$this->markAsSkippedIfChmodIsMissing();

$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';

file_put_contents($sourceFilePath, 'SOURCE FILE');
chmod($sourceFilePath, 0745);

$this->filesystem->copy($sourceFilePath, $targetFilePath);

$this->assertFilePermissions(767, $targetFilePath);
}
}
<?php










namespace Symfony\Component\Filesystem\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;




class ExceptionTest extends TestCase
{
public function testGetPath()
{
$e = new IOException('', 0, null, '/foo');
$this->assertEquals('/foo', $e->getPath(), 'The pass should be returned.');
}

public function testGeneratedMessage()
{
$e = new FileNotFoundException(null, 0, null, '/foo');
$this->assertEquals('/foo', $e->getPath());
$this->assertEquals('File "/foo" could not be found.', $e->getMessage(), 'A message should be generated.');
}

public function testGeneratedMessageWithoutPath()
{
$e = new FileNotFoundException();
$this->assertEquals('File could not be found.', $e->getMessage(), 'A message should be generated.');
}

public function testCustomMessage()
{
$e = new FileNotFoundException('bar', 0, null, '/foo');
$this->assertEquals('bar', $e->getMessage(), 'A custom message should be possible still.');
}
}
<?php










namespace Symfony\Component\Filesystem\Exception;






interface IOExceptionInterface extends ExceptionInterface
{





public function getPath();
}
<?php










namespace Symfony\Component\Filesystem\Exception;






interface ExceptionInterface
{
}
<?php










namespace Symfony\Component\Filesystem\Exception;








class IOException extends \RuntimeException implements IOExceptionInterface
{
private $path;

public function __construct($message, $code = 0, \Exception $previous = null, $path = null)
{
$this->path = $path;

parent::__construct($message, $code, $previous);
}




public function getPath()
{
return $this->path;
}
}
<?php










namespace Symfony\Component\Filesystem\Exception;







class FileNotFoundException extends IOException
{
public function __construct($message = null, $code = 0, \Exception $previous = null, $path = null)
{
if (null === $message) {
if (null === $path) {
$message = 'File could not be found.';
} else {
$message = sprintf('File "%s" could not be found.', $path);
}
}

parent::__construct($message, $code, $previous, $path);
}
}
<?php










namespace Symfony\Polyfill\Mbstring;





















































final class Mbstring
{
const MB_CASE_FOLD = PHP_INT_MAX;

private static $encodingList = array('ASCII', 'UTF-8');
private static $language = 'neutral';
private static $internalEncoding = 'UTF-8';
private static $caseFold = array(
array('µ','ſ',"\xCD\x85",'ς',"\xCF\x90","\xCF\x91","\xCF\x95","\xCF\x96","\xCF\xB0","\xCF\xB1","\xCF\xB5","\xE1\xBA\x9B","\xE1\xBE\xBE"),
array('μ','s','ι', 'σ','β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1",'ι'),
);

public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
} else {
$fromEncoding = self::getEncoding($fromEncoding);
}

$toEncoding = self::getEncoding($toEncoding);

if ('BASE64' === $fromEncoding) {
$s = base64_decode($s);
$fromEncoding = $toEncoding;
}

if ('BASE64' === $toEncoding) {
return base64_encode($s);
}

if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
$fromEncoding = 'Windows-1252';
}
if ('UTF-8' !== $fromEncoding) {
$s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
}

return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
}

if ('HTML-ENTITIES' === $fromEncoding) {
$s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
$fromEncoding = 'UTF-8';
}

return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
}

public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
{
$vars = array(&$a, &$b, &$c, &$d, &$e, &$f);

$ok = true;
array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
$ok = false;
}
});

return $ok ? $fromEncoding : false;
}

public static function mb_decode_mimeheader($s)
{
return iconv_mime_decode($s, 2, self::$internalEncoding);
}

public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
{
trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
}

public static function mb_convert_case($s, $mode, $encoding = null)
{
if ('' === $s .= '') {
return '';
}

$encoding = self::getEncoding($encoding);

if ('UTF-8' === $encoding) {
$encoding = null;
} else {
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
}

if (MB_CASE_TITLE == $mode) {
$s = preg_replace_callback('/\b\p{Ll}/u', array(__CLASS__, 'title_case_upper'), $s);
$s = preg_replace_callback('/\B[\p{Lu}\p{Lt}]+/u', array(__CLASS__, 'title_case_lower'), $s);
} else {
if (MB_CASE_UPPER == $mode) {
static $upper = null;
if (null === $upper) {
$upper = self::getData('upperCase');
}
$map = $upper;
} else {
if (self::MB_CASE_FOLD === $mode) {
$s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
}

static $lower = null;
if (null === $lower) {
$lower = self::getData('lowerCase');
}
$map = $lower;
}

static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);

$i = 0;
$len = strlen($s);

while ($i < $len) {
$ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
$uchr = substr($s, $i, $ulen);
$i += $ulen;

if (isset($map[$uchr])) {
$uchr = $map[$uchr];
$nlen = strlen($uchr);

if ($nlen == $ulen) {
$nlen = $i;
do {
$s[--$nlen] = $uchr[--$ulen];
} while ($ulen);
} else {
$s = substr_replace($s, $uchr, $i - $ulen, $ulen);
$len += $nlen - $ulen;
$i += $nlen - $ulen;
}
}
}
}

if (null === $encoding) {
return $s;
}

return iconv('UTF-8', $encoding.'//IGNORE', $s);
}

public static function mb_internal_encoding($encoding = null)
{
if (null === $encoding) {
return self::$internalEncoding;
}

$encoding = self::getEncoding($encoding);

if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
self::$internalEncoding = $encoding;

return true;
}

return false;
}

public static function mb_language($lang = null)
{
if (null === $lang) {
return self::$language;
}

switch ($lang = strtolower($lang)) {
case 'uni':
case 'neutral':
self::$language = $lang;

return true;
}

return false;
}

public static function mb_list_encodings()
{
return array('UTF-8');
}

public static function mb_encoding_aliases($encoding)
{
switch (strtoupper($encoding)) {
case 'UTF8':
case 'UTF-8':
return array('utf8');
}

return false;
}

public static function mb_check_encoding($var = null, $encoding = null)
{
if (null === $encoding) {
if (null === $var) {
return false;
}
$encoding = self::$internalEncoding;
}

return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
}

public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
{
if (null === $encodingList) {
$encodingList = self::$encodingList;
} else {
if (!is_array($encodingList)) {
$encodingList = array_map('trim', explode(',', $encodingList));
}
$encodingList = array_map('strtoupper', $encodingList);
}

foreach ($encodingList as $enc) {
switch ($enc) {
case 'ASCII':
if (!preg_match('/[\x80-\xFF]/', $str)) {
return $enc;
}
break;

case 'UTF8':
case 'UTF-8':
if (preg_match('//u', $str)) {
return 'UTF-8';
}
break;

default:
if (0 === strncmp($enc, 'ISO-8859-', 9)) {
return $enc;
}
}
}

return false;
}

public static function mb_detect_order($encodingList = null)
{
if (null === $encodingList) {
return self::$encodingList;
}

if (!is_array($encodingList)) {
$encodingList = array_map('trim', explode(',', $encodingList));
}
$encodingList = array_map('strtoupper', $encodingList);

foreach ($encodingList as $enc) {
switch ($enc) {
default:
if (strncmp($enc, 'ISO-8859-', 9)) {
return false;
}
case 'ASCII':
case 'UTF8':
case 'UTF-8':
}
}

self::$encodingList = $encodingList;

return true;
}

public static function mb_strlen($s, $encoding = null)
{
switch ($encoding = self::getEncoding($encoding)) {
case 'ASCII':
case 'CP850':
return strlen($s);
}

return @iconv_strlen($s, $encoding);
}

public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
{
$encoding = self::getEncoding($encoding);

if ('' === $needle .= '') {
trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);

return false;
}

return iconv_strpos($haystack, $needle, $offset, $encoding);
}

public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
{
$encoding = self::getEncoding($encoding);

if ($offset != (int) $offset) {
$offset = 0;
} elseif ($offset = (int) $offset) {
if ($offset < 0) {
$haystack = self::mb_substr($haystack, 0, $offset, $encoding);
$offset = 0;
} else {
$haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
}
}

$pos = iconv_strrpos($haystack, $needle, $encoding);

return false !== $pos ? $offset + $pos : false;
}

public static function mb_strtolower($s, $encoding = null)
{
return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
}

public static function mb_strtoupper($s, $encoding = null)
{
return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
}

public static function mb_substitute_character($c = null)
{
if (0 === strcasecmp($c, 'none')) {
return true;
}

return null !== $c ? false : 'none';
}

public static function mb_substr($s, $start, $length = null, $encoding = null)
{
$encoding = self::getEncoding($encoding);

if ($start < 0) {
$start = iconv_strlen($s, $encoding) + $start;
if ($start < 0) {
$start = 0;
}
}

if (null === $length) {
$length = 2147483647;
} elseif ($length < 0) {
$length = iconv_strlen($s, $encoding) + $length - $start;
if ($length < 0) {
return '';
}
}

return iconv_substr($s, $start, $length, $encoding).'';
}

public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
{
$haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
$needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);

return self::mb_strpos($haystack, $needle, $offset, $encoding);
}

public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
{
$pos = self::mb_stripos($haystack, $needle, 0, $encoding);

return self::getSubpart($pos, $part, $haystack, $encoding);
}

public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
{
$encoding = self::getEncoding($encoding);
$needle = self::mb_substr($needle, 0, 1, $encoding);
$pos = iconv_strrpos($haystack, $needle, $encoding);

return self::getSubpart($pos, $part, $haystack, $encoding);
}

public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
{
$needle = self::mb_substr($needle, 0, 1, $encoding);
$pos = self::mb_strripos($haystack, $needle, $encoding);

return self::getSubpart($pos, $part, $haystack, $encoding);
}

public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
{
$haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
$needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);

return self::mb_strrpos($haystack, $needle, $offset, $encoding);
}

public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
{
$pos = strpos($haystack, $needle);
if (false === $pos) {
return false;
}
if ($part) {
return substr($haystack, 0, $pos);
}

return substr($haystack, $pos);
}

public static function mb_get_info($type = 'all')
{
$info = array(
'internal_encoding' => self::$internalEncoding,
'http_output' => 'pass',
'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
'func_overload' => 0,
'func_overload_list' => 'no overload',
'mail_charset' => 'UTF-8',
'mail_header_encoding' => 'BASE64',
'mail_body_encoding' => 'BASE64',
'illegal_chars' => 0,
'encoding_translation' => 'Off',
'language' => self::$language,
'detect_order' => self::$encodingList,
'substitute_character' => 'none',
'strict_detection' => 'Off',
);

if ('all' === $type) {
return $info;
}
if (isset($info[$type])) {
return $info[$type];
}

return false;
}

public static function mb_http_input($type = '')
{
return false;
}

public static function mb_http_output($encoding = null)
{
return null !== $encoding ? 'pass' === $encoding : 'pass';
}

public static function mb_strwidth($s, $encoding = null)
{
$encoding = self::getEncoding($encoding);

if ('UTF-8' !== $encoding) {
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
}

$s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);

return ($wide << 1) + iconv_strlen($s, 'UTF-8');
}

public static function mb_substr_count($haystack, $needle, $encoding = null)
{
return substr_count($haystack, $needle);
}

public static function mb_output_handler($contents, $status)
{
return $contents;
}

public static function mb_chr($code, $encoding = null)
{
if (0x80 > $code %= 0x200000) {
$s = chr($code);
} elseif (0x800 > $code) {
$s = chr(0xC0 | $code >> 6).chr(0x80 | $code & 0x3F);
} elseif (0x10000 > $code) {
$s = chr(0xE0 | $code >> 12).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F);
} else {
$s = chr(0xF0 | $code >> 18).chr(0x80 | $code >> 12 & 0x3F).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F);
}

if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
$s = mb_convert_encoding($s, $encoding, 'UTF-8');
}

return $s;
}

public static function mb_ord($s, $encoding = null)
{
if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
$s = mb_convert_encoding($s, 'UTF-8', $encoding);
}

$code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
if (0xF0 <= $code) {
return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
}
if (0xE0 <= $code) {
return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
}
if (0xC0 <= $code) {
return (($code - 0xC0) << 6) + $s[2] - 0x80;
}

return $code;
}

private static function getSubpart($pos, $part, $haystack, $encoding)
{
if (false === $pos) {
return false;
}
if ($part) {
return self::mb_substr($haystack, 0, $pos, $encoding);
}

return self::mb_substr($haystack, $pos, null, $encoding);
}

private static function html_encoding_callback($m)
{
$i = 1;
$entities = '';
$m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));

while (isset($m[$i])) {
if (0x80 > $m[$i]) {
$entities .= chr($m[$i++]);
continue;
}
if (0xF0 <= $m[$i]) {
$c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} elseif (0xE0 <= $m[$i]) {
$c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} else {
$c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
}

$entities .= '&#'.$c.';';
}

return $entities;
}

private static function title_case_lower($s)
{
return self::mb_convert_case($s[0], MB_CASE_LOWER, 'UTF-8');
}

private static function title_case_upper($s)
{
return self::mb_convert_case($s[0], MB_CASE_UPPER, 'UTF-8');
}

private static function getData($file)
{
if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
return require $file;
}

return false;
}

private static function getEncoding($encoding)
{
if (null === $encoding) {
return self::$internalEncoding;
}

$encoding = strtoupper($encoding);

if ('8BIT' === $encoding || 'BINARY' === $encoding) {
return 'CP850';
}
if ('UTF8' === $encoding) {
return 'UTF-8';
}

return $encoding;
}
}
<?php

static $data = array (
'a' => 'A',
'b' => 'B',
'c' => 'C',
'd' => 'D',
'e' => 'E',
'f' => 'F',
'g' => 'G',
'h' => 'H',
'i' => 'I',
'j' => 'J',
'k' => 'K',
'l' => 'L',
'm' => 'M',
'n' => 'N',
'o' => 'O',
'p' => 'P',
'q' => 'Q',
'r' => 'R',
's' => 'S',
't' => 'T',
'u' => 'U',
'v' => 'V',
'w' => 'W',
'x' => 'X',
'y' => 'Y',
'z' => 'Z',
'µ' => 'Μ',
'à' => 'À',
'á' => 'Á',
'â' => 'Â',
'ã' => 'Ã',
'ä' => 'Ä',
'å' => 'Å',
'æ' => 'Æ',
'ç' => 'Ç',
'è' => 'È',
'é' => 'É',
'ê' => 'Ê',
'ë' => 'Ë',
'ì' => 'Ì',
'í' => 'Í',
'î' => 'Î',
'ï' => 'Ï',
'ð' => 'Ð',
'ñ' => 'Ñ',
'ò' => 'Ò',
'ó' => 'Ó',
'ô' => 'Ô',
'õ' => 'Õ',
'ö' => 'Ö',
'ø' => 'Ø',
'ù' => 'Ù',
'ú' => 'Ú',
'û' => 'Û',
'ü' => 'Ü',
'ý' => 'Ý',
'þ' => 'Þ',
'ÿ' => 'Ÿ',
'ā' => 'Ā',
'ă' => 'Ă',
'ą' => 'Ą',
'ć' => 'Ć',
'ĉ' => 'Ĉ',
'ċ' => 'Ċ',
'č' => 'Č',
'ď' => 'Ď',
'đ' => 'Đ',
'ē' => 'Ē',
'ĕ' => 'Ĕ',
'ė' => 'Ė',
'ę' => 'Ę',
'ě' => 'Ě',
'ĝ' => 'Ĝ',
'ğ' => 'Ğ',
'ġ' => 'Ġ',
'ģ' => 'Ģ',
'ĥ' => 'Ĥ',
'ħ' => 'Ħ',
'ĩ' => 'Ĩ',
'ī' => 'Ī',
'ĭ' => 'Ĭ',
'į' => 'Į',
'ı' => 'I',
'ij' => 'IJ',
'ĵ' => 'Ĵ',
'ķ' => 'Ķ',
'ĺ' => 'Ĺ',
'ļ' => 'Ļ',
'ľ' => 'Ľ',
'ŀ' => 'Ŀ',
'ł' => 'Ł',
'ń' => 'Ń',
'ņ' => 'Ņ',
'ň' => 'Ň',
'ŋ' => 'Ŋ',
'ō' => 'Ō',
'ŏ' => 'Ŏ',
'ő' => 'Ő',
'œ' => 'Œ',
'ŕ' => 'Ŕ',
'ŗ' => 'Ŗ',
'ř' => 'Ř',
'ś' => 'Ś',
'ŝ' => 'Ŝ',
'ş' => 'Ş',
'š' => 'Š',
'ţ' => 'Ţ',
'ť' => 'Ť',
'ŧ' => 'Ŧ',
'ũ' => 'Ũ',
'ū' => 'Ū',
'ŭ' => 'Ŭ',
'ů' => 'Ů',
'ű' => 'Ű',
'ų' => 'Ų',
'ŵ' => 'Ŵ',
'ŷ' => 'Ŷ',
'ź' => 'Ź',
'ż' => 'Ż',
'ž' => 'Ž',
'ſ' => 'S',
'ƀ' => 'Ƀ',
'ƃ' => 'Ƃ',
'ƅ' => 'Ƅ',
'ƈ' => 'Ƈ',
'ƌ' => 'Ƌ',
'ƒ' => 'Ƒ',
'ƕ' => 'Ƕ',
'ƙ' => 'Ƙ',
'ƚ' => 'Ƚ',
'ƞ' => 'Ƞ',
'ơ' => 'Ơ',
'ƣ' => 'Ƣ',
'ƥ' => 'Ƥ',
'ƨ' => 'Ƨ',
'ƭ' => 'Ƭ',
'ư' => 'Ư',
'ƴ' => 'Ƴ',
'ƶ' => 'Ƶ',
'ƹ' => 'Ƹ',
'ƽ' => 'Ƽ',
'ƿ' => 'Ƿ',
'Dž' => 'DŽ',
'dž' => 'DŽ',
'Lj' => 'LJ',
'lj' => 'LJ',
'Nj' => 'NJ',
'nj' => 'NJ',
'ǎ' => 'Ǎ',
'ǐ' => 'Ǐ',
'ǒ' => 'Ǒ',
'ǔ' => 'Ǔ',
'ǖ' => 'Ǖ',
'ǘ' => 'Ǘ',
'ǚ' => 'Ǚ',
'ǜ' => 'Ǜ',
'ǝ' => 'Ǝ',
'ǟ' => 'Ǟ',
'ǡ' => 'Ǡ',
'ǣ' => 'Ǣ',
'ǥ' => 'Ǥ',
'ǧ' => 'Ǧ',
'ǩ' => 'Ǩ',
'ǫ' => 'Ǫ',
'ǭ' => 'Ǭ',
'ǯ' => 'Ǯ',
'Dz' => 'DZ',
'dz' => 'DZ',
'ǵ' => 'Ǵ',
'ǹ' => 'Ǹ',
'ǻ' => 'Ǻ',
'ǽ' => 'Ǽ',
'ǿ' => 'Ǿ',
'ȁ' => 'Ȁ',
'ȃ' => 'Ȃ',
'ȅ' => 'Ȅ',
'ȇ' => 'Ȇ',
'ȉ' => 'Ȉ',
'ȋ' => 'Ȋ',
'ȍ' => 'Ȍ',
'ȏ' => 'Ȏ',
'ȑ' => 'Ȑ',
'ȓ' => 'Ȓ',
'ȕ' => 'Ȕ',
'ȗ' => 'Ȗ',
'ș' => 'Ș',
'ț' => 'Ț',
'ȝ' => 'Ȝ',
'ȟ' => 'Ȟ',
'ȣ' => 'Ȣ',
'ȥ' => 'Ȥ',
'ȧ' => 'Ȧ',
'ȩ' => 'Ȩ',
'ȫ' => 'Ȫ',
'ȭ' => 'Ȭ',
'ȯ' => 'Ȯ',
'ȱ' => 'Ȱ',
'ȳ' => 'Ȳ',
'ȼ' => 'Ȼ',
'ȿ' => 'Ȿ',
'ɀ' => 'Ɀ',
'ɂ' => 'Ɂ',
'ɇ' => 'Ɇ',
'ɉ' => 'Ɉ',
'ɋ' => 'Ɋ',
'ɍ' => 'Ɍ',
'ɏ' => 'Ɏ',
'ɐ' => 'Ɐ',
'ɑ' => 'Ɑ',
'ɒ' => 'Ɒ',
'ɓ' => 'Ɓ',
'ɔ' => 'Ɔ',
'ɖ' => 'Ɖ',
'ɗ' => 'Ɗ',
'ə' => 'Ə',
'ɛ' => 'Ɛ',
'ɜ' => 'Ɜ',
'ɠ' => 'Ɠ',
'ɡ' => 'Ɡ',
'ɣ' => 'Ɣ',
'ɥ' => 'Ɥ',
'ɦ' => 'Ɦ',
'ɨ' => 'Ɨ',
'ɩ' => 'Ɩ',
'ɫ' => 'Ɫ',
'ɬ' => 'Ɬ',
'ɯ' => 'Ɯ',
'ɱ' => 'Ɱ',
'ɲ' => 'Ɲ',
'ɵ' => 'Ɵ',
'ɽ' => 'Ɽ',
'ʀ' => 'Ʀ',
'ʃ' => 'Ʃ',
'ʇ' => 'Ʇ',
'ʈ' => 'Ʈ',
'ʉ' => 'Ʉ',
'ʊ' => 'Ʊ',
'ʋ' => 'Ʋ',
'ʌ' => 'Ʌ',
'ʒ' => 'Ʒ',
'ʞ' => 'Ʞ',
'ͅ' => 'Ι',
'ͱ' => 'Ͱ',
'ͳ' => 'Ͳ',
'ͷ' => 'Ͷ',
'ͻ' => 'Ͻ',
'ͼ' => 'Ͼ',
'ͽ' => 'Ͽ',
'ά' => 'Ά',
'έ' => 'Έ',
'ή' => 'Ή',
'ί' => 'Ί',
'α' => 'Α',
'β' => 'Β',
'γ' => 'Γ',
'δ' => 'Δ',
'ε' => 'Ε',
'ζ' => 'Ζ',
'η' => 'Η',
'θ' => 'Θ',
'ι' => 'Ι',
'κ' => 'Κ',
'λ' => 'Λ',
'μ' => 'Μ',
'ν' => 'Ν',
'ξ' => 'Ξ',
'ο' => 'Ο',
'π' => 'Π',
'ρ' => 'Ρ',
'ς' => 'Σ',
'σ' => 'Σ',
'τ' => 'Τ',
'υ' => 'Υ',
'φ' => 'Φ',
'χ' => 'Χ',
'ψ' => 'Ψ',
'ω' => 'Ω',
'ϊ' => 'Ϊ',
'ϋ' => 'Ϋ',
'ό' => 'Ό',
'ύ' => 'Ύ',
'ώ' => 'Ώ',
'ϐ' => 'Β',
'ϑ' => 'Θ',
'ϕ' => 'Φ',
'ϖ' => 'Π',
'ϗ' => 'Ϗ',
'ϙ' => 'Ϙ',
'ϛ' => 'Ϛ',
'ϝ' => 'Ϝ',
'ϟ' => 'Ϟ',
'ϡ' => 'Ϡ',
'ϣ' => 'Ϣ',
'ϥ' => 'Ϥ',
'ϧ' => 'Ϧ',
'ϩ' => 'Ϩ',
'ϫ' => 'Ϫ',
'ϭ' => 'Ϭ',
'ϯ' => 'Ϯ',
'ϰ' => 'Κ',
'ϱ' => 'Ρ',
'ϲ' => 'Ϲ',
'ϳ' => 'Ϳ',
'ϵ' => 'Ε',
'ϸ' => 'Ϸ',
'ϻ' => 'Ϻ',
'а' => 'А',
'б' => 'Б',
'в' => 'В',
'г' => 'Г',
'д' => 'Д',
'е' => 'Е',
'ж' => 'Ж',
'з' => 'З',
'и' => 'И',
'й' => 'Й',
'к' => 'К',
'л' => 'Л',
'м' => 'М',
'н' => 'Н',
'о' => 'О',
'п' => 'П',
'р' => 'Р',
'с' => 'С',
'т' => 'Т',
'у' => 'У',
'ф' => 'Ф',
'х' => 'Х',
'ц' => 'Ц',
'ч' => 'Ч',
'ш' => 'Ш',
'щ' => 'Щ',
'ъ' => 'Ъ',
'ы' => 'Ы',
'ь' => 'Ь',
'э' => 'Э',
'ю' => 'Ю',
'я' => 'Я',
'ѐ' => 'Ѐ',
'ё' => 'Ё',
'ђ' => 'Ђ',
'ѓ' => 'Ѓ',
'є' => 'Є',
'ѕ' => 'Ѕ',
'і' => 'І',
'ї' => 'Ї',
'ј' => 'Ј',
'љ' => 'Љ',
'њ' => 'Њ',
'ћ' => 'Ћ',
'ќ' => 'Ќ',
'ѝ' => 'Ѝ',
'ў' => 'Ў',
'џ' => 'Џ',
'ѡ' => 'Ѡ',
'ѣ' => 'Ѣ',
'ѥ' => 'Ѥ',
'ѧ' => 'Ѧ',
'ѩ' => 'Ѩ',
'ѫ' => 'Ѫ',
'ѭ' => 'Ѭ',
'ѯ' => 'Ѯ',
'ѱ' => 'Ѱ',
'ѳ' => 'Ѳ',
'ѵ' => 'Ѵ',
'ѷ' => 'Ѷ',
'ѹ' => 'Ѹ',
'ѻ' => 'Ѻ',
'ѽ' => 'Ѽ',
'ѿ' => 'Ѿ',
'ҁ' => 'Ҁ',
'ҋ' => 'Ҋ',
'ҍ' => 'Ҍ',
'ҏ' => 'Ҏ',
'ґ' => 'Ґ',
'ғ' => 'Ғ',
'ҕ' => 'Ҕ',
'җ' => 'Җ',
'ҙ' => 'Ҙ',
'қ' => 'Қ',
'ҝ' => 'Ҝ',
'ҟ' => 'Ҟ',
'ҡ' => 'Ҡ',
'ң' => 'Ң',
'ҥ' => 'Ҥ',
'ҧ' => 'Ҧ',
'ҩ' => 'Ҩ',
'ҫ' => 'Ҫ',
'ҭ' => 'Ҭ',
'ү' => 'Ү',
'ұ' => 'Ұ',
'ҳ' => 'Ҳ',
'ҵ' => 'Ҵ',
'ҷ' => 'Ҷ',
'ҹ' => 'Ҹ',
'һ' => 'Һ',
'ҽ' => 'Ҽ',
'ҿ' => 'Ҿ',
'ӂ' => 'Ӂ',
'ӄ' => 'Ӄ',
'ӆ' => 'Ӆ',
'ӈ' => 'Ӈ',
'ӊ' => 'Ӊ',
'ӌ' => 'Ӌ',
'ӎ' => 'Ӎ',
'ӏ' => 'Ӏ',
'ӑ' => 'Ӑ',
'ӓ' => 'Ӓ',
'ӕ' => 'Ӕ',
'ӗ' => 'Ӗ',
'ә' => 'Ә',
'ӛ' => 'Ӛ',
'ӝ' => 'Ӝ',
'ӟ' => 'Ӟ',
'ӡ' => 'Ӡ',
'ӣ' => 'Ӣ',
'ӥ' => 'Ӥ',
'ӧ' => 'Ӧ',
'ө' => 'Ө',
'ӫ' => 'Ӫ',
'ӭ' => 'Ӭ',
'ӯ' => 'Ӯ',
'ӱ' => 'Ӱ',
'ӳ' => 'Ӳ',
'ӵ' => 'Ӵ',
'ӷ' => 'Ӷ',
'ӹ' => 'Ӹ',
'ӻ' => 'Ӻ',
'ӽ' => 'Ӽ',
'ӿ' => 'Ӿ',
'ԁ' => 'Ԁ',
'ԃ' => 'Ԃ',
'ԅ' => 'Ԅ',
'ԇ' => 'Ԇ',
'ԉ' => 'Ԉ',
'ԋ' => 'Ԋ',
'ԍ' => 'Ԍ',
'ԏ' => 'Ԏ',
'ԑ' => 'Ԑ',
'ԓ' => 'Ԓ',
'ԕ' => 'Ԕ',
'ԗ' => 'Ԗ',
'ԙ' => 'Ԙ',
'ԛ' => 'Ԛ',
'ԝ' => 'Ԝ',
'ԟ' => 'Ԟ',
'ԡ' => 'Ԡ',
'ԣ' => 'Ԣ',
'ԥ' => 'Ԥ',
'ԧ' => 'Ԧ',
'ԩ' => 'Ԩ',
'ԫ' => 'Ԫ',
'ԭ' => 'Ԭ',
'ԯ' => 'Ԯ',
'ա' => 'Ա',
'բ' => 'Բ',
'գ' => 'Գ',
'դ' => 'Դ',
'ե' => 'Ե',
'զ' => 'Զ',
'է' => 'Է',
'ը' => 'Ը',
'թ' => 'Թ',
'ժ' => 'Ժ',
'ի' => 'Ի',
'լ' => 'Լ',
'խ' => 'Խ',
'ծ' => 'Ծ',
'կ' => 'Կ',
'հ' => 'Հ',
'ձ' => 'Ձ',
'ղ' => 'Ղ',
'ճ' => 'Ճ',
'մ' => 'Մ',
'յ' => 'Յ',
'ն' => 'Ն',
'շ' => 'Շ',
'ո' => 'Ո',
'չ' => 'Չ',
'պ' => 'Պ',
'ջ' => 'Ջ',
'ռ' => 'Ռ',
'ս' => 'Ս',
'վ' => 'Վ',
'տ' => 'Տ',
'ր' => 'Ր',
'ց' => 'Ց',
'ւ' => 'Ւ',
'փ' => 'Փ',
'ք' => 'Ք',
'օ' => 'Օ',
'ֆ' => 'Ֆ',
'ᵹ' => 'Ᵹ',
'ᵽ' => 'Ᵽ',
'ḁ' => 'Ḁ',
'ḃ' => 'Ḃ',
'ḅ' => 'Ḅ',
'ḇ' => 'Ḇ',
'ḉ' => 'Ḉ',
'ḋ' => 'Ḋ',
'ḍ' => 'Ḍ',
'ḏ' => 'Ḏ',
'ḑ' => 'Ḑ',
'ḓ' => 'Ḓ',
'ḕ' => 'Ḕ',
'ḗ' => 'Ḗ',
'ḙ' => 'Ḙ',
'ḛ' => 'Ḛ',
'ḝ' => 'Ḝ',
'ḟ' => 'Ḟ',
'ḡ' => 'Ḡ',
'ḣ' => 'Ḣ',
'ḥ' => 'Ḥ',
'ḧ' => 'Ḧ',
'ḩ' => 'Ḩ',
'ḫ' => 'Ḫ',
'ḭ' => 'Ḭ',
'ḯ' => 'Ḯ',
'ḱ' => 'Ḱ',
'ḳ' => 'Ḳ',
'ḵ' => 'Ḵ',
'ḷ' => 'Ḷ',
'ḹ' => 'Ḹ',
'ḻ' => 'Ḻ',
'ḽ' => 'Ḽ',
'ḿ' => 'Ḿ',
'ṁ' => 'Ṁ',
'ṃ' => 'Ṃ',
'ṅ' => 'Ṅ',
'ṇ' => 'Ṇ',
'ṉ' => 'Ṉ',
'ṋ' => 'Ṋ',
'ṍ' => 'Ṍ',
'ṏ' => 'Ṏ',
'ṑ' => 'Ṑ',
'ṓ' => 'Ṓ',
'ṕ' => 'Ṕ',
'ṗ' => 'Ṗ',
'ṙ' => 'Ṙ',
'ṛ' => 'Ṛ',
'ṝ' => 'Ṝ',
'ṟ' => 'Ṟ',
'ṡ' => 'Ṡ',
'ṣ' => 'Ṣ',
'ṥ' => 'Ṥ',
'ṧ' => 'Ṧ',
'ṩ' => 'Ṩ',
'ṫ' => 'Ṫ',
'ṭ' => 'Ṭ',
'ṯ' => 'Ṯ',
'ṱ' => 'Ṱ',
'ṳ' => 'Ṳ',
'ṵ' => 'Ṵ',
'ṷ' => 'Ṷ',
'ṹ' => 'Ṹ',
'ṻ' => 'Ṻ',
'ṽ' => 'Ṽ',
'ṿ' => 'Ṿ',
'ẁ' => 'Ẁ',
'ẃ' => 'Ẃ',
'ẅ' => 'Ẅ',
'ẇ' => 'Ẇ',
'ẉ' => 'Ẉ',
'ẋ' => 'Ẋ',
'ẍ' => 'Ẍ',
'ẏ' => 'Ẏ',
'ẑ' => 'Ẑ',
'ẓ' => 'Ẓ',
'ẕ' => 'Ẕ',
'ẛ' => 'Ṡ',
'ạ' => 'Ạ',
'ả' => 'Ả',
'ấ' => 'Ấ',
'ầ' => 'Ầ',
'ẩ' => 'Ẩ',
'ẫ' => 'Ẫ',
'ậ' => 'Ậ',
'ắ' => 'Ắ',
'ằ' => 'Ằ',
'ẳ' => 'Ẳ',
'ẵ' => 'Ẵ',
'ặ' => 'Ặ',
'ẹ' => 'Ẹ',
'ẻ' => 'Ẻ',
'ẽ' => 'Ẽ',
'ế' => 'Ế',
'ề' => 'Ề',
'ể' => 'Ể',
'ễ' => 'Ễ',
'ệ' => 'Ệ',
'ỉ' => 'Ỉ',
'ị' => 'Ị',
'ọ' => 'Ọ',
'ỏ' => 'Ỏ',
'ố' => 'Ố',
'ồ' => 'Ồ',
'ổ' => 'Ổ',
'ỗ' => 'Ỗ',
'ộ' => 'Ộ',
'ớ' => 'Ớ',
'ờ' => 'Ờ',
'ở' => 'Ở',
'ỡ' => 'Ỡ',
'ợ' => 'Ợ',
'ụ' => 'Ụ',
'ủ' => 'Ủ',
'ứ' => 'Ứ',
'ừ' => 'Ừ',
'ử' => 'Ử',
'ữ' => 'Ữ',
'ự' => 'Ự',
'ỳ' => 'Ỳ',
'ỵ' => 'Ỵ',
'ỷ' => 'Ỷ',
'ỹ' => 'Ỹ',
'ỻ' => 'Ỻ',
'ỽ' => 'Ỽ',
'ỿ' => 'Ỿ',
'ἀ' => 'Ἀ',
'ἁ' => 'Ἁ',
'ἂ' => 'Ἂ',
'ἃ' => 'Ἃ',
'ἄ' => 'Ἄ',
'ἅ' => 'Ἅ',
'ἆ' => 'Ἆ',
'ἇ' => 'Ἇ',
'ἐ' => 'Ἐ',
'ἑ' => 'Ἑ',
'ἒ' => 'Ἒ',
'ἓ' => 'Ἓ',
'ἔ' => 'Ἔ',
'ἕ' => 'Ἕ',
'ἠ' => 'Ἠ',
'ἡ' => 'Ἡ',
'ἢ' => 'Ἢ',
'ἣ' => 'Ἣ',
'ἤ' => 'Ἤ',
'ἥ' => 'Ἥ',
'ἦ' => 'Ἦ',
'ἧ' => 'Ἧ',
'ἰ' => 'Ἰ',
'ἱ' => 'Ἱ',
'ἲ' => 'Ἲ',
'ἳ' => 'Ἳ',
'ἴ' => 'Ἴ',
'ἵ' => 'Ἵ',
'ἶ' => 'Ἶ',
'ἷ' => 'Ἷ',
'ὀ' => 'Ὀ',
'ὁ' => 'Ὁ',
'ὂ' => 'Ὂ',
'ὃ' => 'Ὃ',
'ὄ' => 'Ὄ',
'ὅ' => 'Ὅ',
'ὑ' => 'Ὑ',
'ὓ' => 'Ὓ',
'ὕ' => 'Ὕ',
'ὗ' => 'Ὗ',
'ὠ' => 'Ὠ',
'ὡ' => 'Ὡ',
'ὢ' => 'Ὢ',
'ὣ' => 'Ὣ',
'ὤ' => 'Ὤ',
'ὥ' => 'Ὥ',
'ὦ' => 'Ὦ',
'ὧ' => 'Ὧ',
'ὰ' => 'Ὰ',
'ά' => 'Ά',
'ὲ' => 'Ὲ',
'έ' => 'Έ',
'ὴ' => 'Ὴ',
'ή' => 'Ή',
'ὶ' => 'Ὶ',
'ί' => 'Ί',
'ὸ' => 'Ὸ',
'ό' => 'Ό',
'ὺ' => 'Ὺ',
'ύ' => 'Ύ',
'ὼ' => 'Ὼ',
'ώ' => 'Ώ',
'ᾀ' => 'ᾈ',
'ᾁ' => 'ᾉ',
'ᾂ' => 'ᾊ',
'ᾃ' => 'ᾋ',
'ᾄ' => 'ᾌ',
'ᾅ' => 'ᾍ',
'ᾆ' => 'ᾎ',
'ᾇ' => 'ᾏ',
'ᾐ' => 'ᾘ',
'ᾑ' => 'ᾙ',
'ᾒ' => 'ᾚ',
'ᾓ' => 'ᾛ',
'ᾔ' => 'ᾜ',
'ᾕ' => 'ᾝ',
'ᾖ' => 'ᾞ',
'ᾗ' => 'ᾟ',
'ᾠ' => 'ᾨ',
'ᾡ' => 'ᾩ',
'ᾢ' => 'ᾪ',
'ᾣ' => 'ᾫ',
'ᾤ' => 'ᾬ',
'ᾥ' => 'ᾭ',
'ᾦ' => 'ᾮ',
'ᾧ' => 'ᾯ',
'ᾰ' => 'Ᾰ',
'ᾱ' => 'Ᾱ',
'ᾳ' => 'ᾼ',
'ι' => 'Ι',
'ῃ' => 'ῌ',
'ῐ' => 'Ῐ',
'ῑ' => 'Ῑ',
'ῠ' => 'Ῠ',
'ῡ' => 'Ῡ',
'ῥ' => 'Ῥ',
'ῳ' => 'ῼ',
'ⅎ' => 'Ⅎ',
'ⅰ' => 'Ⅰ',
'ⅱ' => 'Ⅱ',
'ⅲ' => 'Ⅲ',
'ⅳ' => 'Ⅳ',
'ⅴ' => 'Ⅴ',
'ⅵ' => 'Ⅵ',
'ⅶ' => 'Ⅶ',
'ⅷ' => 'Ⅷ',
'ⅸ' => 'Ⅸ',
'ⅹ' => 'Ⅹ',
'ⅺ' => 'Ⅺ',
'ⅻ' => 'Ⅻ',
'ⅼ' => 'Ⅼ',
'ⅽ' => 'Ⅽ',
'ⅾ' => 'Ⅾ',
'ⅿ' => 'Ⅿ',
'ↄ' => 'Ↄ',
'ⓐ' => 'Ⓐ',
'ⓑ' => 'Ⓑ',
'ⓒ' => 'Ⓒ',
'ⓓ' => 'Ⓓ',
'ⓔ' => 'Ⓔ',
'ⓕ' => 'Ⓕ',
'ⓖ' => 'Ⓖ',
'ⓗ' => 'Ⓗ',
'ⓘ' => 'Ⓘ',
'ⓙ' => 'Ⓙ',
'ⓚ' => 'Ⓚ',
'ⓛ' => 'Ⓛ',
'ⓜ' => 'Ⓜ',
'ⓝ' => 'Ⓝ',
'ⓞ' => 'Ⓞ',
'ⓟ' => 'Ⓟ',
'ⓠ' => 'Ⓠ',
'ⓡ' => 'Ⓡ',
'ⓢ' => 'Ⓢ',
'ⓣ' => 'Ⓣ',
'ⓤ' => 'Ⓤ',
'ⓥ' => 'Ⓥ',
'ⓦ' => 'Ⓦ',
'ⓧ' => 'Ⓧ',
'ⓨ' => 'Ⓨ',
'ⓩ' => 'Ⓩ',
'ⰰ' => 'Ⰰ',
'ⰱ' => 'Ⰱ',
'ⰲ' => 'Ⰲ',
'ⰳ' => 'Ⰳ',
'ⰴ' => 'Ⰴ',
'ⰵ' => 'Ⰵ',
'ⰶ' => 'Ⰶ',
'ⰷ' => 'Ⰷ',
'ⰸ' => 'Ⰸ',
'ⰹ' => 'Ⰹ',
'ⰺ' => 'Ⰺ',
'ⰻ' => 'Ⰻ',
'ⰼ' => 'Ⰼ',
'ⰽ' => 'Ⰽ',
'ⰾ' => 'Ⰾ',
'ⰿ' => 'Ⰿ',
'ⱀ' => 'Ⱀ',
'ⱁ' => 'Ⱁ',
'ⱂ' => 'Ⱂ',
'ⱃ' => 'Ⱃ',
'ⱄ' => 'Ⱄ',
'ⱅ' => 'Ⱅ',
'ⱆ' => 'Ⱆ',
'ⱇ' => 'Ⱇ',
'ⱈ' => 'Ⱈ',
'ⱉ' => 'Ⱉ',
'ⱊ' => 'Ⱊ',
'ⱋ' => 'Ⱋ',
'ⱌ' => 'Ⱌ',
'ⱍ' => 'Ⱍ',
'ⱎ' => 'Ⱎ',
'ⱏ' => 'Ⱏ',
'ⱐ' => 'Ⱐ',
'ⱑ' => 'Ⱑ',
'ⱒ' => 'Ⱒ',
'ⱓ' => 'Ⱓ',
'ⱔ' => 'Ⱔ',
'ⱕ' => 'Ⱕ',
'ⱖ' => 'Ⱖ',
'ⱗ' => 'Ⱗ',
'ⱘ' => 'Ⱘ',
'ⱙ' => 'Ⱙ',
'ⱚ' => 'Ⱚ',
'ⱛ' => 'Ⱛ',
'ⱜ' => 'Ⱜ',
'ⱝ' => 'Ⱝ',
'ⱞ' => 'Ⱞ',
'ⱡ' => 'Ⱡ',
'ⱥ' => 'Ⱥ',
'ⱦ' => 'Ⱦ',
'ⱨ' => 'Ⱨ',
'ⱪ' => 'Ⱪ',
'ⱬ' => 'Ⱬ',
'ⱳ' => 'Ⱳ',
'ⱶ' => 'Ⱶ',
'ⲁ' => 'Ⲁ',
'ⲃ' => 'Ⲃ',
'ⲅ' => 'Ⲅ',
'ⲇ' => 'Ⲇ',
'ⲉ' => 'Ⲉ',
'ⲋ' => 'Ⲋ',
'ⲍ' => 'Ⲍ',
'ⲏ' => 'Ⲏ',
'ⲑ' => 'Ⲑ',
'ⲓ' => 'Ⲓ',
'ⲕ' => 'Ⲕ',
'ⲗ' => 'Ⲗ',
'ⲙ' => 'Ⲙ',
'ⲛ' => 'Ⲛ',
'ⲝ' => 'Ⲝ',
'ⲟ' => 'Ⲟ',
'ⲡ' => 'Ⲡ',
'ⲣ' => 'Ⲣ',
'ⲥ' => 'Ⲥ',
'ⲧ' => 'Ⲧ',
'ⲩ' => 'Ⲩ',
'ⲫ' => 'Ⲫ',
'ⲭ' => 'Ⲭ',
'ⲯ' => 'Ⲯ',
'ⲱ' => 'Ⲱ',
'ⲳ' => 'Ⲳ',
'ⲵ' => 'Ⲵ',
'ⲷ' => 'Ⲷ',
'ⲹ' => 'Ⲹ',
'ⲻ' => 'Ⲻ',
'ⲽ' => 'Ⲽ',
'ⲿ' => 'Ⲿ',
'ⳁ' => 'Ⳁ',
'ⳃ' => 'Ⳃ',
'ⳅ' => 'Ⳅ',
'ⳇ' => 'Ⳇ',
'ⳉ' => 'Ⳉ',
'ⳋ' => 'Ⳋ',
'ⳍ' => 'Ⳍ',
'ⳏ' => 'Ⳏ',
'ⳑ' => 'Ⳑ',
'ⳓ' => 'Ⳓ',
'ⳕ' => 'Ⳕ',
'ⳗ' => 'Ⳗ',
'ⳙ' => 'Ⳙ',
'ⳛ' => 'Ⳛ',
'ⳝ' => 'Ⳝ',
'ⳟ' => 'Ⳟ',
'ⳡ' => 'Ⳡ',
'ⳣ' => 'Ⳣ',
'ⳬ' => 'Ⳬ',
'ⳮ' => 'Ⳮ',
'ⳳ' => 'Ⳳ',
'ⴀ' => 'Ⴀ',
'ⴁ' => 'Ⴁ',
'ⴂ' => 'Ⴂ',
'ⴃ' => 'Ⴃ',
'ⴄ' => 'Ⴄ',
'ⴅ' => 'Ⴅ',
'ⴆ' => 'Ⴆ',
'ⴇ' => 'Ⴇ',
'ⴈ' => 'Ⴈ',
'ⴉ' => 'Ⴉ',
'ⴊ' => 'Ⴊ',
'ⴋ' => 'Ⴋ',
'ⴌ' => 'Ⴌ',
'ⴍ' => 'Ⴍ',
'ⴎ' => 'Ⴎ',
'ⴏ' => 'Ⴏ',
'ⴐ' => 'Ⴐ',
'ⴑ' => 'Ⴑ',
'ⴒ' => 'Ⴒ',
'ⴓ' => 'Ⴓ',
'ⴔ' => 'Ⴔ',
'ⴕ' => 'Ⴕ',
'ⴖ' => 'Ⴖ',
'ⴗ' => 'Ⴗ',
'ⴘ' => 'Ⴘ',
'ⴙ' => 'Ⴙ',
'ⴚ' => 'Ⴚ',
'ⴛ' => 'Ⴛ',
'ⴜ' => 'Ⴜ',
'ⴝ' => 'Ⴝ',
'ⴞ' => 'Ⴞ',
'ⴟ' => 'Ⴟ',
'ⴠ' => 'Ⴠ',
'ⴡ' => 'Ⴡ',
'ⴢ' => 'Ⴢ',
'ⴣ' => 'Ⴣ',
'ⴤ' => 'Ⴤ',
'ⴥ' => 'Ⴥ',
'ⴧ' => 'Ⴧ',
'ⴭ' => 'Ⴭ',
'ꙁ' => 'Ꙁ',
'ꙃ' => 'Ꙃ',
'ꙅ' => 'Ꙅ',
'ꙇ' => 'Ꙇ',
'ꙉ' => 'Ꙉ',
'ꙋ' => 'Ꙋ',
'ꙍ' => 'Ꙍ',
'ꙏ' => 'Ꙏ',
'ꙑ' => 'Ꙑ',
'ꙓ' => 'Ꙓ',
'ꙕ' => 'Ꙕ',
'ꙗ' => 'Ꙗ',
'ꙙ' => 'Ꙙ',
'ꙛ' => 'Ꙛ',
'ꙝ' => 'Ꙝ',
'ꙟ' => 'Ꙟ',
'ꙡ' => 'Ꙡ',
'ꙣ' => 'Ꙣ',
'ꙥ' => 'Ꙥ',
'ꙧ' => 'Ꙧ',
'ꙩ' => 'Ꙩ',
'ꙫ' => 'Ꙫ',
'ꙭ' => 'Ꙭ',
'ꚁ' => 'Ꚁ',
'ꚃ' => 'Ꚃ',
'ꚅ' => 'Ꚅ',
'ꚇ' => 'Ꚇ',
'ꚉ' => 'Ꚉ',
'ꚋ' => 'Ꚋ',
'ꚍ' => 'Ꚍ',
'ꚏ' => 'Ꚏ',
'ꚑ' => 'Ꚑ',
'ꚓ' => 'Ꚓ',
'ꚕ' => 'Ꚕ',
'ꚗ' => 'Ꚗ',
'ꚙ' => 'Ꚙ',
'ꚛ' => 'Ꚛ',
'ꜣ' => 'Ꜣ',
'ꜥ' => 'Ꜥ',
'ꜧ' => 'Ꜧ',
'ꜩ' => 'Ꜩ',
'ꜫ' => 'Ꜫ',
'ꜭ' => 'Ꜭ',
'ꜯ' => 'Ꜯ',
'ꜳ' => 'Ꜳ',
'ꜵ' => 'Ꜵ',
'ꜷ' => 'Ꜷ',
'ꜹ' => 'Ꜹ',
'ꜻ' => 'Ꜻ',
'ꜽ' => 'Ꜽ',
'ꜿ' => 'Ꜿ',
'ꝁ' => 'Ꝁ',
'ꝃ' => 'Ꝃ',
'ꝅ' => 'Ꝅ',
'ꝇ' => 'Ꝇ',
'ꝉ' => 'Ꝉ',
'ꝋ' => 'Ꝋ',
'ꝍ' => 'Ꝍ',
'ꝏ' => 'Ꝏ',
'ꝑ' => 'Ꝑ',
'ꝓ' => 'Ꝓ',
'ꝕ' => 'Ꝕ',
'ꝗ' => 'Ꝗ',
'ꝙ' => 'Ꝙ',
'ꝛ' => 'Ꝛ',
'ꝝ' => 'Ꝝ',
'ꝟ' => 'Ꝟ',
'ꝡ' => 'Ꝡ',
'ꝣ' => 'Ꝣ',
'ꝥ' => 'Ꝥ',
'ꝧ' => 'Ꝧ',
'ꝩ' => 'Ꝩ',
'ꝫ' => 'Ꝫ',
'ꝭ' => 'Ꝭ',
'ꝯ' => 'Ꝯ',
'ꝺ' => 'Ꝺ',
'ꝼ' => 'Ꝼ',
'ꝿ' => 'Ꝿ',
'ꞁ' => 'Ꞁ',
'ꞃ' => 'Ꞃ',
'ꞅ' => 'Ꞅ',
'ꞇ' => 'Ꞇ',
'ꞌ' => 'Ꞌ',
'ꞑ' => 'Ꞑ',
'ꞓ' => 'Ꞓ',
'ꞗ' => 'Ꞗ',
'ꞙ' => 'Ꞙ',
'ꞛ' => 'Ꞛ',
'ꞝ' => 'Ꞝ',
'ꞟ' => 'Ꞟ',
'ꞡ' => 'Ꞡ',
'ꞣ' => 'Ꞣ',
'ꞥ' => 'Ꞥ',
'ꞧ' => 'Ꞧ',
'ꞩ' => 'Ꞩ',
'a' => 'A',
'b' => 'B',
'c' => 'C',
'd' => 'D',
'e' => 'E',
'f' => 'F',
'g' => 'G',
'h' => 'H',
'i' => 'I',
'j' => 'J',
'k' => 'K',
'l' => 'L',
'm' => 'M',
'n' => 'N',
'o' => 'O',
'p' => 'P',
'q' => 'Q',
'r' => 'R',
's' => 'S',
't' => 'T',
'u' => 'U',
'v' => 'V',
'w' => 'W',
'x' => 'X',
'y' => 'Y',
'z' => 'Z',
'𐐨' => '𐐀',
'𐐩' => '𐐁',
'𐐪' => '𐐂',
'𐐫' => '𐐃',
'𐐬' => '𐐄',
'𐐭' => '𐐅',
'𐐮' => '𐐆',
'𐐯' => '𐐇',
'𐐰' => '𐐈',
'𐐱' => '𐐉',
'𐐲' => '𐐊',
'𐐳' => '𐐋',
'𐐴' => '𐐌',
'𐐵' => '𐐍',
'𐐶' => '𐐎',
'𐐷' => '𐐏',
'𐐸' => '𐐐',
'𐐹' => '𐐑',
'𐐺' => '𐐒',
'𐐻' => '𐐓',
'𐐼' => '𐐔',
'𐐽' => '𐐕',
'𐐾' => '𐐖',
'𐐿' => '𐐗',
'𐑀' => '𐐘',
'𐑁' => '𐐙',
'𐑂' => '𐐚',
'𐑃' => '𐐛',
'𐑄' => '𐐜',
'𐑅' => '𐐝',
'𐑆' => '𐐞',
'𐑇' => '𐐟',
'𐑈' => '𐐠',
'𐑉' => '𐐡',
'𐑊' => '𐐢',
'𐑋' => '𐐣',
'𐑌' => '𐐤',
'𐑍' => '𐐥',
'𐑎' => '𐐦',
'𐑏' => '𐐧',
'𑣀' => '𑢠',
'𑣁' => '𑢡',
'𑣂' => '𑢢',
'𑣃' => '𑢣',
'𑣄' => '𑢤',
'𑣅' => '𑢥',
'𑣆' => '𑢦',
'𑣇' => '𑢧',
'𑣈' => '𑢨',
'𑣉' => '𑢩',
'𑣊' => '𑢪',
'𑣋' => '𑢫',
'𑣌' => '𑢬',
'𑣍' => '𑢭',
'𑣎' => '𑢮',
'𑣏' => '𑢯',
'𑣐' => '𑢰',
'𑣑' => '𑢱',
'𑣒' => '𑢲',
'𑣓' => '𑢳',
'𑣔' => '𑢴',
'𑣕' => '𑢵',
'𑣖' => '𑢶',
'𑣗' => '𑢷',
'𑣘' => '𑢸',
'𑣙' => '𑢹',
'𑣚' => '𑢺',
'𑣛' => '𑢻',
'𑣜' => '𑢼',
'𑣝' => '𑢽',
'𑣞' => '𑢾',
'𑣟' => '𑢿',
);

$result =& $data;
unset($data);

return $result;
<?php

static $data = array (
'A' => 'a',
'B' => 'b',
'C' => 'c',
'D' => 'd',
'E' => 'e',
'F' => 'f',
'G' => 'g',
'H' => 'h',
'I' => 'i',
'J' => 'j',
'K' => 'k',
'L' => 'l',
'M' => 'm',
'N' => 'n',
'O' => 'o',
'P' => 'p',
'Q' => 'q',
'R' => 'r',
'S' => 's',
'T' => 't',
'U' => 'u',
'V' => 'v',
'W' => 'w',
'X' => 'x',
'Y' => 'y',
'Z' => 'z',
'À' => 'à',
'Á' => 'á',
'Â' => 'â',
'Ã' => 'ã',
'Ä' => 'ä',
'Å' => 'å',
'Æ' => 'æ',
'Ç' => 'ç',
'È' => 'è',
'É' => 'é',
'Ê' => 'ê',
'Ë' => 'ë',
'Ì' => 'ì',
'Í' => 'í',
'Î' => 'î',
'Ï' => 'ï',
'Ð' => 'ð',
'Ñ' => 'ñ',
'Ò' => 'ò',
'Ó' => 'ó',
'Ô' => 'ô',
'Õ' => 'õ',
'Ö' => 'ö',
'Ø' => 'ø',
'Ù' => 'ù',
'Ú' => 'ú',
'Û' => 'û',
'Ü' => 'ü',
'Ý' => 'ý',
'Þ' => 'þ',
'Ā' => 'ā',
'Ă' => 'ă',
'Ą' => 'ą',
'Ć' => 'ć',
'Ĉ' => 'ĉ',
'Ċ' => 'ċ',
'Č' => 'č',
'Ď' => 'ď',
'Đ' => 'đ',
'Ē' => 'ē',
'Ĕ' => 'ĕ',
'Ė' => 'ė',
'Ę' => 'ę',
'Ě' => 'ě',
'Ĝ' => 'ĝ',
'Ğ' => 'ğ',
'Ġ' => 'ġ',
'Ģ' => 'ģ',
'Ĥ' => 'ĥ',
'Ħ' => 'ħ',
'Ĩ' => 'ĩ',
'Ī' => 'ī',
'Ĭ' => 'ĭ',
'Į' => 'į',
'İ' => 'i',
'IJ' => 'ij',
'Ĵ' => 'ĵ',
'Ķ' => 'ķ',
'Ĺ' => 'ĺ',
'Ļ' => 'ļ',
'Ľ' => 'ľ',
'Ŀ' => 'ŀ',
'Ł' => 'ł',
'Ń' => 'ń',
'Ņ' => 'ņ',
'Ň' => 'ň',
'Ŋ' => 'ŋ',
'Ō' => 'ō',
'Ŏ' => 'ŏ',
'Ő' => 'ő',
'Œ' => 'œ',
'Ŕ' => 'ŕ',
'Ŗ' => 'ŗ',
'Ř' => 'ř',
'Ś' => 'ś',
'Ŝ' => 'ŝ',
'Ş' => 'ş',
'Š' => 'š',
'Ţ' => 'ţ',
'Ť' => 'ť',
'Ŧ' => 'ŧ',
'Ũ' => 'ũ',
'Ū' => 'ū',
'Ŭ' => 'ŭ',
'Ů' => 'ů',
'Ű' => 'ű',
'Ų' => 'ų',
'Ŵ' => 'ŵ',
'Ŷ' => 'ŷ',
'Ÿ' => 'ÿ',
'Ź' => 'ź',
'Ż' => 'ż',
'Ž' => 'ž',
'Ɓ' => 'ɓ',
'Ƃ' => 'ƃ',
'Ƅ' => 'ƅ',
'Ɔ' => 'ɔ',
'Ƈ' => 'ƈ',
'Ɖ' => 'ɖ',
'Ɗ' => 'ɗ',
'Ƌ' => 'ƌ',
'Ǝ' => 'ǝ',
'Ə' => 'ə',
'Ɛ' => 'ɛ',
'Ƒ' => 'ƒ',
'Ɠ' => 'ɠ',
'Ɣ' => 'ɣ',
'Ɩ' => 'ɩ',
'Ɨ' => 'ɨ',
'Ƙ' => 'ƙ',
'Ɯ' => 'ɯ',
'Ɲ' => 'ɲ',
'Ɵ' => 'ɵ',
'Ơ' => 'ơ',
'Ƣ' => 'ƣ',
'Ƥ' => 'ƥ',
'Ʀ' => 'ʀ',
'Ƨ' => 'ƨ',
'Ʃ' => 'ʃ',
'Ƭ' => 'ƭ',
'Ʈ' => 'ʈ',
'Ư' => 'ư',
'Ʊ' => 'ʊ',
'Ʋ' => 'ʋ',
'Ƴ' => 'ƴ',
'Ƶ' => 'ƶ',
'Ʒ' => 'ʒ',
'Ƹ' => 'ƹ',
'Ƽ' => 'ƽ',
'DŽ' => 'dž',
'Dž' => 'dž',
'LJ' => 'lj',
'Lj' => 'lj',
'NJ' => 'nj',
'Nj' => 'nj',
'Ǎ' => 'ǎ',
'Ǐ' => 'ǐ',
'Ǒ' => 'ǒ',
'Ǔ' => 'ǔ',
'Ǖ' => 'ǖ',
'Ǘ' => 'ǘ',
'Ǚ' => 'ǚ',
'Ǜ' => 'ǜ',
'Ǟ' => 'ǟ',
'Ǡ' => 'ǡ',
'Ǣ' => 'ǣ',
'Ǥ' => 'ǥ',
'Ǧ' => 'ǧ',
'Ǩ' => 'ǩ',
'Ǫ' => 'ǫ',
'Ǭ' => 'ǭ',
'Ǯ' => 'ǯ',
'DZ' => 'dz',
'Dz' => 'dz',
'Ǵ' => 'ǵ',
'Ƕ' => 'ƕ',
'Ƿ' => 'ƿ',
'Ǹ' => 'ǹ',
'Ǻ' => 'ǻ',
'Ǽ' => 'ǽ',
'Ǿ' => 'ǿ',
'Ȁ' => 'ȁ',
'Ȃ' => 'ȃ',
'Ȅ' => 'ȅ',
'Ȇ' => 'ȇ',
'Ȉ' => 'ȉ',
'Ȋ' => 'ȋ',
'Ȍ' => 'ȍ',
'Ȏ' => 'ȏ',
'Ȑ' => 'ȑ',
'Ȓ' => 'ȓ',
'Ȕ' => 'ȕ',
'Ȗ' => 'ȗ',
'Ș' => 'ș',
'Ț' => 'ț',
'Ȝ' => 'ȝ',
'Ȟ' => 'ȟ',
'Ƞ' => 'ƞ',
'Ȣ' => 'ȣ',
'Ȥ' => 'ȥ',
'Ȧ' => 'ȧ',
'Ȩ' => 'ȩ',
'Ȫ' => 'ȫ',
'Ȭ' => 'ȭ',
'Ȯ' => 'ȯ',
'Ȱ' => 'ȱ',
'Ȳ' => 'ȳ',
'Ⱥ' => 'ⱥ',
'Ȼ' => 'ȼ',
'Ƚ' => 'ƚ',
'Ⱦ' => 'ⱦ',
'Ɂ' => 'ɂ',
'Ƀ' => 'ƀ',
'Ʉ' => 'ʉ',
'Ʌ' => 'ʌ',
'Ɇ' => 'ɇ',
'Ɉ' => 'ɉ',
'Ɋ' => 'ɋ',
'Ɍ' => 'ɍ',
'Ɏ' => 'ɏ',
'Ͱ' => 'ͱ',
'Ͳ' => 'ͳ',
'Ͷ' => 'ͷ',
'Ϳ' => 'ϳ',
'Ά' => 'ά',
'Έ' => 'έ',
'Ή' => 'ή',
'Ί' => 'ί',
'Ό' => 'ό',
'Ύ' => 'ύ',
'Ώ' => 'ώ',
'Α' => 'α',
'Β' => 'β',
'Γ' => 'γ',
'Δ' => 'δ',
'Ε' => 'ε',
'Ζ' => 'ζ',
'Η' => 'η',
'Θ' => 'θ',
'Ι' => 'ι',
'Κ' => 'κ',
'Λ' => 'λ',
'Μ' => 'μ',
'Ν' => 'ν',
'Ξ' => 'ξ',
'Ο' => 'ο',
'Π' => 'π',
'Ρ' => 'ρ',
'Σ' => 'σ',
'Τ' => 'τ',
'Υ' => 'υ',
'Φ' => 'φ',
'Χ' => 'χ',
'Ψ' => 'ψ',
'Ω' => 'ω',
'Ϊ' => 'ϊ',
'Ϋ' => 'ϋ',
'Ϗ' => 'ϗ',
'Ϙ' => 'ϙ',
'Ϛ' => 'ϛ',
'Ϝ' => 'ϝ',
'Ϟ' => 'ϟ',
'Ϡ' => 'ϡ',
'Ϣ' => 'ϣ',
'Ϥ' => 'ϥ',
'Ϧ' => 'ϧ',
'Ϩ' => 'ϩ',
'Ϫ' => 'ϫ',
'Ϭ' => 'ϭ',
'Ϯ' => 'ϯ',
'ϴ' => 'θ',
'Ϸ' => 'ϸ',
'Ϲ' => 'ϲ',
'Ϻ' => 'ϻ',
'Ͻ' => 'ͻ',
'Ͼ' => 'ͼ',
'Ͽ' => 'ͽ',
'Ѐ' => 'ѐ',
'Ё' => 'ё',
'Ђ' => 'ђ',
'Ѓ' => 'ѓ',
'Є' => 'є',
'Ѕ' => 'ѕ',
'І' => 'і',
'Ї' => 'ї',
'Ј' => 'ј',
'Љ' => 'љ',
'Њ' => 'њ',
'Ћ' => 'ћ',
'Ќ' => 'ќ',
'Ѝ' => 'ѝ',
'Ў' => 'ў',
'Џ' => 'џ',
'А' => 'а',
'Б' => 'б',
'В' => 'в',
'Г' => 'г',
'Д' => 'д',
'Е' => 'е',
'Ж' => 'ж',
'З' => 'з',
'И' => 'и',
'Й' => 'й',
'К' => 'к',
'Л' => 'л',
'М' => 'м',
'Н' => 'н',
'О' => 'о',
'П' => 'п',
'Р' => 'р',
'С' => 'с',
'Т' => 'т',
'У' => 'у',
'Ф' => 'ф',
'Х' => 'х',
'Ц' => 'ц',
'Ч' => 'ч',
'Ш' => 'ш',
'Щ' => 'щ',
'Ъ' => 'ъ',
'Ы' => 'ы',
'Ь' => 'ь',
'Э' => 'э',
'Ю' => 'ю',
'Я' => 'я',
'Ѡ' => 'ѡ',
'Ѣ' => 'ѣ',
'Ѥ' => 'ѥ',
'Ѧ' => 'ѧ',
'Ѩ' => 'ѩ',
'Ѫ' => 'ѫ',
'Ѭ' => 'ѭ',
'Ѯ' => 'ѯ',
'Ѱ' => 'ѱ',
'Ѳ' => 'ѳ',
'Ѵ' => 'ѵ',
'Ѷ' => 'ѷ',
'Ѹ' => 'ѹ',
'Ѻ' => 'ѻ',
'Ѽ' => 'ѽ',
'Ѿ' => 'ѿ',
'Ҁ' => 'ҁ',
'Ҋ' => 'ҋ',
'Ҍ' => 'ҍ',
'Ҏ' => 'ҏ',
'Ґ' => 'ґ',
'Ғ' => 'ғ',
'Ҕ' => 'ҕ',
'Җ' => 'җ',
'Ҙ' => 'ҙ',
'Қ' => 'қ',
'Ҝ' => 'ҝ',
'Ҟ' => 'ҟ',
'Ҡ' => 'ҡ',
'Ң' => 'ң',
'Ҥ' => 'ҥ',
'Ҧ' => 'ҧ',
'Ҩ' => 'ҩ',
'Ҫ' => 'ҫ',
'Ҭ' => 'ҭ',
'Ү' => 'ү',
'Ұ' => 'ұ',
'Ҳ' => 'ҳ',
'Ҵ' => 'ҵ',
'Ҷ' => 'ҷ',
'Ҹ' => 'ҹ',
'Һ' => 'һ',
'Ҽ' => 'ҽ',
'Ҿ' => 'ҿ',
'Ӏ' => 'ӏ',
'Ӂ' => 'ӂ',
'Ӄ' => 'ӄ',
'Ӆ' => 'ӆ',
'Ӈ' => 'ӈ',
'Ӊ' => 'ӊ',
'Ӌ' => 'ӌ',
'Ӎ' => 'ӎ',
'Ӑ' => 'ӑ',
'Ӓ' => 'ӓ',
'Ӕ' => 'ӕ',
'Ӗ' => 'ӗ',
'Ә' => 'ә',
'Ӛ' => 'ӛ',
'Ӝ' => 'ӝ',
'Ӟ' => 'ӟ',
'Ӡ' => 'ӡ',
'Ӣ' => 'ӣ',
'Ӥ' => 'ӥ',
'Ӧ' => 'ӧ',
'Ө' => 'ө',
'Ӫ' => 'ӫ',
'Ӭ' => 'ӭ',
'Ӯ' => 'ӯ',
'Ӱ' => 'ӱ',
'Ӳ' => 'ӳ',
'Ӵ' => 'ӵ',
'Ӷ' => 'ӷ',
'Ӹ' => 'ӹ',
'Ӻ' => 'ӻ',
'Ӽ' => 'ӽ',
'Ӿ' => 'ӿ',
'Ԁ' => 'ԁ',
'Ԃ' => 'ԃ',
'Ԅ' => 'ԅ',
'Ԇ' => 'ԇ',
'Ԉ' => 'ԉ',
'Ԋ' => 'ԋ',
'Ԍ' => 'ԍ',
'Ԏ' => 'ԏ',
'Ԑ' => 'ԑ',
'Ԓ' => 'ԓ',
'Ԕ' => 'ԕ',
'Ԗ' => 'ԗ',
'Ԙ' => 'ԙ',
'Ԛ' => 'ԛ',
'Ԝ' => 'ԝ',
'Ԟ' => 'ԟ',
'Ԡ' => 'ԡ',
'Ԣ' => 'ԣ',
'Ԥ' => 'ԥ',
'Ԧ' => 'ԧ',
'Ԩ' => 'ԩ',
'Ԫ' => 'ԫ',
'Ԭ' => 'ԭ',
'Ԯ' => 'ԯ',
'Ա' => 'ա',
'Բ' => 'բ',
'Գ' => 'գ',
'Դ' => 'դ',
'Ե' => 'ե',
'Զ' => 'զ',
'Է' => 'է',
'Ը' => 'ը',
'Թ' => 'թ',
'Ժ' => 'ժ',
'Ի' => 'ի',
'Լ' => 'լ',
'Խ' => 'խ',
'Ծ' => 'ծ',
'Կ' => 'կ',
'Հ' => 'հ',
'Ձ' => 'ձ',
'Ղ' => 'ղ',
'Ճ' => 'ճ',
'Մ' => 'մ',
'Յ' => 'յ',
'Ն' => 'ն',
'Շ' => 'շ',
'Ո' => 'ո',
'Չ' => 'չ',
'Պ' => 'պ',
'Ջ' => 'ջ',
'Ռ' => 'ռ',
'Ս' => 'ս',
'Վ' => 'վ',
'Տ' => 'տ',
'Ր' => 'ր',
'Ց' => 'ց',
'Ւ' => 'ւ',
'Փ' => 'փ',
'Ք' => 'ք',
'Օ' => 'օ',
'Ֆ' => 'ֆ',
'Ⴀ' => 'ⴀ',
'Ⴁ' => 'ⴁ',
'Ⴂ' => 'ⴂ',
'Ⴃ' => 'ⴃ',
'Ⴄ' => 'ⴄ',
'Ⴅ' => 'ⴅ',
'Ⴆ' => 'ⴆ',
'Ⴇ' => 'ⴇ',
'Ⴈ' => 'ⴈ',
'Ⴉ' => 'ⴉ',
'Ⴊ' => 'ⴊ',
'Ⴋ' => 'ⴋ',
'Ⴌ' => 'ⴌ',
'Ⴍ' => 'ⴍ',
'Ⴎ' => 'ⴎ',
'Ⴏ' => 'ⴏ',
'Ⴐ' => 'ⴐ',
'Ⴑ' => 'ⴑ',
'Ⴒ' => 'ⴒ',
'Ⴓ' => 'ⴓ',
'Ⴔ' => 'ⴔ',
'Ⴕ' => 'ⴕ',
'Ⴖ' => 'ⴖ',
'Ⴗ' => 'ⴗ',
'Ⴘ' => 'ⴘ',
'Ⴙ' => 'ⴙ',
'Ⴚ' => 'ⴚ',
'Ⴛ' => 'ⴛ',
'Ⴜ' => 'ⴜ',
'Ⴝ' => 'ⴝ',
'Ⴞ' => 'ⴞ',
'Ⴟ' => 'ⴟ',
'Ⴠ' => 'ⴠ',
'Ⴡ' => 'ⴡ',
'Ⴢ' => 'ⴢ',
'Ⴣ' => 'ⴣ',
'Ⴤ' => 'ⴤ',
'Ⴥ' => 'ⴥ',
'Ⴧ' => 'ⴧ',
'Ⴭ' => 'ⴭ',
'Ḁ' => 'ḁ',
'Ḃ' => 'ḃ',
'Ḅ' => 'ḅ',
'Ḇ' => 'ḇ',
'Ḉ' => 'ḉ',
'Ḋ' => 'ḋ',
'Ḍ' => 'ḍ',
'Ḏ' => 'ḏ',
'Ḑ' => 'ḑ',
'Ḓ' => 'ḓ',
'Ḕ' => 'ḕ',
'Ḗ' => 'ḗ',
'Ḙ' => 'ḙ',
'Ḛ' => 'ḛ',
'Ḝ' => 'ḝ',
'Ḟ' => 'ḟ',
'Ḡ' => 'ḡ',
'Ḣ' => 'ḣ',
'Ḥ' => 'ḥ',
'Ḧ' => 'ḧ',
'Ḩ' => 'ḩ',
'Ḫ' => 'ḫ',
'Ḭ' => 'ḭ',
'Ḯ' => 'ḯ',
'Ḱ' => 'ḱ',
'Ḳ' => 'ḳ',
'Ḵ' => 'ḵ',
'Ḷ' => 'ḷ',
'Ḹ' => 'ḹ',
'Ḻ' => 'ḻ',
'Ḽ' => 'ḽ',
'Ḿ' => 'ḿ',
'Ṁ' => 'ṁ',
'Ṃ' => 'ṃ',
'Ṅ' => 'ṅ',
'Ṇ' => 'ṇ',
'Ṉ' => 'ṉ',
'Ṋ' => 'ṋ',
'Ṍ' => 'ṍ',
'Ṏ' => 'ṏ',
'Ṑ' => 'ṑ',
'Ṓ' => 'ṓ',
'Ṕ' => 'ṕ',
'Ṗ' => 'ṗ',
'Ṙ' => 'ṙ',
'Ṛ' => 'ṛ',
'Ṝ' => 'ṝ',
'Ṟ' => 'ṟ',
'Ṡ' => 'ṡ',
'Ṣ' => 'ṣ',
'Ṥ' => 'ṥ',
'Ṧ' => 'ṧ',
'Ṩ' => 'ṩ',
'Ṫ' => 'ṫ',
'Ṭ' => 'ṭ',
'Ṯ' => 'ṯ',
'Ṱ' => 'ṱ',
'Ṳ' => 'ṳ',
'Ṵ' => 'ṵ',
'Ṷ' => 'ṷ',
'Ṹ' => 'ṹ',
'Ṻ' => 'ṻ',
'Ṽ' => 'ṽ',
'Ṿ' => 'ṿ',
'Ẁ' => 'ẁ',
'Ẃ' => 'ẃ',
'Ẅ' => 'ẅ',
'Ẇ' => 'ẇ',
'Ẉ' => 'ẉ',
'Ẋ' => 'ẋ',
'Ẍ' => 'ẍ',
'Ẏ' => 'ẏ',
'Ẑ' => 'ẑ',
'Ẓ' => 'ẓ',
'Ẕ' => 'ẕ',
'ẞ' => 'ß',
'Ạ' => 'ạ',
'Ả' => 'ả',
'Ấ' => 'ấ',
'Ầ' => 'ầ',
'Ẩ' => 'ẩ',
'Ẫ' => 'ẫ',
'Ậ' => 'ậ',
'Ắ' => 'ắ',
'Ằ' => 'ằ',
'Ẳ' => 'ẳ',
'Ẵ' => 'ẵ',
'Ặ' => 'ặ',
'Ẹ' => 'ẹ',
'Ẻ' => 'ẻ',
'Ẽ' => 'ẽ',
'Ế' => 'ế',
'Ề' => 'ề',
'Ể' => 'ể',
'Ễ' => 'ễ',
'Ệ' => 'ệ',
'Ỉ' => 'ỉ',
'Ị' => 'ị',
'Ọ' => 'ọ',
'Ỏ' => 'ỏ',
'Ố' => 'ố',
'Ồ' => 'ồ',
'Ổ' => 'ổ',
'Ỗ' => 'ỗ',
'Ộ' => 'ộ',
'Ớ' => 'ớ',
'Ờ' => 'ờ',
'Ở' => 'ở',
'Ỡ' => 'ỡ',
'Ợ' => 'ợ',
'Ụ' => 'ụ',
'Ủ' => 'ủ',
'Ứ' => 'ứ',
'Ừ' => 'ừ',
'Ử' => 'ử',
'Ữ' => 'ữ',
'Ự' => 'ự',
'Ỳ' => 'ỳ',
'Ỵ' => 'ỵ',
'Ỷ' => 'ỷ',
'Ỹ' => 'ỹ',
'Ỻ' => 'ỻ',
'Ỽ' => 'ỽ',
'Ỿ' => 'ỿ',
'Ἀ' => 'ἀ',
'Ἁ' => 'ἁ',
'Ἂ' => 'ἂ',
'Ἃ' => 'ἃ',
'Ἄ' => 'ἄ',
'Ἅ' => 'ἅ',
'Ἆ' => 'ἆ',
'Ἇ' => 'ἇ',
'Ἐ' => 'ἐ',
'Ἑ' => 'ἑ',
'Ἒ' => 'ἒ',
'Ἓ' => 'ἓ',
'Ἔ' => 'ἔ',
'Ἕ' => 'ἕ',
'Ἠ' => 'ἠ',
'Ἡ' => 'ἡ',
'Ἢ' => 'ἢ',
'Ἣ' => 'ἣ',
'Ἤ' => 'ἤ',
'Ἥ' => 'ἥ',
'Ἦ' => 'ἦ',
'Ἧ' => 'ἧ',
'Ἰ' => 'ἰ',
'Ἱ' => 'ἱ',
'Ἲ' => 'ἲ',
'Ἳ' => 'ἳ',
'Ἴ' => 'ἴ',
'Ἵ' => 'ἵ',
'Ἶ' => 'ἶ',
'Ἷ' => 'ἷ',
'Ὀ' => 'ὀ',
'Ὁ' => 'ὁ',
'Ὂ' => 'ὂ',
'Ὃ' => 'ὃ',
'Ὄ' => 'ὄ',
'Ὅ' => 'ὅ',
'Ὑ' => 'ὑ',
'Ὓ' => 'ὓ',
'Ὕ' => 'ὕ',
'Ὗ' => 'ὗ',
'Ὠ' => 'ὠ',
'Ὡ' => 'ὡ',
'Ὢ' => 'ὢ',
'Ὣ' => 'ὣ',
'Ὤ' => 'ὤ',
'Ὥ' => 'ὥ',
'Ὦ' => 'ὦ',
'Ὧ' => 'ὧ',
'ᾈ' => 'ᾀ',
'ᾉ' => 'ᾁ',
'ᾊ' => 'ᾂ',
'ᾋ' => 'ᾃ',
'ᾌ' => 'ᾄ',
'ᾍ' => 'ᾅ',
'ᾎ' => 'ᾆ',
'ᾏ' => 'ᾇ',
'ᾘ' => 'ᾐ',
'ᾙ' => 'ᾑ',
'ᾚ' => 'ᾒ',
'ᾛ' => 'ᾓ',
'ᾜ' => 'ᾔ',
'ᾝ' => 'ᾕ',
'ᾞ' => 'ᾖ',
'ᾟ' => 'ᾗ',
'ᾨ' => 'ᾠ',
'ᾩ' => 'ᾡ',
'ᾪ' => 'ᾢ',
'ᾫ' => 'ᾣ',
'ᾬ' => 'ᾤ',
'ᾭ' => 'ᾥ',
'ᾮ' => 'ᾦ',
'ᾯ' => 'ᾧ',
'Ᾰ' => 'ᾰ',
'Ᾱ' => 'ᾱ',
'Ὰ' => 'ὰ',
'Ά' => 'ά',
'ᾼ' => 'ᾳ',
'Ὲ' => 'ὲ',
'Έ' => 'έ',
'Ὴ' => 'ὴ',
'Ή' => 'ή',
'ῌ' => 'ῃ',
'Ῐ' => 'ῐ',
'Ῑ' => 'ῑ',
'Ὶ' => 'ὶ',
'Ί' => 'ί',
'Ῠ' => 'ῠ',
'Ῡ' => 'ῡ',
'Ὺ' => 'ὺ',
'Ύ' => 'ύ',
'Ῥ' => 'ῥ',
'Ὸ' => 'ὸ',
'Ό' => 'ό',
'Ὼ' => 'ὼ',
'Ώ' => 'ώ',
'ῼ' => 'ῳ',
'Ω' => 'ω',
'K' => 'k',
'Å' => 'å',
'Ⅎ' => 'ⅎ',
'Ⅰ' => 'ⅰ',
'Ⅱ' => 'ⅱ',
'Ⅲ' => 'ⅲ',
'Ⅳ' => 'ⅳ',
'Ⅴ' => 'ⅴ',
'Ⅵ' => 'ⅵ',
'Ⅶ' => 'ⅶ',
'Ⅷ' => 'ⅷ',
'Ⅸ' => 'ⅸ',
'Ⅹ' => 'ⅹ',
'Ⅺ' => 'ⅺ',
'Ⅻ' => 'ⅻ',
'Ⅼ' => 'ⅼ',
'Ⅽ' => 'ⅽ',
'Ⅾ' => 'ⅾ',
'Ⅿ' => 'ⅿ',
'Ↄ' => 'ↄ',
'Ⓐ' => 'ⓐ',
'Ⓑ' => 'ⓑ',
'Ⓒ' => 'ⓒ',
'Ⓓ' => 'ⓓ',
'Ⓔ' => 'ⓔ',
'Ⓕ' => 'ⓕ',
'Ⓖ' => 'ⓖ',
'Ⓗ' => 'ⓗ',
'Ⓘ' => 'ⓘ',
'Ⓙ' => 'ⓙ',
'Ⓚ' => 'ⓚ',
'Ⓛ' => 'ⓛ',
'Ⓜ' => 'ⓜ',
'Ⓝ' => 'ⓝ',
'Ⓞ' => 'ⓞ',
'Ⓟ' => 'ⓟ',
'Ⓠ' => 'ⓠ',
'Ⓡ' => 'ⓡ',
'Ⓢ' => 'ⓢ',
'Ⓣ' => 'ⓣ',
'Ⓤ' => 'ⓤ',
'Ⓥ' => 'ⓥ',
'Ⓦ' => 'ⓦ',
'Ⓧ' => 'ⓧ',
'Ⓨ' => 'ⓨ',
'Ⓩ' => 'ⓩ',
'Ⰰ' => 'ⰰ',
'Ⰱ' => 'ⰱ',
'Ⰲ' => 'ⰲ',
'Ⰳ' => 'ⰳ',
'Ⰴ' => 'ⰴ',
'Ⰵ' => 'ⰵ',
'Ⰶ' => 'ⰶ',
'Ⰷ' => 'ⰷ',
'Ⰸ' => 'ⰸ',
'Ⰹ' => 'ⰹ',
'Ⰺ' => 'ⰺ',
'Ⰻ' => 'ⰻ',
'Ⰼ' => 'ⰼ',
'Ⰽ' => 'ⰽ',
'Ⰾ' => 'ⰾ',
'Ⰿ' => 'ⰿ',
'Ⱀ' => 'ⱀ',
'Ⱁ' => 'ⱁ',
'Ⱂ' => 'ⱂ',
'Ⱃ' => 'ⱃ',
'Ⱄ' => 'ⱄ',
'Ⱅ' => 'ⱅ',
'Ⱆ' => 'ⱆ',
'Ⱇ' => 'ⱇ',
'Ⱈ' => 'ⱈ',
'Ⱉ' => 'ⱉ',
'Ⱊ' => 'ⱊ',
'Ⱋ' => 'ⱋ',
'Ⱌ' => 'ⱌ',
'Ⱍ' => 'ⱍ',
'Ⱎ' => 'ⱎ',
'Ⱏ' => 'ⱏ',
'Ⱐ' => 'ⱐ',
'Ⱑ' => 'ⱑ',
'Ⱒ' => 'ⱒ',
'Ⱓ' => 'ⱓ',
'Ⱔ' => 'ⱔ',
'Ⱕ' => 'ⱕ',
'Ⱖ' => 'ⱖ',
'Ⱗ' => 'ⱗ',
'Ⱘ' => 'ⱘ',
'Ⱙ' => 'ⱙ',
'Ⱚ' => 'ⱚ',
'Ⱛ' => 'ⱛ',
'Ⱜ' => 'ⱜ',
'Ⱝ' => 'ⱝ',
'Ⱞ' => 'ⱞ',
'Ⱡ' => 'ⱡ',
'Ɫ' => 'ɫ',
'Ᵽ' => 'ᵽ',
'Ɽ' => 'ɽ',
'Ⱨ' => 'ⱨ',
'Ⱪ' => 'ⱪ',
'Ⱬ' => 'ⱬ',
'Ɑ' => 'ɑ',
'Ɱ' => 'ɱ',
'Ɐ' => 'ɐ',
'Ɒ' => 'ɒ',
'Ⱳ' => 'ⱳ',
'Ⱶ' => 'ⱶ',
'Ȿ' => 'ȿ',
'Ɀ' => 'ɀ',
'Ⲁ' => 'ⲁ',
'Ⲃ' => 'ⲃ',
'Ⲅ' => 'ⲅ',
'Ⲇ' => 'ⲇ',
'Ⲉ' => 'ⲉ',
'Ⲋ' => 'ⲋ',
'Ⲍ' => 'ⲍ',
'Ⲏ' => 'ⲏ',
'Ⲑ' => 'ⲑ',
'Ⲓ' => 'ⲓ',
'Ⲕ' => 'ⲕ',
'Ⲗ' => 'ⲗ',
'Ⲙ' => 'ⲙ',
'Ⲛ' => 'ⲛ',
'Ⲝ' => 'ⲝ',
'Ⲟ' => 'ⲟ',
'Ⲡ' => 'ⲡ',
'Ⲣ' => 'ⲣ',
'Ⲥ' => 'ⲥ',
'Ⲧ' => 'ⲧ',
'Ⲩ' => 'ⲩ',
'Ⲫ' => 'ⲫ',
'Ⲭ' => 'ⲭ',
'Ⲯ' => 'ⲯ',
'Ⲱ' => 'ⲱ',
'Ⲳ' => 'ⲳ',
'Ⲵ' => 'ⲵ',
'Ⲷ' => 'ⲷ',
'Ⲹ' => 'ⲹ',
'Ⲻ' => 'ⲻ',
'Ⲽ' => 'ⲽ',
'Ⲿ' => 'ⲿ',
'Ⳁ' => 'ⳁ',
'Ⳃ' => 'ⳃ',
'Ⳅ' => 'ⳅ',
'Ⳇ' => 'ⳇ',
'Ⳉ' => 'ⳉ',
'Ⳋ' => 'ⳋ',
'Ⳍ' => 'ⳍ',
'Ⳏ' => 'ⳏ',
'Ⳑ' => 'ⳑ',
'Ⳓ' => 'ⳓ',
'Ⳕ' => 'ⳕ',
'Ⳗ' => 'ⳗ',
'Ⳙ' => 'ⳙ',
'Ⳛ' => 'ⳛ',
'Ⳝ' => 'ⳝ',
'Ⳟ' => 'ⳟ',
'Ⳡ' => 'ⳡ',
'Ⳣ' => 'ⳣ',
'Ⳬ' => 'ⳬ',
'Ⳮ' => 'ⳮ',
'Ⳳ' => 'ⳳ',
'Ꙁ' => 'ꙁ',
'Ꙃ' => 'ꙃ',
'Ꙅ' => 'ꙅ',
'Ꙇ' => 'ꙇ',
'Ꙉ' => 'ꙉ',
'Ꙋ' => 'ꙋ',
'Ꙍ' => 'ꙍ',
'Ꙏ' => 'ꙏ',
'Ꙑ' => 'ꙑ',
'Ꙓ' => 'ꙓ',
'Ꙕ' => 'ꙕ',
'Ꙗ' => 'ꙗ',
'Ꙙ' => 'ꙙ',
'Ꙛ' => 'ꙛ',
'Ꙝ' => 'ꙝ',
'Ꙟ' => 'ꙟ',
'Ꙡ' => 'ꙡ',
'Ꙣ' => 'ꙣ',
'Ꙥ' => 'ꙥ',
'Ꙧ' => 'ꙧ',
'Ꙩ' => 'ꙩ',
'Ꙫ' => 'ꙫ',
'Ꙭ' => 'ꙭ',
'Ꚁ' => 'ꚁ',
'Ꚃ' => 'ꚃ',
'Ꚅ' => 'ꚅ',
'Ꚇ' => 'ꚇ',
'Ꚉ' => 'ꚉ',
'Ꚋ' => 'ꚋ',
'Ꚍ' => 'ꚍ',
'Ꚏ' => 'ꚏ',
'Ꚑ' => 'ꚑ',
'Ꚓ' => 'ꚓ',
'Ꚕ' => 'ꚕ',
'Ꚗ' => 'ꚗ',
'Ꚙ' => 'ꚙ',
'Ꚛ' => 'ꚛ',
'Ꜣ' => 'ꜣ',
'Ꜥ' => 'ꜥ',
'Ꜧ' => 'ꜧ',
'Ꜩ' => 'ꜩ',
'Ꜫ' => 'ꜫ',
'Ꜭ' => 'ꜭ',
'Ꜯ' => 'ꜯ',
'Ꜳ' => 'ꜳ',
'Ꜵ' => 'ꜵ',
'Ꜷ' => 'ꜷ',
'Ꜹ' => 'ꜹ',
'Ꜻ' => 'ꜻ',
'Ꜽ' => 'ꜽ',
'Ꜿ' => 'ꜿ',
'Ꝁ' => 'ꝁ',
'Ꝃ' => 'ꝃ',
'Ꝅ' => 'ꝅ',
'Ꝇ' => 'ꝇ',
'Ꝉ' => 'ꝉ',
'Ꝋ' => 'ꝋ',
'Ꝍ' => 'ꝍ',
'Ꝏ' => 'ꝏ',
'Ꝑ' => 'ꝑ',
'Ꝓ' => 'ꝓ',
'Ꝕ' => 'ꝕ',
'Ꝗ' => 'ꝗ',
'Ꝙ' => 'ꝙ',
'Ꝛ' => 'ꝛ',
'Ꝝ' => 'ꝝ',
'Ꝟ' => 'ꝟ',
'Ꝡ' => 'ꝡ',
'Ꝣ' => 'ꝣ',
'Ꝥ' => 'ꝥ',
'Ꝧ' => 'ꝧ',
'Ꝩ' => 'ꝩ',
'Ꝫ' => 'ꝫ',
'Ꝭ' => 'ꝭ',
'Ꝯ' => 'ꝯ',
'Ꝺ' => 'ꝺ',
'Ꝼ' => 'ꝼ',
'Ᵹ' => 'ᵹ',
'Ꝿ' => 'ꝿ',
'Ꞁ' => 'ꞁ',
'Ꞃ' => 'ꞃ',
'Ꞅ' => 'ꞅ',
'Ꞇ' => 'ꞇ',
'Ꞌ' => 'ꞌ',
'Ɥ' => 'ɥ',
'Ꞑ' => 'ꞑ',
'Ꞓ' => 'ꞓ',
'Ꞗ' => 'ꞗ',
'Ꞙ' => 'ꞙ',
'Ꞛ' => 'ꞛ',
'Ꞝ' => 'ꞝ',
'Ꞟ' => 'ꞟ',
'Ꞡ' => 'ꞡ',
'Ꞣ' => 'ꞣ',
'Ꞥ' => 'ꞥ',
'Ꞧ' => 'ꞧ',
'Ꞩ' => 'ꞩ',
'Ɦ' => 'ɦ',
'Ɜ' => 'ɜ',
'Ɡ' => 'ɡ',
'Ɬ' => 'ɬ',
'Ʞ' => 'ʞ',
'Ʇ' => 'ʇ',
'A' => 'a',
'B' => 'b',
'C' => 'c',
'D' => 'd',
'E' => 'e',
'F' => 'f',
'G' => 'g',
'H' => 'h',
'I' => 'i',
'J' => 'j',
'K' => 'k',
'L' => 'l',
'M' => 'm',
'N' => 'n',
'O' => 'o',
'P' => 'p',
'Q' => 'q',
'R' => 'r',
'S' => 's',
'T' => 't',
'U' => 'u',
'V' => 'v',
'W' => 'w',
'X' => 'x',
'Y' => 'y',
'Z' => 'z',
'𐐀' => '𐐨',
'𐐁' => '𐐩',
'𐐂' => '𐐪',
'𐐃' => '𐐫',
'𐐄' => '𐐬',
'𐐅' => '𐐭',
'𐐆' => '𐐮',
'𐐇' => '𐐯',
'𐐈' => '𐐰',
'𐐉' => '𐐱',
'𐐊' => '𐐲',
'𐐋' => '𐐳',
'𐐌' => '𐐴',
'𐐍' => '𐐵',
'𐐎' => '𐐶',
'𐐏' => '𐐷',
'𐐐' => '𐐸',
'𐐑' => '𐐹',
'𐐒' => '𐐺',
'𐐓' => '𐐻',
'𐐔' => '𐐼',
'𐐕' => '𐐽',
'𐐖' => '𐐾',
'𐐗' => '𐐿',
'𐐘' => '𐑀',
'𐐙' => '𐑁',
'𐐚' => '𐑂',
'𐐛' => '𐑃',
'𐐜' => '𐑄',
'𐐝' => '𐑅',
'𐐞' => '𐑆',
'𐐟' => '𐑇',
'𐐠' => '𐑈',
'𐐡' => '𐑉',
'𐐢' => '𐑊',
'𐐣' => '𐑋',
'𐐤' => '𐑌',
'𐐥' => '𐑍',
'𐐦' => '𐑎',
'𐐧' => '𐑏',
'𑢠' => '𑣀',
'𑢡' => '𑣁',
'𑢢' => '𑣂',
'𑢣' => '𑣃',
'𑢤' => '𑣄',
'𑢥' => '𑣅',
'𑢦' => '𑣆',
'𑢧' => '𑣇',
'𑢨' => '𑣈',
'𑢩' => '𑣉',
'𑢪' => '𑣊',
'𑢫' => '𑣋',
'𑢬' => '𑣌',
'𑢭' => '𑣍',
'𑢮' => '𑣎',
'𑢯' => '𑣏',
'𑢰' => '𑣐',
'𑢱' => '𑣑',
'𑢲' => '𑣒',
'𑢳' => '𑣓',
'𑢴' => '𑣔',
'𑢵' => '𑣕',
'𑢶' => '𑣖',
'𑢷' => '𑣗',
'𑢸' => '𑣘',
'𑢹' => '𑣙',
'𑢺' => '𑣚',
'𑢻' => '𑣛',
'𑢼' => '𑣜',
'𑢽' => '𑣝',
'𑢾' => '𑣞',
'𑢿' => '𑣟',
);

$result =& $data;
unset($data);

return $result;
<?php










use Symfony\Polyfill\Mbstring as p;

if (!function_exists('mb_strlen')) {
define('MB_CASE_UPPER', 0);
define('MB_CASE_LOWER', 1);
define('MB_CASE_TITLE', 2);

function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
}
if (!function_exists('mb_chr')) {
function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
}
<?php










namespace Symfony\Component\DependencyInjection;

@trigger_error('The '.__NAMESPACE__.'\SimpleXMLElement class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\ExpressionLanguage\Expression;








class SimpleXMLElement extends \SimpleXMLElement
{







public function getAttributeAsPhp($name)
{
return self::phpize($this[$name]);
}









public function getArgumentsAsPhp($name, $lowercase = true)
{
$arguments = array();
foreach ($this->$name as $arg) {
if (isset($arg['name'])) {
$arg['key'] = (string) $arg['name'];
}
$key = isset($arg['key']) ? (string) $arg['key'] : (!$arguments ? 0 : max(array_keys($arguments)) + 1);


 if ('parameter' == $name && $lowercase) {
$key = strtolower($key);
}


 
 if (isset($arg['index'])) {
$key = 'index_'.$arg['index'];
}

switch ($arg['type']) {
case 'service':
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
if (isset($arg['on-invalid']) && 'ignore' == $arg['on-invalid']) {
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
} elseif (isset($arg['on-invalid']) && 'null' == $arg['on-invalid']) {
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
}

if (isset($arg['strict'])) {
$strict = self::phpize($arg['strict']);
} else {
$strict = true;
}

$arguments[$key] = new Reference((string) $arg['id'], $invalidBehavior, $strict);
break;
case 'expression':
$arguments[$key] = new Expression((string) $arg);
break;
case 'collection':
$arguments[$key] = $arg->getArgumentsAsPhp($name, false);
break;
case 'string':
$arguments[$key] = (string) $arg;
break;
case 'constant':
$arguments[$key] = constant((string) $arg);
break;
default:
$arguments[$key] = self::phpize($arg);
}
}

return $arguments;
}








public static function phpize($value)
{
return XmlUtils::phpize($value);
}
}
<?php










namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;








class RealServiceInstantiator implements InstantiatorInterface
{



public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator)
{
return call_user_func($realInstantiator);
}
}
<?php










namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;







interface InstantiatorInterface
{











public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator);
}
<?php










namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;

use Symfony\Component\DependencyInjection\Definition;






class NullDumper implements DumperInterface
{



public function isProxyCandidate(Definition $definition)
{
return false;
}




public function getProxyFactoryCode(Definition $definition, $id)
{
return '';
}




public function getProxyCode(Definition $definition)
{
return '';
}
}
<?php










namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper;

use Symfony\Component\DependencyInjection\Definition;






interface DumperInterface
{







public function isProxyCandidate(Definition $definition);









public function getProxyFactoryCode(Definition $definition, $id);








public function getProxyCode(Definition $definition);
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;






class DefinitionDecorator extends Definition
{
private $parent;
private $changes = array();




public function __construct($parent)
{
parent::__construct();

$this->parent = $parent;
}






public function getParent()
{
return $this->parent;
}






public function getChanges()
{
return $this->changes;
}




public function setClass($class)
{
$this->changes['class'] = true;

return parent::setClass($class);
}




public function setFactory($callable)
{
$this->changes['factory'] = true;

return parent::setFactory($callable);
}




public function setFactoryClass($class)
{
$this->changes['factory_class'] = true;

return parent::setFactoryClass($class);
}




public function setFactoryMethod($method)
{
$this->changes['factory_method'] = true;

return parent::setFactoryMethod($method);
}




public function setFactoryService($service, $triggerDeprecationError = true)
{
$this->changes['factory_service'] = true;

return parent::setFactoryService($service, $triggerDeprecationError);
}




public function setConfigurator($callable)
{
$this->changes['configurator'] = true;

return parent::setConfigurator($callable);
}




public function setFile($file)
{
$this->changes['file'] = true;

return parent::setFile($file);
}




public function setPublic($boolean)
{
$this->changes['public'] = true;

return parent::setPublic($boolean);
}




public function setLazy($boolean)
{
$this->changes['lazy'] = true;

return parent::setLazy($boolean);
}




public function setDecoratedService($id, $renamedId = null, $priority = 0)
{
$this->changes['decorated_service'] = true;

return parent::setDecoratedService($id, $renamedId, $priority);
}




public function setDeprecated($boolean = true, $template = null)
{
$this->changes['deprecated'] = true;

return parent::setDeprecated($boolean, $template);
}




public function setAutowired($autowired)
{
$this->changes['autowire'] = true;

return parent::setAutowired($autowired);
}













public function getArgument($index)
{
if (array_key_exists('index_'.$index, $this->arguments)) {
return $this->arguments['index_'.$index];
}

$lastIndex = count(array_filter(array_keys($this->arguments), 'is_int')) - 1;

if ($index < 0 || $index > $lastIndex) {
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, $lastIndex));
}

return $this->arguments[$index];
}
















public function replaceArgument($index, $value)
{
if (!is_int($index)) {
throw new InvalidArgumentException('$index must be an integer.');
}

$this->arguments['index_'.$index] = $value;

return $this;
}
}
<?php










namespace Symfony\Component\DependencyInjection;






interface TaggedContainerInterface extends ContainerInterface
{







public function findTaggedServiceIds($name);
}
<?php










namespace Symfony\Component\DependencyInjection;








class Scope implements ScopeInterface
{
private $name;
private $parentName;

public function __construct($name, $parentName = ContainerInterface::SCOPE_CONTAINER)
{
$this->name = $name;
$this->parentName = $parentName;
}

public function getName()
{
return $this->name;
}

public function getParentName()
{
return $this->parentName;
}
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;







































class Container implements IntrospectableContainerInterface, ResettableContainerInterface
{



protected $parameterBag;

protected $services = array();
protected $methodMap = array();
protected $aliases = array();
protected $scopes = array();
protected $scopeChildren = array();
protected $scopedServices = array();
protected $scopeStacks = array();
protected $loading = array();

private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');




public function __construct(ParameterBagInterface $parameterBag = null)
{
$this->parameterBag = $parameterBag ?: new ParameterBag();
}









public function compile()
{
$this->parameterBag->resolve();

$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
}






public function isFrozen()
{
return $this->parameterBag instanceof FrozenParameterBag;
}






public function getParameterBag()
{
return $this->parameterBag;
}










public function getParameter($name)
{
return $this->parameterBag->get($name);
}








public function hasParameter($name)
{
return $this->parameterBag->has($name);
}







public function setParameter($name, $value)
{
$this->parameterBag->set($name, $value);
}
















public function set($id, $service, $scope = self::SCOPE_CONTAINER)
{
if (!in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) {
@trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
}

if (self::SCOPE_PROTOTYPE === $scope) {
throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id));
}

$id = strtolower($id);

if ('service_container' === $id) {

 
 
 return;
}
if (self::SCOPE_CONTAINER !== $scope) {
if (!isset($this->scopedServices[$scope])) {
throw new RuntimeException(sprintf('You cannot set service "%s" of inactive scope.', $id));
}

$this->scopedServices[$scope][$id] = $service;
}

if (isset($this->aliases[$id])) {
unset($this->aliases[$id]);
}

$this->services[$id] = $service;

if (method_exists($this, $method = 'synchronize'.strtr($id, $this->underscoreMap).'Service')) {
$this->$method();
}

if (null === $service) {
if (self::SCOPE_CONTAINER !== $scope) {
unset($this->scopedServices[$scope][$id]);
}

unset($this->services[$id]);
}
}








public function has($id)
{
for ($i = 2;;) {
if ('service_container' === $id
|| isset($this->aliases[$id])
|| isset($this->services[$id])
|| array_key_exists($id, $this->services)
) {
return true;
}
if (--$i && $id !== $lcId = strtolower($id)) {
$id = $lcId;
} else {
return method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service');
}
}
}


















public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
{

 
 
 
 for ($i = 2;;) {
if ('service_container' === $id) {
return $this;
}
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}

 if (isset($this->services[$id]) || array_key_exists($id, $this->services)) {
return $this->services[$id];
}

if (isset($this->loading[$id])) {
throw new ServiceCircularReferenceException($id, array_keys($this->loading));
}

if (isset($this->methodMap[$id])) {
$method = $this->methodMap[$id];
} elseif (--$i && $id !== $lcId = strtolower($id)) {
$id = $lcId;
continue;
} elseif (method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {

 } else {
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
if (!$id) {
throw new ServiceNotFoundException($id);
}

$alternatives = array();
foreach ($this->getServiceIds() as $knownId) {
$lev = levenshtein($id, $knownId);
if ($lev <= strlen($id) / 3 || false !== strpos($knownId, $id)) {
$alternatives[] = $knownId;
}
}

throw new ServiceNotFoundException($id, null, null, $alternatives);
}

return;
}

$this->loading[$id] = true;

try {
$service = $this->$method();
} catch (\Exception $e) {
unset($this->loading[$id]);
unset($this->services[$id]);

if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
return;
}

throw $e;
} catch (\Throwable $e) {
unset($this->loading[$id]);
unset($this->services[$id]);

throw $e;
}

unset($this->loading[$id]);

return $service;
}
}








public function initialized($id)
{
$id = strtolower($id);

if ('service_container' === $id) {

 
 return true;
}

if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}

return isset($this->services[$id]) || array_key_exists($id, $this->services);
}




public function reset()
{
if (!empty($this->scopedServices)) {
throw new LogicException('Resetting the container is not allowed when a scope is active.');
}

$this->services = array();
}






public function getServiceIds()
{
$ids = array();
foreach (get_class_methods($this) as $method) {
if (preg_match('/^get(.+)Service$/', $method, $match)) {
$ids[] = self::underscore($match[1]);
}
}
$ids[] = 'service_container';

return array_unique(array_merge($ids, array_keys($this->services)));
}











public function enterScope($name)
{
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

if (!isset($this->scopes[$name])) {
throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
}

if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) {
throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name]));
}


 
 
 if (isset($this->scopedServices[$name])) {
$services = array($this->services, $name => $this->scopedServices[$name]);
unset($this->scopedServices[$name]);

foreach ($this->scopeChildren[$name] as $child) {
if (isset($this->scopedServices[$child])) {
$services[$child] = $this->scopedServices[$child];
unset($this->scopedServices[$child]);
}
}


 $this->services = call_user_func_array('array_diff_key', $services);
array_shift($services);


 if (!isset($this->scopeStacks[$name])) {
$this->scopeStacks[$name] = new \SplStack();
}
$this->scopeStacks[$name]->push($services);
}

$this->scopedServices[$name] = array();
}











public function leaveScope($name)
{
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

if (!isset($this->scopedServices[$name])) {
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
}


 
 $services = array($this->services, $this->scopedServices[$name]);
unset($this->scopedServices[$name]);

foreach ($this->scopeChildren[$name] as $child) {
if (isset($this->scopedServices[$child])) {
$services[] = $this->scopedServices[$child];
unset($this->scopedServices[$child]);
}
}


 $this->services = call_user_func_array('array_diff_key', $services);


 if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) {
$services = $this->scopeStacks[$name]->pop();
$this->scopedServices += $services;

if ($this->scopeStacks[$name]->isEmpty()) {
unset($this->scopeStacks[$name]);
}

foreach ($services as $array) {
foreach ($array as $id => $service) {
$this->set($id, $service, $name);
}
}
}
}










public function addScope(ScopeInterface $scope)
{
$name = $scope->getName();
$parentScope = $scope->getParentName();

if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
}
if (isset($this->scopes[$name])) {
throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name));
}
if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) {
throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope));
}

$this->scopes[$name] = $parentScope;
$this->scopeChildren[$name] = array();


 while ($parentScope !== self::SCOPE_CONTAINER) {
$this->scopeChildren[$parentScope][] = $name;
$parentScope = $this->scopes[$parentScope];
}
}










public function hasScope($name)
{
if ('request' !== $name) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return isset($this->scopes[$name]);
}












public function isScopeActive($name)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

return isset($this->scopedServices[$name]);
}








public static function camelize($id)
{
return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));
}








public static function underscore($id)
{
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), str_replace('_', '.', $id)));
}

private function __clone()
{
}
}
<?php










namespace Symfony\Component\DependencyInjection;








interface ScopeInterface
{
public function getName();

public function getParentName();
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;






class ContainerBuilder extends Container implements TaggedContainerInterface
{



private $extensions = array();




private $extensionsByNs = array();




private $definitions = array();




private $obsoleteDefinitions = array();




private $aliasDefinitions = array();




private $resources = array();

private $extensionConfigs = array();




private $compiler;

private $trackResources = true;




private $proxyInstantiator;




private $expressionLanguage;




private $expressionLanguageProviders = array();




private $usedTags = array();









public function setResourceTracking($track)
{
$this->trackResources = (bool) $track;
}






public function isTrackingResources()
{
return $this->trackResources;
}






public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator)
{
$this->proxyInstantiator = $proxyInstantiator;
}






public function registerExtension(ExtensionInterface $extension)
{
$this->extensions[$extension->getAlias()] = $extension;

if (false !== $extension->getNamespace()) {
$this->extensionsByNs[$extension->getNamespace()] = $extension;
}
}










public function getExtension($name)
{
if (isset($this->extensions[$name])) {
return $this->extensions[$name];
}

if (isset($this->extensionsByNs[$name])) {
return $this->extensionsByNs[$name];
}

throw new LogicException(sprintf('Container extension "%s" is not registered', $name));
}






public function getExtensions()
{
return $this->extensions;
}








public function hasExtension($name)
{
return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]);
}






public function getResources()
{
return array_unique($this->resources);
}








public function addResource(ResourceInterface $resource)
{
if (!$this->trackResources) {
return $this;
}

$this->resources[] = $resource;

return $this;
}








public function setResources(array $resources)
{
if (!$this->trackResources) {
return $this;
}

$this->resources = $resources;

return $this;
}








public function addObjectResource($object)
{
if ($this->trackResources) {
$this->addClassResource(new \ReflectionClass($object));
}

return $this;
}








public function addClassResource(\ReflectionClass $class)
{
if (!$this->trackResources) {
return $this;
}

do {
if (is_file($class->getFileName())) {
$this->addResource(new FileResource($class->getFileName()));
}
} while ($class = $class->getParentClass());

return $this;
}












public function loadFromExtension($extension, array $values = array())
{
if ($this->isFrozen()) {
throw new BadMethodCallException('Cannot load from an extension on a frozen container.');
}

$namespace = $this->getExtension($extension)->getAlias();

$this->extensionConfigs[$namespace][] = $values;

return $this;
}









public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
{
$this->getCompiler()->addPass($pass, $type);

$this->addObjectResource($pass);

return $this;
}






public function getCompilerPassConfig()
{
return $this->getCompiler()->getPassConfig();
}






public function getCompiler()
{
if (null === $this->compiler) {
$this->compiler = new Compiler();
}

return $this->compiler;
}








public function getScopes($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->scopes;
}








public function getScopeChildren($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->scopeChildren;
}












public function set($id, $service, $scope = self::SCOPE_CONTAINER)
{
$id = strtolower($id);
$set = isset($this->definitions[$id]);

if ($this->isFrozen() && ($set || isset($this->obsoleteDefinitions[$id])) && !$this->{$set ? 'definitions' : 'obsoleteDefinitions'}[$id]->isSynthetic()) {

 throw new BadMethodCallException(sprintf('Setting service "%s" on a frozen container is not allowed.', $id));
}

if ($set) {
$this->obsoleteDefinitions[$id] = $this->definitions[$id];
}

unset($this->definitions[$id], $this->aliasDefinitions[$id]);

parent::set($id, $service, $scope);

if (isset($this->obsoleteDefinitions[$id]) && $this->obsoleteDefinitions[$id]->isSynchronized(false)) {
$this->synchronize($id);
}
}






public function removeDefinition($id)
{
unset($this->definitions[strtolower($id)]);
}








public function has($id)
{
$id = strtolower($id);

return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id);
}
















public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
{
$id = strtolower($id);

if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
return $service;
}

if (!array_key_exists($id, $this->definitions) && isset($this->aliasDefinitions[$id])) {
return $this->get((string) $this->aliasDefinitions[$id], $invalidBehavior);
}

try {
$definition = $this->getDefinition($id);
} catch (ServiceNotFoundException $e) {
if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
return;
}

throw $e;
}

$this->loading[$id] = true;

try {
$service = $this->createService($definition, $id);
} catch (\Exception $e) {
unset($this->loading[$id]);

if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
return;
}

throw $e;
} catch (\Throwable $e) {
unset($this->loading[$id]);

throw $e;
}

unset($this->loading[$id]);

return $service;
}























public function merge(ContainerBuilder $container)
{
if ($this->isFrozen()) {
throw new BadMethodCallException('Cannot merge on a frozen container.');
}

$this->addDefinitions($container->getDefinitions());
$this->addAliases($container->getAliases());
$this->getParameterBag()->add($container->getParameterBag()->all());

if ($this->trackResources) {
foreach ($container->getResources() as $resource) {
$this->addResource($resource);
}
}

foreach ($this->extensions as $name => $extension) {
if (!isset($this->extensionConfigs[$name])) {
$this->extensionConfigs[$name] = array();
}

$this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name));
}
}








public function getExtensionConfig($name)
{
if (!isset($this->extensionConfigs[$name])) {
$this->extensionConfigs[$name] = array();
}

return $this->extensionConfigs[$name];
}







public function prependExtensionConfig($name, array $config)
{
if (!isset($this->extensionConfigs[$name])) {
$this->extensionConfigs[$name] = array();
}

array_unshift($this->extensionConfigs[$name], $config);
}















public function compile()
{
$compiler = $this->getCompiler();

if ($this->trackResources) {
foreach ($compiler->getPassConfig()->getPasses() as $pass) {
$this->addObjectResource($pass);
}
}

$compiler->compile($this);

if ($this->trackResources) {
foreach ($this->definitions as $definition) {
if ($definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) {
$this->addClassResource(new \ReflectionClass($class));
}
}
}

$this->extensionConfigs = array();

parent::compile();
}






public function getServiceIds()
{
return array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliasDefinitions), parent::getServiceIds()));
}






public function addAliases(array $aliases)
{
foreach ($aliases as $alias => $id) {
$this->setAlias($alias, $id);
}
}






public function setAliases(array $aliases)
{
$this->aliasDefinitions = array();
$this->addAliases($aliases);
}










public function setAlias($alias, $id)
{
$alias = strtolower($alias);

if (is_string($id)) {
$id = new Alias($id);
} elseif (!$id instanceof Alias) {
throw new InvalidArgumentException('$id must be a string, or an Alias object.');
}

if ($alias === (string) $id) {
throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias));
}

unset($this->definitions[$alias]);

$this->aliasDefinitions[$alias] = $id;
}






public function removeAlias($alias)
{
unset($this->aliasDefinitions[strtolower($alias)]);
}








public function hasAlias($id)
{
return isset($this->aliasDefinitions[strtolower($id)]);
}






public function getAliases()
{
return $this->aliasDefinitions;
}










public function getAlias($id)
{
$id = strtolower($id);

if (!isset($this->aliasDefinitions[$id])) {
throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
}

return $this->aliasDefinitions[$id];
}












public function register($id, $class = null)
{
return $this->setDefinition($id, new Definition($class));
}






public function addDefinitions(array $definitions)
{
foreach ($definitions as $id => $definition) {
$this->setDefinition($id, $definition);
}
}






public function setDefinitions(array $definitions)
{
$this->definitions = array();
$this->addDefinitions($definitions);
}






public function getDefinitions()
{
return $this->definitions;
}











public function setDefinition($id, Definition $definition)
{
if ($this->isFrozen()) {
throw new BadMethodCallException('Adding definition to a frozen container is not allowed');
}

$id = strtolower($id);

unset($this->aliasDefinitions[$id]);

return $this->definitions[$id] = $definition;
}








public function hasDefinition($id)
{
return array_key_exists(strtolower($id), $this->definitions);
}










public function getDefinition($id)
{
$id = strtolower($id);

if (!array_key_exists($id, $this->definitions)) {
throw new ServiceNotFoundException($id);
}

return $this->definitions[$id];
}












public function findDefinition($id)
{
$id = strtolower($id);

while (isset($this->aliasDefinitions[$id])) {
$id = (string) $this->aliasDefinitions[$id];
}

return $this->getDefinition($id);
}

















public function createService(Definition $definition, $id, $tryProxy = true)
{
if ($definition instanceof DefinitionDecorator) {
throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
}

if ($definition->isSynthetic()) {
throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
}

if ($definition->isDeprecated()) {
@trigger_error($definition->getDeprecationMessage($id), E_USER_DEPRECATED);
}

if ($tryProxy && $definition->isLazy()) {
$container = $this;

$proxy = $this
->getProxyInstantiator()
->instantiateProxy(
$container,
$definition,
$id, function () use ($definition, $id, $container) {
return $container->createService($definition, $id, false);
}
);
$this->shareService($definition, $proxy, $id);

return $proxy;
}

$parameterBag = $this->getParameterBag();

if (null !== $definition->getFile()) {
require_once $parameterBag->resolveValue($definition->getFile());
}

$arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())));

if (null !== $factory = $definition->getFactory()) {
if (is_array($factory)) {
$factory = array($this->resolveServices($parameterBag->resolveValue($factory[0])), $factory[1]);
} elseif (!is_string($factory)) {
throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
}

$service = call_user_func_array($factory, $arguments);

if (!$definition->isDeprecated() && is_array($factory) && is_string($factory[0])) {
$r = new \ReflectionClass($factory[0]);

if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
@trigger_error(sprintf('The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name), E_USER_DEPRECATED);
}
}
} elseif (null !== $definition->getFactoryMethod(false)) {
if (null !== $definition->getFactoryClass(false)) {
$factory = $parameterBag->resolveValue($definition->getFactoryClass(false));
} elseif (null !== $definition->getFactoryService(false)) {
$factory = $this->get($parameterBag->resolveValue($definition->getFactoryService(false)));
} else {
throw new RuntimeException(sprintf('Cannot create service "%s" from factory method without a factory service or factory class.', $id));
}

$service = call_user_func_array(array($factory, $definition->getFactoryMethod(false)), $arguments);
} else {
$r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));

$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);

if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
@trigger_error(sprintf('The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name), E_USER_DEPRECATED);
}
}

if ($tryProxy || !$definition->isLazy()) {

 $this->shareService($definition, $service, $id);
}

$properties = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())));
foreach ($properties as $name => $value) {
$service->$name = $value;
}

foreach ($definition->getMethodCalls() as $call) {
$this->callMethod($service, $call);
}

if ($callable = $definition->getConfigurator()) {
if (is_array($callable)) {
$callable[0] = $parameterBag->resolveValue($callable[0]);

if ($callable[0] instanceof Reference) {
$callable[0] = $this->get((string) $callable[0], $callable[0]->getInvalidBehavior());
} elseif ($callable[0] instanceof Definition) {
$callable[0] = $this->createService($callable[0], null);
}
}

if (!is_callable($callable)) {
throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
}

call_user_func($callable, $service);
}

return $service;
}









public function resolveServices($value)
{
if (is_array($value)) {
foreach ($value as $k => $v) {
$value[$k] = $this->resolveServices($v);
}
} elseif ($value instanceof Reference) {
$value = $this->get((string) $value, $value->getInvalidBehavior());
} elseif ($value instanceof Definition) {
$value = $this->createService($value, null);
} elseif ($value instanceof Expression) {
$value = $this->getExpressionLanguage()->evaluate($value, array('container' => $this));
}

return $value;
}



















public function findTaggedServiceIds($name)
{
$this->usedTags[] = $name;
$tags = array();
foreach ($this->getDefinitions() as $id => $definition) {
if ($definition->hasTag($name)) {
$tags[$id] = $definition->getTag($name);
}
}

return $tags;
}






public function findTags()
{
$tags = array();
foreach ($this->getDefinitions() as $id => $definition) {
$tags = array_merge(array_keys($definition->getTags()), $tags);
}

return array_unique($tags);
}






public function findUnusedTags()
{
return array_values(array_diff($this->findTags(), $this->usedTags));
}

public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
{
$this->expressionLanguageProviders[] = $provider;
}




public function getExpressionLanguageProviders()
{
return $this->expressionLanguageProviders;
}








public static function getServiceConditionals($value)
{
$services = array();

if (is_array($value)) {
foreach ($value as $v) {
$services = array_unique(array_merge($services, self::getServiceConditionals($v)));
}
} elseif ($value instanceof Reference && $value->getInvalidBehavior() === ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
$services[] = (string) $value;
}

return $services;
}






private function getProxyInstantiator()
{
if (!$this->proxyInstantiator) {
$this->proxyInstantiator = new RealServiceInstantiator();
}

return $this->proxyInstantiator;
}











private function synchronize($id)
{
if ('request' !== $id) {
@trigger_error('The '.__METHOD__.' method is deprecated in version 2.7 and will be removed in version 3.0.', E_USER_DEPRECATED);
}

foreach ($this->definitions as $definitionId => $definition) {

 if (!$this->initialized($definitionId)) {
continue;
}

foreach ($definition->getMethodCalls() as $call) {
foreach ($call[1] as $argument) {
if ($argument instanceof Reference && $id == (string) $argument) {
$this->callMethod($this->get($definitionId), $call);
}
}
}
}
}

private function callMethod($service, $call)
{
$services = self::getServiceConditionals($call[1]);

foreach ($services as $s) {
if (!$this->has($s)) {
return;
}
}

call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1]))));
}










private function shareService(Definition $definition, $service, $id)
{
if (null !== $id && $definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
throw new InactiveScopeException($id, $scope);
}

$this->services[$lowerId = strtolower($id)] = $service;

if (self::SCOPE_CONTAINER !== $scope) {
$this->scopedServices[$scope][$lowerId] = $service;
}
}
}

private function getExpressionLanguage()
{
if (null === $this->expressionLanguage) {
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
}
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
}

return $this->expressionLanguage;
}
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;








class ExpressionLanguage extends BaseExpressionLanguage
{
public function __construct(ParserCacheInterface $cache = null, array $providers = array())
{

 array_unshift($providers, new ExpressionLanguageProvider());

parent::__construct($cache, $providers);
}
}
<?php










namespace Symfony\Component\DependencyInjection;






class Reference
{
private $id;
private $invalidBehavior;
private $strict;










public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $strict = true)
{
$this->id = strtolower($id);
$this->invalidBehavior = $invalidBehavior;
$this->strict = $strict;
}




public function __toString()
{
return $this->id;
}






public function getInvalidBehavior()
{
return $this->invalidBehavior;
}








public function isStrict($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->strict;
}
}
<?php










namespace Symfony\Component\DependencyInjection;









interface IntrospectableContainerInterface extends ContainerInterface
{







public function initialized($id);
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;







interface ContainerInterface
{
const EXCEPTION_ON_INVALID_REFERENCE = 1;
const NULL_ON_INVALID_REFERENCE = 2;
const IGNORE_ON_INVALID_REFERENCE = 3;
const SCOPE_CONTAINER = 'container';
const SCOPE_PROTOTYPE = 'prototype';










public function set($id, $service, $scope = self::SCOPE_CONTAINER);














public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);








public function has($id);










public function getParameter($name);








public function hasParameter($name);







public function setParameter($name, $value);








public function enterScope($name);








public function leaveScope($name);








public function addScope(ScopeInterface $scope);










public function hasScope($name);












public function isScopeActive($name);
}
<?php










namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\Variable;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
use Symfony\Component\DependencyInjection\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use Symfony\Component\HttpKernel\Kernel;







class PhpDumper extends Dumper
{





const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz';






const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_';

private $inlinedDefinitions;
private $definitionVariables;
private $referenceVariables;
private $variableCount;
private $reservedVariables = array('instance', 'class');
private $expressionLanguage;
private $targetDirRegex;
private $targetDirMaxMatches;
private $docStar;




private $expressionLanguageProviders = array();




private $proxyDumper;




public function __construct(ContainerBuilder $container)
{
parent::__construct($container);

$this->inlinedDefinitions = new \SplObjectStorage();
}






public function setProxyDumper(ProxyDumper $proxyDumper)
{
$this->proxyDumper = $proxyDumper;
}














public function dump(array $options = array())
{
$this->targetDirRegex = null;
$options = array_merge(array(
'class' => 'ProjectServiceContainer',
'base_class' => 'Container',
'namespace' => '',
'debug' => true,
), $options);
$this->docStar = $options['debug'] ? '*' : '';

if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) {

 
 

$dir = explode(DIRECTORY_SEPARATOR, realpath($dir));
$i = count($dir);

if (3 <= $i) {
$regex = '';
$lastOptionalDir = $i > 8 ? $i - 5 : 3;
$this->targetDirMaxMatches = $i - $lastOptionalDir;

while (--$i >= $lastOptionalDir) {
$regex = sprintf('(%s%s)?', preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex);
}

do {
$regex = preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#').$regex;
} while (0 < --$i);

$this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#';
}
}

$code = $this->startClass($options['class'], $options['base_class'], $options['namespace']);

if ($this->container->isFrozen()) {
$code .= $this->addFrozenConstructor();
$code .= $this->addFrozenCompile();
$code .= $this->addIsFrozenMethod();
} else {
$code .= $this->addConstructor();
}

$code .=
$this->addServices().
$this->addDefaultParametersMethod().
$this->endClass().
$this->addProxyClasses()
;
$this->targetDirRegex = null;

return $code;
}






private function getProxyDumper()
{
if (!$this->proxyDumper) {
$this->proxyDumper = new NullDumper();
}

return $this->proxyDumper;
}









private function addServiceLocalTempVariables($cId, $definition)
{
static $template = "        \$%s = %s;\n";

$localDefinitions = array_merge(
array($definition),
$this->getInlinedDefinitions($definition)
);

$calls = $behavior = array();
foreach ($localDefinitions as $iDefinition) {
$this->getServiceCallsFromArguments($iDefinition->getArguments(), $calls, $behavior);
$this->getServiceCallsFromArguments($iDefinition->getMethodCalls(), $calls, $behavior);
$this->getServiceCallsFromArguments($iDefinition->getProperties(), $calls, $behavior);
$this->getServiceCallsFromArguments(array($iDefinition->getConfigurator()), $calls, $behavior);
$this->getServiceCallsFromArguments(array($iDefinition->getFactory()), $calls, $behavior);
}

$code = '';
foreach ($calls as $id => $callCount) {
if ('service_container' === $id || $id === $cId) {
continue;
}

if ($callCount > 1) {
$name = $this->getNextVariableName();
$this->referenceVariables[$id] = new Variable($name);

if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $behavior[$id]) {
$code .= sprintf($template, $name, $this->getServiceCall($id));
} else {
$code .= sprintf($template, $name, $this->getServiceCall($id, new Reference($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)));
}
}
}

if ('' !== $code) {
$code .= "\n";
}

return $code;
}






private function addProxyClasses()
{

$definitions = array_filter(
$this->container->getDefinitions(),
array($this->getProxyDumper(), 'isProxyCandidate')
);
$code = '';
$strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments');

foreach ($definitions as $definition) {
$proxyCode = "\n".$this->getProxyDumper()->getProxyCode($definition);
if ($strip) {
$proxyCode = "<?php\n".$proxyCode;
$proxyCode = substr(Kernel::stripComments($proxyCode), 5);
}
$code .= $proxyCode;
}

return $code;
}









private function addServiceInclude($id, $definition)
{
$template = "        require_once %s;\n";
$code = '';

if (null !== $file = $definition->getFile()) {
$code .= sprintf($template, $this->dumpValue($file));
}

foreach ($this->getInlinedDefinitions($definition) as $definition) {
if (null !== $file = $definition->getFile()) {
$code .= sprintf($template, $this->dumpValue($file));
}
}

if ('' !== $code) {
$code .= "\n";
}

return $code;
}












private function addServiceInlinedDefinitions($id, $definition)
{
$code = '';
$variableMap = $this->definitionVariables;
$nbOccurrences = new \SplObjectStorage();
$processed = new \SplObjectStorage();
$inlinedDefinitions = $this->getInlinedDefinitions($definition);

foreach ($inlinedDefinitions as $definition) {
if (false === $nbOccurrences->contains($definition)) {
$nbOccurrences->offsetSet($definition, 1);
} else {
$i = $nbOccurrences->offsetGet($definition);
$nbOccurrences->offsetSet($definition, $i + 1);
}
}

foreach ($inlinedDefinitions as $sDefinition) {
if ($processed->contains($sDefinition)) {
continue;
}
$processed->offsetSet($sDefinition);

$class = $this->dumpValue($sDefinition->getClass());
if ($nbOccurrences->offsetGet($sDefinition) > 1 || $sDefinition->getMethodCalls() || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) {
$name = $this->getNextVariableName();
$variableMap->offsetSet($sDefinition, new Variable($name));


 
 
 
 
 
 
 if ($this->hasReference($id, $sDefinition->getArguments())) {
throw new ServiceCircularReferenceException($id, array($id));
}

$code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = ');

if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) {
$code .= $this->addServiceProperties(null, $sDefinition, $name);
$code .= $this->addServiceMethodCalls(null, $sDefinition, $name);
$code .= $this->addServiceConfigurator(null, $sDefinition, $name);
}

$code .= "\n";
}
}

return $code;
}









private function addServiceReturn($id, $definition)
{
if ($this->isSimpleInstance($id, $definition)) {
return "    }\n";
}

return "\n        return \$instance;\n    }\n";
}












private function addServiceInstance($id, Definition $definition)
{
$class = $definition->getClass();

if ('\\' === substr($class, 0, 1)) {
$class = substr($class, 1);
}

$class = $this->dumpValue($class);

if (0 === strpos($class, "'") && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id));
}

$simple = $this->isSimpleInstance($id, $definition);
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
$instantiation = '';

if (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
$instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance');
} elseif (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
$instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance');
} elseif (!$simple) {
$instantiation = '$instance';
}

$return = '';
if ($simple) {
$return = 'return ';
} else {
$instantiation .= ' = ';
}

$code = $this->addNewInstance($id, $definition, $return, $instantiation);

if (!$simple) {
$code .= "\n";
}

return $code;
}









private function isSimpleInstance($id, Definition $definition)
{
foreach (array_merge(array($definition), $this->getInlinedDefinitions($definition)) as $sDefinition) {
if ($definition !== $sDefinition && !$this->hasReference($id, $sDefinition->getMethodCalls())) {
continue;
}

if ($sDefinition->getMethodCalls() || $sDefinition->getProperties() || $sDefinition->getConfigurator()) {
return false;
}
}

return true;
}










private function addServiceMethodCalls($id, Definition $definition, $variableName = 'instance')
{
$calls = '';
foreach ($definition->getMethodCalls() as $call) {
$arguments = array();
foreach ($call[1] as $value) {
$arguments[] = $this->dumpValue($value);
}

$calls .= $this->wrapServiceConditionals($call[1], sprintf("        \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments)));
}

return $calls;
}

private function addServiceProperties($id, Definition $definition, $variableName = 'instance')
{
$code = '';
foreach ($definition->getProperties() as $name => $value) {
$code .= sprintf("        \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value));
}

return $code;
}











private function addServiceInlinedDefinitionsSetup($id, Definition $definition)
{
$this->referenceVariables[$id] = new Variable('instance');

$code = '';
$processed = new \SplObjectStorage();
foreach ($this->getInlinedDefinitions($definition) as $iDefinition) {
if ($processed->contains($iDefinition)) {
continue;
}
$processed->offsetSet($iDefinition);

if (!$this->hasReference($id, $iDefinition->getMethodCalls(), true) && !$this->hasReference($id, $iDefinition->getProperties(), true)) {
continue;
}


 
 if ($this->isSimpleInstance($id, $definition)) {
throw new ServiceCircularReferenceException($id, array($id));
}

$name = (string) $this->definitionVariables->offsetGet($iDefinition);
$code .= $this->addServiceProperties(null, $iDefinition, $name);
$code .= $this->addServiceMethodCalls(null, $iDefinition, $name);
$code .= $this->addServiceConfigurator(null, $iDefinition, $name);
}

if ('' !== $code) {
$code .= "\n";
}

return $code;
}










private function addServiceConfigurator($id, Definition $definition, $variableName = 'instance')
{
if (!$callable = $definition->getConfigurator()) {
return '';
}

if (is_array($callable)) {
if ($callable[0] instanceof Reference
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
return sprintf("        %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
}

$class = $this->dumpValue($callable[0]);

 if (strpos($class, "'") === 0) {
return sprintf("        %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName);
}

return sprintf("        call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
}

return sprintf("        %s(\$%s);\n", $callable, $variableName);
}









private function addService($id, Definition $definition)
{
$this->definitionVariables = new \SplObjectStorage();
$this->referenceVariables = array();
$this->variableCount = 0;

$return = array();

if ($definition->isSynthetic()) {
$return[] = '@throws RuntimeException always since this service is expected to be injected dynamically';
} elseif ($class = $definition->getClass()) {
$return[] = sprintf('@return %s A %s instance', 0 === strpos($class, '%') ? 'object' : '\\'.ltrim($class, '\\'), ltrim($class, '\\'));
} elseif ($definition->getFactory()) {
$factory = $definition->getFactory();
if (is_string($factory)) {
$return[] = sprintf('@return object An instance returned by %s()', $factory);
} elseif (is_array($factory) && (is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) {
if (is_string($factory[0]) || $factory[0] instanceof Reference) {
$return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]);
} elseif ($factory[0] instanceof Definition) {
$return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]);
}
}
} elseif ($definition->getFactoryClass(false)) {
$return[] = sprintf('@return object An instance returned by %s::%s()', $definition->getFactoryClass(false), $definition->getFactoryMethod(false));
} elseif ($definition->getFactoryService(false)) {
$return[] = sprintf('@return object An instance returned by %s::%s()', $definition->getFactoryService(false), $definition->getFactoryMethod(false));
}

$scope = $definition->getScope(false);
if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
$return[] = '';
}
$return[] = sprintf("@throws InactiveScopeException when the '%s' service is requested while the '%s' scope is not active", $id, $scope);
}

if ($definition->isDeprecated()) {
if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
$return[] = '';
}

$return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id));
}

$return = str_replace("\n     * \n", "\n     *\n", implode("\n     * ", $return));

$doc = '';
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
$doc .= <<<'EOF'

     *
     * This service is shared.
     * This method always returns the same instance of the service.
EOF;
}

if (!$definition->isPublic()) {
$doc .= <<<'EOF'

     *
     * This service is private.
     * If you want to be able to request this service from the container directly,
     * make it public, otherwise you might end up with broken code.
EOF;
}

if ($definition->isAutowired()) {
$doc = <<<EOF

     *
     * This service is autowired.
EOF;
}

if ($definition->isLazy()) {
$lazyInitialization = '$lazyLoad = true';
$lazyInitializationDoc = "\n     * @param bool    \$lazyLoad whether to try lazy-loading the service with a proxy\n     *";
} else {
$lazyInitialization = '';
$lazyInitializationDoc = '';
}


 $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
$visibility = $isProxyCandidate ? 'public' : 'protected';
$code = <<<EOF

    /*{$this->docStar}
     * Gets the '$id' service.$doc
     *$lazyInitializationDoc
     * $return
     */
    {$visibility} function get{$this->camelize($id)}Service($lazyInitialization)
    {

EOF;

$code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id) : '';

if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
$code .= <<<EOF
        if (!isset(\$this->scopedServices['$scope'])) {
            throw new InactiveScopeException('$id', '$scope');
        }


EOF;
}

if ($definition->isSynthetic()) {
$code .= sprintf("        throw new RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n    }\n", $id);
} else {
if ($definition->isDeprecated()) {
$code .= sprintf("        @trigger_error(%s, E_USER_DEPRECATED);\n\n", var_export($definition->getDeprecationMessage($id), true));
}

$code .=
$this->addServiceInclude($id, $definition).
$this->addServiceLocalTempVariables($id, $definition).
$this->addServiceInlinedDefinitions($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceInlinedDefinitionsSetup($id, $definition).
$this->addServiceProperties($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
$this->addServiceReturn($id, $definition)
;
}

$this->definitionVariables = null;
$this->referenceVariables = null;

return $code;
}






private function addServices()
{
$publicServices = $privateServices = $synchronizers = '';
$definitions = $this->container->getDefinitions();
ksort($definitions);
foreach ($definitions as $id => $definition) {
if ($definition->isPublic()) {
$publicServices .= $this->addService($id, $definition);
} else {
$privateServices .= $this->addService($id, $definition);
}

$synchronizers .= $this->addServiceSynchronizer($id, $definition);
}

return $publicServices.$synchronizers.$privateServices;
}











private function addServiceSynchronizer($id, Definition $definition)
{
if (!$definition->isSynchronized(false)) {
return;
}

if ('request' !== $id) {
@trigger_error('Synchronized services were deprecated in version 2.7 and won\'t work anymore in 3.0.', E_USER_DEPRECATED);
}

$code = '';
foreach ($this->container->getDefinitions() as $definitionId => $definition) {
foreach ($definition->getMethodCalls() as $call) {
foreach ($call[1] as $argument) {
if ($argument instanceof Reference && $id == (string) $argument) {
$arguments = array();
foreach ($call[1] as $value) {
$arguments[] = $this->dumpValue($value);
}

$call = $this->wrapServiceConditionals($call[1], sprintf("\$this->get('%s')->%s(%s);", $definitionId, $call[0], implode(', ', $arguments)));

$code .= <<<EOF
        if (\$this->initialized('$definitionId')) {
            $call
        }

EOF;
}
}
}
}

if (!$code) {
return;
}

return <<<EOF

    /*{$this->docStar}
     * Updates the '$id' service.
     */
    protected function synchronize{$this->camelize($id)}Service()
    {
$code    }

EOF;
}

private function addNewInstance($id, Definition $definition, $return, $instantiation)
{
$class = $this->dumpValue($definition->getClass());

$arguments = array();
foreach ($definition->getArguments() as $value) {
$arguments[] = $this->dumpValue($value);
}

if (null !== $definition->getFactory()) {
$callable = $definition->getFactory();
if (is_array($callable)) {
if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) {
throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $callable[1] ?: 'n/a'));
}

if ($callable[0] instanceof Reference
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
return sprintf("        $return{$instantiation}%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : '');
}

$class = $this->dumpValue($callable[0]);

 if (strpos($class, "'") === 0) {
return sprintf("        $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '');
}

return sprintf("        $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : '');
}

return sprintf("        $return{$instantiation}\\%s(%s);\n", $callable, $arguments ? implode(', ', $arguments) : '');
} elseif (null !== $definition->getFactoryMethod(false)) {
if (null !== $definition->getFactoryClass(false)) {
$class = $this->dumpValue($definition->getFactoryClass(false));


 if (strpos($class, "'") === 0) {
return sprintf("        $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $definition->getFactoryMethod(false), $arguments ? implode(', ', $arguments) : '');
}

return sprintf("        $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass(false)), $definition->getFactoryMethod(false), $arguments ? ', '.implode(', ', $arguments) : '');
}

if (null !== $definition->getFactoryService(false)) {
return sprintf("        $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService(false)), $definition->getFactoryMethod(false), implode(', ', $arguments));
}

throw new RuntimeException(sprintf('Factory method requires a factory service or factory class in service definition for %s', $id));
}

if (false !== strpos($class, '$')) {
return sprintf("        \$class = %s;\n\n        $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments));
}

return sprintf("        $return{$instantiation}new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments));
}










private function startClass($class, $baseClass, $namespace)
{
$bagClass = $this->container->isFrozen() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;';
$namespaceLine = $namespace ? "namespace $namespace;\n" : '';

return <<<EOF
<?php
$namespaceLine
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
$bagClass

/*{$this->docStar}
 * $class.
 *
 * This class has been auto-generated
 * by the Symfony Dependency Injection Component.
 */
class $class extends $baseClass
{
    private \$parameters;
    private \$targetDirs = array();

EOF;
}






private function addConstructor()
{
$targetDirs = $this->exportTargetDirs();
$arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null;

$code = <<<EOF

    /*{$this->docStar}
     * Constructor.
     */
    public function __construct()
    {{$targetDirs}
        parent::__construct($arguments);

EOF;

if (count($scopes = $this->container->getScopes(false)) > 0) {
$code .= "\n";
$code .= '        $this->scopes = '.$this->dumpValue($scopes).";\n";
$code .= '        $this->scopeChildren = '.$this->dumpValue($this->container->getScopeChildren(false)).";\n";
}

$code .= $this->addMethodMap();
$code .= $this->addAliases();

$code .= <<<'EOF'
    }

EOF;

return $code;
}






private function addFrozenConstructor()
{
$targetDirs = $this->exportTargetDirs();

$code = <<<EOF

    /*{$this->docStar}
     * Constructor.
     */
    public function __construct()
    {{$targetDirs}
EOF;

if ($this->container->getParameterBag()->all()) {
$code .= "\n        \$this->parameters = \$this->getDefaultParameters();\n";
}

$code .= <<<'EOF'

        $this->services =
        $this->scopedServices =
        $this->scopeStacks = array();
EOF;

$code .= "\n";
if (count($scopes = $this->container->getScopes(false)) > 0) {
$code .= '        $this->scopes = '.$this->dumpValue($scopes).";\n";
$code .= '        $this->scopeChildren = '.$this->dumpValue($this->container->getScopeChildren(false)).";\n";
} else {
$code .= "        \$this->scopes = array();\n";
$code .= "        \$this->scopeChildren = array();\n";
}

$code .= $this->addMethodMap();
$code .= $this->addAliases();

$code .= <<<'EOF'
    }

EOF;

return $code;
}






private function addFrozenCompile()
{
return <<<EOF

    /*{$this->docStar}
     * {@inheritdoc}
     */
    public function compile()
    {
        throw new LogicException('You cannot compile a dumped frozen container.');
    }

EOF;
}






private function addIsFrozenMethod()
{
return <<<EOF

    /*{$this->docStar}
     * {@inheritdoc}
     */
    public function isFrozen()
    {
        return true;
    }

EOF;
}






private function addMethodMap()
{
if (!$definitions = $this->container->getDefinitions()) {
return '';
}

$code = "        \$this->methodMap = array(\n";
ksort($definitions);
foreach ($definitions as $id => $definition) {
$code .= '            '.var_export($id, true).' => '.var_export('get'.$this->camelize($id).'Service', true).",\n";
}

return $code."        );\n";
}






private function addAliases()
{
if (!$aliases = $this->container->getAliases()) {
return $this->container->isFrozen() ? "\n        \$this->aliases = array();\n" : '';
}

$code = "        \$this->aliases = array(\n";
ksort($aliases);
foreach ($aliases as $alias => $id) {
$id = (string) $id;
while (isset($aliases[$id])) {
$id = (string) $aliases[$id];
}
$code .= '            '.var_export($alias, true).' => '.var_export($id, true).",\n";
}

return $code."        );\n";
}






private function addDefaultParametersMethod()
{
if (!$this->container->getParameterBag()->all()) {
return '';
}

$parameters = $this->exportParameters($this->container->getParameterBag()->all());

$code = '';
if ($this->container->isFrozen()) {
$code .= <<<'EOF'

    /**
     * {@inheritdoc}
     */
    public function getParameter($name)
    {
        $name = strtolower($name);

        if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
            throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
        }

        return $this->parameters[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function hasParameter($name)
    {
        $name = strtolower($name);

        return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
    }

    /**
     * {@inheritdoc}
     */
    public function setParameter($name, $value)
    {
        throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
    }

    /**
     * {@inheritdoc}
     */
    public function getParameterBag()
    {
        if (null === $this->parameterBag) {
            $this->parameterBag = new FrozenParameterBag($this->parameters);
        }

        return $this->parameterBag;
    }

EOF;
if ('' === $this->docStar) {
$code = str_replace('/**', '/*', $code);
}
}

$code .= <<<EOF

    /*{$this->docStar}
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
        return $parameters;
    }

EOF;

return $code;
}












private function exportParameters(array $parameters, $path = '', $indent = 12)
{
$php = array();
foreach ($parameters as $key => $value) {
if (is_array($value)) {
$value = $this->exportParameters($value, $path.'/'.$key, $indent + 4);
} elseif ($value instanceof Variable) {
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key));
} elseif ($value instanceof Definition) {
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key));
} elseif ($value instanceof Reference) {
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key));
} elseif ($value instanceof Expression) {
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path.'/'.$key));
} else {
$value = $this->export($value);
}

$php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), var_export($key, true), $value);
}

return sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', $indent - 4));
}






private function endClass()
{
return <<<'EOF'
}

EOF;
}









private function wrapServiceConditionals($value, $code)
{
if (!$services = ContainerBuilder::getServiceConditionals($value)) {
return $code;
}

$conditions = array();
foreach ($services as $service) {
$conditions[] = sprintf("\$this->has('%s')", $service);
}


 $code = implode("\n", array_map(function ($line) { return $line ? '    '.$line : $line; }, explode("\n", $code)));

return sprintf("        if (%s) {\n%s        }\n", implode(' && ', $conditions), $code);
}








private function getServiceCallsFromArguments(array $arguments, array &$calls, array &$behavior)
{
foreach ($arguments as $argument) {
if (is_array($argument)) {
$this->getServiceCallsFromArguments($argument, $calls, $behavior);
} elseif ($argument instanceof Reference) {
$id = (string) $argument;

if (!isset($calls[$id])) {
$calls[$id] = 0;
}
if (!isset($behavior[$id])) {
$behavior[$id] = $argument->getInvalidBehavior();
} elseif (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $behavior[$id]) {
$behavior[$id] = $argument->getInvalidBehavior();
}

++$calls[$id];
}
}
}








private function getInlinedDefinitions(Definition $definition)
{
if (false === $this->inlinedDefinitions->contains($definition)) {
$definitions = array_merge(
$this->getDefinitionsFromArguments($definition->getArguments()),
$this->getDefinitionsFromArguments($definition->getMethodCalls()),
$this->getDefinitionsFromArguments($definition->getProperties()),
$this->getDefinitionsFromArguments(array($definition->getConfigurator())),
$this->getDefinitionsFromArguments(array($definition->getFactory()))
);

$this->inlinedDefinitions->offsetSet($definition, $definitions);

return $definitions;
}

return $this->inlinedDefinitions->offsetGet($definition);
}








private function getDefinitionsFromArguments(array $arguments)
{
$definitions = array();
foreach ($arguments as $argument) {
if (is_array($argument)) {
$definitions = array_merge($definitions, $this->getDefinitionsFromArguments($argument));
} elseif ($argument instanceof Definition) {
$definitions = array_merge(
$definitions,
$this->getInlinedDefinitions($argument),
array($argument)
);
}
}

return $definitions;
}











private function hasReference($id, array $arguments, $deep = false, array &$visited = array())
{
foreach ($arguments as $argument) {
if (is_array($argument)) {
if ($this->hasReference($id, $argument, $deep, $visited)) {
return true;
}
} elseif ($argument instanceof Reference) {
$argumentId = (string) $argument;
if ($id === $argumentId) {
return true;
}

if ($deep && !isset($visited[$argumentId]) && 'service_container' !== $argumentId) {
$visited[$argumentId] = true;

$service = $this->container->getDefinition($argumentId);


 
 if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) {
continue;
}

$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());

if ($this->hasReference($id, $arguments, $deep, $visited)) {
return true;
}
}
}
}

return false;
}











private function dumpValue($value, $interpolate = true)
{
if (is_array($value)) {
$code = array();
foreach ($value as $k => $v) {
$code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate));
}

return sprintf('array(%s)', implode(', ', $code));
} elseif ($value instanceof Definition) {
if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) {
return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate);
}
if (count($value->getMethodCalls()) > 0) {
throw new RuntimeException('Cannot dump definitions which have method calls.');
}
if (null !== $value->getConfigurator()) {
throw new RuntimeException('Cannot dump definitions which have a configurator.');
}

$arguments = array();
foreach ($value->getArguments() as $argument) {
$arguments[] = $this->dumpValue($argument);
}

if (null !== $value->getFactory()) {
$factory = $value->getFactory();

if (is_string($factory)) {
return sprintf('\\%s(%s)', $factory, implode(', ', $arguments));
}

if (is_array($factory)) {
if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $factory[1])) {
throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $factory[1] ?: 'n/a'));
}

if (is_string($factory[0])) {
return sprintf('%s::%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory[0])), $factory[1], implode(', ', $arguments));
}

if ($factory[0] instanceof Definition) {
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($factory[0]), $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
}

if ($factory[0] instanceof Reference) {
return sprintf('%s->%s(%s)', $this->dumpValue($factory[0]), $factory[1], implode(', ', $arguments));
}
}

throw new RuntimeException('Cannot dump definition because of invalid factory');
}

if (null !== $value->getFactoryMethod(false)) {
if (null !== $value->getFactoryClass(false)) {
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass(false)), $value->getFactoryMethod(false), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
} elseif (null !== $value->getFactoryService(false)) {
$service = $this->dumpValue($value->getFactoryService(false));

return sprintf('%s->%s(%s)', 0 === strpos($service, '$') ? sprintf('$this->get(%s)', $service) : $this->getServiceCall($value->getFactoryService(false)), $value->getFactoryMethod(false), implode(', ', $arguments));
}

throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.');
}

$class = $value->getClass();
if (null === $class) {
throw new RuntimeException('Cannot dump definitions which have no class nor factory.');
}

return sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), implode(', ', $arguments));
} elseif ($value instanceof Variable) {
return '$'.$value;
} elseif ($value instanceof Reference) {
if (null !== $this->referenceVariables && isset($this->referenceVariables[$id = (string) $value])) {
return $this->dumpValue($this->referenceVariables[$id], $interpolate);
}

return $this->getServiceCall((string) $value, $value);
} elseif ($value instanceof Expression) {
return $this->getExpressionLanguage()->compile((string) $value, array('this' => 'container'));
} elseif ($value instanceof Parameter) {
return $this->dumpParameter($value);
} elseif (true === $interpolate && is_string($value)) {
if (preg_match('/^%([^%]+)%$/', $value, $match)) {

 
 return $this->dumpParameter(strtolower($match[1]));
} else {
$that = $this;
$replaceParameters = function ($match) use ($that) {
return "'.".$that->dumpParameter(strtolower($match[2])).".'";
};

$code = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameters, $this->export($value)));

return $code;
}
} elseif (is_object($value) || is_resource($value)) {
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
}

return $this->export($value);
}










private function dumpLiteralClass($class)
{
if (false !== strpos($class, '$')) {
throw new RuntimeException('Cannot dump definitions which have a variable class name.');
}
if (0 !== strpos($class, "'") || !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) {
throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s)', $class ?: 'n/a'));
}

return '\\'.substr(str_replace('\\\\', '\\', $class), 1, -1);
}








public function dumpParameter($name)
{
if ($this->container->isFrozen() && $this->container->hasParameter($name)) {
return $this->dumpValue($this->container->getParameter($name), false);
}

return sprintf("\$this->getParameter('%s')", strtolower($name));
}







public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6.2 and will be removed in 3.0. Use the Symfony\Component\DependencyInjection\ContainerBuilder::addExpressionLanguageProvider method instead.', E_USER_DEPRECATED);

$this->expressionLanguageProviders[] = $provider;
}









private function getServiceCall($id, Reference $reference = null)
{
if ('service_container' === $id) {
return '$this';
}

if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
return sprintf('$this->get(\'%s\', ContainerInterface::NULL_ON_INVALID_REFERENCE)', $id);
}

if ($this->container->hasAlias($id)) {
$id = (string) $this->container->getAlias($id);
}

return sprintf('$this->get(\'%s\')', $id);
}










private function camelize($id)
{
$name = Container::camelize($id);

if (!preg_match('/^[a-zA-Z0-9_\x7f-\xff]+$/', $name)) {
throw new InvalidArgumentException(sprintf('Service id "%s" cannot be converted to a valid PHP method name.', $id));
}

return $name;
}






private function getNextVariableName()
{
$firstChars = self::FIRST_CHARS;
$firstCharsLength = strlen($firstChars);
$nonFirstChars = self::NON_FIRST_CHARS;
$nonFirstCharsLength = strlen($nonFirstChars);

while (true) {
$name = '';
$i = $this->variableCount;

if ('' === $name) {
$name .= $firstChars[$i % $firstCharsLength];
$i = (int) ($i / $firstCharsLength);
}

while ($i > 0) {
--$i;
$name .= $nonFirstChars[$i % $nonFirstCharsLength];
$i = (int) ($i / $nonFirstCharsLength);
}

++$this->variableCount;


 if (in_array($name, $this->reservedVariables, true)) {
continue;
}

return $name;
}
}

private function getExpressionLanguage()
{
if (null === $this->expressionLanguage) {
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
}
$providers = array_merge($this->container->getExpressionLanguageProviders(), $this->expressionLanguageProviders);
$this->expressionLanguage = new ExpressionLanguage(null, $providers);

if ($this->container->isTrackingResources()) {
foreach ($providers as $provider) {
$this->container->addObjectResource($provider);
}
}
}

return $this->expressionLanguage;
}

private function exportTargetDirs()
{
return null === $this->targetDirRegex ? '' : <<<EOF

        \$dir = __DIR__;
        for (\$i = 1; \$i <= {$this->targetDirMaxMatches}; ++\$i) {
            \$this->targetDirs[\$i] = \$dir = dirname(\$dir);
        }
EOF;
}

private function export($value)
{
if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) {
$prefix = $matches[0][1] ? var_export(substr($value, 0, $matches[0][1]), true).'.' : '';
$suffix = $matches[0][1] + strlen($matches[0][0]);
$suffix = isset($value[$suffix]) ? '.'.var_export(substr($value, $suffix), true) : '';
$dirname = '__DIR__';

if (0 < $offset = 1 + $this->targetDirMaxMatches - count($matches)) {
$dirname = sprintf('$this->targetDirs[%d]', $offset);
}

if ($prefix || $suffix) {
return sprintf('(%s%s%s)', $prefix, $dirname, $suffix);
}

return $dirname;
}

return var_export($value, true);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\ExpressionLanguage\Expression;







class XmlDumper extends Dumper
{



private $document;








public function dump(array $options = array())
{
$this->document = new \DOMDocument('1.0', 'utf-8');
$this->document->formatOutput = true;

$container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container');
$container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd');

$this->addParameters($container);
$this->addServices($container);

$this->document->appendChild($container);
$xml = $this->document->saveXML();
$this->document = null;

return $xml;
}






private function addParameters(\DOMElement $parent)
{
$data = $this->container->getParameterBag()->all();
if (!$data) {
return;
}

if ($this->container->isFrozen()) {
$data = $this->escape($data);
}

$parameters = $this->document->createElement('parameters');
$parent->appendChild($parameters);
$this->convertParameters($data, 'parameter', $parameters);
}







private function addMethodCalls(array $methodcalls, \DOMElement $parent)
{
foreach ($methodcalls as $methodcall) {
$call = $this->document->createElement('call');
$call->setAttribute('method', $methodcall[0]);
if (count($methodcall[1])) {
$this->convertParameters($methodcall[1], 'argument', $call);
}
$parent->appendChild($call);
}
}








private function addService($definition, $id, \DOMElement $parent)
{
$service = $this->document->createElement('service');
if (null !== $id) {
$service->setAttribute('id', $id);
}
if ($class = $definition->getClass()) {
if ('\\' === substr($class, 0, 1)) {
$class = substr($class, 1);
}

$service->setAttribute('class', $class);
}
if ($definition->getFactoryMethod(false)) {
$service->setAttribute('factory-method', $definition->getFactoryMethod(false));
}
if ($definition->getFactoryClass(false)) {
$service->setAttribute('factory-class', $definition->getFactoryClass(false));
}
if ($definition->getFactoryService(false)) {
$service->setAttribute('factory-service', $definition->getFactoryService(false));
}
if (!$definition->isShared()) {
$service->setAttribute('shared', 'false');
}
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
$service->setAttribute('scope', $scope);
}
if (!$definition->isPublic()) {
$service->setAttribute('public', 'false');
}
if ($definition->isSynthetic()) {
$service->setAttribute('synthetic', 'true');
}
if ($definition->isSynchronized(false)) {
$service->setAttribute('synchronized', 'true');
}
if ($definition->isLazy()) {
$service->setAttribute('lazy', 'true');
}
if (null !== $decorated = $definition->getDecoratedService()) {
list($decorated, $renamedId, $priority) = $decorated;
$service->setAttribute('decorates', $decorated);
if (null !== $renamedId) {
$service->setAttribute('decoration-inner-name', $renamedId);
}
if (0 !== $priority) {
$service->setAttribute('decoration-priority', $priority);
}
}

foreach ($definition->getTags() as $name => $tags) {
foreach ($tags as $attributes) {
$tag = $this->document->createElement('tag');
$tag->setAttribute('name', $name);
foreach ($attributes as $key => $value) {
$tag->setAttribute($key, $value);
}
$service->appendChild($tag);
}
}

if ($definition->getFile()) {
$file = $this->document->createElement('file');
$file->appendChild($this->document->createTextNode($definition->getFile()));
$service->appendChild($file);
}

if ($parameters = $definition->getArguments()) {
$this->convertParameters($parameters, 'argument', $service);
}

if ($parameters = $definition->getProperties()) {
$this->convertParameters($parameters, 'property', $service, 'name');
}

$this->addMethodCalls($definition->getMethodCalls(), $service);

if ($callable = $definition->getFactory()) {
$factory = $this->document->createElement('factory');

if (is_array($callable) && $callable[0] instanceof Definition) {
$this->addService($callable[0], null, $factory);
$factory->setAttribute('method', $callable[1]);
} elseif (is_array($callable)) {
$factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
$factory->setAttribute('method', $callable[1]);
} else {
$factory->setAttribute('function', $callable);
}
$service->appendChild($factory);
}

if ($definition->isDeprecated()) {
$deprecated = $this->document->createElement('deprecated');
$deprecated->appendChild($this->document->createTextNode($definition->getDeprecationMessage('%service_id%')));

$service->appendChild($deprecated);
}

if ($definition->isAutowired()) {
$service->setAttribute('autowire', 'true');
}

foreach ($definition->getAutowiringTypes() as $autowiringTypeValue) {
$autowiringType = $this->document->createElement('autowiring-type');
$autowiringType->appendChild($this->document->createTextNode($autowiringTypeValue));

$service->appendChild($autowiringType);
}

if ($callable = $definition->getConfigurator()) {
$configurator = $this->document->createElement('configurator');

if (is_array($callable) && $callable[0] instanceof Definition) {
$this->addService($callable[0], null, $configurator);
$configurator->setAttribute('method', $callable[1]);
} elseif (is_array($callable)) {
$configurator->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
$configurator->setAttribute('method', $callable[1]);
} else {
$configurator->setAttribute('function', $callable);
}
$service->appendChild($configurator);
}

$parent->appendChild($service);
}








private function addServiceAlias($alias, Alias $id, \DOMElement $parent)
{
$service = $this->document->createElement('service');
$service->setAttribute('id', $alias);
$service->setAttribute('alias', $id);
if (!$id->isPublic()) {
$service->setAttribute('public', 'false');
}
$parent->appendChild($service);
}






private function addServices(\DOMElement $parent)
{
$definitions = $this->container->getDefinitions();
if (!$definitions) {
return;
}

$services = $this->document->createElement('services');
foreach ($definitions as $id => $definition) {
$this->addService($definition, $id, $services);
}

$aliases = $this->container->getAliases();
foreach ($aliases as $alias => $id) {
while (isset($aliases[(string) $id])) {
$id = $aliases[(string) $id];
}
$this->addServiceAlias($alias, $id, $services);
}
$parent->appendChild($services);
}









private function convertParameters(array $parameters, $type, \DOMElement $parent, $keyAttribute = 'key')
{
$withKeys = array_keys($parameters) !== range(0, count($parameters) - 1);
foreach ($parameters as $key => $value) {
$element = $this->document->createElement($type);
if ($withKeys) {
$element->setAttribute($keyAttribute, $key);
}

if (is_array($value)) {
$element->setAttribute('type', 'collection');
$this->convertParameters($value, $type, $element, 'key');
} elseif ($value instanceof Reference) {
$element->setAttribute('type', 'service');
$element->setAttribute('id', (string) $value);
$behaviour = $value->getInvalidBehavior();
if ($behaviour == ContainerInterface::NULL_ON_INVALID_REFERENCE) {
$element->setAttribute('on-invalid', 'null');
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
$element->setAttribute('on-invalid', 'ignore');
}
if (!$value->isStrict(false)) {
$element->setAttribute('strict', 'false');
}
} elseif ($value instanceof Definition) {
$element->setAttribute('type', 'service');
$this->addService($value, null, $element);
} elseif ($value instanceof Expression) {
$element->setAttribute('type', 'expression');
$text = $this->document->createTextNode(self::phpToXml((string) $value));
$element->appendChild($text);
} else {
if (in_array($value, array('null', 'true', 'false'), true)) {
$element->setAttribute('type', 'string');
}
$text = $this->document->createTextNode(self::phpToXml($value));
$element->appendChild($text);
}
$parent->appendChild($element);
}
}








private function escape(array $arguments)
{
$args = array();
foreach ($arguments as $k => $v) {
if (is_array($v)) {
$args[$k] = $this->escape($v);
} elseif (is_string($v)) {
$args[$k] = str_replace('%', '%%', $v);
} else {
$args[$k] = $v;
}
}

return $args;
}










public static function phpToXml($value)
{
switch (true) {
case null === $value:
return 'null';
case true === $value:
return 'true';
case false === $value:
return 'false';
case $value instanceof Parameter:
return '%'.$value.'%';
case is_object($value) || is_resource($value):
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
default:
return (string) $value;
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\ContainerBuilder;






abstract class Dumper implements DumperInterface
{
protected $container;




public function __construct(ContainerBuilder $container)
{
$this->container = $container;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\Yaml\Dumper as YmlDumper;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\ExpressionLanguage\Expression;






class YamlDumper extends Dumper
{
private $dumper;








public function dump(array $options = array())
{
if (!class_exists('Symfony\Component\Yaml\Dumper')) {
throw new RuntimeException('Unable to dump the container as the Symfony Yaml Component is not installed.');
}

if (null === $this->dumper) {
$this->dumper = new YmlDumper();
}

return $this->addParameters()."\n".$this->addServices();
}









private function addService($id, $definition)
{
$code = "    $id:\n";
if ($class = $definition->getClass()) {
if ('\\' === substr($class, 0, 1)) {
$class = substr($class, 1);
}

$code .= sprintf("        class: %s\n", $this->dumper->dump($class));
}

if (!$definition->isPublic()) {
$code .= "        public: false\n";
}

$tagsCode = '';
foreach ($definition->getTags() as $name => $tags) {
foreach ($tags as $attributes) {
$att = array();
foreach ($attributes as $key => $value) {
$att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value));
}
$att = $att ? ', '.implode(', ', $att) : '';

$tagsCode .= sprintf("            - { name: %s%s }\n", $this->dumper->dump($name), $att);
}
}
if ($tagsCode) {
$code .= "        tags:\n".$tagsCode;
}

if ($definition->getFile()) {
$code .= sprintf("        file: %s\n", $this->dumper->dump($definition->getFile()));
}

if ($definition->isSynthetic()) {
$code .= sprintf("        synthetic: true\n");
}

if ($definition->isSynchronized(false)) {
$code .= sprintf("        synchronized: true\n");
}

if ($definition->isDeprecated()) {
$code .= sprintf("        deprecated: %s\n", $definition->getDeprecationMessage('%service_id%'));
}

if ($definition->isAutowired()) {
$code .= "        autowire: true\n";
}

$autowiringTypesCode = '';
foreach ($definition->getAutowiringTypes() as $autowiringType) {
$autowiringTypesCode .= sprintf("            - %s\n", $this->dumper->dump($autowiringType));
}
if ($autowiringTypesCode) {
$code .= sprintf("        autowiring_types:\n%s", $autowiringTypesCode);
}

if ($definition->getFactoryClass(false)) {
$code .= sprintf("        factory_class: %s\n", $this->dumper->dump($definition->getFactoryClass(false)));
}

if ($definition->isLazy()) {
$code .= sprintf("        lazy: true\n");
}

if ($definition->getFactoryMethod(false)) {
$code .= sprintf("        factory_method: %s\n", $this->dumper->dump($definition->getFactoryMethod(false)));
}

if ($definition->getFactoryService(false)) {
$code .= sprintf("        factory_service: %s\n", $this->dumper->dump($definition->getFactoryService(false)));
}

if ($definition->getArguments()) {
$code .= sprintf("        arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0));
}

if ($definition->getProperties()) {
$code .= sprintf("        properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0));
}

if ($definition->getMethodCalls()) {
$code .= sprintf("        calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12));
}

if (!$definition->isShared()) {
$code .= "        shared: false\n";
}

if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
$code .= sprintf("        scope: %s\n", $this->dumper->dump($scope));
}

if (null !== $decorated = $definition->getDecoratedService()) {
list($decorated, $renamedId, $priority) = $decorated;
$code .= sprintf("        decorates: %s\n", $decorated);
if (null !== $renamedId) {
$code .= sprintf("        decoration_inner_name: %s\n", $renamedId);
}
if (0 !== $priority) {
$code .= sprintf("        decoration_priority: %s\n", $priority);
}
}

if ($callable = $definition->getFactory()) {
$code .= sprintf("        factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
}

if ($callable = $definition->getConfigurator()) {
$code .= sprintf("        configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0));
}

return $code;
}









private function addServiceAlias($alias, $id)
{
if ($id->isPublic()) {
return sprintf("    %s: '@%s'\n", $alias, $id);
}

return sprintf("    %s:\n        alias: %s\n        public: false\n", $alias, $id);
}






private function addServices()
{
if (!$this->container->getDefinitions()) {
return '';
}

$code = "services:\n";
foreach ($this->container->getDefinitions() as $id => $definition) {
$code .= $this->addService($id, $definition);
}

$aliases = $this->container->getAliases();
foreach ($aliases as $alias => $id) {
while (isset($aliases[(string) $id])) {
$id = $aliases[(string) $id];
}
$code .= $this->addServiceAlias($alias, $id);
}

return $code;
}






private function addParameters()
{
if (!$this->container->getParameterBag()->all()) {
return '';
}

$parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isFrozen());

return $this->dumper->dump(array('parameters' => $parameters), 2);
}








private function dumpCallable($callable)
{
if (is_array($callable)) {
if ($callable[0] instanceof Reference) {
$callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]);
} else {
$callable = array($callable[0], $callable[1]);
}
}

return $callable;
}










private function dumpValue($value)
{
if (is_array($value)) {
$code = array();
foreach ($value as $k => $v) {
$code[$k] = $this->dumpValue($v);
}

return $code;
} elseif ($value instanceof Reference) {
return $this->getServiceCall((string) $value, $value);
} elseif ($value instanceof Parameter) {
return $this->getParameterCall((string) $value);
} elseif ($value instanceof Expression) {
return $this->getExpressionCall((string) $value);
} elseif (is_object($value) || is_resource($value)) {
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
}

return $value;
}









private function getServiceCall($id, Reference $reference = null)
{
if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
return sprintf('@?%s', $id);
}

return sprintf('@%s', $id);
}








private function getParameterCall($id)
{
return sprintf('%%%s%%', $id);
}

private function getExpressionCall($expression)
{
return sprintf('@=%s', $expression);
}









private function prepareParameters(array $parameters, $escape = true)
{
$filtered = array();
foreach ($parameters as $key => $value) {
if (is_array($value)) {
$value = $this->prepareParameters($value, $escape);
} elseif ($value instanceof Reference || is_string($value) && 0 === strpos($value, '@')) {
$value = '@'.$value;
}

$filtered[$key] = $value;
}

return $escape ? $this->escape($filtered) : $filtered;
}








private function escape(array $arguments)
{
$args = array();
foreach ($arguments as $k => $v) {
if (is_array($v)) {
$args[$k] = $this->escape($v);
} elseif (is_string($v)) {
$args[$k] = str_replace('%', '%%', $v);
} else {
$args[$k] = $v;
}
}

return $args;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Dumper;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Scope;










class GraphvizDumper extends Dumper
{
private $nodes;
private $edges;
private $options = array(
'graph' => array('ratio' => 'compress'),
'node' => array('fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'),
'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5),
'node.instance' => array('fillcolor' => '#9999ff', 'style' => 'filled'),
'node.definition' => array('fillcolor' => '#eeeeee'),
'node.missing' => array('fillcolor' => '#ff9999', 'style' => 'filled'),
);

















public function dump(array $options = array())
{
foreach (array('graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing') as $key) {
if (isset($options[$key])) {
$this->options[$key] = array_merge($this->options[$key], $options[$key]);
}
}

$this->nodes = $this->findNodes();

$this->edges = array();
foreach ($this->container->getDefinitions() as $id => $definition) {
$this->edges[$id] = array_merge(
$this->findEdges($id, $definition->getArguments(), true, ''),
$this->findEdges($id, $definition->getProperties(), false, '')
);

foreach ($definition->getMethodCalls() as $call) {
$this->edges[$id] = array_merge(
$this->edges[$id],
$this->findEdges($id, $call[1], false, $call[0].'()')
);
}
}

return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot();
}






private function addNodes()
{
$code = '';
foreach ($this->nodes as $id => $node) {
$aliases = $this->getAliases($id);

$code .= sprintf("  node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes']));
}

return $code;
}






private function addEdges()
{
$code = '';
foreach ($this->edges as $id => $edges) {
foreach ($edges as $edge) {
$code .= sprintf("  node_%s -> node_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed');
}
}

return $code;
}











private function findEdges($id, array $arguments, $required, $name)
{
$edges = array();
foreach ($arguments as $argument) {
if ($argument instanceof Parameter) {
$argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null;
} elseif (is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) {
$argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null;
}

if ($argument instanceof Reference) {
if (!$this->container->has((string) $argument)) {
$this->nodes[(string) $argument] = array('name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']);
}

$edges[] = array('name' => $name, 'required' => $required, 'to' => $argument);
} elseif (is_array($argument)) {
$edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name));
}
}

return $edges;
}






private function findNodes()
{
$nodes = array();

$container = $this->cloneContainer();

foreach ($container->getDefinitions() as $id => $definition) {
$class = $definition->getClass();

if ('\\' === substr($class, 0, 1)) {
$class = substr($class, 1);
}

try {
$class = $this->container->getParameterBag()->resolveValue($class);
} catch (ParameterNotFoundException $e) {
}

$nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false) ? 'filled' : 'dotted')));
$container->setDefinition($id, new Definition('stdClass'));
}

foreach ($container->getServiceIds() as $id) {
$service = $container->get($id);

if (array_key_exists($id, $container->getAliases())) {
continue;
}

if (!$container->hasDefinition($id)) {
$class = ('service_container' === $id) ? get_class($this->container) : get_class($service);
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => $this->options['node.instance']);
}
}

return $nodes;
}

private function cloneContainer()
{
$parameterBag = new ParameterBag($this->container->getParameterBag()->all());

$container = new ContainerBuilder($parameterBag);
$container->setDefinitions($this->container->getDefinitions());
$container->setAliases($this->container->getAliases());
$container->setResources($this->container->getResources());
foreach ($this->container->getScopes(false) as $scope => $parentScope) {
$container->addScope(new Scope($scope, $parentScope));
}
foreach ($this->container->getExtensions() as $extension) {
$container->registerExtension($extension);
}

return $container;
}






private function startDot()
{
return sprintf("digraph sc {\n  %s\n  node [%s];\n  edge [%s];\n\n",
$this->addOptions($this->options['graph']),
$this->addOptions($this->options['node']),
$this->addOptions($this->options['edge'])
);
}






private function endDot()
{
return "}\n";
}








private function addAttributes(array $attributes)
{
$code = array();
foreach ($attributes as $k => $v) {
$code[] = sprintf('%s="%s"', $k, $v);
}

return $code ? ', '.implode(', ', $code) : '';
}








private function addOptions(array $options)
{
$code = array();
foreach ($options as $k => $v) {
$code[] = sprintf('%s="%s"', $k, $v);
}

return implode(' ', $code);
}








private function dotize($id)
{
return strtolower(preg_replace('/\W/i', '_', $id));
}








private function getAliases($id)
{
$aliases = array();
foreach ($this->container->getAliases() as $alias => $origin) {
if ($id == $origin) {
$aliases[] = $alias;
}
}

return $aliases;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Dumper;






interface DumperInterface
{







public function dump(array $options = array());
}
<?php










namespace Symfony\Component\DependencyInjection;














class Variable
{
private $name;




public function __construct($name)
{
$this->name = $name;
}






public function __toString()
{
return $this->name;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Resource\FileResource;









class PhpFileLoader extends FileLoader
{



public function load($resource, $type = null)
{

 $container = $this->container;
$loader = $this;

$path = $this->locator->locate($resource);
$this->setCurrentDir(dirname($path));
$this->container->addResource(new FileResource($path));

include $path;
}




public function supports($resource, $type = null)
{
return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\ExpressionLanguage\Expression;






class XmlFileLoader extends FileLoader
{
const NS = 'http://symfony.com/schema/dic/services';




public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);

$xml = $this->parseFileToDOM($path);

$this->container->addResource(new FileResource($path));


 $this->processAnonymousServices($xml, $path);


 $this->parseImports($xml, $path);


 $this->parseParameters($xml);


 $this->loadFromExtensions($xml);


 $this->parseDefinitions($xml, $path);
}




public function supports($resource, $type = null)
{
return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION);
}






private function parseParameters(\DOMDocument $xml)
{
if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) {
$this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter'));
}
}







private function parseImports(\DOMDocument $xml, $file)
{
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);

if (false === $imports = $xpath->query('//container:imports/container:import')) {
return;
}

$defaultDirectory = dirname($file);
foreach ($imports as $import) {
$this->setCurrentDir($defaultDirectory);
$this->import($import->getAttribute('resource'), null, (bool) XmlUtils::phpize($import->getAttribute('ignore-errors')), $file);
}
}







private function parseDefinitions(\DOMDocument $xml, $file)
{
$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);

if (false === $services = $xpath->query('//container:services/container:service')) {
return;
}

foreach ($services as $service) {
if (null !== $definition = $this->parseDefinition($service, $file)) {
$this->container->setDefinition((string) $service->getAttribute('id'), $definition);
}
}
}









private function parseDefinition(\DOMElement $service, $file)
{
if ($alias = $service->getAttribute('alias')) {
$public = true;
if ($publicAttr = $service->getAttribute('public')) {
$public = XmlUtils::phpize($publicAttr);
}
$this->container->setAlias((string) $service->getAttribute('id'), new Alias($alias, $public));

return;
}

if ($parent = $service->getAttribute('parent')) {
$definition = new DefinitionDecorator($parent);
} else {
$definition = new Definition();
}

foreach (array('class', 'shared', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'lazy', 'abstract') as $key) {
if ($value = $service->getAttribute($key)) {
if (in_array($key, array('factory-class', 'factory-method', 'factory-service'))) {
@trigger_error(sprintf('The "%s" attribute of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use the "factory" element instead.', $key, (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED);
}
$method = 'set'.str_replace('-', '', $key);
$definition->$method(XmlUtils::phpize($value));
}
}

if ($value = $service->getAttribute('autowire')) {
$definition->setAutowired(XmlUtils::phpize($value));
}

if ($value = $service->getAttribute('scope')) {
$triggerDeprecation = 'request' !== (string) $service->getAttribute('id');

if ($triggerDeprecation) {
@trigger_error(sprintf('The "scope" attribute of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED);
}

$definition->setScope(XmlUtils::phpize($value), false);
}

if ($value = $service->getAttribute('synchronized')) {
$triggerDeprecation = 'request' !== (string) $service->getAttribute('id');

if ($triggerDeprecation) {
@trigger_error(sprintf('The "synchronized" attribute of service "%s" in file "%s" is deprecated since version 2.7 and will be removed in 3.0.', (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED);
}

$definition->setSynchronized(XmlUtils::phpize($value), $triggerDeprecation);
}

if ($files = $this->getChildren($service, 'file')) {
$definition->setFile($files[0]->nodeValue);
}

if ($deprecated = $this->getChildren($service, 'deprecated')) {
$definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null);
}

$definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property'));

if ($factories = $this->getChildren($service, 'factory')) {
$factory = $factories[0];
if ($function = $factory->getAttribute('function')) {
$definition->setFactory($function);
} else {
$factoryService = $this->getChildren($factory, 'service');

if (isset($factoryService[0])) {
$class = $this->parseDefinition($factoryService[0], $file);
} elseif ($childService = $factory->getAttribute('service')) {
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
} else {
$class = $factory->getAttribute('class');
}

$definition->setFactory(array($class, $factory->getAttribute('method')));
}
}

if ($configurators = $this->getChildren($service, 'configurator')) {
$configurator = $configurators[0];
if ($function = $configurator->getAttribute('function')) {
$definition->setConfigurator($function);
} else {
$configuratorService = $this->getChildren($configurator, 'service');

if (isset($configuratorService[0])) {
$class = $this->parseDefinition($configuratorService[0], $file);
} elseif ($childService = $configurator->getAttribute('service')) {
$class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
} else {
$class = $configurator->getAttribute('class');
}

$definition->setConfigurator(array($class, $configurator->getAttribute('method')));
}
}

foreach ($this->getChildren($service, 'call') as $call) {
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument'));
}

foreach ($this->getChildren($service, 'tag') as $tag) {
$parameters = array();
foreach ($tag->attributes as $name => $node) {
if ('name' === $name) {
continue;
}

if (false !== strpos($name, '-') && false === strpos($name, '_') && !array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) {
$parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue);
}

 $parameters[$name] = XmlUtils::phpize($node->nodeValue);
}

if ('' === $tag->getAttribute('name')) {
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', (string) $service->getAttribute('id'), $file));
}

$definition->addTag($tag->getAttribute('name'), $parameters);
}

foreach ($this->getChildren($service, 'autowiring-type') as $type) {
$definition->addAutowiringType($type->textContent);
}

if ($value = $service->getAttribute('decorates')) {
$renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null;
$priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0;
$definition->setDecoratedService($value, $renameId, $priority);
}

return $definition;
}










private function parseFileToDOM($file)
{
try {
$dom = XmlUtils::loadFile($file, array($this, 'validateSchema'));
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Unable to parse file "%s".', $file), $e->getCode(), $e);
}

$this->validateExtensions($dom, $file);

return $dom;
}







private function processAnonymousServices(\DOMDocument $xml, $file)
{
$definitions = array();
$count = 0;

$xpath = new \DOMXPath($xml);
$xpath->registerNamespace('container', self::NS);


 if (false !== $nodes = $xpath->query('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]')) {
foreach ($nodes as $node) {

 $id = sprintf('%s_%d', hash('sha256', $file), ++$count);
$node->setAttribute('id', $id);

if ($services = $this->getChildren($node, 'service')) {
$definitions[$id] = array($services[0], $file, false);
$services[0]->setAttribute('id', $id);


 
 $services[0]->setAttribute('public', 'false');
}
}
}


 if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) {
foreach ($nodes as $node) {

 $id = sprintf('%s_%d', hash('sha256', $file), ++$count);
$node->setAttribute('id', $id);
$definitions[$id] = array($node, $file, true);
}
}


 krsort($definitions);
foreach ($definitions as $id => $def) {
list($domElement, $file, $wild) = $def;

if (null !== $definition = $this->parseDefinition($domElement, $file)) {
$this->container->setDefinition($id, $definition);
}

if (true === $wild) {
$tmpDomElement = new \DOMElement('_services', null, self::NS);
$domElement->parentNode->replaceChild($tmpDomElement, $domElement);
$tmpDomElement->setAttribute('id', $id);
} else {
$domElement->parentNode->removeChild($domElement);
}
}
}










private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true)
{
$arguments = array();
foreach ($this->getChildren($node, $name) as $arg) {
if ($arg->hasAttribute('name')) {
$arg->setAttribute('key', $arg->getAttribute('name'));
}


 
 if ($arg->hasAttribute('index')) {
$key = 'index_'.$arg->getAttribute('index');
} elseif (!$arg->hasAttribute('key')) {

 $arguments[] = null;
$keys = array_keys($arguments);
$key = array_pop($keys);
} else {
$key = $arg->getAttribute('key');


 if ('parameter' == $name && $lowercase) {
$key = strtolower($key);
}
}

switch ($arg->getAttribute('type')) {
case 'service':
$onInvalid = $arg->getAttribute('on-invalid');
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
if ('ignore' == $onInvalid) {
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
} elseif ('null' == $onInvalid) {
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
}

if ($strict = $arg->getAttribute('strict')) {
$strict = XmlUtils::phpize($strict);
} else {
$strict = true;
}

$arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior, $strict);
break;
case 'expression':
$arguments[$key] = new Expression($arg->nodeValue);
break;
case 'collection':
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, false);
break;
case 'string':
$arguments[$key] = $arg->nodeValue;
break;
case 'constant':
$arguments[$key] = constant(trim($arg->nodeValue));
break;
default:
$arguments[$key] = XmlUtils::phpize($arg->nodeValue);
}
}

return $arguments;
}









private function getChildren(\DOMNode $node, $name)
{
$children = array();
foreach ($node->childNodes as $child) {
if ($child instanceof \DOMElement && $child->localName === $name && $child->namespaceURI === self::NS) {
$children[] = $child;
}
}

return $children;
}










public function validateSchema(\DOMDocument $dom)
{
$schemaLocations = array('http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd'));

if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) {
$items = preg_split('/\s+/', $element);
for ($i = 0, $nb = count($items); $i < $nb; $i += 2) {
if (!$this->container->hasExtension($items[$i])) {
continue;
}

if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) {
$path = str_replace($extension->getNamespace(), str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]);

if (!is_file($path)) {
throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s"', get_class($extension), $path));
}

$schemaLocations[$items[$i]] = $path;
}
}
}

$tmpfiles = array();
$imports = '';
foreach ($schemaLocations as $namespace => $location) {
$parts = explode('/', $location);
if (0 === stripos($location, 'phar://')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
if ($tmpfile) {
copy($location, $tmpfile);
$tmpfiles[] = $tmpfile;
$parts = explode('/', str_replace('\\', '/', $tmpfile));
}
}
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
$location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));

$imports .= sprintf('  <xsd:import namespace="%s" schemaLocation="%s" />'."\n", $namespace, $location);
}

$source = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns="http://symfony.com/schema"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://symfony.com/schema"
    elementFormDefault="qualified">

    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
$imports
</xsd:schema>
EOF
;

$disableEntities = libxml_disable_entity_loader(false);
$valid = @$dom->schemaValidateSource($source);
libxml_disable_entity_loader($disableEntities);

foreach ($tmpfiles as $tmpfile) {
@unlink($tmpfile);
}

return $valid;
}









private function validateExtensions(\DOMDocument $dom, $file)
{
foreach ($dom->documentElement->childNodes as $node) {
if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) {
continue;
}


 if (!$this->container->hasExtension($node->namespaceURI)) {
$extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getNamespace(); }, $this->container->getExtensions()));
throw new InvalidArgumentException(sprintf(
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
$node->tagName,
$file,
$node->namespaceURI,
$extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
));
}
}
}






private function loadFromExtensions(\DOMDocument $xml)
{
foreach ($xml->documentElement->childNodes as $node) {
if (!$node instanceof \DOMElement || $node->namespaceURI === self::NS) {
continue;
}

$values = static::convertDomElementToArray($node);
if (!is_array($values)) {
$values = array();
}

$this->container->loadFromExtension($node->namespaceURI, $values);
}
}




















public static function convertDomElementToArray(\DOMElement $element)
{
return XmlUtils::convertDomElementToArray($element);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader;
use Symfony\Component\Config\FileLocatorInterface;






abstract class FileLoader extends BaseFileLoader
{
protected $container;





public function __construct(ContainerBuilder $container, FileLocatorInterface $locator)
{
$this->container = $container;

parent::__construct($locator);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Resource\DirectoryResource;






class DirectoryLoader extends FileLoader
{



public function load($file, $type = null)
{
$file = rtrim($file, '/');
$path = $this->locator->locate($file);
$this->container->addResource(new DirectoryResource($path));

foreach (scandir($path) as $dir) {
if ('.' !== $dir[0]) {
if (is_dir($path.'/'.$dir)) {
$dir .= '/'; 
 }

$this->setCurrentDir($path);

$this->import($dir, null, false, $path);
}
}
}




public function supports($resource, $type = null)
{
if ('directory' === $type) {
return true;
}

return null === $type && is_string($resource) && '/' === substr($resource, -1);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;






class IniFileLoader extends FileLoader
{



public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);

$this->container->addResource(new FileResource($path));

$result = parse_ini_file($path, true);
if (false === $result || array() === $result) {
throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource));
}

if (isset($result['parameters']) && is_array($result['parameters'])) {
foreach ($result['parameters'] as $key => $value) {
$this->container->setParameter($key, $value);
}
}
}




public function supports($resource, $type = null)
{
return is_string($resource) && 'ini' === pathinfo($resource, PATHINFO_EXTENSION);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Loader\Loader;








class ClosureLoader extends Loader
{
private $container;




public function __construct(ContainerBuilder $container)
{
$this->container = $container;
}




public function load($resource, $type = null)
{
call_user_func($resource, $this->container);
}




public function supports($resource, $type = null)
{
return $resource instanceof \Closure;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Loader;

use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser as YamlParser;
use Symfony\Component\ExpressionLanguage\Expression;








class YamlFileLoader extends FileLoader
{
private $yamlParser;




public function load($resource, $type = null)
{
$path = $this->locator->locate($resource);

$content = $this->loadFile($path);

$this->container->addResource(new FileResource($path));


 if (null === $content) {
return;
}


 $this->parseImports($content, $path);


 if (isset($content['parameters'])) {
if (!is_array($content['parameters'])) {
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $resource));
}

foreach ($content['parameters'] as $key => $value) {
$this->container->setParameter($key, $this->resolveServices($value));
}
}


 $this->loadFromExtensions($content);


 $this->parseDefinitions($content, $resource);
}




public function supports($resource, $type = null)
{
return is_string($resource) && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yml', 'yaml'), true);
}







private function parseImports(array $content, $file)
{
if (!isset($content['imports'])) {
return;
}

if (!is_array($content['imports'])) {
throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file));
}

$defaultDirectory = dirname($file);
foreach ($content['imports'] as $import) {
if (!is_array($import)) {
throw new InvalidArgumentException(sprintf('The values in the "imports" key should be arrays in %s. Check your YAML syntax.', $file));
}

$this->setCurrentDir($defaultDirectory);
$this->import($import['resource'], null, isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false, $file);
}
}







private function parseDefinitions(array $content, $file)
{
if (!isset($content['services'])) {
return;
}

if (!is_array($content['services'])) {
throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
}

foreach ($content['services'] as $id => $service) {
$this->parseDefinition($id, $service, $file);
}
}










private function parseDefinition($id, $service, $file)
{
if (is_string($service) && 0 === strpos($service, '@')) {
$this->container->setAlias($id, substr($service, 1));

return;
}

if (!is_array($service)) {
throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file));
}

if (isset($service['alias'])) {
$public = !array_key_exists('public', $service) || (bool) $service['public'];
$this->container->setAlias($id, new Alias($service['alias'], $public));

return;
}

if (isset($service['parent'])) {
$definition = new DefinitionDecorator($service['parent']);
} else {
$definition = new Definition();
}

if (isset($service['class'])) {
$definition->setClass($service['class']);
}

if (isset($service['shared'])) {
$definition->setShared($service['shared']);
}

if (isset($service['scope'])) {
if ('request' !== $id) {
@trigger_error(sprintf('The "scope" key of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED);
}
$definition->setScope($service['scope'], false);
}

if (isset($service['synthetic'])) {
$definition->setSynthetic($service['synthetic']);
}

if (isset($service['synchronized'])) {
@trigger_error(sprintf('The "synchronized" key of service "%s" in file "%s" is deprecated since version 2.7 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED);
$definition->setSynchronized($service['synchronized'], 'request' !== $id);
}

if (isset($service['lazy'])) {
$definition->setLazy($service['lazy']);
}

if (isset($service['public'])) {
$definition->setPublic($service['public']);
}

if (isset($service['abstract'])) {
$definition->setAbstract($service['abstract']);
}

if (array_key_exists('deprecated', $service)) {
$definition->setDeprecated(true, $service['deprecated']);
}

if (isset($service['factory'])) {
if (is_string($service['factory'])) {
if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
$parts = explode(':', $service['factory']);
$definition->setFactory(array($this->resolveServices('@'.$parts[0]), $parts[1]));
} else {
$definition->setFactory($service['factory']);
}
} else {
$definition->setFactory(array($this->resolveServices($service['factory'][0]), $service['factory'][1]));
}
}

if (isset($service['factory_class'])) {
@trigger_error(sprintf('The "factory_class" key of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $id, $file), E_USER_DEPRECATED);
$definition->setFactoryClass($service['factory_class']);
}

if (isset($service['factory_method'])) {
@trigger_error(sprintf('The "factory_method" key of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $id, $file), E_USER_DEPRECATED);
$definition->setFactoryMethod($service['factory_method']);
}

if (isset($service['factory_service'])) {
@trigger_error(sprintf('The "factory_service" key of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $id, $file), E_USER_DEPRECATED);
$definition->setFactoryService($service['factory_service']);
}

if (isset($service['file'])) {
$definition->setFile($service['file']);
}

if (isset($service['arguments'])) {
$definition->setArguments($this->resolveServices($service['arguments']));
}

if (isset($service['properties'])) {
$definition->setProperties($this->resolveServices($service['properties']));
}

if (isset($service['configurator'])) {
if (is_string($service['configurator'])) {
$definition->setConfigurator($service['configurator']);
} else {
$definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1]));
}
}

if (isset($service['calls'])) {
if (!is_array($service['calls'])) {
throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

foreach ($service['calls'] as $call) {
if (isset($call['method'])) {
$method = $call['method'];
$args = isset($call['arguments']) ? $this->resolveServices($call['arguments']) : array();
} else {
$method = $call[0];
$args = isset($call[1]) ? $this->resolveServices($call[1]) : array();
}

$definition->addMethodCall($method, $args);
}
}

if (isset($service['tags'])) {
if (!is_array($service['tags'])) {
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

foreach ($service['tags'] as $tag) {
if (!is_array($tag)) {
throw new InvalidArgumentException(sprintf('A "tags" entry must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

if (!isset($tag['name'])) {
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
}

if (!is_string($tag['name']) || '' === $tag['name']) {
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file));
}

$name = $tag['name'];
unset($tag['name']);

foreach ($tag as $attribute => $value) {
if (!is_scalar($value) && null !== $value) {
throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s. Check your YAML syntax.', $id, $name, $attribute, $file));
}
}

$definition->addTag($name, $tag);
}
}

if (isset($service['decorates'])) {
if ('' !== $service['decorates'] && '@' === $service['decorates'][0]) {
throw new InvalidArgumentException(sprintf('The value of the "decorates" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['decorates'], substr($service['decorates'], 1)));
}

$renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
$priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0;
$definition->setDecoratedService($service['decorates'], $renameId, $priority);
}

if (isset($service['autowire'])) {
$definition->setAutowired($service['autowire']);
}

if (isset($service['autowiring_types'])) {
if (is_string($service['autowiring_types'])) {
$definition->addAutowiringType($service['autowiring_types']);
} else {
if (!is_array($service['autowiring_types'])) {
throw new InvalidArgumentException(sprintf('Parameter "autowiring_types" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

foreach ($service['autowiring_types'] as $autowiringType) {
if (!is_string($autowiringType)) {
throw new InvalidArgumentException(sprintf('A "autowiring_types" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

$definition->addAutowiringType($autowiringType);
}
}
}

$this->container->setDefinition($id, $definition);
}










protected function loadFile($file)
{
if (!class_exists('Symfony\Component\Yaml\Parser')) {
throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.');
}

if (!stream_is_local($file)) {
throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file));
}

if (!file_exists($file)) {
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file));
}

if (null === $this->yamlParser) {
$this->yamlParser = new YamlParser();
}

try {
$configuration = $this->yamlParser->parse(file_get_contents($file));
} catch (ParseException $e) {
throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e);
}

return $this->validate($configuration, $file);
}











private function validate($content, $file)
{
if (null === $content) {
return $content;
}

if (!is_array($content)) {
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
}

foreach ($content as $namespace => $data) {
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
continue;
}

if (!$this->container->hasExtension($namespace)) {
$extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
throw new InvalidArgumentException(sprintf(
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
$namespace,
$file,
$namespace,
$extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
));
}
}

return $content;
}








private function resolveServices($value)
{
if (is_array($value)) {
$value = array_map(array($this, 'resolveServices'), $value);
} elseif (is_string($value) && 0 === strpos($value, '@=')) {
return new Expression(substr($value, 2));
} elseif (is_string($value) && 0 === strpos($value, '@')) {
if (0 === strpos($value, '@@')) {
$value = substr($value, 1);
$invalidBehavior = null;
} elseif (0 === strpos($value, '@?')) {
$value = substr($value, 2);
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
} else {
$value = substr($value, 1);
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
}

if ('=' === substr($value, -1)) {
$value = substr($value, 0, -1);
$strict = false;
} else {
$strict = true;
}

if (null !== $invalidBehavior) {
$value = new Reference($value, $invalidBehavior, $strict);
}
}

return $value;
}






private function loadFromExtensions(array $content)
{
foreach ($content as $namespace => $values) {
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
continue;
}

if (!is_array($values)) {
$values = array();
}

$this->container->loadFromExtension($namespace, $values);
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\LogicException;






class FrozenParameterBag extends ParameterBag
{








public function __construct(array $parameters = array())
{
$this->parameters = $parameters;
$this->resolved = true;
}




public function clear()
{
throw new LogicException('Impossible to call clear() on a frozen ParameterBag.');
}




public function add(array $parameters)
{
throw new LogicException('Impossible to call add() on a frozen ParameterBag.');
}




public function set($name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}




public function remove($name)
{
throw new LogicException('Impossible to call remove() on a frozen ParameterBag.');
}
}
<?php










namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;






class ParameterBag implements ParameterBagInterface
{
protected $parameters = array();
protected $resolved = false;




public function __construct(array $parameters = array())
{
$this->add($parameters);
}




public function clear()
{
$this->parameters = array();
}






public function add(array $parameters)
{
foreach ($parameters as $key => $value) {
$this->parameters[strtolower($key)] = $value;
}
}




public function all()
{
return $this->parameters;
}




public function get($name)
{
$name = strtolower($name);

if (!array_key_exists($name, $this->parameters)) {
if (!$name) {
throw new ParameterNotFoundException($name);
}

$alternatives = array();
foreach ($this->parameters as $key => $parameterValue) {
$lev = levenshtein($name, $key);
if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) {
$alternatives[] = $key;
}
}

throw new ParameterNotFoundException($name, null, null, null, $alternatives);
}

return $this->parameters[$name];
}







public function set($name, $value)
{
$this->parameters[strtolower($name)] = $value;
}




public function has($name)
{
return array_key_exists(strtolower($name), $this->parameters);
}






public function remove($name)
{
unset($this->parameters[strtolower($name)]);
}




public function resolve()
{
if ($this->resolved) {
return;
}

$parameters = array();
foreach ($this->parameters as $key => $value) {
try {
$value = $this->resolveValue($value);
$parameters[$key] = $this->unescapeValue($value);
} catch (ParameterNotFoundException $e) {
$e->setSourceKey($key);

throw $e;
}
}

$this->parameters = $parameters;
$this->resolved = true;
}













public function resolveValue($value, array $resolving = array())
{
if (is_array($value)) {
$args = array();
foreach ($value as $k => $v) {
$args[$this->resolveValue($k, $resolving)] = $this->resolveValue($v, $resolving);
}

return $args;
}

if (!is_string($value)) {
return $value;
}

return $this->resolveString($value, $resolving);
}













public function resolveString($value, array $resolving = array())
{

 
 
 if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
$key = strtolower($match[1]);

if (isset($resolving[$key])) {
throw new ParameterCircularReferenceException(array_keys($resolving));
}

$resolving[$key] = true;

return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
}

$self = $this;

return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($self, $resolving, $value) {

 if (!isset($match[1])) {
return '%%';
}

$key = strtolower($match[1]);
if (isset($resolving[$key])) {
throw new ParameterCircularReferenceException(array_keys($resolving));
}

$resolved = $self->get($key);

if (!is_string($resolved) && !is_numeric($resolved)) {
throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".', $key, gettype($resolved), $value));
}

$resolved = (string) $resolved;
$resolving[$key] = true;

return $self->isResolved() ? $resolved : $self->resolveString($resolved, $resolving);
}, $value);
}

public function isResolved()
{
return $this->resolved;
}




public function escapeValue($value)
{
if (is_string($value)) {
return str_replace('%', '%%', $value);
}

if (is_array($value)) {
$result = array();
foreach ($value as $k => $v) {
$result[$k] = $this->escapeValue($v);
}

return $result;
}

return $value;
}




public function unescapeValue($value)
{
if (is_string($value)) {
return str_replace('%%', '%', $value);
}

if (is_array($value)) {
$result = array();
foreach ($value as $k => $v) {
$result[$k] = $this->unescapeValue($v);
}

return $result;
}

return $value;
}
}
<?php










namespace Symfony\Component\DependencyInjection\ParameterBag;

use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;






interface ParameterBagInterface
{





public function clear();








public function add(array $parameters);






public function all();










public function get($name);









public function set($name, $value);








public function has($name);




public function resolve();








public function resolveValue($value);








public function escapeValue($value);








public function unescapeValue($value);
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;




class LegacyContainerBuilderTest extends TestCase
{
public function testCreateServiceFactoryMethod()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'Bar\FooClass')->setFactoryClass('Bar\FooClass')->setFactoryMethod('getInstance')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')));
$builder->setParameter('value', 'bar');
$this->assertTrue($builder->get('foo1')->called, '->createService() calls the factory method to create the service instance');
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() passes the arguments to the factory method');
}

public function testCreateServiceFactoryService()
{
$builder = new ContainerBuilder();
$builder->register('baz_service')->setFactoryService('baz_factory')->setFactoryMethod('getInstance');
$builder->register('baz_factory', 'BazClass');

$this->assertInstanceOf('BazClass', $builder->get('baz_service'));
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;

class ContainerTest extends TestCase
{
public function testConstructor()
{
$sc = new Container();
$this->assertSame($sc, $sc->get('service_container'), '__construct() automatically registers itself as a service');

$sc = new Container(new ParameterBag(array('foo' => 'bar')));
$this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '__construct() takes an array of parameters as its first argument');
}




public function testCamelize($id, $expected)
{
$this->assertEquals($expected, Container::camelize($id), sprintf('Container::camelize("%s")', $id));
}

public function dataForTestCamelize()
{
return array(
array('foo_bar', 'FooBar'),
array('foo.bar', 'Foo_Bar'),
array('foo.bar_baz', 'Foo_BarBaz'),
array('foo._bar', 'Foo_Bar'),
array('foo_.bar', 'Foo_Bar'),
array('_foo', 'Foo'),
array('.foo', '_Foo'),
array('foo_', 'Foo'),
array('foo.', 'Foo_'),
array('foo\bar', 'Foo_Bar'),
);
}




public function testUnderscore($id, $expected)
{
$this->assertEquals($expected, Container::underscore($id), sprintf('Container::underscore("%s")', $id));
}

public function dataForTestUnderscore()
{
return array(
array('FooBar', 'foo_bar'),
array('Foo_Bar', 'foo.bar'),
array('Foo_BarBaz', 'foo.bar_baz'),
array('FooBar_BazQux', 'foo_bar.baz_qux'),
array('_Foo', '.foo'),
array('Foo_', 'foo.'),
);
}

public function testCompile()
{
$sc = new Container(new ParameterBag(array('foo' => 'bar')));
$this->assertFalse($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
$sc->compile();
$this->assertTrue($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag');
$this->assertInstanceOf('Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag', $sc->getParameterBag(), '->compile() changes the parameter bag to a FrozenParameterBag instance');
$this->assertEquals(array('foo' => 'bar'), $sc->getParameterBag()->all(), '->compile() copies the current parameters to the new parameter bag');
}

public function testIsFrozen()
{
$sc = new Container(new ParameterBag(array('foo' => 'bar')));
$this->assertFalse($sc->isFrozen(), '->isFrozen() returns false if the parameters are not frozen');
$sc->compile();
$this->assertTrue($sc->isFrozen(), '->isFrozen() returns true if the parameters are frozen');
}

public function testGetParameterBag()
{
$sc = new Container();
$this->assertEquals(array(), $sc->getParameterBag()->all(), '->getParameterBag() returns an empty array if no parameter has been defined');
}

public function testGetSetParameter()
{
$sc = new Container(new ParameterBag(array('foo' => 'bar')));
$sc->setParameter('bar', 'foo');
$this->assertEquals('foo', $sc->getParameter('bar'), '->setParameter() sets the value of a new parameter');

$sc->setParameter('foo', 'baz');
$this->assertEquals('baz', $sc->getParameter('foo'), '->setParameter() overrides previously set parameter');

$sc->setParameter('Foo', 'baz1');
$this->assertEquals('baz1', $sc->getParameter('foo'), '->setParameter() converts the key to lowercase');
$this->assertEquals('baz1', $sc->getParameter('FOO'), '->getParameter() converts the key to lowercase');

try {
$sc->getParameter('baba');
$this->fail('->getParameter() thrown an \InvalidArgumentException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist');
}
}

public function testGetServiceIds()
{
$sc = new Container();
$sc->set('foo', $obj = new \stdClass());
$sc->set('bar', $obj = new \stdClass());
$this->assertEquals(array('service_container', 'foo', 'bar'), $sc->getServiceIds(), '->getServiceIds() returns all defined service ids');

$sc = new ProjectServiceContainer();
$sc->set('foo', $obj = new \stdClass());
$this->assertEquals(array('scoped', 'scoped_foo', 'scoped_synchronized_foo', 'inactive', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container', 'foo'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods, followed by service ids defined by set()');
}

public function testSet()
{
$sc = new Container();
$sc->set('foo', $foo = new \stdClass());
$this->assertSame($foo, $sc->get('foo'), '->set() sets a service');
}

public function testSetWithNullResetTheService()
{
$sc = new Container();
$sc->set('foo', null);
$this->assertFalse($sc->has('foo'), '->set() with null service resets the service');
}





public function testSetDoesNotAllowPrototypeScope()
{
$c = new Container();
$c->set('foo', new \stdClass(), Container::SCOPE_PROTOTYPE);
}





public function testSetDoesNotAllowInactiveScope()
{
$c = new Container();
$c->addScope(new Scope('foo'));
$c->set('foo', new \stdClass(), 'foo');
}




public function testSetAlsoSetsScopedService()
{
$c = new Container();
$c->addScope(new Scope('foo'));
$c->enterScope('foo');
$c->set('foo', $foo = new \stdClass(), 'foo');

$scoped = $this->getField($c, 'scopedServices');
$this->assertTrue(isset($scoped['foo']['foo']), '->set() sets a scoped service');
$this->assertSame($foo, $scoped['foo']['foo'], '->set() sets a scoped service');
}




public function testSetAlsoCallsSynchronizeService()
{
$c = new ProjectServiceContainer();
$c->addScope(new Scope('foo'));
$c->enterScope('foo');
$c->set('scoped_synchronized_foo', $bar = new \stdClass(), 'foo');
$this->assertTrue($c->synchronized, '->set() calls synchronize*Service() if it is defined for the service');
}

public function testSetReplacesAlias()
{
$c = new ProjectServiceContainer();

$c->set('alias', $foo = new \stdClass());
$this->assertSame($foo, $c->get('alias'), '->set() replaces an existing alias');
}

public function testGet()
{
$sc = new ProjectServiceContainer();
$sc->set('foo', $foo = new \stdClass());
$this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
$this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
$this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
$this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
$this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
$this->assertSame($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined');

$sc->set('bar', $bar = new \stdClass());
$this->assertSame($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()');

try {
$sc->get('');
$this->fail('->get() throws a \InvalidArgumentException exception if the service is empty');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty');
}
$this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
}

public function testGetThrowServiceNotFoundException()
{
$sc = new ProjectServiceContainer();
$sc->set('foo', $foo = new \stdClass());
$sc->set('baz', $foo = new \stdClass());

try {
$sc->get('foo1');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent service "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
}

try {
$sc->get('bag');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent service "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices');
}
}

public function testGetCircularReference()
{
$sc = new ProjectServiceContainer();
try {
$sc->get('circular');
$this->fail('->get() throws a ServiceCircularReferenceException if it contains circular reference');
} catch (\Exception $e) {
$this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException', $e, '->get() throws a ServiceCircularReferenceException if it contains circular reference');
$this->assertStringStartsWith('Circular reference detected for service "circular"', $e->getMessage(), '->get() throws a \LogicException if it contains circular reference');
}
}




public function testGetReturnsNullOnInactiveScope()
{
$sc = new ProjectServiceContainer();
$this->assertNull($sc->get('inactive', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}





public function testGetSyntheticServiceAlwaysThrows()
{
require_once __DIR__.'/Fixtures/php/services9.php';

$container = new \ProjectServiceContainer();
$container->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE);
}

public function testHas()
{
$sc = new ProjectServiceContainer();
$sc->set('foo', new \stdClass());
$this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist');
$this->assertTrue($sc->has('foo'), '->has() returns true if the service exists');
$this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined');
$this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined');
$this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined');
$this->assertTrue($sc->has('foo\\baz'), '->has() returns true if a get*Method() is defined');
}

public function testInitialized()
{
$sc = new ProjectServiceContainer();
$sc->set('foo', new \stdClass());
$this->assertTrue($sc->initialized('foo'), '->initialized() returns true if service is loaded');
$this->assertFalse($sc->initialized('foo1'), '->initialized() returns false if service is not loaded');
$this->assertFalse($sc->initialized('bar'), '->initialized() returns false if a service is defined, but not currently loaded');
$this->assertFalse($sc->initialized('alias'), '->initialized() returns false if an aliased service is not initialized');

$sc->set('bar', new \stdClass());
$this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized');
}

public function testReset()
{
$c = new Container();
$c->set('bar', new \stdClass());

$c->reset();

$this->assertNull($c->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}






public function testCannotResetInActiveScope()
{
$c = new Container();
$c->addScope(new Scope('foo'));
$c->set('bar', new \stdClass());

$c->enterScope('foo');

$c->reset();
}




public function testResetAfterLeavingScope()
{
$c = new Container();
$c->addScope(new Scope('foo'));
$c->set('bar', new \stdClass());

$c->enterScope('foo');
$c->leaveScope('foo');

$c->reset();

$this->assertNull($c->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}




public function testEnterLeaveCurrentScope()
{
$container = new ProjectServiceContainer();
$container->addScope(new Scope('foo'));

$container->enterScope('foo');
$container->set('foo', new \stdClass(), 'foo');
$scoped1 = $container->get('scoped');
$scopedFoo1 = $container->get('scoped_foo');

$container->enterScope('foo');
$container->set('foo', new \stdClass(), 'foo');
$scoped2 = $container->get('scoped');
$scoped3 = $container->get('SCOPED');
$scopedFoo2 = $container->get('scoped_foo');

$container->set('foo', null, 'foo');
$container->leaveScope('foo');
$scoped4 = $container->get('scoped');
$scopedFoo3 = $container->get('scoped_foo');

$this->assertNotSame($scoped1, $scoped2);
$this->assertSame($scoped2, $scoped3);
$this->assertSame($scoped1, $scoped4);
$this->assertNotSame($scopedFoo1, $scopedFoo2);
$this->assertSame($scopedFoo1, $scopedFoo3);
}




public function testEnterLeaveScopeWithChildScopes()
{
$container = new Container();
$container->addScope(new Scope('foo'));
$container->addScope(new Scope('bar', 'foo'));

$this->assertFalse($container->isScopeActive('foo'));

$container->enterScope('foo');
$container->enterScope('bar');

$this->assertTrue($container->isScopeActive('foo'));
$this->assertFalse($container->has('a'));

$a = new \stdClass();
$container->set('a', $a, 'bar');

$scoped = $this->getField($container, 'scopedServices');
$this->assertTrue(isset($scoped['bar']['a']));
$this->assertSame($a, $scoped['bar']['a']);
$this->assertTrue($container->has('a'));

$container->leaveScope('foo');

$scoped = $this->getField($container, 'scopedServices');
$this->assertFalse(isset($scoped['bar']));
$this->assertFalse($container->isScopeActive('foo'));
$this->assertFalse($container->has('a'));
}




public function testEnterScopeRecursivelyWithInactiveChildScopes()
{
$container = new Container();
$container->addScope(new Scope('foo'));
$container->addScope(new Scope('bar', 'foo'));

$this->assertFalse($container->isScopeActive('foo'));

$container->enterScope('foo');

$this->assertTrue($container->isScopeActive('foo'));
$this->assertFalse($container->isScopeActive('bar'));
$this->assertFalse($container->has('a'));

$a = new \stdClass();
$container->set('a', $a, 'foo');

$scoped = $this->getField($container, 'scopedServices');
$this->assertTrue(isset($scoped['foo']['a']));
$this->assertSame($a, $scoped['foo']['a']);
$this->assertTrue($container->has('a'));

$container->enterScope('foo');

$scoped = $this->getField($container, 'scopedServices');
$this->assertFalse(isset($scoped['a']));
$this->assertTrue($container->isScopeActive('foo'));
$this->assertFalse($container->isScopeActive('bar'));
$this->assertFalse($container->has('a'));

$container->enterScope('bar');

$this->assertTrue($container->isScopeActive('bar'));

$container->leaveScope('foo');

$this->assertTrue($container->isScopeActive('foo'));
$this->assertFalse($container->isScopeActive('bar'));
$this->assertTrue($container->has('a'));
}




public function testEnterChildScopeRecursively()
{
$container = new Container();
$container->addScope(new Scope('foo'));
$container->addScope(new Scope('bar', 'foo'));

$container->enterScope('foo');
$container->enterScope('bar');

$this->assertTrue($container->isScopeActive('bar'));
$this->assertFalse($container->has('a'));

$a = new \stdClass();
$container->set('a', $a, 'bar');

$scoped = $this->getField($container, 'scopedServices');
$this->assertTrue(isset($scoped['bar']['a']));
$this->assertSame($a, $scoped['bar']['a']);
$this->assertTrue($container->has('a'));

$container->enterScope('bar');

$scoped = $this->getField($container, 'scopedServices');
$this->assertFalse(isset($scoped['a']));
$this->assertTrue($container->isScopeActive('foo'));
$this->assertTrue($container->isScopeActive('bar'));
$this->assertFalse($container->has('a'));

$container->leaveScope('bar');

$this->assertTrue($container->isScopeActive('foo'));
$this->assertTrue($container->isScopeActive('bar'));
$this->assertTrue($container->has('a'));
}





public function testEnterScopeNotAdded()
{
$container = new Container();
$container->enterScope('foo');
}





public function testEnterScopeDoesNotAllowInactiveParentScope()
{
$container = new Container();
$container->addScope(new Scope('foo'));
$container->addScope(new Scope('bar', 'foo'));
$container->enterScope('bar');
}




public function testLeaveScopeNotActive()
{
$container = new Container();
$container->addScope(new Scope('foo'));

try {
$container->leaveScope('foo');
$this->fail('->leaveScope() throws a \LogicException if the scope is not active yet');
} catch (\Exception $e) {
$this->assertInstanceOf('\LogicException', $e, '->leaveScope() throws a \LogicException if the scope is not active yet');
$this->assertEquals('The scope "foo" is not active.', $e->getMessage(), '->leaveScope() throws a \LogicException if the scope is not active yet');
}

try {
$container->leaveScope('bar');
$this->fail('->leaveScope() throws a \LogicException if the scope does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('\LogicException', $e, '->leaveScope() throws a \LogicException if the scope does not exist');
$this->assertEquals('The scope "bar" is not active.', $e->getMessage(), '->leaveScope() throws a \LogicException if the scope does not exist');
}
}






public function testAddScopeDoesNotAllowBuiltInScopes($scope)
{
$container = new Container();
$container->addScope(new Scope($scope));
}





public function testAddScopeDoesNotAllowExistingScope()
{
$container = new Container();
$container->addScope(new Scope('foo'));
$container->addScope(new Scope('foo'));
}






public function testAddScopeDoesNotAllowInvalidParentScope($scope)
{
$c = new Container();
$c->addScope(new Scope('foo', $scope));
}




public function testAddScope()
{
$c = new Container();
$c->addScope(new Scope('foo'));
$c->addScope(new Scope('bar', 'foo'));

$this->assertSame(array('foo' => 'container', 'bar' => 'foo'), $this->getField($c, 'scopes'));
$this->assertSame(array('foo' => array('bar'), 'bar' => array()), $this->getField($c, 'scopeChildren'));

$c->addScope(new Scope('baz', 'bar'));

$this->assertSame(array('foo' => 'container', 'bar' => 'foo', 'baz' => 'bar'), $this->getField($c, 'scopes'));
$this->assertSame(array('foo' => array('bar', 'baz'), 'bar' => array('baz'), 'baz' => array()), $this->getField($c, 'scopeChildren'));
}




public function testHasScope()
{
$c = new Container();

$this->assertFalse($c->hasScope('foo'));
$c->addScope(new Scope('foo'));
$this->assertTrue($c->hasScope('foo'));
}





public function testGetThrowsException()
{
$c = new ProjectServiceContainer();

try {
$c->get('throw_exception');
} catch (\Exception $e) {

 }


 $c->get('throw_exception');
}

public function testGetThrowsExceptionOnServiceConfiguration()
{
$c = new ProjectServiceContainer();

try {
$c->get('throws_exception_on_service_configuration');
} catch (\Exception $e) {

 }

$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));


 try {
$c->get('throws_exception_on_service_configuration');
} catch (\Exception $e) {

 }
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
}




public function testIsScopeActive()
{
$c = new Container();

$this->assertFalse($c->isScopeActive('foo'));
$c->addScope(new Scope('foo'));

$this->assertFalse($c->isScopeActive('foo'));
$c->enterScope('foo');

$this->assertTrue($c->isScopeActive('foo'));
$c->leaveScope('foo');

$this->assertFalse($c->isScopeActive('foo'));
}

public function getLegacyInvalidParentScopes()
{
return array(
array(ContainerInterface::SCOPE_PROTOTYPE),
array('bar'),
);
}

public function getLegacyBuiltInScopes()
{
return array(
array(ContainerInterface::SCOPE_CONTAINER),
array(ContainerInterface::SCOPE_PROTOTYPE),
);
}

protected function getField($obj, $field)
{
$reflection = new \ReflectionProperty($obj, $field);
$reflection->setAccessible(true);

return $reflection->getValue($obj);
}

public function testAlias()
{
$c = new ProjectServiceContainer();

$this->assertTrue($c->has('alias'));
$this->assertSame($c->get('alias'), $c->get('bar'));
}

public function testThatCloningIsNotSupported()
{
$class = new \ReflectionClass('Symfony\Component\DependencyInjection\Container');
$clone = $class->getMethod('__clone');
if (PHP_VERSION_ID >= 50400) {
$this->assertFalse($class->isCloneable());
}
$this->assertTrue($clone->isPrivate());
}
}

class ProjectServiceContainer extends Container
{
public $__bar;
public $__foo_bar;
public $__foo_baz;
public $synchronized;

public function __construct()
{
parent::__construct();

$this->__bar = new \stdClass();
$this->__foo_bar = new \stdClass();
$this->__foo_baz = new \stdClass();
$this->synchronized = false;
$this->aliases = array('alias' => 'bar');
}

protected function getScopedService()
{
if (!$this->isScopeActive('foo')) {
throw new \RuntimeException('Invalid call');
}

return $this->services['scoped'] = $this->scopedServices['foo']['scoped'] = new \stdClass();
}

protected function getScopedFooService()
{
if (!$this->isScopeActive('foo')) {
throw new \RuntimeException('invalid call');
}

return $this->services['scoped_foo'] = $this->scopedServices['foo']['scoped_foo'] = new \stdClass();
}

protected function getScopedSynchronizedFooService()
{
if (!$this->isScopeActive('foo')) {
throw new \RuntimeException('invalid call');
}

return $this->services['scoped_bar'] = $this->scopedServices['foo']['scoped_bar'] = new \stdClass();
}

protected function synchronizeFooService()
{

 $this->get('foo');
}

protected function synchronizeScopedSynchronizedFooService()
{
$this->synchronized = true;
}

protected function getInactiveService()
{
throw new InactiveScopeException('request', 'request');
}

protected function getBarService()
{
return $this->__bar;
}

protected function getFooBarService()
{
return $this->__foo_bar;
}

protected function getFoo_BazService()
{
return $this->__foo_baz;
}

protected function getCircularService()
{
return $this->get('circular');
}

protected function getThrowExceptionService()
{
throw new \Exception('Something went terribly wrong!');
}

protected function getThrowsExceptionOnServiceConfigurationService()
{
$this->services['throws_exception_on_service_configuration'] = $instance = new \stdClass();

throw new \Exception('Something was terribly wrong while trying to configure the service!');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\LazyProxy\Instantiator;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;






class RealServiceInstantiatorTest extends TestCase
{
public function testInstantiateProxy()
{
$instantiator = new RealServiceInstantiator();
$instance = new \stdClass();
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
$callback = function () use ($instance) {
return $instance;
};

$this->assertSame($instance, $instantiator->instantiateProxy($container, new Definition(), 'foo', $callback));
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\LazyProxy\PhpDumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;






class NullDumperTest extends TestCase
{
public function testNullDumper()
{
$dumper = new NullDumper();
$definition = new Definition('stdClass');

$this->assertFalse($dumper->isProxyCandidate($definition));
$this->assertSame('', $dumper->getProxyFactoryCode($definition, 'foo'));
$this->assertSame('', $dumper->getProxyCode($definition));
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\DefinitionDecorator;

class DefinitionDecoratorTest extends TestCase
{
public function testConstructor()
{
$def = new DefinitionDecorator('foo');

$this->assertEquals('foo', $def->getParent());
$this->assertEquals(array(), $def->getChanges());
}




public function testSetProperty($property, $changeKey)
{
$def = new DefinitionDecorator('foo');

$getter = 'get'.ucfirst($property);
$setter = 'set'.ucfirst($property);

$this->assertNull($def->$getter());
$this->assertSame($def, $def->$setter('foo'));
$this->assertEquals('foo', $def->$getter());
$this->assertEquals(array($changeKey => true), $def->getChanges());
}

public function getPropertyTests()
{
return array(
array('class', 'class'),
array('factory', 'factory'),
array('configurator', 'configurator'),
array('file', 'file'),
);
}





public function testLegacySetProperty($property, $changeKey)
{
$def = new DefinitionDecorator('foo');

$getter = 'get'.ucfirst($property);
$setter = 'set'.ucfirst($property);

$this->assertNull($def->$getter());
$this->assertSame($def, $def->$setter('foo'));
$this->assertEquals('foo', $def->$getter());
$this->assertEquals(array($changeKey => true), $def->getChanges());
}

public function provideLegacyPropertyTests()
{
return array(
array('factoryClass', 'factory_class'),
array('factoryMethod', 'factory_method'),
array('factoryService', 'factory_service'),
);
}

public function testSetPublic()
{
$def = new DefinitionDecorator('foo');

$this->assertTrue($def->isPublic());
$this->assertSame($def, $def->setPublic(false));
$this->assertFalse($def->isPublic());
$this->assertEquals(array('public' => true), $def->getChanges());
}

public function testSetLazy()
{
$def = new DefinitionDecorator('foo');

$this->assertFalse($def->isLazy());
$this->assertSame($def, $def->setLazy(false));
$this->assertFalse($def->isLazy());
$this->assertEquals(array('lazy' => true), $def->getChanges());
}

public function testSetAutowired()
{
$def = new DefinitionDecorator('foo');

$this->assertFalse($def->isAutowired());
$this->assertSame($def, $def->setAutowired(false));
$this->assertFalse($def->isAutowired());
$this->assertEquals(array('autowire' => true), $def->getChanges());
}

public function testSetArgument()
{
$def = new DefinitionDecorator('foo');

$this->assertEquals(array(), $def->getArguments());
$this->assertSame($def, $def->replaceArgument(0, 'foo'));
$this->assertEquals(array('index_0' => 'foo'), $def->getArguments());
}




public function testReplaceArgumentShouldRequireIntegerIndex()
{
$def = new DefinitionDecorator('foo');

$def->replaceArgument('0', 'foo');
}

public function testReplaceArgument()
{
$def = new DefinitionDecorator('foo');

$def->setArguments(array(0 => 'foo', 1 => 'bar'));
$this->assertEquals('foo', $def->getArgument(0));
$this->assertEquals('bar', $def->getArgument(1));

$this->assertSame($def, $def->replaceArgument(1, 'baz'));
$this->assertEquals('foo', $def->getArgument(0));
$this->assertEquals('baz', $def->getArgument(1));

$this->assertEquals(array(0 => 'foo', 1 => 'bar', 'index_1' => 'baz'), $def->getArguments());
}




public function testGetArgumentShouldCheckBounds()
{
$def = new DefinitionDecorator('foo');

$def->setArguments(array(0 => 'foo'));
$def->replaceArgument(0, 'foo');

$def->getArgument(1);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ContainerInterface;

class DefinitionTest extends TestCase
{
public function testConstructor()
{
$def = new Definition('stdClass');
$this->assertEquals('stdClass', $def->getClass(), '__construct() takes the class name as its first argument');

$def = new Definition('stdClass', array('foo'));
$this->assertEquals(array('foo'), $def->getArguments(), '__construct() takes an optional array of arguments as its second argument');
}

public function testSetGetFactory()
{
$def = new Definition('stdClass');

$this->assertSame($def, $def->setFactory('foo'), '->setFactory() implements a fluent interface');
$this->assertEquals('foo', $def->getFactory(), '->getFactory() returns the factory');

$def->setFactory('Foo::bar');
$this->assertEquals(array('Foo', 'bar'), $def->getFactory(), '->setFactory() converts string static method call to the array');
}

public function testSetGetClass()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->setClass('foo'), '->setClass() implements a fluent interface');
$this->assertEquals('foo', $def->getClass(), '->getClass() returns the class name');
}

public function testSetGetDecoratedService()
{
$def = new Definition('stdClass');
$this->assertNull($def->getDecoratedService());
$def->setDecoratedService('foo', 'foo.renamed', 5);
$this->assertEquals(array('foo', 'foo.renamed', 5), $def->getDecoratedService());
$def->setDecoratedService(null);
$this->assertNull($def->getDecoratedService());

$def = new Definition('stdClass');
$this->assertNull($def->getDecoratedService());
$def->setDecoratedService('foo', 'foo.renamed');
$this->assertEquals(array('foo', 'foo.renamed', 0), $def->getDecoratedService());
$def->setDecoratedService(null);
$this->assertNull($def->getDecoratedService());

$def = new Definition('stdClass');
$def->setDecoratedService('foo');
$this->assertEquals(array('foo', null, 0), $def->getDecoratedService());
$def->setDecoratedService(null);
$this->assertNull($def->getDecoratedService());

$def = new Definition('stdClass');

if (method_exists($this, 'expectException')) {
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('The decorated service inner name for "foo" must be different than the service name itself.');
} else {
$this->setExpectedException('InvalidArgumentException', 'The decorated service inner name for "foo" must be different than the service name itself.');
}

$def->setDecoratedService('foo', 'foo');
}

public function testArguments()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->setArguments(array('foo')), '->setArguments() implements a fluent interface');
$this->assertEquals(array('foo'), $def->getArguments(), '->getArguments() returns the arguments');
$this->assertSame($def, $def->addArgument('bar'), '->addArgument() implements a fluent interface');
$this->assertEquals(array('foo', 'bar'), $def->getArguments(), '->addArgument() adds an argument');
}

public function testMethodCalls()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->setMethodCalls(array(array('foo', array('foo')))), '->setMethodCalls() implements a fluent interface');
$this->assertEquals(array(array('foo', array('foo'))), $def->getMethodCalls(), '->getMethodCalls() returns the methods to call');
$this->assertSame($def, $def->addMethodCall('bar', array('bar')), '->addMethodCall() implements a fluent interface');
$this->assertEquals(array(array('foo', array('foo')), array('bar', array('bar'))), $def->getMethodCalls(), '->addMethodCall() adds a method to call');
$this->assertTrue($def->hasMethodCall('bar'), '->hasMethodCall() returns true if first argument is a method to call registered');
$this->assertFalse($def->hasMethodCall('no_registered'), '->hasMethodCall() returns false if first argument is not a method to call registered');
$this->assertSame($def, $def->removeMethodCall('bar'), '->removeMethodCall() implements a fluent interface');
$this->assertEquals(array(array('foo', array('foo'))), $def->getMethodCalls(), '->removeMethodCall() removes a method to call');
}





public function testExceptionOnEmptyMethodCall()
{
$def = new Definition('stdClass');
$def->addMethodCall('');
}

public function testSetGetFile()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->setFile('foo'), '->setFile() implements a fluent interface');
$this->assertEquals('foo', $def->getFile(), '->getFile() returns the file to include');
}

public function testSetIsShared()
{
$def = new Definition('stdClass');
$this->assertTrue($def->isShared(), '->isShared() returns true by default');
$this->assertSame($def, $def->setShared(false), '->setShared() implements a fluent interface');
$this->assertFalse($def->isShared(), '->isShared() returns false if the instance must not be shared');
}




public function testPrototypeScopedDefinitionAreNotShared()
{
$def = new Definition('stdClass');
$def->setScope(ContainerInterface::SCOPE_PROTOTYPE);

$this->assertFalse($def->isShared());
$this->assertEquals(ContainerInterface::SCOPE_PROTOTYPE, $def->getScope());
}




public function testSetGetScope()
{
$def = new Definition('stdClass');
$this->assertEquals('container', $def->getScope());
$this->assertSame($def, $def->setScope('foo'));
$this->assertEquals('foo', $def->getScope());
}

public function testSetIsPublic()
{
$def = new Definition('stdClass');
$this->assertTrue($def->isPublic(), '->isPublic() returns true by default');
$this->assertSame($def, $def->setPublic(false), '->setPublic() implements a fluent interface');
$this->assertFalse($def->isPublic(), '->isPublic() returns false if the instance must not be public.');
}

public function testSetIsSynthetic()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isSynthetic(), '->isSynthetic() returns false by default');
$this->assertSame($def, $def->setSynthetic(true), '->setSynthetic() implements a fluent interface');
$this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the service is synthetic.');
}




public function testLegacySetIsSynchronized()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isSynchronized(), '->isSynchronized() returns false by default');
$this->assertSame($def, $def->setSynchronized(true), '->setSynchronized() implements a fluent interface');
$this->assertTrue($def->isSynchronized(), '->isSynchronized() returns true if the service is synchronized.');
}

public function testSetIsLazy()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isLazy(), '->isLazy() returns false by default');
$this->assertSame($def, $def->setLazy(true), '->setLazy() implements a fluent interface');
$this->assertTrue($def->isLazy(), '->isLazy() returns true if the service is lazy.');
}

public function testSetIsAbstract()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isAbstract(), '->isAbstract() returns false by default');
$this->assertSame($def, $def->setAbstract(true), '->setAbstract() implements a fluent interface');
$this->assertTrue($def->isAbstract(), '->isAbstract() returns true if the instance must not be public.');
}

public function testSetIsDeprecated()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isDeprecated(), '->isDeprecated() returns false by default');
$this->assertSame($def, $def->setDeprecated(true), '->setDeprecated() implements a fluent interface');
$this->assertTrue($def->isDeprecated(), '->isDeprecated() returns true if the instance should not be used anymore.');
$this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template');
}





public function testSetDeprecatedWithInvalidDeprecationTemplate($message)
{
$def = new Definition('stdClass');
$def->setDeprecated(false, $message);
}

public function invalidDeprecationMessageProvider()
{
return array(
"With \rs" => array("invalid \r message %service_id%"),
"With \ns" => array("invalid \n message %service_id%"),
'With */s' => array('invalid */ message %service_id%'),
'message not containing require %service_id% variable' => array('this is deprecated'),
);
}

public function testSetGetConfigurator()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->setConfigurator('foo'), '->setConfigurator() implements a fluent interface');
$this->assertEquals('foo', $def->getConfigurator(), '->getConfigurator() returns the configurator');
}

public function testClearTags()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface');
$def->addTag('foo', array('foo' => 'bar'));
$def->clearTags();
$this->assertEquals(array(), $def->getTags(), '->clearTags() removes all current tags');
}

public function testClearTag()
{
$def = new Definition('stdClass');
$this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface');
$def->addTag('1foo1', array('foo1' => 'bar1'));
$def->addTag('2foo2', array('foo2' => 'bar2'));
$def->addTag('3foo3', array('foo3' => 'bar3'));
$def->clearTag('2foo2');
$this->assertTrue($def->hasTag('1foo1'));
$this->assertFalse($def->hasTag('2foo2'));
$this->assertTrue($def->hasTag('3foo3'));
$def->clearTag('1foo1');
$this->assertFalse($def->hasTag('1foo1'));
$this->assertTrue($def->hasTag('3foo3'));
}

public function testTags()
{
$def = new Definition('stdClass');
$this->assertEquals(array(), $def->getTag('foo'), '->getTag() returns an empty array if the tag is not defined');
$this->assertFalse($def->hasTag('foo'));
$this->assertSame($def, $def->addTag('foo'), '->addTag() implements a fluent interface');
$this->assertTrue($def->hasTag('foo'));
$this->assertEquals(array(array()), $def->getTag('foo'), '->getTag() returns attributes for a tag name');
$def->addTag('foo', array('foo' => 'bar'));
$this->assertEquals(array(array(), array('foo' => 'bar')), $def->getTag('foo'), '->addTag() can adds the same tag several times');
$def->addTag('bar', array('bar' => 'bar'));
$this->assertEquals($def->getTags(), array(
'foo' => array(array(), array('foo' => 'bar')),
'bar' => array(array('bar' => 'bar')),
), '->getTags() returns all tags');
}

public function testSetArgument()
{
$def = new Definition('stdClass');

$def->addArgument('foo');
$this->assertSame(array('foo'), $def->getArguments());

$this->assertSame($def, $def->replaceArgument(0, 'moo'));
$this->assertSame(array('moo'), $def->getArguments());

$def->addArgument('moo');
$def
->replaceArgument(0, 'foo')
->replaceArgument(1, 'bar')
;
$this->assertSame(array('foo', 'bar'), $def->getArguments());
}




public function testGetArgumentShouldCheckBounds()
{
$def = new Definition('stdClass');

$def->addArgument('foo');
$def->getArgument(1);
}





public function testReplaceArgumentShouldCheckBounds()
{
$def = new Definition('stdClass');

$def->addArgument('foo');
$def->replaceArgument(1, 'bar');
}





public function testReplaceArgumentWithoutExistingArgumentsShouldCheckBounds()
{
$def = new Definition('stdClass');
$def->replaceArgument(0, 'bar');
}

public function testSetGetProperties()
{
$def = new Definition('stdClass');

$this->assertEquals(array(), $def->getProperties());
$this->assertSame($def, $def->setProperties(array('foo' => 'bar')));
$this->assertEquals(array('foo' => 'bar'), $def->getProperties());
}

public function testSetProperty()
{
$def = new Definition('stdClass');

$this->assertEquals(array(), $def->getProperties());
$this->assertSame($def, $def->setProperty('foo', 'bar'));
$this->assertEquals(array('foo' => 'bar'), $def->getProperties());
}

public function testAutowired()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isAutowired());
$def->setAutowired(true);
$this->assertTrue($def->isAutowired());
}

public function testTypes()
{
$def = new Definition('stdClass');

$this->assertEquals(array(), $def->getAutowiringTypes());
$this->assertSame($def, $def->setAutowiringTypes(array('Foo')));
$this->assertEquals(array('Foo'), $def->getAutowiringTypes());
$this->assertSame($def, $def->addAutowiringType('Bar'));
$this->assertTrue($def->hasAutowiringType('Bar'));
$this->assertSame($def, $def->removeAutowiringType('Foo'));
$this->assertEquals(array('Bar'), $def->getAutowiringTypes());
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

require_once __DIR__.'/Fixtures/includes/classes.php';
require_once __DIR__.'/Fixtures/includes/ProjectExtension.php';

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
use Symfony\Component\ExpressionLanguage\Expression;

class ContainerBuilderTest extends TestCase
{
public function testDefinitions()
{
$builder = new ContainerBuilder();
$definitions = array(
'foo' => new Definition('Bar\FooClass'),
'bar' => new Definition('BarClass'),
);
$builder->setDefinitions($definitions);
$this->assertEquals($definitions, $builder->getDefinitions(), '->setDefinitions() sets the service definitions');
$this->assertTrue($builder->hasDefinition('foo'), '->hasDefinition() returns true if a service definition exists');
$this->assertFalse($builder->hasDefinition('foobar'), '->hasDefinition() returns false if a service definition does not exist');

$builder->setDefinition('foobar', $foo = new Definition('FooBarClass'));
$this->assertEquals($foo, $builder->getDefinition('foobar'), '->getDefinition() returns a service definition if defined');
$this->assertTrue($builder->setDefinition('foobar', $foo = new Definition('FooBarClass')) === $foo, '->setDefinition() implements a fluid interface by returning the service reference');

$builder->addDefinitions($defs = array('foobar' => new Definition('FooBarClass')));
$this->assertEquals(array_merge($definitions, $defs), $builder->getDefinitions(), '->addDefinitions() adds the service definitions');

try {
$builder->getDefinition('baz');
$this->fail('->getDefinition() throws a ServiceNotFoundException if the service definition does not exist');
} catch (ServiceNotFoundException $e) {
$this->assertEquals('You have requested a non-existent service "baz".', $e->getMessage(), '->getDefinition() throws a ServiceNotFoundException if the service definition does not exist');
}
}





public function testCreateDeprecatedService()
{
$definition = new Definition('stdClass');
$definition->setDeprecated(true);

$builder = new ContainerBuilder();
$builder->createService($definition, 'deprecated_foo');
}

public function testRegister()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'Bar\FooClass');
$this->assertTrue($builder->hasDefinition('foo'), '->register() registers a new service definition');
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $builder->getDefinition('foo'), '->register() returns the newly created Definition instance');
}

public function testHas()
{
$builder = new ContainerBuilder();
$this->assertFalse($builder->has('foo'), '->has() returns false if the service does not exist');
$builder->register('foo', 'Bar\FooClass');
$this->assertTrue($builder->has('foo'), '->has() returns true if a service definition exists');
$builder->set('bar', new \stdClass());
$this->assertTrue($builder->has('bar'), '->has() returns true if a service exists');
}

public function testGet()
{
$builder = new ContainerBuilder();
try {
$builder->get('foo');
$this->fail('->get() throws a ServiceNotFoundException if the service does not exist');
} catch (ServiceNotFoundException $e) {
$this->assertEquals('You have requested a non-existent service "foo".', $e->getMessage(), '->get() throws a ServiceNotFoundException if the service does not exist');
}

$this->assertNull($builder->get('foo', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service does not exist and NULL_ON_INVALID_REFERENCE is passed as a second argument');

$builder->register('foo', 'stdClass');
$this->assertInternalType('object', $builder->get('foo'), '->get() returns the service definition associated with the id');
$builder->set('bar', $bar = new \stdClass());
$this->assertEquals($bar, $builder->get('bar'), '->get() returns the service associated with the id');
$builder->register('bar', 'stdClass');
$this->assertEquals($bar, $builder->get('bar'), '->get() returns the service associated with the id even if a definition has been defined');

$builder->register('baz', 'stdClass')->setArguments(array(new Reference('baz')));
try {
@$builder->get('baz');
$this->fail('->get() throws a ServiceCircularReferenceException if the service has a circular reference to itself');
} catch (ServiceCircularReferenceException $e) {
$this->assertEquals('Circular reference detected for service "baz", path: "baz".', $e->getMessage(), '->get() throws a LogicException if the service has a circular reference to itself');
}

$this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared');
}

public function testNonSharedServicesReturnsDifferentInstances()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'stdClass')->setShared(false);

$this->assertNotSame($builder->get('bar'), $builder->get('bar'));
}





public function testGetUnsetLoadingServiceWhenCreateServiceThrowsAnException()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'stdClass')->setSynthetic(true);


 try {
$builder->get('foo');
} catch (RuntimeException $e) {
}


 $builder->get('foo');
}




public function testGetReturnsNullOnInactiveScope()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'stdClass')->setScope('request');

$this->assertNull($builder->get('foo', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}




public function testGetReturnsNullOnInactiveScopeWhenServiceIsCreatedByAMethod()
{
$builder = new ProjectContainer();

$this->assertNull($builder->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}

public function testGetServiceIds()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'stdClass');
$builder->bar = $bar = new \stdClass();
$builder->register('bar', 'stdClass');
$this->assertEquals(array('foo', 'bar', 'service_container'), $builder->getServiceIds(), '->getServiceIds() returns all defined service ids');
}

public function testAliases()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'stdClass');
$builder->setAlias('bar', 'foo');
$this->assertTrue($builder->hasAlias('bar'), '->hasAlias() returns true if the alias exists');
$this->assertFalse($builder->hasAlias('foobar'), '->hasAlias() returns false if the alias does not exist');
$this->assertEquals('foo', (string) $builder->getAlias('bar'), '->getAlias() returns the aliased service');
$this->assertTrue($builder->has('bar'), '->setAlias() defines a new service');
$this->assertTrue($builder->get('bar') === $builder->get('foo'), '->setAlias() creates a service that is an alias to another one');

try {
$builder->setAlias('foobar', 'foobar');
$this->fail('->setAlias() throws an InvalidArgumentException if the alias references itself');
} catch (\InvalidArgumentException $e) {
$this->assertEquals('An alias can not reference itself, got a circular reference on "foobar".', $e->getMessage(), '->setAlias() throws an InvalidArgumentException if the alias references itself');
}

try {
$builder->getAlias('foobar');
$this->fail('->getAlias() throws an InvalidArgumentException if the alias does not exist');
} catch (\InvalidArgumentException $e) {
$this->assertEquals('The service alias "foobar" does not exist.', $e->getMessage(), '->getAlias() throws an InvalidArgumentException if the alias does not exist');
}
}

public function testGetAliases()
{
$builder = new ContainerBuilder();
$builder->setAlias('bar', 'foo');
$builder->setAlias('foobar', 'foo');
$builder->setAlias('moo', new Alias('foo', false));

$aliases = $builder->getAliases();
$this->assertEquals('foo', (string) $aliases['bar']);
$this->assertTrue($aliases['bar']->isPublic());
$this->assertEquals('foo', (string) $aliases['foobar']);
$this->assertEquals('foo', (string) $aliases['moo']);
$this->assertFalse($aliases['moo']->isPublic());

$builder->register('bar', 'stdClass');
$this->assertFalse($builder->hasAlias('bar'));

$builder->set('foobar', 'stdClass');
$builder->set('moo', 'stdClass');
$this->assertCount(0, $builder->getAliases(), '->getAliases() does not return aliased services that have been overridden');
}

public function testSetAliases()
{
$builder = new ContainerBuilder();
$builder->setAliases(array('bar' => 'foo', 'foobar' => 'foo'));

$aliases = $builder->getAliases();
$this->assertTrue(isset($aliases['bar']));
$this->assertTrue(isset($aliases['foobar']));
}

public function testAddAliases()
{
$builder = new ContainerBuilder();
$builder->setAliases(array('bar' => 'foo'));
$builder->addAliases(array('foobar' => 'foo'));

$aliases = $builder->getAliases();
$this->assertTrue(isset($aliases['bar']));
$this->assertTrue(isset($aliases['foobar']));
}

public function testSetReplacesAlias()
{
$builder = new ContainerBuilder();
$builder->setAlias('alias', 'aliased');
$builder->set('aliased', new \stdClass());

$builder->set('alias', $foo = new \stdClass());
$this->assertSame($foo, $builder->get('alias'), '->set() replaces an existing alias');
}

public function testAliasesKeepInvalidBehavior()
{
$builder = new ContainerBuilder();

$aliased = new Definition('stdClass');
$aliased->addMethodCall('setBar', array(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)));
$builder->setDefinition('aliased', $aliased);
$builder->setAlias('alias', 'aliased');

$this->assertEquals(new \stdClass(), $builder->get('alias'));
}

public function testAddGetCompilerPass()
{
$builder = new ContainerBuilder();
$builder->setResourceTracking(false);
$builderCompilerPasses = $builder->getCompiler()->getPassConfig()->getPasses();
$builder->addCompilerPass($this->getMockBuilder('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface')->getMock());

$this->assertCount(count($builder->getCompiler()->getPassConfig()->getPasses()) - 1, $builderCompilerPasses);
}

public function testCreateService()
{
$builder = new ContainerBuilder();
$builder->register('foo1', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
$this->assertInstanceOf('\Bar\FooClass', $builder->get('foo1'), '->createService() requires the file defined by the service definition');
$builder->register('foo2', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/%file%.php');
$builder->setParameter('file', 'foo');
$this->assertInstanceOf('\Bar\FooClass', $builder->get('foo2'), '->createService() replaces parameters in the file provided by the service definition');
}

public function testCreateProxyWithRealServiceInstantiator()
{
$builder = new ContainerBuilder();

$builder->register('foo1', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
$builder->getDefinition('foo1')->setLazy(true);

$foo1 = $builder->get('foo1');

$this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls');
$this->assertSame('Bar\FooClass', get_class($foo1));
}

public function testCreateServiceClass()
{
$builder = new ContainerBuilder();
$builder->register('foo1', '%class%');
$builder->setParameter('class', 'stdClass');
$this->assertInstanceOf('\stdClass', $builder->get('foo1'), '->createService() replaces parameters in the class provided by the service definition');
}

public function testCreateServiceArguments()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'Bar\FooClass')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar'), '%%unescape_it%%'));
$builder->setParameter('value', 'bar');
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->arguments, '->createService() replaces parameters and service references in the arguments provided by the service definition');
}

public function testCreateServiceFactory()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'Bar\FooClass')->setFactory('Bar\FooClass::getInstance');
$builder->register('qux', 'Bar\FooClass')->setFactory(array('Bar\FooClass', 'getInstance'));
$builder->register('bar', 'Bar\FooClass')->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'));
$builder->register('baz', 'Bar\FooClass')->setFactory(array(new Reference('bar'), 'getInstance'));

$this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance');
$this->assertTrue($builder->get('qux')->called, '->createService() calls the factory method to create the service instance');
$this->assertTrue($builder->get('bar')->called, '->createService() uses anonymous service as factory');
$this->assertTrue($builder->get('baz')->called, '->createService() uses another service as factory');
}




public function testLegacyCreateServiceFactory()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'Bar\FooClass');
$builder
->register('foo1', 'Bar\FooClass')
->setFactoryClass('%foo_class%')
->setFactoryMethod('getInstance')
->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')))
;
$builder->setParameter('value', 'bar');
$builder->setParameter('foo_class', 'Bar\FooClass');
$this->assertTrue($builder->get('foo1')->called, '->createService() calls the factory method to create the service instance');
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() passes the arguments to the factory method');
}




public function testLegacyCreateServiceFactoryService()
{
$builder = new ContainerBuilder();
$builder->register('foo_service', 'Bar\FooClass');
$builder
->register('foo', 'Bar\FooClass')
->setFactoryService('%foo_service%')
->setFactoryMethod('getInstance')
;
$builder->setParameter('foo_service', 'foo_service');
$this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance');
}

public function testCreateServiceMethodCalls()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', array(array('%value%', new Reference('bar'))));
$builder->setParameter('value', 'bar');
$this->assertEquals(array('bar', $builder->get('bar')), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments');
}

public function testCreateServiceMethodCallsWithEscapedParam()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', array(array('%%unescape_it%%')));
$builder->setParameter('value', 'bar');
$this->assertEquals(array('%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments');
}

public function testCreateServiceProperties()
{
$builder = new ContainerBuilder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'Bar\FooClass')->setProperty('bar', array('%value%', new Reference('bar'), '%%unescape_it%%'));
$builder->setParameter('value', 'bar');
$this->assertEquals(array('bar', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the properties');
}

public function testCreateServiceConfigurator()
{
$builder = new ContainerBuilder();
$builder->register('foo1', 'Bar\FooClass')->setConfigurator('sc_configure');
$this->assertTrue($builder->get('foo1')->configured, '->createService() calls the configurator');

$builder->register('foo2', 'Bar\FooClass')->setConfigurator(array('%class%', 'configureStatic'));
$builder->setParameter('class', 'BazClass');
$this->assertTrue($builder->get('foo2')->configured, '->createService() calls the configurator');

$builder->register('baz', 'BazClass');
$builder->register('foo3', 'Bar\FooClass')->setConfigurator(array(new Reference('baz'), 'configure'));
$this->assertTrue($builder->get('foo3')->configured, '->createService() calls the configurator');

$builder->register('foo4', 'Bar\FooClass')->setConfigurator(array($builder->getDefinition('baz'), 'configure'));
$this->assertTrue($builder->get('foo4')->configured, '->createService() calls the configurator');

$builder->register('foo5', 'Bar\FooClass')->setConfigurator('foo');
try {
$builder->get('foo5');
$this->fail('->createService() throws an InvalidArgumentException if the configure callable is not a valid callable');
} catch (\InvalidArgumentException $e) {
$this->assertEquals('The configure callable for class "Bar\FooClass" is not a callable.', $e->getMessage(), '->createService() throws an InvalidArgumentException if the configure callable is not a valid callable');
}
}




public function testCreateSyntheticService()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'Bar\FooClass')->setSynthetic(true);
$builder->get('foo');
}

public function testCreateServiceWithExpression()
{
$builder = new ContainerBuilder();
$builder->setParameter('bar', 'bar');
$builder->register('bar', 'BarClass');
$builder->register('foo', 'Bar\FooClass')->addArgument(array('foo' => new Expression('service("bar").foo ~ parameter("bar")')));
$this->assertEquals('foobar', $builder->get('foo')->arguments['foo']);
}

public function testResolveServices()
{
$builder = new ContainerBuilder();
$builder->register('foo', 'Bar\FooClass');
$this->assertEquals($builder->get('foo'), $builder->resolveServices(new Reference('foo')), '->resolveServices() resolves service references to service instances');
$this->assertEquals(array('foo' => array('foo', $builder->get('foo'))), $builder->resolveServices(array('foo' => array('foo', new Reference('foo')))), '->resolveServices() resolves service references to service instances in nested arrays');
$this->assertEquals($builder->get('foo'), $builder->resolveServices(new Expression('service("foo")')), '->resolveServices() resolves expressions');
}





public function testResolveServicesWithDecoratedDefinition()
{
$builder = new ContainerBuilder();
$builder->setDefinition('grandpa', new Definition('stdClass'));
$builder->setDefinition('parent', new DefinitionDecorator('grandpa'));
$builder->setDefinition('foo', new DefinitionDecorator('parent'));

$builder->get('foo');
}

public function testResolveServicesWithCustomDefinitionClass()
{
$builder = new ContainerBuilder();
$builder->setDefinition('foo', new CustomDefinition('stdClass'));

$this->assertInstanceOf('stdClass', $builder->get('foo'));
}

public function testMerge()
{
$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$container->setResourceTracking(false);
$config = new ContainerBuilder(new ParameterBag(array('foo' => 'bar')));
$container->merge($config);
$this->assertEquals(array('bar' => 'foo', 'foo' => 'bar'), $container->getParameterBag()->all(), '->merge() merges current parameters with the loaded ones');

$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$container->setResourceTracking(false);
$config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%')));
$container->merge($config);
$container->compile();
$this->assertEquals(array('bar' => 'foo', 'foo' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');

$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$container->setResourceTracking(false);
$config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%', 'baz' => '%foo%')));
$container->merge($config);
$container->compile();
$this->assertEquals(array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');

$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->register('foo', 'Bar\FooClass');
$container->register('bar', 'BarClass');
$config = new ContainerBuilder();
$config->setDefinition('baz', new Definition('BazClass'));
$config->setAlias('alias_for_foo', 'foo');
$container->merge($config);
$this->assertEquals(array('foo', 'bar', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones');

$aliases = $container->getAliases();
$this->assertTrue(isset($aliases['alias_for_foo']));
$this->assertEquals('foo', (string) $aliases['alias_for_foo']);

$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->register('foo', 'Bar\FooClass');
$config->setDefinition('foo', new Definition('BazClass'));
$container->merge($config);
$this->assertEquals('BazClass', $container->getDefinition('foo')->getClass(), '->merge() overrides already defined services');
}




public function testMergeLogicException()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->compile();
$container->merge(new ContainerBuilder());
}

public function testfindTaggedServiceIds()
{
$builder = new ContainerBuilder();
$builder
->register('foo', 'Bar\FooClass')
->addTag('foo', array('foo' => 'foo'))
->addTag('bar', array('bar' => 'bar'))
->addTag('foo', array('foofoo' => 'foofoo'))
;
$this->assertEquals($builder->findTaggedServiceIds('foo'), array(
'foo' => array(
array('foo' => 'foo'),
array('foofoo' => 'foofoo'),
),
), '->findTaggedServiceIds() returns an array of service ids and its tag attributes');
$this->assertEquals(array(), $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services');
}

public function testFindUnusedTags()
{
$builder = new ContainerBuilder();
$builder
->register('foo', 'Bar\FooClass')
->addTag('kernel.event_listener', array('foo' => 'foo'))
->addTag('kenrel.event_listener', array('bar' => 'bar'))
;
$builder->findTaggedServiceIds('kernel.event_listener');
$this->assertEquals(array('kenrel.event_listener'), $builder->findUnusedTags(), '->findUnusedTags() returns an array with unused tags');
}

public function testFindDefinition()
{
$container = new ContainerBuilder();
$container->setDefinition('foo', $definition = new Definition('Bar\FooClass'));
$container->setAlias('bar', 'foo');
$container->setAlias('foobar', 'bar');
$this->assertEquals($definition, $container->findDefinition('foobar'), '->findDefinition() returns a Definition');
}

public function testAddObjectResource()
{
$container = new ContainerBuilder();

$container->setResourceTracking(false);
$container->addObjectResource(new \BarClass());

$this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');

$container->setResourceTracking(true);
$container->addObjectResource(new \BarClass());

$resources = $container->getResources();

$this->assertCount(1, $resources, '1 resource was registered');


$resource = end($resources);

$this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource);
$this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource()));
}

public function testAddClassResource()
{
$container = new ContainerBuilder();

$container->setResourceTracking(false);
$container->addClassResource(new \ReflectionClass('BarClass'));

$this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');

$container->setResourceTracking(true);
$container->addClassResource(new \ReflectionClass('BarClass'));

$resources = $container->getResources();

$this->assertCount(1, $resources, '1 resource was registered');


$resource = end($resources);

$this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource);
$this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource()));
}

public function testCompilesClassDefinitionsOfLazyServices()
{
$container = new ContainerBuilder();

$this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking');

$container->register('foo', 'BarClass');
$container->getDefinition('foo')->setLazy(true);

$container->compile();

$classesPath = realpath(__DIR__.'/Fixtures/includes/classes.php');
$matchingResources = array_filter(
$container->getResources(),
function (ResourceInterface $resource) use ($classesPath) {
return $resource instanceof FileResource && $classesPath === realpath($resource->getResource());
}
);

$this->assertNotEmpty($matchingResources);
}

public function testResources()
{
$container = new ContainerBuilder();
$container->addResource($a = new FileResource(__DIR__.'/Fixtures/xml/services1.xml'));
$container->addResource($b = new FileResource(__DIR__.'/Fixtures/xml/services2.xml'));
$resources = array();
foreach ($container->getResources() as $resource) {
if (false === strpos($resource, '.php')) {
$resources[] = $resource;
}
}
$this->assertEquals(array($a, $b), $resources, '->getResources() returns an array of resources read for the current configuration');
$this->assertSame($container, $container->setResources(array()));
$this->assertEquals(array(), $container->getResources());
}

public function testExtension()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);

$container->registerExtension($extension = new \ProjectExtension());
$this->assertTrue($container->getExtension('project') === $extension, '->registerExtension() registers an extension');

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('LogicException');
$container->getExtension('no_registered');
}

public function testRegisteredButNotLoadedExtension()
{
$extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
$extension->expects($this->once())->method('getAlias')->will($this->returnValue('project'));
$extension->expects($this->never())->method('load');

$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->registerExtension($extension);
$container->compile();
}

public function testRegisteredAndLoadedExtension()
{
$extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
$extension->expects($this->exactly(2))->method('getAlias')->will($this->returnValue('project'));
$extension->expects($this->once())->method('load')->with(array(array('foo' => 'bar')));

$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->registerExtension($extension);
$container->loadFromExtension('project', array('foo' => 'bar'));
$container->compile();
}

public function testPrivateServiceUser()
{
$fooDefinition = new Definition('BarClass');
$fooUserDefinition = new Definition('BarUserClass', array(new Reference('bar')));
$container = new ContainerBuilder();
$container->setResourceTracking(false);

$fooDefinition->setPublic(false);

$container->addDefinitions(array(
'bar' => $fooDefinition,
'bar_user' => $fooUserDefinition,
));

$container->compile();
$this->assertInstanceOf('BarClass', $container->get('bar_user')->bar);
}




public function testThrowsExceptionWhenSetServiceOnAFrozenContainer()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->setDefinition('a', new Definition('stdClass'));
$container->compile();
$container->set('a', new \stdClass());
}

public function testThrowsExceptionWhenAddServiceOnAFrozenContainer()
{
$container = new ContainerBuilder();
$container->compile();
$container->set('a', $foo = new \stdClass());
$this->assertSame($foo, $container->get('a'));
}

public function testNoExceptionWhenSetSyntheticServiceOnAFrozenContainer()
{
$container = new ContainerBuilder();
$def = new Definition('stdClass');
$def->setSynthetic(true);
$container->setDefinition('a', $def);
$container->compile();
$container->set('a', $a = new \stdClass());
$this->assertEquals($a, $container->get('a'));
}




public function testLegacySetOnSynchronizedService()
{
$container = new ContainerBuilder();
$container->register('baz', 'BazClass')
->setSynchronized(true)
;
$container->register('bar', 'BarClass')
->addMethodCall('setBaz', array(new Reference('baz')))
;

$container->set('baz', $baz = new \BazClass());
$this->assertSame($baz, $container->get('bar')->getBaz());

$container->set('baz', $baz = new \BazClass());
$this->assertSame($baz, $container->get('bar')->getBaz());
}




public function testLegacySynchronizedServiceWithScopes()
{
$container = new ContainerBuilder();
$container->addScope(new Scope('foo'));
$container->register('baz', 'BazClass')
->setSynthetic(true)
->setSynchronized(true)
->setScope('foo')
;
$container->register('bar', 'BarClass')
->addMethodCall('setBaz', array(new Reference('baz', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)))
;
$container->compile();

$container->enterScope('foo');
$container->set('baz', $outerBaz = new \BazClass(), 'foo');
$this->assertSame($outerBaz, $container->get('bar')->getBaz());

$container->enterScope('foo');
$container->set('baz', $innerBaz = new \BazClass(), 'foo');
$this->assertSame($innerBaz, $container->get('bar')->getBaz());
$container->leaveScope('foo');

$this->assertNotSame($innerBaz, $container->get('bar')->getBaz());
$this->assertSame($outerBaz, $container->get('bar')->getBaz());

$container->leaveScope('foo');
}




public function testThrowsExceptionWhenSetDefinitionOnAFrozenContainer()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->compile();
$container->setDefinition('a', new Definition());
}

public function testExtensionConfig()
{
$container = new ContainerBuilder();

$configs = $container->getExtensionConfig('foo');
$this->assertEmpty($configs);

$first = array('foo' => 'bar');
$container->prependExtensionConfig('foo', $first);
$configs = $container->getExtensionConfig('foo');
$this->assertEquals(array($first), $configs);

$second = array('ding' => 'dong');
$container->prependExtensionConfig('foo', $second);
$configs = $container->getExtensionConfig('foo');
$this->assertEquals(array($second, $first), $configs);
}

public function testAbstractAlias()
{
$container = new ContainerBuilder();

$abstract = new Definition('AbstractClass');
$abstract->setAbstract(true);

$container->setDefinition('abstract_service', $abstract);
$container->setAlias('abstract_alias', 'abstract_service');

$container->compile();

$this->assertSame('abstract_service', (string) $container->getAlias('abstract_alias'));
}

public function testLazyLoadedService()
{
$loader = new ClosureLoader($container = new ContainerBuilder());
$loader->load(function (ContainerBuilder $container) {
$container->set('a', new \BazClass());
$definition = new Definition('BazClass');
$definition->setLazy(true);
$container->setDefinition('a', $definition);
});

$container->setResourceTracking(true);

$container->compile();

$class = new \BazClass();
$reflectionClass = new \ReflectionClass($class);

$r = new \ReflectionProperty($container, 'resources');
$r->setAccessible(true);
$resources = $r->getValue($container);

$classInList = false;
foreach ($resources as $resource) {
if ($resource->getResource() === $reflectionClass->getFileName()) {
$classInList = true;
break;
}
}

$this->assertTrue($classInList);
}

public function testInitializePropertiesBeforeMethodCalls()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass');
$container->register('bar', 'MethodCallClass')
->setProperty('simple', 'bar')
->setProperty('complex', new Reference('foo'))
->addMethodCall('callMe');

$container->compile();

$this->assertTrue($container->get('bar')->callPassed(), '->compile() initializes properties before method calls');
}

public function testAutowiring()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$bDefinition = $container->register('b', __NAMESPACE__.'\B');
$bDefinition->setAutowired(true);

$container->compile();

$this->assertEquals('a', (string) $container->getDefinition('b')->getArgument(0));
}
}

class FooClass
{
}

class ProjectContainer extends ContainerBuilder
{
public function getFoobazService()
{
throw new InactiveScopeException('foo', 'request');
}
}

class A
{
}

class B
{
public function __construct(A $a)
{
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Reference;

class ReferenceTest extends TestCase
{
public function testConstructor()
{
$ref = new Reference('foo');
$this->assertEquals('foo', (string) $ref, '__construct() sets the id of the reference, which is used for the __toString() method');
}

public function testCaseInsensitive()
{
$ref = new Reference('FooBar');
$this->assertEquals('foobar', (string) $ref, 'the id is lowercased as the container is case insensitive');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
use Symfony\Component\Yaml\Yaml;

class YamlDumperTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
}

public function testDump()
{
$dumper = new YamlDumper($container = new ContainerBuilder());

$this->assertEqualYamlStructure(file_get_contents(self::$fixturesPath.'/yaml/services1.yml'), $dumper->dump(), '->dump() dumps an empty container as an empty YAML file');
}

public function testAddParameters()
{
$container = include self::$fixturesPath.'/containers/container8.php';
$dumper = new YamlDumper($container);
$this->assertEqualYamlStructure(file_get_contents(self::$fixturesPath.'/yaml/services8.yml'), $dumper->dump(), '->dump() dumps parameters');
}




public function testLegacyAddService()
{
$container = include self::$fixturesPath.'/containers/legacy-container9.php';
$dumper = new YamlDumper($container);

$this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/legacy-services9.yml')), $dumper->dump(), '->dump() dumps services');

$dumper = new YamlDumper($container = new ContainerBuilder());
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
try {
$dumper->dump();
$this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
}
}

public function testAddService()
{
$container = include self::$fixturesPath.'/containers/container9.php';
$dumper = new YamlDumper($container);
$this->assertEqualYamlStructure(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/services9.yml')), $dumper->dump(), '->dump() dumps services');

$dumper = new YamlDumper($container = new ContainerBuilder());
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
try {
$dumper->dump();
$this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
}
}

public function testDumpAutowireData()
{
$container = include self::$fixturesPath.'/containers/container24.php';
$dumper = new YamlDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump());
}

private function assertEqualYamlStructure($yaml, $expected, $message = '')
{
$this->assertEquals(Yaml::parse($expected), Yaml::parse($yaml), $message);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;

class XmlDumperTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
}

public function testDump()
{
$dumper = new XmlDumper(new ContainerBuilder());

$this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services1.xml', $dumper->dump(), '->dump() dumps an empty container as an empty XML file');
}

public function testExportParameters()
{
$container = include self::$fixturesPath.'//containers/container8.php';
$dumper = new XmlDumper($container);
$this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters');
}

public function testAddParameters()
{
$container = include self::$fixturesPath.'//containers/container8.php';
$dumper = new XmlDumper($container);
$this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters');
}




public function testLegacyAddService()
{
$container = include self::$fixturesPath.'/containers/legacy-container9.php';
$dumper = new XmlDumper($container);

$this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/xml/legacy-services9.xml')), $dumper->dump(), '->dump() dumps services');

$dumper = new XmlDumper($container = new ContainerBuilder());
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
try {
$dumper->dump();
$this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
}
}

public function testAddService()
{
$container = include self::$fixturesPath.'/containers/container9.php';
$dumper = new XmlDumper($container);

$this->assertEquals(str_replace('%path%', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/xml/services9.xml')), $dumper->dump(), '->dump() dumps services');

$dumper = new XmlDumper($container = new ContainerBuilder());
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
try {
$dumper->dump();
$this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
}
}

public function testDumpAnonymousServices()
{
$container = include self::$fixturesPath.'/containers/container11.php';
$dumper = new XmlDumper($container);
$this->assertEquals('<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
  <services>
    <service id="foo" class="FooClass">
      <argument type="service">
        <service class="BarClass">
          <argument type="service">
            <service class="BazClass"/>
          </argument>
        </service>
      </argument>
    </service>
  </services>
</container>
', $dumper->dump());
}

public function testDumpEntities()
{
$container = include self::$fixturesPath.'/containers/container12.php';
$dumper = new XmlDumper($container);
$this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?>
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
  <services>
    <service id=\"foo\" class=\"FooClass\Foo\">
      <tag name=\"foo&quot;bar\bar\" foo=\"foo&quot;barřž€\"/>
      <argument>foo&lt;&gt;&amp;bar</argument>
    </service>
  </services>
</container>
", $dumper->dump());
}




public function testDumpDecoratedServices($expectedXmlDump, $container)
{
$dumper = new XmlDumper($container);
$this->assertEquals($expectedXmlDump, $dumper->dump());
}

public function provideDecoratedServicesData()
{
$fixturesPath = realpath(__DIR__.'/../Fixtures/');

return array(
array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
  <services>
    <service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\" decoration-inner-name=\"bar.woozy\"/>
  </services>
</container>
", include $fixturesPath.'/containers/container15.php'),
array("<?xml version=\"1.0\" encoding=\"utf-8\"?>
<container xmlns=\"http://symfony.com/schema/dic/services\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd\">
  <services>
    <service id=\"foo\" class=\"FooClass\Foo\" decorates=\"bar\"/>
  </services>
</container>
", include $fixturesPath.'/containers/container16.php'),
);
}




public function testCompiledContainerCanBeDumped($containerFile)
{
$fixturesPath = __DIR__.'/../Fixtures';
$container = require $fixturesPath.'/containers/'.$containerFile.'.php';
$container->compile();
$dumper = new XmlDumper($container);
$dumper->dump();
}

public function provideCompiledContainerData()
{
return array(
array('container8'),
array('container9'),
array('container11'),
array('container12'),
array('container14'),
);
}

public function testDumpInlinedServices()
{
$container = include self::$fixturesPath.'/containers/container21.php';
$dumper = new XmlDumper($container);

$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services21.xml'), $dumper->dump());
}

public function testDumpAutowireData()
{
$container = include self::$fixturesPath.'/containers/container24.php';
$dumper = new XmlDumper($container);

$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services24.xml'), $dumper->dump());
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper;

class GraphvizDumperTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = __DIR__.'/../Fixtures/';
}




public function testLegacyDump()
{
$container = include self::$fixturesPath.'/containers/legacy-container9.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/legacy-services9.dot')), $dumper->dump(), '->dump() dumps services');
}

public function testDump()
{
$dumper = new GraphvizDumper($container = new ContainerBuilder());

$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services1.dot', $dumper->dump(), '->dump() dumps an empty container as an empty dot file');

$container = include self::$fixturesPath.'/containers/container9.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services9.dot')), $dumper->dump(), '->dump() dumps services');

$container = include self::$fixturesPath.'/containers/container10.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10.dot')), $dumper->dump(), '->dump() dumps services');

$container = include self::$fixturesPath.'/containers/container10.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals($dumper->dump(array(
'graph' => array('ratio' => 'normal'),
'node' => array('fontsize' => 13, 'fontname' => 'Verdana', 'shape' => 'square'),
'edge' => array('fontsize' => 12, 'fontname' => 'Verdana', 'color' => 'white', 'arrowhead' => 'closed', 'arrowsize' => 1),
'node.instance' => array('fillcolor' => 'green', 'style' => 'empty'),
'node.definition' => array('fillcolor' => 'grey'),
'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'),
)), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services');
}

public function testDumpWithFrozenContainer()
{
$container = include self::$fixturesPath.'/containers/container13.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services13.dot')), $dumper->dump(), '->dump() dumps services');
}

public function testDumpWithFrozenCustomClassContainer()
{
$container = include self::$fixturesPath.'/containers/container14.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services');
}

public function testDumpWithUnresolvedParameter()
{
$container = include self::$fixturesPath.'/containers/container17.php';
$dumper = new GraphvizDumper($container);

$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services17.dot')), $dumper->dump(), '->dump() dumps services');
}




public function testDumpWithScopes()
{
$container = include self::$fixturesPath.'/containers/legacy-container18.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services18.dot')), $dumper->dump(), '->dump() dumps services');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Dumper;

use DummyProxyDumper;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Variable;
use Symfony\Component\ExpressionLanguage\Expression;

require_once __DIR__.'/../Fixtures/includes/classes.php';

class PhpDumperTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
}

public function testDump()
{
$dumper = new PhpDumper(new ContainerBuilder());

$this->assertStringEqualsFile(self::$fixturesPath.'/php/services1.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class');
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services1-1.php', $dumper->dump(array('class' => 'Container', 'base_class' => 'AbstractContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Dump')), '->dump() takes a class and a base_class options');
}

public function testDumpOptimizationString()
{
$definition = new Definition();
$definition->setClass('stdClass');
$definition->addArgument(array(
'only dot' => '.',
'concatenation as value' => '.\'\'.',
'concatenation from the start value' => '\'\'.',
'.' => 'dot as a key',
'.\'\'.' => 'concatenation as a key',
'\'\'.' => 'concatenation from the start key',
'optimize concatenation' => 'string1%some_string%string2',
'optimize concatenation with empty string' => 'string1%empty_value%string2',
'optimize concatenation from the start' => '%empty_value%start',
'optimize concatenation at the end' => 'end%empty_value%',
));

$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->setDefinition('test', $definition);
$container->setParameter('empty_value', '');
$container->setParameter('some_string', '-');
$container->compile();

$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services10.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class');
}

public function testDumpRelativeDir()
{
$definition = new Definition();
$definition->setClass('stdClass');
$definition->addArgument('%foo%');
$definition->addArgument(array('%foo%' => '%buz%/'));

$container = new ContainerBuilder();
$container->setDefinition('test', $definition);
$container->setParameter('foo', 'wiz'.dirname(__DIR__));
$container->setParameter('bar', __DIR__);
$container->setParameter('baz', '%bar%/PhpDumperTest.php');
$container->setParameter('buz', dirname(dirname(__DIR__)));
$container->compile();

$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(array('file' => __FILE__)), '->dump() dumps __DIR__ relative strings');
}





public function testExportParameters($parameters)
{
$dumper = new PhpDumper(new ContainerBuilder(new ParameterBag($parameters)));
$dumper->dump();
}

public function provideInvalidParameters()
{
return array(
array(array('foo' => new Definition('stdClass'))),
array(array('foo' => new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")'))),
array(array('foo' => new Reference('foo'))),
array(array('foo' => new Variable('foo'))),
);
}

public function testAddParameters()
{
$container = include self::$fixturesPath.'/containers/container8.php';
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services8.php', $dumper->dump(), '->dump() dumps parameters');
}

public function testAddService()
{

 $container = include self::$fixturesPath.'/containers/container9.php';
$dumper = new PhpDumper($container);
$this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services');


 $container = include self::$fixturesPath.'/containers/container9.php';
$container->compile();
$dumper = new PhpDumper($container);
$this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9_compiled.php')), $dumper->dump(), '->dump() dumps services');

$dumper = new PhpDumper($container = new ContainerBuilder());
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
try {
$dumper->dump();
$this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
} catch (\Exception $e) {
$this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
}
}




public function testLegacySynchronizedServices()
{
$container = include self::$fixturesPath.'/containers/container20.php';
$dumper = new PhpDumper($container);
$this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services20.php')), $dumper->dump(), '->dump() dumps services');
}

public function testServicesWithAnonymousFactories()
{
$container = include self::$fixturesPath.'/containers/container19.php';
$dumper = new PhpDumper($container);

$this->assertStringEqualsFile(self::$fixturesPath.'/php/services19.php', $dumper->dump(), '->dump() dumps services with anonymous factories');
}





public function testAddServiceInvalidServiceId()
{
$container = new ContainerBuilder();
$container->register('bar$', 'FooClass');
$dumper = new PhpDumper($container);
$dumper->dump();
}






public function testInvalidFactories($factory)
{
$container = new ContainerBuilder();
$def = new Definition('stdClass');
$def->setFactory($factory);
$container->setDefinition('bar', $def);
$dumper = new PhpDumper($container);
$dumper->dump();
}

public function provideInvalidFactories()
{
return array(
array(array('', 'method')),
array(array('class', '')),
array(array('...', 'method')),
array(array('class', '...')),
);
}

public function testAliases()
{
$container = include self::$fixturesPath.'/containers/container9.php';
$container->compile();
$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Aliases')));

$container = new \Symfony_DI_PhpDumper_Test_Aliases();
$container->set('foo', $foo = new \stdClass());
$this->assertSame($foo, $container->get('foo'));
$this->assertSame($foo, $container->get('alias_for_foo'));
$this->assertSame($foo, $container->get('alias_for_alias'));
}

public function testFrozenContainerWithoutAliases()
{
$container = new ContainerBuilder();
$container->compile();

$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Frozen_No_Aliases')));

$container = new \Symfony_DI_PhpDumper_Test_Frozen_No_Aliases();
$this->assertFalse($container->has('foo'));
}

public function testOverrideServiceWhenUsingADumpedContainer()
{
require_once self::$fixturesPath.'/php/services9.php';
require_once self::$fixturesPath.'/includes/foo.php';

$container = new \ProjectServiceContainer();
$container->set('bar', $bar = new \stdClass());
$container->setParameter('foo_bar', 'foo_bar');

$this->assertSame($bar, $container->get('bar'), '->set() overrides an already defined service');
}

public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFromAnotherOne()
{
require_once self::$fixturesPath.'/php/services9.php';
require_once self::$fixturesPath.'/includes/foo.php';
require_once self::$fixturesPath.'/includes/classes.php';

$container = new \ProjectServiceContainer();
$container->set('bar', $bar = new \stdClass());

$this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service');
}




public function testCircularReference()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
$container->register('bar', 'stdClass')->setPublic(false)->addMethodCall('setA', array(new Reference('baz')));
$container->register('baz', 'stdClass')->addMethodCall('setA', array(new Reference('foo')));
$container->compile();

$dumper = new PhpDumper($container);
$dumper->dump();
}

public function testDumpAutowireData()
{
$container = include self::$fixturesPath.'/containers/container24.php';
$dumper = new PhpDumper($container);

$this->assertEquals(file_get_contents(self::$fixturesPath.'/php/services24.php'), $dumper->dump());
}

public function testInlinedDefinitionReferencingServiceContainer()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->addMethodCall('add', array(new Reference('service_container')))->setPublic(false);
$container->register('bar', 'stdClass')->addArgument(new Reference('foo'));
$container->compile();

$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container');
}

public function testInitializePropertiesBeforeMethodCalls()
{
require_once self::$fixturesPath.'/includes/classes.php';

$container = new ContainerBuilder();
$container->register('foo', 'stdClass');
$container->register('bar', 'MethodCallClass')
->setProperty('simple', 'bar')
->setProperty('complex', new Reference('foo'))
->addMethodCall('callMe');
$container->compile();

$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls')));

$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
}

public function testCircularReferenceAllowanceForLazyServices()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
$container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
$container->compile();

$dumper = new PhpDumper($container);
$dumper->dump();
}

public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
{










$container = new ContainerBuilder();

$eventManagerDefinition = new Definition('stdClass');

$connectionDefinition = $container->register('connection', 'stdClass');
$connectionDefinition->addArgument($eventManagerDefinition);

$container->register('entity_manager', 'stdClass')
->setLazy(true)
->addArgument(new Reference('connection'));

$lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
$lazyServiceDefinition->setLazy(true);
$lazyServiceDefinition->addArgument(new Reference('entity_manager'));

$eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));

$container->compile();

$dumper = new PhpDumper($container);

$dumper->setProxyDumper(new DummyProxyDumper());
$dumper->dump();
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;

class DirectoryLoaderTest extends TestCase
{
private static $fixturesPath;

private $container;
private $loader;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
}

protected function setUp()
{
$locator = new FileLocator(self::$fixturesPath);
$this->container = new ContainerBuilder();
$this->loader = new DirectoryLoader($this->container, $locator);
$resolver = new LoaderResolver(array(
new PhpFileLoader($this->container, $locator),
new IniFileLoader($this->container, $locator),
new YamlFileLoader($this->container, $locator),
$this->loader,
));
$this->loader->setResolver($resolver);
}

public function testDirectoryCanBeLoadedRecursively()
{
$this->loader->load('directory/');
$this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml', 'php' => 'php'), $this->container->getParameterBag()->all(), '->load() takes a single directory');
}

public function testImports()
{
$this->loader->resolve('directory/import/import.yml')->load('directory/import/import.yml');
$this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml'), $this->container->getParameterBag()->all(), '->load() takes a single file that imports a directory');
}





public function testExceptionIsRaisedWhenDirectoryDoesNotExist()
{
$this->loader->load('foo/');
}

public function testSupports()
{
$loader = new DirectoryLoader(new ContainerBuilder(), new FileLocator());

$this->assertTrue($loader->supports('directory/'), '->supports("directory/") returns true');
$this->assertTrue($loader->supports('directory/', 'directory'), '->supports("directory/", "directory") returns true');
$this->assertFalse($loader->supports('directory'), '->supports("directory") returns false');
$this->assertTrue($loader->supports('directory', 'directory'), '->supports("directory", "directory") returns true');
$this->assertFalse($loader->supports('directory', 'foo'), '->supports("directory", "foo") returns false');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\ExpressionLanguage\Expression;

class YamlFileLoaderTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
require_once self::$fixturesPath.'/includes/foo.php';
require_once self::$fixturesPath.'/includes/ProjectExtension.php';
}

public function testLoadFile()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini'));
$r = new \ReflectionObject($loader);
$m = $r->getMethod('loadFile');
$m->setAccessible(true);

try {
$m->invoke($loader, 'foo.yml');
$this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist');
$this->assertEquals('The service file "foo.yml" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist');
}

try {
$m->invoke($loader, 'parameters.ini');
$this->fail('->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
$this->assertEquals('The service file "parameters.ini" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file is not a valid YAML file');
}

$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));

foreach (array('nonvalid1', 'nonvalid2') as $fixture) {
try {
$m->invoke($loader, $fixture.'.yml');
$this->fail('->load() throws an InvalidArgumentException if the loaded file does not validate');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not validate');
$this->assertStringMatchesFormat('The service file "nonvalid%d.yml" is not valid.', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not validate');
}
}
}





public function testLoadInvalidFile($file)
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));

$loader->load($file.'.yml');
}

public function provideInvalidFiles()
{
return array(
array('bad_parameters'),
array('bad_imports'),
array('bad_import'),
array('bad_services'),
array('bad_service'),
array('bad_calls'),
array('bad_format'),
);
}

public function testLoadParameters()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services2.yml');
$this->assertEquals(array('foo' => 'bar', 'mixedcase' => array('MixedCaseKey' => 'value'), 'values' => array(true, false, 0, 1000.3), 'bar' => 'foo', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar')), $container->getParameterBag()->all(), '->load() converts YAML keys to lowercase');
}

public function testLoadImports()
{
$container = new ContainerBuilder();
$resolver = new LoaderResolver(array(
new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')),
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')),
));
$loader->setResolver($resolver);
$loader->load('services4.yml');

$actual = $container->getParameterBag()->all();
$expected = array('foo' => 'bar', 'values' => array(true, false), 'bar' => '%foo%', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value'), 'imported_from_ini' => true, 'imported_from_xml' => true);
$this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');


 $loader->load('services4_bad_import.yml');
}




public function testLegacyLoadServices()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('legacy-services6.yml');
$services = $container->getDefinitions();
$this->assertEquals('FooClass', $services['constructor']->getClass());
$this->assertEquals('getInstance', $services['constructor']->getFactoryMethod());
$this->assertEquals('BazClass', $services['factory_service']->getClass());
$this->assertEquals('baz_factory', $services['factory_service']->getFactoryService());
$this->assertEquals('getInstance', $services['factory_service']->getFactoryMethod());
$this->assertEquals('container', $services['scope.container']->getScope());
$this->assertEquals('custom', $services['scope.custom']->getScope());
$this->assertEquals('prototype', $services['scope.prototype']->getScope());
$this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag');
$this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag');
$this->assertTrue($services['request']->isLazy(), '->load() parses the lazy flag');
$this->assertNull($services['request']->getDecoratedService());
}

public function testLoadServices()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services6.yml');
$services = $container->getDefinitions();
$this->assertTrue(isset($services['foo']), '->load() parses service elements');
$this->assertFalse($services['not_shared']->isShared(), '->load() parses the shared flag');
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts service element to Definition instances');
$this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute');
$this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag');
$this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags');
$this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag');
$this->assertEquals(array(new Reference('baz'), 'configure'), $services['configurator2']->getConfigurator(), '->load() parses the configurator tag');
$this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag');
$this->assertEquals(array(array('setBar', array()), array('setBar', array()), array('setBar', array(new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')))), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag');
$this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag');
$this->assertEquals('factory', $services['new_factory1']->getFactory(), '->load() parses the factory tag');
$this->assertEquals(array(new Reference('baz'), 'getClass'), $services['new_factory2']->getFactory(), '->load() parses the factory tag');
$this->assertEquals(array('BazClass', 'getInstance'), $services['new_factory3']->getFactory(), '->load() parses the factory tag');

$aliases = $container->getAliases();
$this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses aliases');
$this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases');
$this->assertTrue($aliases['alias_for_foo']->isPublic());
$this->assertTrue(isset($aliases['another_alias_for_foo']));
$this->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
$this->assertFalse($aliases['another_alias_for_foo']->isPublic());

$this->assertEquals(array('decorated', null, 0), $services['decorator_service']->getDecoratedService());
$this->assertEquals(array('decorated', 'decorated.pif-pouf', 0), $services['decorator_service_with_name']->getDecoratedService());
$this->assertEquals(array('decorated', 'decorated.pif-pouf', 5), $services['decorator_service_with_name_and_priority']->getDecoratedService());
}

public function testLoadFactoryShortSyntax()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services14.yml');
$services = $container->getDefinitions();

$this->assertEquals(array(new Reference('baz'), 'getClass'), $services['factory']->getFactory(), '->load() parses the factory tag with service:method');
$this->assertEquals(array('FooBacFactory', 'createFooBar'), $services['factory_with_static_call']->getFactory(), '->load() parses the factory tag with Class::method');
}

public function testExtensions()
{
$container = new ContainerBuilder();
$container->registerExtension(new \ProjectExtension());
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services10.yml');
$container->compile();
$services = $container->getDefinitions();
$parameters = $container->getParameterBag()->all();

$this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
$this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');

$this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements');
$this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');

try {
$loader->load('services11.yml');
$this->fail('->load() throws an InvalidArgumentException if the tag is not valid');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid');
$this->assertStringStartsWith('There is no extension able to load the configuration for "foobarfoobar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid');
}
}

public function testSupports()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator());

$this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable');
$this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable');
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}

public function testNonArrayTagsThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
try {
$loader->load('badtag1.yml');
$this->fail('->load() should throw an exception when the tags key of a service is not an array');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tags key is not an array');
$this->assertStringStartsWith('Parameter "tags" must be an array for service', $e->getMessage(), '->load() throws an InvalidArgumentException if the tags key is not an array');
}
}





public function testNonArrayTagThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('badtag4.yml');
}

public function testTagWithoutNameThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
try {
$loader->load('badtag2.yml');
$this->fail('->load() should throw an exception when a tag is missing the name key');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag is missing the name key');
$this->assertStringStartsWith('A "tags" entry is missing a "name" key for service ', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag is missing the name key');
}
}

public function testTagWithAttributeArrayThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
try {
$loader->load('badtag3.yml');
$this->fail('->load() should throw an exception when a tag-attribute is not a scalar');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar');
$this->assertStringStartsWith('A "tags" attribute must be of a scalar-type for service "foo_service", tag "foo", attribute "bar"', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar');
}
}

public function testLoadYamlOnlyWithKeys()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services21.yml');

$definition = $container->getDefinition('manager');
$this->assertEquals(array(array('setLogger', array(new Reference('logger'))), array('setClass', array('User'))), $definition->getMethodCalls());
$this->assertEquals(array(true), $definition->getArguments());
$this->assertEquals(array('manager' => array(array('alias' => 'user'))), $definition->getTags());
}





public function testTagWithEmptyNameThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('tag_name_empty_string.yml');
}





public function testTagWithNonStringNameThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('tag_name_no_string.yml');
}




public function testTypesNotArray()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('bad_types1.yml');
}




public function testTypeNotString()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('bad_types2.yml');
}

public function testTypes()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services22.yml');

$this->assertEquals(array('Foo', 'Bar'), $container->getDefinition('foo_service')->getAutowiringTypes());
$this->assertEquals(array('Foo'), $container->getDefinition('baz_service')->getAutowiringTypes());
}

public function testAutowire()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('services23.yml');

$this->assertTrue($container->getDefinition('bar_service')->isAutowired());
}





public function testDecoratedServicesWithWrongSyntaxThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('bad_decorates.yml');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\Config\FileLocator;

class IniFileLoaderTest extends TestCase
{
protected static $fixturesPath;

protected $container;
protected $loader;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
}

protected function setUp()
{
$this->container = new ContainerBuilder();
$this->loader = new IniFileLoader($this->container, new FileLocator(self::$fixturesPath.'/ini'));
}

public function testIniFileCanBeLoaded()
{
$this->loader->load('parameters.ini');
$this->assertEquals(array('foo' => 'bar', 'bar' => '%foo%'), $this->container->getParameterBag()->all(), '->load() takes a single file name as its first argument');
}





public function testExceptionIsRaisedWhenIniFileDoesNotExist()
{
$this->loader->load('foo.ini');
}





public function testExceptionIsRaisedWhenIniFileCannotBeParsed()
{
@$this->loader->load('nonvalid.ini');
}

public function testSupports()
{
$loader = new IniFileLoader(new ContainerBuilder(), new FileLocator());

$this->assertTrue($loader->supports('foo.ini'), '->supports() returns true if the resource is loadable');
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;

class ClosureLoaderTest extends TestCase
{
public function testSupports()
{
$loader = new ClosureLoader(new ContainerBuilder());

$this->assertTrue($loader->supports(function ($container) {}), '->supports() returns true if the resource is loadable');
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}

public function testLoad()
{
$loader = new ClosureLoader($container = new ContainerBuilder());

$loader->load(function ($container) {
$container->setParameter('foo', 'foo');
});

$this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a \Closure resource');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\Config\FileLocator;

class PhpFileLoaderTest extends TestCase
{
public function testSupports()
{
$loader = new PhpFileLoader(new ContainerBuilder(), new FileLocator());

$this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable');
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}

public function testLoad()
{
$loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator());

$loader->load(__DIR__.'/../Fixtures/php/simple.php');

$this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a PHP file resource');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Loader;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\ExpressionLanguage\Expression;

class XmlFileLoaderTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
require_once self::$fixturesPath.'/includes/foo.php';
require_once self::$fixturesPath.'/includes/ProjectExtension.php';
require_once self::$fixturesPath.'/includes/ProjectWithXsdExtension.php';
}

public function testLoad()
{
$loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini'));

try {
$loader->load('foo.xml');
$this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist');
$this->assertStringStartsWith('The file "foo.xml" does not exist (in:', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist');
}
}

public function testParseFile()
{
$loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini'));
$r = new \ReflectionObject($loader);
$m = $r->getMethod('parseFileToDOM');
$m->setAccessible(true);

try {
$m->invoke($loader, self::$fixturesPath.'/ini/parameters.ini');
$this->fail('->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
$this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'parameters.ini'), $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');

$e = $e->getPrevious();
$this->assertInstanceOf('InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
$this->assertStringStartsWith('[ERROR 4] Start tag expected, \'<\' not found (in', $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');
}

$loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/xml'));

try {
$m->invoke($loader, self::$fixturesPath.'/xml/nonvalid.xml');
$this->fail('->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
$this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'nonvalid.xml'), $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file');

$e = $e->getPrevious();
$this->assertInstanceOf('InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
$this->assertStringStartsWith('[ERROR 1845] Element \'nonvalid\': No matching global declaration available for the validation root. (in', $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD');
}

$xml = $m->invoke($loader, self::$fixturesPath.'/xml/services1.xml');
$this->assertInstanceOf('DOMDocument', $xml, '->parseFileToDOM() returns an SimpleXMLElement object');
}

public function testLoadWithExternalEntitiesDisabled()
{
$disableEntities = libxml_disable_entity_loader(true);

$containerBuilder = new ContainerBuilder();
$loader = new XmlFileLoader($containerBuilder, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services2.xml');

libxml_disable_entity_loader($disableEntities);

$this->assertTrue(count($containerBuilder->getParameterBag()->all()) > 0, 'Parameters can be read from the config file.');
}

public function testLoadParameters()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services2.xml');

$actual = $container->getParameterBag()->all();
$expected = array(
'a string',
'foo' => 'bar',
'values' => array(
0,
'integer' => 4,
100 => null,
'true',
true,
false,
'on',
'off',
'float' => 1.3,
1000.3,
'a string',
array('foo', 'bar'),
),
'mixedcase' => array('MixedCaseKey' => 'value'),
'constant' => PHP_EOL,
);

$this->assertEquals($expected, $actual, '->load() converts XML values to PHP ones');
}

public function testLoadImports()
{
$container = new ContainerBuilder();
$resolver = new LoaderResolver(array(
new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yml')),
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
));
$loader->setResolver($resolver);
$loader->load('services4.xml');

$actual = $container->getParameterBag()->all();
$expected = array(
'a string',
'foo' => 'bar',
'values' => array(
0,
'integer' => 4,
100 => null,
'true',
true,
false,
'on',
'off',
'float' => 1.3,
1000.3,
'a string',
array('foo', 'bar'),
),
'mixedcase' => array('MixedCaseKey' => 'value'),
'constant' => PHP_EOL,
'bar' => '%foo%',
'imported_from_ini' => true,
'imported_from_yaml' => true,
);

$this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');


 $loader->load('services4_bad_import.xml');
}

public function testLoadAnonymousServices()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services5.xml');
$services = $container->getDefinitions();
$this->assertCount(6, $services, '->load() attributes unique ids to anonymous services');


 $args = $services['foo']->getArguments();
$this->assertCount(1, $args, '->load() references anonymous services as "normal" ones');
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $args[0], '->load() converts anonymous services to references to "normal" services');
$this->assertTrue(isset($services[(string) $args[0]]), '->load() makes a reference to the created ones');
$inner = $services[(string) $args[0]];
$this->assertEquals('BarClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones');
$this->assertFalse($inner->isPublic());


 $args = $inner->getArguments();
$this->assertCount(1, $args, '->load() references anonymous services as "normal" ones');
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $args[0], '->load() converts anonymous services to references to "normal" services');
$this->assertTrue(isset($services[(string) $args[0]]), '->load() makes a reference to the created ones');
$inner = $services[(string) $args[0]];
$this->assertEquals('BazClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones');
$this->assertFalse($inner->isPublic());


 $properties = $services['foo']->getProperties();
$property = $properties['p'];
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $property, '->load() converts anonymous services to references to "normal" services');
$this->assertTrue(isset($services[(string) $property]), '->load() makes a reference to the created ones');
$inner = $services[(string) $property];
$this->assertEquals('BuzClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones');
$this->assertFalse($inner->isPublic());


 $service = $container->findTaggedServiceIds('biz_tag');
$this->assertCount(1, $service);

foreach ($service as $id => $tag) {
$service = $container->getDefinition($id);
}
$this->assertEquals('BizClass', $service->getClass(), '->load() uses the same configuration as for the anonymous ones');
$this->assertTrue($service->isPublic());


 $container->compile();
$services = $container->getDefinitions();
$fooArgs = $services['foo']->getArguments();
$barArgs = $services['bar']->getArguments();
$this->assertSame($fooArgs[0], $barArgs[0]);
}




public function testLegacyLoadServices()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('legacy-services6.xml');
$services = $container->getDefinitions();
$this->assertEquals('FooClass', $services['constructor']->getClass());
$this->assertEquals('getInstance', $services['constructor']->getFactoryMethod());
$this->assertNull($services['factory_service']->getClass());
$this->assertEquals('baz_factory', $services['factory_service']->getFactoryService());
$this->assertEquals('getInstance', $services['factory_service']->getFactoryMethod());
$this->assertEquals('container', $services['scope.container']->getScope());
$this->assertEquals('custom', $services['scope.custom']->getScope());
$this->assertEquals('prototype', $services['scope.prototype']->getScope());
$this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag');
$this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag');
$this->assertTrue($services['request']->isLazy(), '->load() parses the lazy flag');
$this->assertNull($services['request']->getDecoratedService());
}

public function testLoadServices()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services6.xml');
$services = $container->getDefinitions();
$this->assertTrue(isset($services['foo']), '->load() parses <service> elements');
$this->assertFalse($services['not_shared']->isShared(), '->load() parses shared flag');
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts <service> element to Definition instances');
$this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute');
$this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag');
$this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags');
$this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag');
$this->assertEquals(array(new Reference('baz', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false), 'configure'), $services['configurator2']->getConfigurator(), '->load() parses the configurator tag');
$this->assertEquals(array('BazClass', 'configureStatic'), $services['configurator3']->getConfigurator(), '->load() parses the configurator tag');
$this->assertEquals(array(array('setBar', array()), array('setBar', array(new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')))), $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag');
$this->assertEquals(array(array('setBar', array('foo', new Reference('foo'), array(true, false)))), $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag');
$this->assertEquals('factory', $services['new_factory1']->getFactory(), '->load() parses the factory tag');
$this->assertEquals(array(new Reference('baz', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false), 'getClass'), $services['new_factory2']->getFactory(), '->load() parses the factory tag');
$this->assertEquals(array('BazClass', 'getInstance'), $services['new_factory3']->getFactory(), '->load() parses the factory tag');

$aliases = $container->getAliases();
$this->assertTrue(isset($aliases['alias_for_foo']), '->load() parses <service> elements');
$this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases');
$this->assertTrue($aliases['alias_for_foo']->isPublic());
$this->assertTrue(isset($aliases['another_alias_for_foo']));
$this->assertEquals('foo', (string) $aliases['another_alias_for_foo']);
$this->assertFalse($aliases['another_alias_for_foo']->isPublic());

$this->assertEquals(array('decorated', null, 0), $services['decorator_service']->getDecoratedService());
$this->assertEquals(array('decorated', 'decorated.pif-pouf', 0), $services['decorator_service_with_name']->getDecoratedService());
$this->assertEquals(array('decorated', 'decorated.pif-pouf', 5), $services['decorator_service_with_name_and_priority']->getDecoratedService());
}

public function testParsesTags()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services10.xml');

$services = $container->findTaggedServiceIds('foo_tag');
$this->assertCount(1, $services);

foreach ($services as $id => $tagAttributes) {
foreach ($tagAttributes as $attributes) {
$this->assertArrayHasKey('other_option', $attributes);
$this->assertEquals('lorem', $attributes['other_option']);
$this->assertArrayHasKey('other-option', $attributes, 'unnormalized tag attributes should not be removed');

$this->assertEquals('ciz', $attributes['some_option'], 'no overriding should be done when normalizing');
$this->assertEquals('cat', $attributes['some-option']);

$this->assertArrayNotHasKey('an_other_option', $attributes, 'normalization should not be done when an underscore is already found');
}
}
}




public function testParseTagsWithoutNameThrowsException()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('tag_without_name.xml');
}





public function testParseTagWithEmptyNameThrowsException()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('tag_with_empty_name.xml');
}

public function testDeprecated()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services_deprecated.xml');

$this->assertTrue($container->getDefinition('foo')->isDeprecated());
$message = 'The "foo" service is deprecated. You should stop using it, as it will soon be removed.';
$this->assertSame($message, $container->getDefinition('foo')->getDeprecationMessage('foo'));

$this->assertTrue($container->getDefinition('bar')->isDeprecated());
$message = 'The "bar" service is deprecated.';
$this->assertSame($message, $container->getDefinition('bar')->getDeprecationMessage('bar'));
}

public function testConvertDomElementToArray()
{
$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo>bar</foo>');
$this->assertEquals('bar', XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo foo="bar" />');
$this->assertEquals(array('foo' => 'bar'), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo><foo>bar</foo></foo>');
$this->assertEquals(array('foo' => 'bar'), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo><foo>bar<foo>bar</foo></foo></foo>');
$this->assertEquals(array('foo' => array('value' => 'bar', 'foo' => 'bar')), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo><foo></foo></foo>');
$this->assertEquals(array('foo' => null), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo><foo><!-- foo --></foo></foo>');
$this->assertEquals(array('foo' => null), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');

$doc = new \DOMDocument('1.0');
$doc->loadXML('<foo><foo foo="bar"/><foo foo="bar"/></foo>');
$this->assertEquals(array('foo' => array(array('foo' => 'bar'), array('foo' => 'bar'))), XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array');
}

public function testExtensions()
{
$container = new ContainerBuilder();
$container->registerExtension(new \ProjectExtension());
$container->registerExtension(new \ProjectWithXsdExtension());
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));


 $loader->load('extensions/services1.xml');
$container->compile();
$services = $container->getDefinitions();
$parameters = $container->getParameterBag()->all();

$this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
$this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');

$this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements');
$this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');


 $container = new ContainerBuilder();
$container->registerExtension(new \ProjectExtension());
$container->registerExtension(new \ProjectWithXsdExtension());
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('extensions/services2.xml');
$container->compile();
$services = $container->getDefinitions();
$parameters = $container->getParameterBag()->all();

$this->assertTrue(isset($services['project.service.bar']), '->load() parses extension elements');
$this->assertTrue(isset($parameters['project.parameter.bar']), '->load() parses extension elements');

$this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements');
$this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements');

$container = new ContainerBuilder();
$container->registerExtension(new \ProjectExtension());
$container->registerExtension(new \ProjectWithXsdExtension());
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));


 try {
$loader->load('extensions/services3.xml');
$this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
$this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'services3.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');

$e = $e->getPrevious();
$this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
$this->assertContains('The attribute \'bar\' is not allowed', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
}


 try {
$loader->load('extensions/services4.xml');
$this->fail('->load() throws an InvalidArgumentException if the tag is not valid');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid');
$this->assertStringStartsWith('There is no extension able to load the configuration for "project:bar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid');
}
}

public function testExtensionInPhar()
{
if (extension_loaded('suhosin') && false === strpos(ini_get('suhosin.executor.include.whitelist'), 'phar')) {
$this->markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.');
}

require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar';


 $container = new ContainerBuilder();
$container->registerExtension(new \ProjectWithXsdExtensionInPhar());
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('extensions/services6.xml');


 try {
$loader->load('extensions/services7.xml');
$this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
$this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'services7.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');

$e = $e->getPrevious();
$this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
$this->assertContains('The attribute \'bar\' is not allowed', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD');
}
}

public function testSupports()
{
$loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator());

$this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}

public function testNoNamingConflictsForAnonymousServices()
{
$container = new ContainerBuilder();

$loader1 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension1'));
$loader1->load('services.xml');
$services = $container->getDefinitions();
$this->assertCount(2, $services, '->load() attributes unique ids to anonymous services');
$loader2 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension2'));
$loader2->load('services.xml');
$services = $container->getDefinitions();
$this->assertCount(4, $services, '->load() attributes unique ids to anonymous services');

$services = $container->getDefinitions();
$args1 = $services['extension1.foo']->getArguments();
$inner1 = $services[(string) $args1[0]];
$this->assertEquals('BarClass1', $inner1->getClass(), '->load() uses the same configuration as for the anonymous ones');
$args2 = $services['extension2.foo']->getArguments();
$inner2 = $services[(string) $args2[0]];
$this->assertEquals('BarClass2', $inner2->getClass(), '->load() uses the same configuration as for the anonymous ones');
}

public function testDocTypeIsNotAllowed()
{
$container = new ContainerBuilder();

$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));


 try {
$loader->load('withdoctype.xml');
$this->fail('->load() throws an InvalidArgumentException if the configuration contains a document type');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration contains a document type');
$this->assertRegExp(sprintf('#^Unable to parse file ".+%s".$#', 'withdoctype.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration contains a document type');

$e = $e->getPrevious();
$this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration contains a document type');
$this->assertSame('Document types are not allowed.', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration contains a document type');
}
}

public function testXmlNamespaces()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('namespaces.xml');
$services = $container->getDefinitions();

$this->assertTrue(isset($services['foo']), '->load() parses <srv:service> elements');
$this->assertEquals(1, count($services['foo']->getTag('foo.tag')), '->load parses <srv:tag> elements');
$this->assertEquals(array(array('setBar', array('foo'))), $services['foo']->getMethodCalls(), '->load() parses the <srv:call> tag');
}

public function testLoadIndexedArguments()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services14.xml');

$this->assertEquals(array('index_0' => 'app'), $container->findDefinition('logger')->getArguments());
}

public function testLoadInlinedServices()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services21.xml');

$foo = $container->getDefinition('foo');

$fooFactory = $foo->getFactory();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $fooFactory[0]);
$this->assertSame('FooFactory', $fooFactory[0]->getClass());
$this->assertSame('createFoo', $fooFactory[1]);

$fooFactoryFactory = $fooFactory[0]->getFactory();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $fooFactoryFactory[0]);
$this->assertSame('Foobar', $fooFactoryFactory[0]->getClass());
$this->assertSame('createFooFactory', $fooFactoryFactory[1]);

$fooConfigurator = $foo->getConfigurator();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $fooConfigurator[0]);
$this->assertSame('Bar', $fooConfigurator[0]->getClass());
$this->assertSame('configureFoo', $fooConfigurator[1]);

$barConfigurator = $fooConfigurator[0]->getConfigurator();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $barConfigurator[0]);
$this->assertSame('Baz', $barConfigurator[0]->getClass());
$this->assertSame('configureBar', $barConfigurator[1]);
}

public function testType()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services22.xml');

$this->assertEquals(array('Bar', 'Baz'), $container->getDefinition('foo')->getAutowiringTypes());
}

public function testAutowire()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services23.xml');

$this->assertTrue($container->getDefinition('bar')->isAutowired());
}

public function testArgumentWithKeyOutsideCollection()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('with_key_outside_collection.xml');

$this->assertSame(array('type' => 'foo', 'bar'), $container->getDefinition('foo')->getArguments());
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;

class CrossCheckTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = __DIR__.'/Fixtures/';

require_once self::$fixturesPath.'/includes/classes.php';
require_once self::$fixturesPath.'/includes/foo.php';
}




public function testCrossCheck($fixture, $type)
{
$loaderClass = 'Symfony\\Component\\DependencyInjection\\Loader\\'.ucfirst($type).'FileLoader';
$dumperClass = 'Symfony\\Component\\DependencyInjection\\Dumper\\'.ucfirst($type).'Dumper';

$tmp = tempnam(sys_get_temp_dir(), 'sf');

copy(self::$fixturesPath.'/'.$type.'/'.$fixture, $tmp);

$container1 = new ContainerBuilder();
$loader1 = new $loaderClass($container1, new FileLocator());
$loader1->load($tmp);

$dumper = new $dumperClass($container1);
file_put_contents($tmp, $dumper->dump());

$container2 = new ContainerBuilder();
$loader2 = new $loaderClass($container2, new FileLocator());
$loader2->load($tmp);

unlink($tmp);

$this->assertEquals($container2->getAliases(), $container1->getAliases(), 'loading a dump from a previously loaded container returns the same container');
$this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container');
$this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers');

$this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container');

$services1 = array();
foreach ($container1 as $id => $service) {
$services1[$id] = serialize($service);
}
$services2 = array();
foreach ($container2 as $id => $service) {
$services2[$id] = serialize($service);
}

unset($services1['service_container'], $services2['service_container']);

$this->assertEquals($services2, $services1, 'Iterator on the containers returns the same services');
}

public function crossCheckLoadersDumpers()
{
return array(
array('services1.xml', 'xml'),
array('services2.xml', 'xml'),
array('services6.xml', 'xml'),
array('services8.xml', 'xml'),
array('services9.xml', 'xml'),
array('services1.yml', 'yaml'),
array('services2.yml', 'yaml'),
array('services6.yml', 'yaml'),
array('services8.yml', 'yaml'),
array('services9.yml', 'yaml'),
);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\ParameterBag;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

class ParameterBagTest extends TestCase
{
public function testConstructor()
{
$bag = new ParameterBag($parameters = array(
'foo' => 'foo',
'bar' => 'bar',
));
$this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument');
}

public function testClear()
{
$bag = new ParameterBag($parameters = array(
'foo' => 'foo',
'bar' => 'bar',
));
$bag->clear();
$this->assertEquals(array(), $bag->all(), '->clear() removes all parameters');
}

public function testRemove()
{
$bag = new ParameterBag(array(
'foo' => 'foo',
'bar' => 'bar',
));
$bag->remove('foo');
$this->assertEquals(array('bar' => 'bar'), $bag->all(), '->remove() removes a parameter');
$bag->remove('BAR');
$this->assertEquals(array(), $bag->all(), '->remove() converts key to lowercase before removing');
}

public function testGetSet()
{
$bag = new ParameterBag(array('foo' => 'bar'));
$bag->set('bar', 'foo');
$this->assertEquals('foo', $bag->get('bar'), '->set() sets the value of a new parameter');

$bag->set('foo', 'baz');
$this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter');

$bag->set('Foo', 'baz1');
$this->assertEquals('baz1', $bag->get('foo'), '->set() converts the key to lowercase');
$this->assertEquals('baz1', $bag->get('FOO'), '->get() converts the key to lowercase');

try {
$bag->get('baba');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
}
}

public function testGetThrowParameterNotFoundException()
{
$bag = new ParameterBag(array(
'foo' => 'foo',
'bar' => 'bar',
'baz' => 'baz',
));

try {
$bag->get('foo1');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
}

try {
$bag->get('bag');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
}

try {
$bag->get('');
$this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist');
$this->assertEquals('You have requested a non-existent parameter "".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices');
}
}

public function testHas()
{
$bag = new ParameterBag(array('foo' => 'bar'));
$this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined');
$this->assertTrue($bag->has('Foo'), '->has() converts the key to lowercase');
$this->assertFalse($bag->has('bar'), '->has() returns false if a parameter is not defined');
}

public function testResolveValue()
{
$bag = new ParameterBag(array());
$this->assertEquals('foo', $bag->resolveValue('foo'), '->resolveValue() returns its argument unmodified if no placeholders are found');

$bag = new ParameterBag(array('foo' => 'bar'));
$this->assertEquals('I\'m a bar', $bag->resolveValue('I\'m a %foo%'), '->resolveValue() replaces placeholders by their values');
$this->assertEquals(array('bar' => 'bar'), $bag->resolveValue(array('%foo%' => '%foo%')), '->resolveValue() replaces placeholders in keys and values of arrays');
$this->assertEquals(array('bar' => array('bar' => array('bar' => 'bar'))), $bag->resolveValue(array('%foo%' => array('%foo%' => array('%foo%' => '%foo%')))), '->resolveValue() replaces placeholders in nested arrays');
$this->assertEquals('I\'m a %%foo%%', $bag->resolveValue('I\'m a %%foo%%'), '->resolveValue() supports % escaping by doubling it');
$this->assertEquals('I\'m a bar %%foo bar', $bag->resolveValue('I\'m a %foo% %%foo %foo%'), '->resolveValue() supports % escaping by doubling it');
$this->assertEquals(array('foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar'))), $bag->resolveValue(array('foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar')))), '->resolveValue() supports % escaping by doubling it');

$bag = new ParameterBag(array('foo' => true));
$this->assertTrue($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
$bag = new ParameterBag(array('foo' => null));
$this->assertNull($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');

$bag = new ParameterBag(array('foo' => 'bar', 'baz' => '%%%foo% %foo%%% %%foo%% %%%foo%%%'));
$this->assertEquals('%%bar bar%% %%foo%% %%bar%%', $bag->resolveValue('%baz%'), '->resolveValue() replaces params placed besides escaped %');

$bag = new ParameterBag(array('baz' => '%%s?%%s'));
$this->assertEquals('%%s?%%s', $bag->resolveValue('%baz%'), '->resolveValue() is not replacing greedily');

$bag = new ParameterBag(array());
try {
$bag->resolveValue('%foobar%');
$this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
} catch (ParameterNotFoundException $e) {
$this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
}

try {
$bag->resolveValue('foo %foobar% bar');
$this->fail('->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
} catch (ParameterNotFoundException $e) {
$this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
}

$bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => array()));
try {
$bag->resolveValue('%foo%');
$this->fail('->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter');
} catch (RuntimeException $e) {
$this->assertEquals('A string value must be composed of strings and/or numbers, but found parameter "bar" of type array inside string value "a %bar%".', $e->getMessage(), '->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter');
}

$bag = new ParameterBag(array('foo' => '%bar%', 'bar' => '%foobar%', 'foobar' => '%foo%'));
try {
$bag->resolveValue('%foo%');
$this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
} catch (ParameterCircularReferenceException $e) {
$this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
}

$bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => 'a %foobar%', 'foobar' => 'a %foo%'));
try {
$bag->resolveValue('%foo%');
$this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
} catch (ParameterCircularReferenceException $e) {
$this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference');
}

$bag = new ParameterBag(array('host' => 'foo.bar', 'port' => 1337));
$this->assertEquals('foo.bar:1337', $bag->resolveValue('%host%:%port%'));
}

public function testResolveIndicatesWhyAParameterIsNeeded()
{
$bag = new ParameterBag(array('foo' => '%bar%'));

try {
$bag->resolve();
} catch (ParameterNotFoundException $e) {
$this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage());
}

$bag = new ParameterBag(array('foo' => '%bar%'));

try {
$bag->resolve();
} catch (ParameterNotFoundException $e) {
$this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage());
}
}

public function testResolveUnescapesValue()
{
$bag = new ParameterBag(array(
'foo' => array('bar' => array('ding' => 'I\'m a bar %%foo %%bar')),
'bar' => 'I\'m a %%foo%%',
));

$bag->resolve();

$this->assertEquals('I\'m a %foo%', $bag->get('bar'), '->resolveValue() supports % escaping by doubling it');
$this->assertEquals(array('bar' => array('ding' => 'I\'m a bar %foo %bar')), $bag->get('foo'), '->resolveValue() supports % escaping by doubling it');
}

public function testEscapeValue()
{
$bag = new ParameterBag();

$bag->add(array(
'foo' => $bag->escapeValue(array('bar' => array('ding' => 'I\'m a bar %foo %bar', 'zero' => null))),
'bar' => $bag->escapeValue('I\'m a %foo%'),
));

$this->assertEquals('I\'m a %%foo%%', $bag->get('bar'), '->escapeValue() escapes % by doubling it');
$this->assertEquals(array('bar' => array('ding' => 'I\'m a bar %%foo %%bar', 'zero' => null)), $bag->get('foo'), '->escapeValue() escapes % by doubling it');
}




public function testResolveStringWithSpacesReturnsString($expected, $test, $description)
{
$bag = new ParameterBag(array('foo' => 'bar'));

try {
$this->assertEquals($expected, $bag->resolveString($test), $description);
} catch (ParameterNotFoundException $e) {
$this->fail(sprintf('%s - "%s"', $description, $expected));
}
}

public function stringsWithSpacesProvider()
{
return array(
array('bar', '%foo%', 'Parameters must be wrapped by %.'),
array('% foo %', '% foo %', 'Parameters should not have spaces.'),
array('{% set my_template = "foo" %}', '{% set my_template = "foo" %}', 'Twig-like strings are not parameters.'),
array('50% is less than 100%', '50% is less than 100%', 'Text between % signs is allowed, if there are spaces.'),
);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\ParameterBag;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;

class FrozenParameterBagTest extends TestCase
{
public function testConstructor()
{
$parameters = array(
'foo' => 'foo',
'bar' => 'bar',
);
$bag = new FrozenParameterBag($parameters);
$this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument');
}




public function testClear()
{
$bag = new FrozenParameterBag(array());
$bag->clear();
}




public function testSet()
{
$bag = new FrozenParameterBag(array());
$bag->set('foo', 'bar');
}




public function testAdd()
{
$bag = new FrozenParameterBag(array());
$bag->add(array());
}




public function testRemove()
{
$bag = new FrozenParameterBag(array('foo' => 'bar'));
$bag->remove('foo');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Parameter;

class ParameterTest extends TestCase
{
public function testConstructor()
{
$ref = new Parameter('foo');
$this->assertEquals('foo', (string) $ref, '__construct() sets the id of the parameter, which is used for the __toString() method');
}
}
<?php

$container->setParameter('php', 'php');
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct();
$this->methodMap = array(
'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService',
'service_with_method_call_and_factory' => 'getServiceWithMethodCallAndFactoryService',
);
}









protected function getServiceFromAnonymousFactoryService()
{
return $this->services['service_from_anonymous_factory'] = call_user_func(array(new \Bar\FooClass(), 'getInstance'));
}









protected function getServiceWithMethodCallAndFactoryService()
{
$this->services['service_with_method_call_and_factory'] = $instance = new \Bar\FooClass();

$instance->setBar(\Bar\FooClass::getInstance());

return $instance;
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct();
$this->methodMap = array(
'foo' => 'getFooService',
);
}








protected function getFooService()
{
return $this->services['foo'] = new \Foo();
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
$this->services =
$this->scopedServices =
$this->scopeStacks = array();
$this->scopes = array();
$this->scopeChildren = array();
$this->methodMap = array(
'bar' => 'getBarService',
);

$this->aliases = array();
}




public function compile()
{
throw new LogicException('You cannot compile a dumped frozen container.');
}




public function isFrozen()
{
return true;
}









protected function getBarService()
{
$a = new \stdClass();
$a->add($this);

return $this->services['bar'] = new \stdClass($a);
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
$this->parameters = $this->getDefaultParameters();

$this->services =
$this->scopedServices =
$this->scopeStacks = array();
$this->scopes = array();
$this->scopeChildren = array();
$this->methodMap = array(
'test' => 'getTestService',
);

$this->aliases = array();
}




public function compile()
{
throw new LogicException('You cannot compile a dumped frozen container.');
}




public function isFrozen()
{
return true;
}









protected function getTestService()
{
return $this->services['test'] = new \stdClass(array('only dot' => '.', 'concatenation as value' => '.\'\'.', 'concatenation from the start value' => '\'\'.', '.' => 'dot as a key', '.\'\'.' => 'concatenation as a key', '\'\'.' => 'concatenation from the start key', 'optimize concatenation' => 'string1-string2', 'optimize concatenation with empty string' => 'string1string2', 'optimize concatenation from the start' => 'start', 'optimize concatenation at the end' => 'end'));
}




public function getParameter($name)
{
$name = strtolower($name);

if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}

return $this->parameters[$name];
}




public function hasParameter($name)
{
$name = strtolower($name);

return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
}




public function setParameter($name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}




public function getParameterBag()
{
if (null === $this->parameterBag) {
$this->parameterBag = new FrozenParameterBag($this->parameters);
}

return $this->parameterBag;
}






protected function getDefaultParameters()
{
return array(
'empty_value' => '',
'some_string' => '-',
);
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
$dir = __DIR__;
for ($i = 1; $i <= 5; ++$i) {
$this->targetDirs[$i] = $dir = dirname($dir);
}
$this->parameters = $this->getDefaultParameters();

$this->services =
$this->scopedServices =
$this->scopeStacks = array();
$this->scopes = array();
$this->scopeChildren = array();
$this->methodMap = array(
'test' => 'getTestService',
);

$this->aliases = array();
}




public function compile()
{
throw new LogicException('You cannot compile a dumped frozen container.');
}




public function isFrozen()
{
return true;
}









protected function getTestService()
{
return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), array(('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')));
}




public function getParameter($name)
{
$name = strtolower($name);

if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}

return $this->parameters[$name];
}




public function hasParameter($name)
{
$name = strtolower($name);

return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
}




public function setParameter($name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}




public function getParameterBag()
{
if (null === $this->parameterBag) {
$this->parameterBag = new FrozenParameterBag($this->parameters);
}

return $this->parameterBag;
}






protected function getDefaultParameters()
{
return array(
'foo' => ('wiz'.$this->targetDirs[1]),
'bar' => __DIR__,
'baz' => (__DIR__.'/PhpDumperTest.php'),
'buz' => $this->targetDirs[2],
);
}
}
<?php
namespace Symfony\Component\DependencyInjection\Dump;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class Container extends AbstractContainer
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct();
}
}
<?php

$container->setParameter('foo', 'foo');
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
$this->parameters = $this->getDefaultParameters();

$this->services =
$this->scopedServices =
$this->scopeStacks = array();
$this->scopes = array();
$this->scopeChildren = array();
$this->methodMap = array(
'bar' => 'getBarService',
'baz' => 'getBazService',
'configured_service' => 'getConfiguredServiceService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'deprecated_service' => 'getDeprecatedServiceService',
'factory_service' => 'getFactoryServiceService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
'foo_with_inline' => 'getFooWithInlineService',
'method_call1' => 'getMethodCall1Service',
'new_factory_service' => 'getNewFactoryServiceService',
'request' => 'getRequestService',
'service_from_static_method' => 'getServiceFromStaticMethodService',
);
$this->aliases = array(
'alias_for_alias' => 'foo',
'alias_for_foo' => 'foo',
'decorated' => 'decorator_service_with_name',
);
}




public function compile()
{
throw new LogicException('You cannot compile a dumped frozen container.');
}




public function isFrozen()
{
return true;
}









protected function getBarService()
{
$a = $this->get('foo.baz');

$this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar'));

$a->configure($instance);

return $instance;
}









protected function getBazService()
{
$this->services['baz'] = $instance = new \Baz();

$instance->setFoo($this->get('foo_with_inline'));

return $instance;
}









protected function getConfiguredServiceService()
{
$a = new \ConfClass();
$a->setFoo($this->get('baz'));

$this->services['configured_service'] = $instance = new \stdClass();

$a->configureStdClass($instance);

return $instance;
}









protected function getDecoratorServiceService()
{
return $this->services['decorator_service'] = new \stdClass();
}









protected function getDecoratorServiceWithNameService()
{
return $this->services['decorator_service_with_name'] = new \stdClass();
}











protected function getDeprecatedServiceService()
{
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);

return $this->services['deprecated_service'] = new \stdClass();
}









protected function getFactoryServiceService()
{
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
}









protected function getFooService()
{
$a = $this->get('foo.baz');

$this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array('bar' => 'foo is bar', 'foobar' => 'bar'), true, $this);

$instance->foo = 'bar';
$instance->moo = $a;
$instance->qux = array('bar' => 'foo is bar', 'foobar' => 'bar');
$instance->setBar($this->get('bar'));
$instance->initialize();
sc_configure($instance);

return $instance;
}









protected function getFoo_BazService()
{
$this->services['foo.baz'] = $instance = \BazClass::getInstance();

\BazClass::configureStatic1($instance);

return $instance;
}






protected function getFooBarService()
{
return new \Bar\FooClass();
}









protected function getFooWithInlineService()
{
$a = new \Bar();

$this->services['foo_with_inline'] = $instance = new \Foo();

$a->pub = 'pub';
$a->setBaz($this->get('baz'));

$instance->setBar($a);

return $instance;
}









protected function getMethodCall1Service()
{
require_once '%path%foo.php';

$this->services['method_call1'] = $instance = new \Bar\FooClass();

$instance->setBar($this->get('foo'));
$instance->setBar(NULL);
$instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));

return $instance;
}









protected function getNewFactoryServiceService()
{
$a = new \FactoryClass();
$a->foo = 'bar';

$this->services['new_factory_service'] = $instance = $a->getInstance();

$instance->foo = 'bar';

return $instance;
}









protected function getRequestService()
{
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
}









protected function getServiceFromStaticMethodService()
{
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
}




public function getParameter($name)
{
$name = strtolower($name);

if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) {
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}

return $this->parameters[$name];
}




public function hasParameter($name)
{
$name = strtolower($name);

return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters);
}




public function setParameter($name, $value)
{
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
}




public function getParameterBag()
{
if (null === $this->parameterBag) {
$this->parameterBag = new FrozenParameterBag($this->parameters);
}

return $this->parameterBag;
}






protected function getDefaultParameters()
{
return array(
'baz_class' => 'BazClass',
'foo_class' => 'Bar\\FooClass',
'foo' => 'bar',
);
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct(new ParameterBag($this->getDefaultParameters()));
}






protected function getDefaultParameters()
{
return array(
'foo' => '%baz%',
'baz' => 'bar',
'bar' => 'foo is %%foo bar',
'escape' => '@escapeme',
'values' => array(
0 => true,
1 => false,
2 => NULL,
3 => 0,
4 => 1000.3,
5 => 'true',
6 => 'false',
7 => 'null',
),
);
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct(new ParameterBag($this->getDefaultParameters()));
$this->methodMap = array(
'bar' => 'getBarService',
'baz' => 'getBazService',
'configurator_service' => 'getConfiguratorServiceService',
'configured_service' => 'getConfiguredServiceService',
'decorated' => 'getDecoratedService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'deprecated_service' => 'getDeprecatedServiceService',
'factory_service' => 'getFactoryServiceService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
'foo_bar' => 'getFooBarService',
'foo_with_inline' => 'getFooWithInlineService',
'inlined' => 'getInlinedService',
'method_call1' => 'getMethodCall1Service',
'new_factory' => 'getNewFactoryService',
'new_factory_service' => 'getNewFactoryServiceService',
'request' => 'getRequestService',
'service_from_static_method' => 'getServiceFromStaticMethodService',
);
$this->aliases = array(
'alias_for_alias' => 'foo',
'alias_for_foo' => 'foo',
);
}









protected function getBarService()
{
$a = $this->get('foo.baz');

$this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar'));

$a->configure($instance);

return $instance;
}









protected function getBazService()
{
$this->services['baz'] = $instance = new \Baz();

$instance->setFoo($this->get('foo_with_inline'));

return $instance;
}









protected function getConfiguredServiceService()
{
$this->services['configured_service'] = $instance = new \stdClass();

$this->get('configurator_service')->configureStdClass($instance);

return $instance;
}









protected function getDecoratedService()
{
return $this->services['decorated'] = new \stdClass();
}









protected function getDecoratorServiceService()
{
return $this->services['decorator_service'] = new \stdClass();
}









protected function getDecoratorServiceWithNameService()
{
return $this->services['decorator_service_with_name'] = new \stdClass();
}











protected function getDeprecatedServiceService()
{
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);

return $this->services['deprecated_service'] = new \stdClass();
}









protected function getFactoryServiceService()
{
return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
}









protected function getFooService()
{
$a = $this->get('foo.baz');

$this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')), true, $this);

$instance->foo = 'bar';
$instance->moo = $a;
$instance->qux = array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo'));
$instance->setBar($this->get('bar'));
$instance->initialize();
sc_configure($instance);

return $instance;
}









protected function getFoo_BazService()
{
$this->services['foo.baz'] = $instance = call_user_func(array($this->getParameter('baz_class'), 'getInstance'));

call_user_func(array($this->getParameter('baz_class'), 'configureStatic1'), $instance);

return $instance;
}






protected function getFooBarService()
{
$class = $this->getParameter('foo_class');

return new $class();
}









protected function getFooWithInlineService()
{
$this->services['foo_with_inline'] = $instance = new \Foo();

$instance->setBar($this->get('inlined'));

return $instance;
}









protected function getMethodCall1Service()
{
require_once '%path%foo.php';

$this->services['method_call1'] = $instance = new \Bar\FooClass();

$instance->setBar($this->get('foo'));
$instance->setBar($this->get('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE));
if ($this->has('foo3')) {
$instance->setBar($this->get('foo3', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}
if ($this->has('foobaz')) {
$instance->setBar($this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}
$instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default"))));

return $instance;
}









protected function getNewFactoryServiceService()
{
$this->services['new_factory_service'] = $instance = $this->get('new_factory')->getInstance();

$instance->foo = 'bar';

return $instance;
}









protected function getRequestService()
{
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
}









protected function getServiceFromStaticMethodService()
{
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
}













protected function getConfiguratorServiceService()
{
$this->services['configurator_service'] = $instance = new \ConfClass();

$instance->setFoo($this->get('baz'));

return $instance;
}













protected function getInlinedService()
{
$this->services['inlined'] = $instance = new \Bar();

$instance->pub = 'pub';
$instance->setBaz($this->get('baz'));

return $instance;
}













protected function getNewFactoryService()
{
$this->services['new_factory'] = $instance = new \FactoryClass();

$instance->foo = 'bar';

return $instance;
}






protected function getDefaultParameters()
{
return array(
'baz_class' => 'BazClass',
'foo_class' => 'Bar\\FooClass',
'foo' => 'bar',
);
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct();
$this->methodMap = array(
'depends_on_request' => 'getDependsOnRequestService',
'request' => 'getRequestService',
);
}









protected function getDependsOnRequestService()
{
$this->services['depends_on_request'] = $instance = new \stdClass();

$instance->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));

return $instance;
}









protected function getRequestService()
{
return $this->services['request'] = new \Request();
}




protected function synchronizeRequestService()
{
if ($this->initialized('depends_on_request')) {
$this->get('depends_on_request')->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;







class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();




public function __construct()
{
parent::__construct();
}
}
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

$container = new ContainerBuilder();

$bar = new Definition('Bar');
$bar->setConfigurator(array(new Definition('Baz'), 'configureBar'));

$fooFactory = new Definition('FooFactory');
$fooFactory->setFactory(array(new Definition('Foobar'), 'createFooFactory'));

$container
->register('foo', 'Foo')
->setFactory(array($fooFactory, 'createFoo'))
->setConfigurator(array($bar, 'configureFoo'))
;

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Scope;

$container = new ContainerBuilder();
$container->addScope(new Scope('request'));
$container->
register('foo', 'FooClass')->
setScope('request')
;
$container->compile();

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

$container = new ContainerBuilder(new ParameterBag(array(
'FOO' => '%baz%',
'baz' => 'bar',
'bar' => 'foo is %%foo bar',
'escape' => '@escapeme',
'values' => array(true, false, null, 0, 1000.3, 'true', 'false', 'null'),
)));

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
->register('foo', 'FooClass\\Foo')
->setDecoratedService('bar', 'bar.woozy')
;

return $container;
<?php

namespace Container14;

use Symfony\Component\DependencyInjection\ContainerBuilder;





if (!class_exists('Container14\ProjectServiceContainer')) {
class ProjectServiceContainer extends ContainerBuilder
{
}
}

return new ProjectServiceContainer();
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
->register('foo', 'FooClass\\Foo')
->setDecoratedService('bar')
;

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container
->register('foo', '%foo.class%')
;

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

require_once __DIR__.'/../includes/classes.php';

$container = new ContainerBuilder();

$container
->register('service_from_anonymous_factory', 'Bar\FooClass')
->setFactory(array(new Definition('Bar\FooClass'), 'getInstance'))
;

$anonymousServiceWithFactory = new Definition('Bar\FooClass');
$anonymousServiceWithFactory->setFactory('Bar\FooClass::getInstance');
$container
->register('service_with_method_call_and_factory', 'Bar\FooClass')
->addMethodCall('setBar', array($anonymousServiceWithFactory))
;

return $container;
<?php

require_once __DIR__.'/../includes/classes.php';

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\ExpressionLanguage\Expression;

$container = new ContainerBuilder();
$container
->register('foo', '\Bar\FooClass')
->addTag('foo', array('foo' => 'foo'))
->addTag('foo', array('bar' => 'bar', 'baz' => 'baz'))
->setFactory(array('Bar\\FooClass', 'getInstance'))
->setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))
->setProperties(array('foo' => 'bar', 'moo' => new Reference('foo.baz'), 'qux' => array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%')))
->addMethodCall('setBar', array(new Reference('bar')))
->addMethodCall('initialize')
->setConfigurator('sc_configure')
;
$container
->register('foo.baz', '%baz_class%')
->setFactory(array('%baz_class%', 'getInstance'))
->setConfigurator(array('%baz_class%', 'configureStatic1'))
;
$container
->register('bar', 'Bar\FooClass')
->setArguments(array('foo', new Reference('foo.baz'), new Parameter('foo_bar')))
->setConfigurator(array(new Reference('foo.baz'), 'configure'))
;
$container
->register('foo_bar', '%foo_class%')
->setShared(false)
;
$container->getParameterBag()->clear();
$container->getParameterBag()->add(array(
'baz_class' => 'BazClass',
'foo_class' => 'Bar\FooClass',
'foo' => 'bar',
));
$container->setAlias('alias_for_foo', 'foo');
$container->setAlias('alias_for_alias', 'alias_for_foo');
$container
->register('method_call1', 'Bar\FooClass')
->setFile(realpath(__DIR__.'/../includes/foo.php'))
->addMethodCall('setBar', array(new Reference('foo')))
->addMethodCall('setBar', array(new Reference('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)))
->addMethodCall('setBar', array(new Reference('foo3', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
->addMethodCall('setBar', array(new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
->addMethodCall('setBar', array(new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')))
;
$container
->register('foo_with_inline', 'Foo')
->addMethodCall('setBar', array(new Reference('inlined')))
;
$container
->register('inlined', 'Bar')
->setProperty('pub', 'pub')
->addMethodCall('setBaz', array(new Reference('baz')))
->setPublic(false)
;
$container
->register('baz', 'Baz')
->addMethodCall('setFoo', array(new Reference('foo_with_inline')))
;
$container
->register('request', 'Request')
->setSynthetic(true)
;
$container
->register('configurator_service', 'ConfClass')
->setPublic(false)
->addMethodCall('setFoo', array(new Reference('baz')))
;
$container
->register('configured_service', 'stdClass')
->setConfigurator(array(new Reference('configurator_service'), 'configureStdClass'))
;
$container
->register('decorated', 'stdClass')
;
$container
->register('decorator_service', 'stdClass')
->setDecoratedService('decorated')
;
$container
->register('decorator_service_with_name', 'stdClass')
->setDecoratedService('decorated', 'decorated.pif-pouf')
;
$container
->register('deprecated_service', 'stdClass')
->setDeprecated(true)
;
$container
->register('new_factory', 'FactoryClass')
->setProperty('foo', 'bar')
->setPublic(false)
;
$container
->register('factory_service', 'Bar')
->setFactory(array(new Reference('foo.baz'), 'getInstance'))
;
$container
->register('new_factory_service', 'FooBarBaz')
->setProperty('foo', 'bar')
->setFactory(array(new Reference('new_factory'), 'getInstance'))
;
$container
->register('service_from_static_method', 'Bar\FooClass')
->setFactory(array('Bar\FooClass', 'getInstance'))
;

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();
$container->
register('foo', 'FooClass')->
addArgument(new Reference('bar'))
;
$container->
register('bar', 'BarClass')
;
$container->compile();

return $container;
<?php

require_once __DIR__.'/../includes/classes.php';

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();
$container
->register('request', 'Request')
->setSynchronized(true)
;
$container
->register('depends_on_request', 'stdClass')
->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)))
;

return $container;
<?php

require_once __DIR__.'/../includes/classes.php';

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();
$container->
register('foo', 'Bar\FooClass')->
addTag('foo', array('foo' => 'foo'))->
addTag('foo', array('bar' => 'bar'))->
setFactoryClass('Bar\\FooClass')->
setFactoryMethod('getInstance')->
setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))->
setProperties(array('foo' => 'bar', 'moo' => new Reference('foo.baz'), 'qux' => array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%')))->
addMethodCall('setBar', array(new Reference('bar')))->
addMethodCall('initialize')->
setConfigurator('sc_configure')
;
$container->
register('foo.baz', '%baz_class%')->
setFactoryClass('%baz_class%')->
setFactoryMethod('getInstance')->
setConfigurator(array('%baz_class%', 'configureStatic1'))
;
$container->
register('factory_service', 'Bar')->
setFactoryService('foo.baz')->
setFactoryMethod('getInstance')
;
$container
->register('foo_bar', '%foo_class%')
->setScope('prototype')
;
$container->getParameterBag()->clear();
$container->getParameterBag()->add(array(
'foo_class' => 'Bar\FooClass',
'baz_class' => 'BazClass',
'foo' => 'bar',
));

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

$container = new ContainerBuilder();
$container->
register('foo', 'FooClass')->
addArgument(new Definition('BarClass', array(new Definition('BazClass'))))
;

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$container->
register('foo', 'FooClass\\Foo')->
addArgument('foo<>&bar')->
addTag('foo"bar\\bar', array('foo' => 'foo"barřž€'))
;

return $container;
<?php

require_once __DIR__.'/../includes/classes.php';

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$container = new ContainerBuilder();
$container->
register('foo', 'FooClass')->
addArgument(new Reference('bar'))
;

return $container;
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

$container = new ContainerBuilder();

$container
->register('foo', 'Foo')
->setAutowired(true)
->addAutowiringType('A')
->addAutowiringType('B')
;

return $container;
<?php










namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

use Symfony\Component\DependencyInjection\Definition;

class CustomDefinition extends Definition
{
}
<?php

namespace Bar;

class FooClass
{
public $foo;
public $moo;

public $bar = null;
public $initialized = false;
public $configured = false;
public $called = false;
public $arguments = array();

public function __construct($arguments = array())
{
$this->arguments = $arguments;
}

public static function getInstance($arguments = array())
{
$obj = new self($arguments);
$obj->called = true;

return $obj;
}

public function initialize()
{
$this->initialized = true;
}

public function configure()
{
$this->configured = true;
}

public function setBar($value = null)
{
$this->bar = $value;
}
}
<?php

class ProjectWithXsdExtension extends ProjectExtension
{
public function getXsdValidationBasePath()
{
return __DIR__.'/schema';
}

public function getNamespace()
{
return 'http://www.example.com/schema/projectwithxsd';
}

public function getAlias()
{
return 'projectwithxsd';
}
}
<?php

$file = __DIR__.'/ProjectWithXsdExtensionInPhar.phar';
if (is_file($file)) {
@unlink($file);
}

$phar = new Phar($file, 0, 'ProjectWithXsdExtensionInPhar.phar');
$phar->addFromString('ProjectWithXsdExtensionInPhar.php', <<<'EOT'
<?php

class ProjectWithXsdExtensionInPhar extends ProjectExtension
{
    public function getXsdValidationBasePath()
    {
        return __DIR__.'/schema';
    }

    public function getNamespace()
    {
        return 'http://www.example.com/schema/projectwithxsdinphar';
    }

    public function getAlias()
    {
        return 'projectwithxsdinphar';
    }
}
EOT
);
$phar->addFromString('schema/project-1.0.xsd', <<<'EOT'
<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://www.example.com/schema/projectwithxsdinphar"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com/schema/projectwithxsdinphar"
    elementFormDefault="qualified">

  <xsd:element name="bar" type="bar" />

  <xsd:complexType name="bar">
    <xsd:attribute name="foo" type="xsd:string" />
  </xsd:complexType>
</xsd:schema>
EOT
);
$phar->setStub('<?php Phar::mapPhar("ProjectWithXsdExtensionInPhar.phar"); require_once "phar://ProjectWithXsdExtensionInPhar.phar/ProjectWithXsdExtensionInPhar.php"; __HALT_COMPILER(); ?>');
<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;

class ProjectExtension implements ExtensionInterface
{
public function load(array $configs, ContainerBuilder $configuration)
{
$config = call_user_func_array('array_merge', $configs);

$configuration->setDefinition('project.service.bar', new Definition('FooClass'));
$configuration->setParameter('project.parameter.bar', isset($config['foo']) ? $config['foo'] : 'foobar');

$configuration->setDefinition('project.service.foo', new Definition('FooClass'));
$configuration->setParameter('project.parameter.foo', isset($config['foo']) ? $config['foo'] : 'foobar');

return $configuration;
}

public function getXsdValidationBasePath()
{
return false;
}

public function getNamespace()
{
return 'http://www.example.com/schema/project';
}

public function getAlias()
{
return 'project';
}

public function getConfiguration(array $config, ContainerBuilder $container)
{
}
}
<?php

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;

function sc_configure($instance)
{
$instance->configure();
}

class BarClass
{
protected $baz;
public $foo = 'foo';

public function setBaz(BazClass $baz)
{
$this->baz = $baz;
}

public function getBaz()
{
return $this->baz;
}
}

class BazClass
{
protected $foo;

public function setFoo(Foo $foo)
{
$this->foo = $foo;
}

public function configure($instance)
{
$instance->configure();
}

public static function getInstance()
{
return new self();
}

public static function configureStatic($instance)
{
$instance->configure();
}

public static function configureStatic1()
{
}
}

class BarUserClass
{
public $bar;

public function __construct(BarClass $bar)
{
$this->bar = $bar;
}
}

class MethodCallClass
{
public $simple;
public $complex;
private $callPassed = false;

public function callMe()
{
$this->callPassed = is_scalar($this->simple) && is_object($this->complex);
}

public function callPassed()
{
return $this->callPassed;
}
}

class DummyProxyDumper implements ProxyDumper
{
public function isProxyCandidate(Definition $definition)
{
return false;
}

public function getProxyFactoryCode(Definition $definition, $id)
{
return '';
}

public function getProxyCode(Definition $definition)
{
return '';
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Extension;

use PHPUnit\Framework\TestCase;

class ExtensionTest extends TestCase
{



public function testIsConfigEnabledReturnsTheResolvedValue($enabled)
{
$pb = $this->getMockBuilder('Symfony\Component\DependencyInjection\ParameterBag\ParameterBag')
->setMethods(array('resolveValue'))
->getMock()
;

$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
->setMethods(array('getParameterBag'))
->getMock()
;

$pb->expects($this->once())
->method('resolveValue')
->with($this->equalTo($enabled))
->will($this->returnValue($enabled))
;

$container->expects($this->once())
->method('getParameterBag')
->will($this->returnValue($pb))
;

$extension = $this->getMockBuilder('Symfony\Component\DependencyInjection\Extension\Extension')
->setMethods(array())
->getMockForAbstractClass()
;

$r = new \ReflectionMethod('Symfony\Component\DependencyInjection\Extension\Extension', 'isConfigEnabled');
$r->setAccessible(true);

$r->invoke($extension, $container, array('enabled' => $enabled));
}

public function getResolvedEnabledFixtures()
{
return array(
array(true),
array(false),
);
}





public function testIsConfigEnabledOnNonEnableableConfig()
{
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
->getMock()
;

$extension = $this->getMockBuilder('Symfony\Component\DependencyInjection\Extension\Extension')
->setMethods(array())
->getMockForAbstractClass()
;

$r = new \ReflectionMethod('Symfony\Component\DependencyInjection\Extension\Extension', 'isConfigEnabled');
$r->setAccessible(true);

$r->invoke($extension, $container, array());
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\ReplaceAliasByActualDefinitionPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

require_once __DIR__.'/../Fixtures/includes/foo.php';

class ReplaceAliasByActualDefinitionPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();

$aDefinition = $container->register('a', '\stdClass');
$aDefinition->setFactoryService('b', false);

$aDefinition->setFactory(array(new Reference('b'), 'createA'));

$bDefinition = new Definition('\stdClass');
$bDefinition->setPublic(false);
$container->setDefinition('b', $bDefinition);

$container->setAlias('a_alias', 'a');
$container->setAlias('b_alias', 'b');

$container->setAlias('container', 'service_container');

$this->process($container);

$this->assertTrue($container->has('a'), '->process() does nothing to public definitions.');
$this->assertTrue($container->hasAlias('a_alias'));
$this->assertFalse($container->has('b'), '->process() removes non-public definitions.');
$this->assertTrue(
$container->has('b_alias') && !$container->hasAlias('b_alias'),
'->process() replaces alias to actual.'
);

$this->assertSame('b_alias', $aDefinition->getFactoryService(false));
$this->assertTrue($container->has('container'));

$resolvedFactory = $aDefinition->getFactory();
$this->assertSame('b_alias', (string) $resolvedFactory[0]);
}




public function testPrivateAliasesInFactory()
{
$container = new ContainerBuilder();

$container->register('a', 'Bar\FooClass');
$container->register('b', 'Bar\FooClass')
->setFactoryService('a')
->setFactoryMethod('getInstance');

$container->register('c', 'stdClass')->setPublic(false);
$container->setAlias('c_alias', 'c');

$this->process($container);

$this->assertInstanceOf('Bar\FooClass', $container->get('b'));
}




public function testProcessWithInvalidAlias()
{
$container = new ContainerBuilder();
$container->setAlias('a_alias', 'a');
$this->process($container);
}

protected function process(ContainerBuilder $container)
{
$pass = new ReplaceAliasByActualDefinitionPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass;




class ExtensionCompilerPassTest extends TestCase
{
private $container;
private $pass;

protected function setUp()
{
$this->container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock();
$this->pass = new ExtensionCompilerPass();
}

public function testProcess()
{
$extension1 = $this->createExtensionMock(true);
$extension1->expects($this->once())->method('process');
$extension2 = $this->createExtensionMock(false);
$extension3 = $this->createExtensionMock(false);
$extension4 = $this->createExtensionMock(true);
$extension4->expects($this->once())->method('process');

$this->container->expects($this->any())
->method('getExtensions')
->will($this->returnValue(array($extension1, $extension2, $extension3, $extension4)))
;

$this->pass->process($this->container);
}

private function createExtensionMock($hasInlineCompile)
{
return $this->getMockBuilder('Symfony\Component\DependencyInjection\\'.(
$hasInlineCompile
? 'Compiler\CompilerPassInterface'
: 'Extension\ExtensionInterface'
))->getMock();
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Compiler\CheckExceptionOnInvalidReferenceBehaviorPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckExceptionOnInvalidReferenceBehaviorPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();

$container
->register('a', '\stdClass')
->addArgument(new Reference('b'))
;
$container->register('b', '\stdClass');
}




public function testProcessThrowsExceptionOnInvalidReference()
{
$container = new ContainerBuilder();

$container
->register('a', '\stdClass')
->addArgument(new Reference('b'))
;

$this->process($container);
}




public function testProcessThrowsExceptionOnInvalidReferenceFromInlinedDefinition()
{
$container = new ContainerBuilder();

$def = new Definition();
$def->addArgument(new Reference('b'));

$container
->register('a', '\stdClass')
->addArgument($def)
;

$this->process($container);
}

private function process(ContainerBuilder $container)
{
$pass = new CheckExceptionOnInvalidReferenceBehaviorPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Compiler\ResolveReferencesToAliasesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveReferencesToAliasesPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$container->setAlias('bar', 'foo');
$def = $container
->register('moo')
->setArguments(array(new Reference('bar')))
;

$this->process($container);

$arguments = $def->getArguments();
$this->assertEquals('foo', (string) $arguments[0]);
}

public function testProcessRecursively()
{
$container = new ContainerBuilder();
$container->setAlias('bar', 'foo');
$container->setAlias('moo', 'bar');
$def = $container
->register('foobar')
->setArguments(array(new Reference('moo')))
;

$this->process($container);

$arguments = $def->getArguments();
$this->assertEquals('foo', (string) $arguments[0]);
}




public function testAliasCircularReference()
{
$container = new ContainerBuilder();
$container->setAlias('bar', 'foo');
$container->setAlias('foo', 'bar');
$this->process($container);
}

public function testResolveFactory()
{
$container = new ContainerBuilder();
$container->register('factory', 'Factory');
$container->setAlias('factory_alias', new Alias('factory'));
$foo = new Definition();
$foo->setFactory(array(new Reference('factory_alias'), 'createFoo'));
$container->setDefinition('foo', $foo);
$bar = new Definition();
$bar->setFactory(array('Factory', 'createFoo'));
$container->setDefinition('bar', $bar);

$this->process($container);

$resolvedFooFactory = $container->getDefinition('foo')->getFactory();
$resolvedBarFactory = $container->getDefinition('bar')->getFactory();

$this->assertSame('factory', (string) $resolvedFooFactory[0]);
$this->assertSame('Factory', (string) $resolvedBarFactory[0]);
}




public function testResolveFactoryService()
{
$container = new ContainerBuilder();
$container->register('factory', 'Factory');
$container->setAlias('factory_alias', new Alias('factory'));
$foo = new Definition();
$foo->setFactoryService('factory_alias');
$foo->setFactoryMethod('createFoo');
$container->setDefinition('foo', $foo);

$this->process($container);

$this->assertSame('factory', $foo->getFactoryService());
}

protected function process(ContainerBuilder $container)
{
$pass = new ResolveReferencesToAliasesPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\Compiler\RemoveUnusedDefinitionsPass;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class RemoveUnusedDefinitionsPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
;
$container
->register('bar')
->setPublic(false)
;
$container
->register('moo')
->setArguments(array(new Reference('bar')))
;

$this->process($container);

$this->assertFalse($container->hasDefinition('foo'));
$this->assertTrue($container->hasDefinition('bar'));
$this->assertTrue($container->hasDefinition('moo'));
}

public function testProcessRemovesUnusedDefinitionsRecursively()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
;
$container
->register('bar')
->setArguments(array(new Reference('foo')))
->setPublic(false)
;

$this->process($container);

$this->assertFalse($container->hasDefinition('foo'));
$this->assertFalse($container->hasDefinition('bar'));
}

public function testProcessWorksWithInlinedDefinitions()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
;
$container
->register('bar')
->setArguments(array(new Definition(null, array(new Reference('foo')))))
;

$this->process($container);

$this->assertTrue($container->hasDefinition('foo'));
$this->assertTrue($container->hasDefinition('bar'));
}

public function testProcessWontRemovePrivateFactory()
{
$container = new ContainerBuilder();

$container
->register('foo', 'stdClass')
->setFactory(array('stdClass', 'getInstance'))
->setPublic(false);

$container
->register('bar', 'stdClass')
->setFactory(array(new Reference('foo'), 'getInstance'))
->setPublic(false);

$container
->register('foobar')
->addArgument(new Reference('bar'));

$this->process($container);

$this->assertTrue($container->hasDefinition('foo'));
$this->assertTrue($container->hasDefinition('bar'));
$this->assertTrue($container->hasDefinition('foobar'));
}

protected function process(ContainerBuilder $container)
{
$repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass()));
$repeatedPass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class InlineServiceDefinitionsPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$container
->register('inlinable.service')
->setPublic(false)
;

$container
->register('service')
->setArguments(array(new Reference('inlinable.service')))
;

$this->process($container);

$arguments = $container->getDefinition('service')->getArguments();
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $arguments[0]);
$this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
}

public function testProcessDoesNotInlinesWhenAliasedServiceIsShared()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
;
$container->setAlias('moo', 'foo');

$container
->register('service')
->setArguments(array($ref = new Reference('foo')))
;

$this->process($container);

$arguments = $container->getDefinition('service')->getArguments();
$this->assertSame($ref, $arguments[0]);
}




public function testProcessDoesNotInlineWhenAliasedServiceIsNotOfPrototypeScope()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
;
$container->setAlias('moo', 'foo');

$container
->register('service')
->setArguments(array($ref = new Reference('foo')))
;

$this->process($container);

$arguments = $container->getDefinition('service')->getArguments();
$this->assertSame($ref, $arguments[0]);
}

public function testProcessDoesInlineNonSharedService()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setShared(false)
;
$container
->register('bar')
->setPublic(false)
->setShared(false)
;
$container->setAlias('moo', 'bar');

$container
->register('service')
->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
;

$this->process($container);

$arguments = $container->getDefinition('service')->getArguments();
$this->assertEquals($container->getDefinition('foo'), $arguments[0]);
$this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
$this->assertSame($ref, $arguments[1]);
$this->assertEquals($container->getDefinition('bar'), $arguments[2]);
$this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
}




public function testProcessDoesInlineServiceOfPrototypeScope()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setScope('prototype')
;
$container
->register('bar')
->setPublic(false)
->setScope('prototype')
;
$container->setAlias('moo', 'bar');

$container
->register('service')
->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
;

$this->process($container);

$arguments = $container->getDefinition('service')->getArguments();
$this->assertEquals($container->getDefinition('foo'), $arguments[0]);
$this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
$this->assertSame($ref, $arguments[1]);
$this->assertEquals($container->getDefinition('bar'), $arguments[2]);
$this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
}

public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition()
{
$container = new ContainerBuilder();

$a = $container->register('a')->setPublic(false);
$b = $container
->register('b')
->addArgument(new Reference('a'))
->addArgument(new Definition(null, array(new Reference('a'))))
;

$this->process($container);

$arguments = $b->getArguments();
$this->assertSame($a, $arguments[0]);

$inlinedArguments = $arguments[1]->getArguments();
$this->assertSame($a, $inlinedArguments[0]);
}

public function testProcessInlinesPrivateFactoryReference()
{
$container = new ContainerBuilder();

$container->register('a')->setPublic(false);
$b = $container
->register('b')
->setPublic(false)
->setFactory(array(new Reference('a'), 'a'))
;

$container
->register('foo')
->setArguments(array(
$ref = new Reference('b'),
));

$this->process($container);

$inlinedArguments = $container->getDefinition('foo')->getArguments();
$this->assertSame($b, $inlinedArguments[0]);
}

public function testProcessDoesNotInlinePrivateFactoryIfReferencedMultipleTimesWithinTheSameDefinition()
{
$container = new ContainerBuilder();
$container
->register('a')
;
$container
->register('b')
->setPublic(false)
->setFactory(array(new Reference('a'), 'a'))
;

$container
->register('foo')
->setArguments(array(
$ref1 = new Reference('b'),
$ref2 = new Reference('b'),
))
;
$this->process($container);

$args = $container->getDefinition('foo')->getArguments();
$this->assertSame($ref1, $args[0]);
$this->assertSame($ref2, $args[1]);
}

public function testProcessDoesNotInlineReferenceWhenUsedByInlineFactory()
{
$container = new ContainerBuilder();
$container
->register('a')
;
$container
->register('b')
->setPublic(false)
->setFactory(array(new Reference('a'), 'a'))
;

$inlineFactory = new Definition();
$inlineFactory->setPublic(false);
$inlineFactory->setFactory(array(new Reference('b'), 'b'));

$container
->register('foo')
->setArguments(array(
$ref = new Reference('b'),
$inlineFactory,
))
;
$this->process($container);

$args = $container->getDefinition('foo')->getArguments();
$this->assertSame($ref, $args[0]);
}




public function testProcessInlinesOnlyIfSameScope()
{
$container = new ContainerBuilder();

$container->addScope(new Scope('foo'));
$a = $container->register('a')->setPublic(false)->setScope('foo');
$b = $container->register('b')->addArgument(new Reference('a'));

$this->process($container);
$arguments = $b->getArguments();
$this->assertEquals(new Reference('a'), $arguments[0]);
$this->assertTrue($container->hasDefinition('a'));
}

public function testProcessDoesNotInlineWhenServiceIsPrivateButLazy()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
->setLazy(true)
;

$container
->register('service')
->setArguments(array($ref = new Reference('foo')))
;

$this->process($container);

$arguments = $container->getDefinition('service')->getArguments();
$this->assertSame($ref, $arguments[0]);
}

public function testProcessDoesNotInlineWhenServiceReferencesItself()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(false)
->addMethodCall('foo', array($ref = new Reference('foo')))
;

$this->process($container);

$calls = $container->getDefinition('foo')->getMethodCalls();
$this->assertSame($ref, $calls[0][1][0]);
}

protected function process(ContainerBuilder $container)
{
$repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()));
$repeatedPass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AnalyzeServiceReferencesPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();

$a = $container
->register('a')
->addArgument($ref1 = new Reference('b'))
;

$b = $container
->register('b')
->addMethodCall('setA', array($ref2 = new Reference('a')))
;

$c = $container
->register('c')
->addArgument($ref3 = new Reference('a'))
->addArgument($ref4 = new Reference('b'))
;

$d = $container
->register('d')
->setProperty('foo', $ref5 = new Reference('b'))
;

$e = $container
->register('e')
->setConfigurator(array($ref6 = new Reference('b'), 'methodName'))
;

$graph = $this->process($container);

$this->assertCount(4, $edges = $graph->getNode('b')->getInEdges());

$this->assertSame($ref1, $edges[0]->getValue());
$this->assertSame($ref4, $edges[1]->getValue());
$this->assertSame($ref5, $edges[2]->getValue());
$this->assertSame($ref6, $edges[3]->getValue());
}

public function testProcessDetectsReferencesFromInlinedDefinitions()
{
$container = new ContainerBuilder();

$container
->register('a')
;

$container
->register('b')
->addArgument(new Definition(null, array($ref = new Reference('a'))))
;

$graph = $this->process($container);

$this->assertCount(1, $refs = $graph->getNode('a')->getInEdges());
$this->assertSame($ref, $refs[0]->getValue());
}

public function testProcessDetectsReferencesFromInlinedFactoryDefinitions()
{
$container = new ContainerBuilder();

$container
->register('a')
;

$factory = new Definition();
$factory->setFactory(array(new Reference('a'), 'a'));

$container
->register('b')
->addArgument($factory)
;

$graph = $this->process($container);

$this->assertTrue($graph->hasNode('a'));
$this->assertCount(1, $refs = $graph->getNode('a')->getInEdges());
}

public function testProcessDoesNotSaveDuplicateReferences()
{
$container = new ContainerBuilder();

$container
->register('a')
;
$container
->register('b')
->addArgument(new Definition(null, array($ref1 = new Reference('a'))))
->addArgument(new Definition(null, array($ref2 = new Reference('a'))))
;

$graph = $this->process($container);

$this->assertCount(2, $graph->getNode('a')->getInEdges());
}

public function testProcessDetectsFactoryReferences()
{
$container = new ContainerBuilder();

$container
->register('foo', 'stdClass')
->setFactory(array('stdClass', 'getInstance'));

$container
->register('bar', 'stdClass')
->setFactory(array(new Reference('foo'), 'getInstance'));

$graph = $this->process($container);

$this->assertTrue($graph->hasNode('foo'));
$this->assertCount(1, $graph->getNode('foo')->getInEdges());
}

protected function process(ContainerBuilder $container)
{
$pass = new RepeatedPass(array(new AnalyzeServiceReferencesPass()));
$pass->process($container);

return $container->getCompiler()->getServiceReferenceGraph();
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass;

class DecoratorServicePassTest extends TestCase
{
public function testProcessWithoutAlias()
{
$container = new ContainerBuilder();
$fooDefinition = $container
->register('foo')
->setPublic(false)
;
$fooExtendedDefinition = $container
->register('foo.extended')
->setPublic(true)
->setDecoratedService('foo')
;
$barDefinition = $container
->register('bar')
->setPublic(true)
;
$barExtendedDefinition = $container
->register('bar.extended')
->setPublic(true)
->setDecoratedService('bar', 'bar.yoo')
;

$this->process($container);

$this->assertEquals('foo.extended', $container->getAlias('foo'));
$this->assertFalse($container->getAlias('foo')->isPublic());

$this->assertEquals('bar.extended', $container->getAlias('bar'));
$this->assertTrue($container->getAlias('bar')->isPublic());

$this->assertSame($fooDefinition, $container->getDefinition('foo.extended.inner'));
$this->assertFalse($container->getDefinition('foo.extended.inner')->isPublic());

$this->assertSame($barDefinition, $container->getDefinition('bar.yoo'));
$this->assertFalse($container->getDefinition('bar.yoo')->isPublic());

$this->assertNull($fooExtendedDefinition->getDecoratedService());
$this->assertNull($barExtendedDefinition->getDecoratedService());
}

public function testProcessWithAlias()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setPublic(true)
;
$container->setAlias('foo.alias', new Alias('foo', false));
$fooExtendedDefinition = $container
->register('foo.extended')
->setPublic(true)
->setDecoratedService('foo.alias')
;

$this->process($container);

$this->assertEquals('foo.extended', $container->getAlias('foo.alias'));
$this->assertFalse($container->getAlias('foo.alias')->isPublic());

$this->assertEquals('foo', $container->getAlias('foo.extended.inner'));
$this->assertFalse($container->getAlias('foo.extended.inner')->isPublic());

$this->assertNull($fooExtendedDefinition->getDecoratedService());
}

public function testProcessWithPriority()
{
$container = new ContainerBuilder();
$fooDefinition = $container
->register('foo')
->setPublic(false)
;
$barDefinition = $container
->register('bar')
->setPublic(true)
->setDecoratedService('foo')
;
$bazDefinition = $container
->register('baz')
->setPublic(true)
->setDecoratedService('foo', null, 5)
;
$quxDefinition = $container
->register('qux')
->setPublic(true)
->setDecoratedService('foo', null, 3)
;

$this->process($container);

$this->assertEquals('bar', $container->getAlias('foo'));
$this->assertFalse($container->getAlias('foo')->isPublic());

$this->assertSame($fooDefinition, $container->getDefinition('baz.inner'));
$this->assertFalse($container->getDefinition('baz.inner')->isPublic());

$this->assertEquals('qux', $container->getAlias('bar.inner'));
$this->assertFalse($container->getAlias('bar.inner')->isPublic());

$this->assertEquals('baz', $container->getAlias('qux.inner'));
$this->assertFalse($container->getAlias('qux.inner')->isPublic());

$this->assertNull($barDefinition->getDecoratedService());
$this->assertNull($bazDefinition->getDecoratedService());
$this->assertNull($quxDefinition->getDecoratedService());
}

public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinition()
{
$container = new ContainerBuilder();
$container
->register('foo')
->setTags(array('bar' => array('attr' => 'baz')))
;
$container
->register('baz')
->setTags(array('foobar' => array('attr' => 'bar')))
->setDecoratedService('foo')
;

$this->process($container);

$this->assertEmpty($container->getDefinition('baz.inner')->getTags());
$this->assertEquals(array('bar' => array('attr' => 'baz'), 'foobar' => array('attr' => 'bar')), $container->getDefinition('baz')->getTags());
}

public function testProcessMergesAutowiringTypesInDecoratingDefinitionAndRemoveThemFromDecoratedDefinition()
{
$container = new ContainerBuilder();

$container
->register('parent')
->addAutowiringType('Bar')
;

$container
->register('child')
->setDecoratedService('parent')
->addAutowiringType('Foo')
;

$this->process($container);

$this->assertEquals(array('Bar', 'Foo'), $container->getDefinition('child')->getAutowiringTypes());
$this->assertEmpty($container->getDefinition('child.inner')->getAutowiringTypes());
}

protected function process(ContainerBuilder $container)
{
$repeatedPass = new DecoratorServicePass();
$repeatedPass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

class MergeExtensionConfigurationPassTest extends TestCase
{
public function testExpressionLanguageProviderForwarding()
{
$tmpProviders = array();

$extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock();
$extension->expects($this->any())
->method('getXsdValidationBasePath')
->will($this->returnValue(false));
$extension->expects($this->any())
->method('getNamespace')
->will($this->returnValue('http://example.org/schema/dic/foo'));
$extension->expects($this->any())
->method('getAlias')
->will($this->returnValue('foo'));
$extension->expects($this->once())
->method('load')
->will($this->returnCallback(function (array $config, ContainerBuilder $container) use (&$tmpProviders) {
$tmpProviders = $container->getExpressionLanguageProviders();
}));

$provider = $this->getMockBuilder('Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface')->getMock();
$container = new ContainerBuilder(new ParameterBag());
$container->registerExtension($extension);
$container->prependExtensionConfig('foo', array('bar' => true));
$container->addExpressionLanguageProvider($provider);

$pass = new MergeExtensionConfigurationPass();
$pass->process($container);

$this->assertEquals(array($provider), $tmpProviders);
}

public function testExtensionConfigurationIsTrackedByDefault()
{
$extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\Extension')->getMock();
$extension->expects($this->once())
->method('getConfiguration')
->will($this->returnValue(new FooConfiguration()));
$extension->expects($this->any())
->method('getAlias')
->will($this->returnValue('foo'));

$container = new ContainerBuilder(new ParameterBag());
$container->registerExtension($extension);
$container->prependExtensionConfig('foo', array('bar' => true));

$pass = new MergeExtensionConfigurationPass();
$pass->process($container);

$this->assertContains(new FileResource(__FILE__), $container->getResources(), '', false, false);
}
}

class FooConfiguration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
return new TreeBuilder();
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveParameterPlaceHoldersPassTest extends TestCase
{
private $compilerPass;
private $container;
private $fooDefinition;

protected function setUp()
{
$this->compilerPass = new ResolveParameterPlaceHoldersPass();
$this->container = $this->createContainerBuilder();
$this->compilerPass->process($this->container);
$this->fooDefinition = $this->container->getDefinition('foo');
}

public function testClassParametersShouldBeResolved()
{
$this->assertSame('Foo', $this->fooDefinition->getClass());
}

public function testFactoryParametersShouldBeResolved()
{
$this->assertSame(array('FooFactory', 'getFoo'), $this->fooDefinition->getFactory());
}

public function testArgumentParametersShouldBeResolved()
{
$this->assertSame(array('bar', 'baz'), $this->fooDefinition->getArguments());
}

public function testMethodCallParametersShouldBeResolved()
{
$this->assertSame(array(array('foobar', array('bar', 'baz'))), $this->fooDefinition->getMethodCalls());
}

public function testPropertyParametersShouldBeResolved()
{
$this->assertSame(array('bar' => 'baz'), $this->fooDefinition->getProperties());
}

public function testFileParametersShouldBeResolved()
{
$this->assertSame('foo.php', $this->fooDefinition->getFile());
}

public function testAliasParametersShouldBeResolved()
{
$this->assertSame('foo', $this->container->getAlias('bar')->__toString());
}

private function createContainerBuilder()
{
$containerBuilder = new ContainerBuilder();

$containerBuilder->setParameter('foo.class', 'Foo');
$containerBuilder->setParameter('foo.factory.class', 'FooFactory');
$containerBuilder->setParameter('foo.arg1', 'bar');
$containerBuilder->setParameter('foo.arg2', 'baz');
$containerBuilder->setParameter('foo.method', 'foobar');
$containerBuilder->setParameter('foo.property.name', 'bar');
$containerBuilder->setParameter('foo.property.value', 'baz');
$containerBuilder->setParameter('foo.file', 'foo.php');
$containerBuilder->setParameter('alias.id', 'bar');

$fooDefinition = $containerBuilder->register('foo', '%foo.class%');
$fooDefinition->setFactory(array('%foo.factory.class%', 'getFoo'));
$fooDefinition->setArguments(array('%foo.arg1%', '%foo.arg2%'));
$fooDefinition->addMethodCall('%foo.method%', array('%foo.arg1%', '%foo.arg2%'));
$fooDefinition->setProperty('%foo.property.name%', '%foo.property.value%');
$fooDefinition->setFile('%foo.file%');

$containerBuilder->setAlias('%alias.id%', 'foo');

return $containerBuilder;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;




class LegacyResolveParameterPlaceHoldersPassTest extends TestCase
{
public function testFactoryClassParametersShouldBeResolved()
{
$compilerPass = new ResolveParameterPlaceHoldersPass();

$container = new ContainerBuilder();
$container->setParameter('foo.factory.class', 'FooFactory');
$fooDefinition = $container->register('foo', '%foo.factory.class%');
$fooDefinition->setFactoryClass('%foo.factory.class%');
$compilerPass->process($container);
$fooDefinition = $container->getDefinition('foo');

$this->assertSame('FooFactory', $fooDefinition->getFactoryClass());
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
use Symfony\Component\DependencyInjection\Compiler\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckCircularReferencesPassTest extends TestCase
{



public function testProcess()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->register('b')->addArgument(new Reference('a'));

$this->process($container);
}




public function testProcessWithAliases()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->setAlias('b', 'c');
$container->setAlias('c', 'a');

$this->process($container);
}




public function testProcessWithFactory()
{
$container = new ContainerBuilder();

$container
->register('a', 'stdClass')
->setFactory(array(new Reference('b'), 'getInstance'));

$container
->register('b', 'stdClass')
->setFactory(array(new Reference('a'), 'getInstance'));

$this->process($container);
}




public function testProcessDetectsIndirectCircularReference()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->register('b')->addArgument(new Reference('c'));
$container->register('c')->addArgument(new Reference('a'));

$this->process($container);
}




public function testProcessDetectsIndirectCircularReferenceWithFactory()
{
$container = new ContainerBuilder();

$container->register('a')->addArgument(new Reference('b'));

$container
->register('b', 'stdClass')
->setFactory(array(new Reference('c'), 'getInstance'));

$container->register('c')->addArgument(new Reference('a'));

$this->process($container);
}




public function testDeepCircularReference()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->register('b')->addArgument(new Reference('c'));
$container->register('c')->addArgument(new Reference('b'));

$this->process($container);
}

public function testProcessIgnoresMethodCalls()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->register('b')->addMethodCall('setA', array(new Reference('a')));

$this->process($container);
}

protected function process(ContainerBuilder $container)
{
$compiler = new Compiler();
$passConfig = $compiler->getPassConfig();
$passConfig->setOptimizationPasses(array(
new AnalyzeServiceReferencesPass(true),
new CheckCircularReferencesPass(),
));
$passConfig->setRemovingPasses(array());

$compiler->compile($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\DependencyInjection\Compiler\CheckReferenceValidityPass;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckReferenceValidityPassTest extends TestCase
{



public function testProcessIgnoresScopeWideningIfNonStrictReference()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false));
$container->register('b')->setScope('prototype');

$this->process($container);
}





public function testProcessDetectsScopeWidening()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->register('b')->setScope('prototype');

$this->process($container);
}




public function testProcessIgnoresCrossScopeHierarchyReferenceIfNotStrict()
{
$container = new ContainerBuilder();
$container->addScope(new Scope('a'));
$container->addScope(new Scope('b'));

$container->register('a')->setScope('a')->addArgument(new Reference('b', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false));
$container->register('b')->setScope('b');

$this->process($container);
}





public function testProcessDetectsCrossScopeHierarchyReference()
{
$container = new ContainerBuilder();
$container->addScope(new Scope('a'));
$container->addScope(new Scope('b'));

$container->register('a')->setScope('a')->addArgument(new Reference('b'));
$container->register('b')->setScope('b');

$this->process($container);
}




public function testProcessDetectsReferenceToAbstractDefinition()
{
$container = new ContainerBuilder();

$container->register('a')->setAbstract(true);
$container->register('b')->addArgument(new Reference('a'));

$this->process($container);
}

public function testProcess()
{
$container = new ContainerBuilder();
$container->register('a')->addArgument(new Reference('b'));
$container->register('b');

$this->process($container);
}

protected function process(ContainerBuilder $container)
{
$pass = new CheckReferenceValidityPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\AutoAliasServicePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AutoAliasServicePassTest extends TestCase
{



public function testProcessWithMissingParameter()
{
$container = new ContainerBuilder();

$container->register('example')
->addTag('auto_alias', array('format' => '%non_existing%.example'));

$pass = new AutoAliasServicePass();
$pass->process($container);
}




public function testProcessWithMissingFormat()
{
$container = new ContainerBuilder();

$container->register('example')
->addTag('auto_alias', array());
$container->setParameter('existing', 'mysql');

$pass = new AutoAliasServicePass();
$pass->process($container);
}

public function testProcessWithNonExistingAlias()
{
$container = new ContainerBuilder();

$container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault')
->addTag('auto_alias', array('format' => '%existing%.example'));
$container->setParameter('existing', 'mysql');

$pass = new AutoAliasServicePass();
$pass->process($container);

$this->assertEquals('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault', $container->getDefinition('example')->getClass());
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault', $container->get('example'));
}

public function testProcessWithExistingAlias()
{
$container = new ContainerBuilder();

$container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault')
->addTag('auto_alias', array('format' => '%existing%.example'));

$container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql');
$container->setParameter('existing', 'mysql');

$pass = new AutoAliasServicePass();
$pass->process($container);

$this->assertTrue($container->hasAlias('example'));
$this->assertEquals('mysql.example', $container->getAlias('example'));
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql', $container->get('example'));
}

public function testProcessWithManualAlias()
{
$container = new ContainerBuilder();

$container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault')
->addTag('auto_alias', array('format' => '%existing%.example'));

$container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql');
$container->register('mariadb.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariadb');
$container->setAlias('example', 'mariadb.example');
$container->setParameter('existing', 'mysql');

$pass = new AutoAliasServicePass();
$pass->process($container);

$this->assertTrue($container->hasAlias('example'));
$this->assertEquals('mariadb.example', $container->getAlias('example'));
$this->assertInstanceOf('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariaDb', $container->get('example'));
}
}

class ServiceClassDefault
{
}

class ServiceClassMysql extends ServiceClassDefault
{
}

class ServiceClassMariaDb extends ServiceClassMysql
{
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;




class IntegrationTest extends TestCase
{









public function testProcessRemovesAndInlinesRecursively()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);

$a = $container
->register('a', '\stdClass')
->addArgument(new Reference('c'))
;

$b = $container
->register('b', '\stdClass')
->addArgument(new Reference('c'))
->setPublic(false)
;

$c = $container
->register('c', '\stdClass')
->setPublic(false)
;

$container->compile();

$this->assertTrue($container->hasDefinition('a'));
$arguments = $a->getArguments();
$this->assertSame($c, $arguments[0]);
$this->assertFalse($container->hasDefinition('b'));
$this->assertFalse($container->hasDefinition('c'));
}

public function testProcessInlinesReferencesToAliases()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);

$a = $container
->register('a', '\stdClass')
->addArgument(new Reference('b'))
;

$container->setAlias('b', new Alias('c', false));

$c = $container
->register('c', '\stdClass')
->setPublic(false)
;

$container->compile();

$this->assertTrue($container->hasDefinition('a'));
$arguments = $a->getArguments();
$this->assertSame($c, $arguments[0]);
$this->assertFalse($container->hasAlias('b'));
$this->assertFalse($container->hasDefinition('c'));
}

public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDefinition()
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);

$container
->register('a', '\stdClass')
->addArgument(new Reference('b'))
->addMethodCall('setC', array(new Reference('c')))
;

$container
->register('b', '\stdClass')
->addArgument(new Reference('c'))
->setPublic(false)
;

$container
->register('c', '\stdClass')
->setPublic(false)
;

$container->compile();

$this->assertTrue($container->hasDefinition('a'));
$this->assertFalse($container->hasDefinition('b'));
$this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\CheckDefinitionValidityPass;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CheckDefinitionValidityPassTest extends TestCase
{



public function testProcessDetectsSyntheticNonPublicDefinitions()
{
$container = new ContainerBuilder();
$container->register('a')->setSynthetic(true)->setPublic(false);

$this->process($container);
}





public function testProcessDetectsSyntheticPrototypeDefinitions()
{
$container = new ContainerBuilder();
$container->register('a')->setSynthetic(true)->setScope(ContainerInterface::SCOPE_PROTOTYPE);

$this->process($container);
}





public function testProcessDetectsSharedPrototypeDefinitions()
{
$container = new ContainerBuilder();
$container->register('a')->setShared(true)->setScope(ContainerInterface::SCOPE_PROTOTYPE);

$this->process($container);
}




public function testProcessDetectsNonSyntheticNonAbstractDefinitionWithoutClass()
{
$container = new ContainerBuilder();
$container->register('a')->setSynthetic(false)->setAbstract(false);

$this->process($container);
}





public function testLegacyProcessDetectsBothFactorySyntaxesUsed()
{
$container = new ContainerBuilder();
$container->register('a')->setFactory(array('a', 'b'))->setFactoryClass('a');

$this->process($container);
}

public function testProcess()
{
$container = new ContainerBuilder();
$container->register('a', 'class');
$container->register('b', 'class')->setSynthetic(true)->setPublic(true);
$container->register('c', 'class')->setAbstract(true);
$container->register('d', 'class')->setSynthetic(true);

$this->process($container);
}

public function testValidTags()
{
$container = new ContainerBuilder();
$container->register('a', 'class')->addTag('foo', array('bar' => 'baz'));
$container->register('b', 'class')->addTag('foo', array('bar' => null));
$container->register('c', 'class')->addTag('foo', array('bar' => 1));
$container->register('d', 'class')->addTag('foo', array('bar' => 1.1));

$this->process($container);
}




public function testInvalidTags()
{
$container = new ContainerBuilder();
$container->register('a', 'class')->addTag('foo', array('bar' => array('baz' => 'baz')));

$this->process($container);
}

protected function process(ContainerBuilder $container)
{
$pass = new CheckDefinitionValidityPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Compiler\ResolveInvalidReferencesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveInvalidReferencesPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$def = $container
->register('foo')
->setArguments(array(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE)))
->addMethodCall('foo', array(new Reference('moo', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
;

$this->process($container);

$arguments = $def->getArguments();
$this->assertNull($arguments[0]);
$this->assertCount(0, $def->getMethodCalls());
}

public function testProcessIgnoreNonExistentServices()
{
$container = new ContainerBuilder();
$def = $container
->register('foo')
->setArguments(array(new Reference('bar')))
;

$this->process($container);

$arguments = $def->getArguments();
$this->assertEquals('bar', (string) $arguments[0]);
}

public function testProcessRemovesPropertiesOnInvalid()
{
$container = new ContainerBuilder();
$def = $container
->register('foo')
->setProperty('foo', new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE))
;

$this->process($container);

$this->assertEquals(array(), $def->getProperties());
}




public function testStrictFlagIsPreserved()
{
$container = new ContainerBuilder();
$container->register('bar');
$def = $container
->register('foo')
->addArgument(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE, false))
;

$this->process($container);

$this->assertFalse($def->getArgument(0)->isStrict());
}

protected function process(ContainerBuilder $container)
{
$pass = new ResolveInvalidReferencesPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use Symfony\Bug\NotExistClass;

class OptionalServiceClass extends NotExistClass
{
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ResolveDefinitionTemplatesPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$container->register('parent', 'foo')->setArguments(array('moo', 'b'))->setProperty('foo', 'moo');
$container->setDefinition('child', new DefinitionDecorator('parent'))
->replaceArgument(0, 'a')
->setProperty('foo', 'bar')
->setClass('bar')
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertNotInstanceOf('Symfony\Component\DependencyInjection\DefinitionDecorator', $def);
$this->assertEquals('bar', $def->getClass());
$this->assertEquals(array('a', 'b'), $def->getArguments());
$this->assertEquals(array('foo' => 'bar'), $def->getProperties());
}

public function testProcessAppendsMethodCallsAlways()
{
$container = new ContainerBuilder();

$container
->register('parent')
->addMethodCall('foo', array('bar'))
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
->addMethodCall('bar', array('foo'))
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertEquals(array(
array('foo', array('bar')),
array('bar', array('foo')),
), $def->getMethodCalls());
}

public function testProcessDoesNotCopyAbstract()
{
$container = new ContainerBuilder();

$container
->register('parent')
->setAbstract(true)
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertFalse($def->isAbstract());
}




public function testProcessDoesNotCopyScope()
{
$container = new ContainerBuilder();

$container
->register('parent')
->setScope('foo')
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertEquals(ContainerInterface::SCOPE_CONTAINER, $def->getScope());
}

public function testProcessDoesNotCopyShared()
{
$container = new ContainerBuilder();

$container
->register('parent')
->setShared(false)
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertTrue($def->isShared());
}

public function testProcessDoesNotCopyTags()
{
$container = new ContainerBuilder();

$container
->register('parent')
->addTag('foo')
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertEquals(array(), $def->getTags());
}

public function testProcessDoesNotCopyDecoratedService()
{
$container = new ContainerBuilder();

$container
->register('parent')
->setDecoratedService('foo')
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertNull($def->getDecoratedService());
}

public function testProcessDoesNotDropShared()
{
$container = new ContainerBuilder();

$container
->register('parent')
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
->setShared(false)
;

$this->process($container);

$def = $container->getDefinition('child');
$this->assertFalse($def->isShared());
}

public function testProcessHandlesMultipleInheritance()
{
$container = new ContainerBuilder();

$container
->register('parent', 'foo')
->setArguments(array('foo', 'bar', 'c'))
;

$container
->setDefinition('child2', new DefinitionDecorator('child1'))
->replaceArgument(1, 'b')
;

$container
->setDefinition('child1', new DefinitionDecorator('parent'))
->replaceArgument(0, 'a')
;

$this->process($container);

$def = $container->getDefinition('child2');
$this->assertEquals(array('a', 'b', 'c'), $def->getArguments());
$this->assertEquals('foo', $def->getClass());
}

public function testSetLazyOnServiceHasParent()
{
$container = new ContainerBuilder();

$container->register('parent', 'stdClass');

$container->setDefinition('child1', new DefinitionDecorator('parent'))
->setLazy(true)
;

$this->process($container);

$this->assertTrue($container->getDefinition('child1')->isLazy());
}

public function testSetLazyOnServiceIsParent()
{
$container = new ContainerBuilder();

$container->register('parent', 'stdClass')
->setLazy(true)
;

$container->setDefinition('child1', new DefinitionDecorator('parent'));

$this->process($container);

$this->assertTrue($container->getDefinition('child1')->isLazy());
}

public function testSetAutowiredOnServiceHasParent()
{
$container = new ContainerBuilder();

$container->register('parent', 'stdClass');

$container->setDefinition('child1', new DefinitionDecorator('parent'))
->setAutowired(true)
;

$this->process($container);

$this->assertTrue($container->getDefinition('child1')->isAutowired());
}

public function testSetAutowiredOnServiceIsParent()
{
$container = new ContainerBuilder();

$container->register('parent', 'stdClass')
->setAutowired(true)
;

$container->setDefinition('child1', new DefinitionDecorator('parent'));

$this->process($container);

$this->assertTrue($container->getDefinition('child1')->isAutowired());
}

public function testDeepDefinitionsResolving()
{
$container = new ContainerBuilder();

$container->register('parent', 'parentClass');
$container->register('sibling', 'siblingClass')
->setConfigurator(new DefinitionDecorator('parent'), 'foo')
->setFactory(array(new DefinitionDecorator('parent'), 'foo'))
->addArgument(new DefinitionDecorator('parent'))
->setProperty('prop', new DefinitionDecorator('parent'))
->addMethodCall('meth', array(new DefinitionDecorator('parent')))
;

$this->process($container);

$configurator = $container->getDefinition('sibling')->getConfigurator();
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($configurator));
$this->assertSame('parentClass', $configurator->getClass());

$factory = $container->getDefinition('sibling')->getFactory();
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($factory[0]));
$this->assertSame('parentClass', $factory[0]->getClass());

$argument = $container->getDefinition('sibling')->getArgument(0);
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($argument));
$this->assertSame('parentClass', $argument->getClass());

$properties = $container->getDefinition('sibling')->getProperties();
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($properties['prop']));
$this->assertSame('parentClass', $properties['prop']->getClass());

$methodCalls = $container->getDefinition('sibling')->getMethodCalls();
$this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($methodCalls[0][1][0]));
$this->assertSame('parentClass', $methodCalls[0][1][0]->getClass());
}

public function testSetDecoratedServiceOnServiceHasParent()
{
$container = new ContainerBuilder();

$container->register('parent', 'stdClass');

$container->setDefinition('child1', new DefinitionDecorator('parent'))
->setDecoratedService('foo', 'foo_inner', 5)
;

$this->process($container);

$this->assertEquals(array('foo', 'foo_inner', 5), $container->getDefinition('child1')->getDecoratedService());
}

public function testDecoratedServiceCopiesDeprecatedStatusFromParent()
{
$container = new ContainerBuilder();
$container->register('deprecated_parent')
->setDeprecated(true)
;

$container->setDefinition('decorated_deprecated_parent', new DefinitionDecorator('deprecated_parent'));

$this->process($container);

$this->assertTrue($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
}

public function testDecoratedServiceCanOverwriteDeprecatedParentStatus()
{
$container = new ContainerBuilder();
$container->register('deprecated_parent')
->setDeprecated(true)
;

$container->setDefinition('decorated_deprecated_parent', new DefinitionDecorator('deprecated_parent'))
->setDeprecated(false)
;

$this->process($container);

$this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated());
}

public function testProcessMergeAutowiringTypes()
{
$container = new ContainerBuilder();

$container
->register('parent')
->addAutowiringType('Foo')
;

$container
->setDefinition('child', new DefinitionDecorator('parent'))
->addAutowiringType('Bar')
;

$this->process($container);

$childDef = $container->getDefinition('child');
$this->assertEquals(array('Foo', 'Bar'), $childDef->getAutowiringTypes());

$parentDef = $container->getDefinition('parent');
$this->assertSame(array('Foo'), $parentDef->getAutowiringTypes());
}

protected function process(ContainerBuilder $container)
{
$pass = new ResolveDefinitionTemplatesPass();
$pass->process($container);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;




class AutowirePassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();

$container->register('foo', __NAMESPACE__.'\Foo');
$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
$barDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(1, $container->getDefinition('bar')->getArguments());
$this->assertEquals('foo', (string) $container->getDefinition('bar')->getArgument(0));
}

public function testProcessAutowireParent()
{
$container = new ContainerBuilder();

$container->register('b', __NAMESPACE__.'\B');
$cDefinition = $container->register('c', __NAMESPACE__.'\C');
$cDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(1, $container->getDefinition('c')->getArguments());
$this->assertEquals('b', (string) $container->getDefinition('c')->getArgument(0));
}

public function testProcessAutowireInterface()
{
$container = new ContainerBuilder();

$container->register('f', __NAMESPACE__.'\F');
$gDefinition = $container->register('g', __NAMESPACE__.'\G');
$gDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(3, $container->getDefinition('g')->getArguments());
$this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(0));
$this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(1));
$this->assertEquals('f', (string) $container->getDefinition('g')->getArgument(2));
}

public function testCompleteExistingDefinition()
{
$container = new ContainerBuilder();

$container->register('b', __NAMESPACE__.'\B');
$container->register('f', __NAMESPACE__.'\F');
$hDefinition = $container->register('h', __NAMESPACE__.'\H')->addArgument(new Reference('b'));
$hDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(2, $container->getDefinition('h')->getArguments());
$this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0));
$this->assertEquals('f', (string) $container->getDefinition('h')->getArgument(1));
}

public function testCompleteExistingDefinitionWithNotDefinedArguments()
{
$container = new ContainerBuilder();

$container->register('b', __NAMESPACE__.'\B');
$container->register('f', __NAMESPACE__.'\F');
$hDefinition = $container->register('h', __NAMESPACE__.'\H')->addArgument('')->addArgument('');
$hDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(2, $container->getDefinition('h')->getArguments());
$this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0));
$this->assertEquals('f', (string) $container->getDefinition('h')->getArgument(1));
}





public function testTypeCollision()
{
$container = new ContainerBuilder();

$container->register('c1', __NAMESPACE__.'\CollisionA');
$container->register('c2', __NAMESPACE__.'\CollisionB');
$container->register('c3', __NAMESPACE__.'\CollisionB');
$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}





public function testTypeNotGuessable()
{
$container = new ContainerBuilder();

$container->register('a1', __NAMESPACE__.'\Foo');
$container->register('a2', __NAMESPACE__.'\Foo');
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}





public function testTypeNotGuessableWithSubclass()
{
$container = new ContainerBuilder();

$container->register('a1', __NAMESPACE__.'\B');
$container->register('a2', __NAMESPACE__.'\B');
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgumentForSubclass');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}





public function testTypeNotGuessableNoServicesFound()
{
$container = new ContainerBuilder();

$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}

public function testTypeNotGuessableWithTypeSet()
{
$container = new ContainerBuilder();

$container->register('a1', __NAMESPACE__.'\Foo');
$container->register('a2', __NAMESPACE__.'\Foo');
$container->register('a3', __NAMESPACE__.'\Foo')->addAutowiringType(__NAMESPACE__.'\Foo');
$aDefinition = $container->register('a', __NAMESPACE__.'\NotGuessableArgument');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(1, $container->getDefinition('a')->getArguments());
$this->assertEquals('a3', (string) $container->getDefinition('a')->getArgument(0));
}

public function testWithTypeSet()
{
$container = new ContainerBuilder();

$container->register('c1', __NAMESPACE__.'\CollisionA');
$container->register('c2', __NAMESPACE__.'\CollisionB')->addAutowiringType(__NAMESPACE__.'\CollisionInterface');
$aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(1, $container->getDefinition('a')->getArguments());
$this->assertEquals('c2', (string) $container->getDefinition('a')->getArgument(0));
}

public function testCreateDefinition()
{
$container = new ContainerBuilder();

$coopTilleulsDefinition = $container->register('coop_tilleuls', __NAMESPACE__.'\LesTilleuls');
$coopTilleulsDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));

$dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas');
$this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
$this->assertFalse($dunglasDefinition->isPublic());
$this->assertCount(1, $dunglasDefinition->getArguments());
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\lille', $dunglasDefinition->getArgument(0));

$lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille');
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
}

public function testResolveParameter()
{
$container = new ContainerBuilder();

$container->setParameter('class_name', __NAMESPACE__.'\Foo');
$container->register('foo', '%class_name%');
$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
$barDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertEquals('foo', $container->getDefinition('bar')->getArgument(0));
}

public function testOptionalParameter()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$container->register('foo', __NAMESPACE__.'\Foo');
$optDefinition = $container->register('opt', __NAMESPACE__.'\OptionalParameter');
$optDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$definition = $container->getDefinition('opt');
$this->assertNull($definition->getArgument(0));
$this->assertEquals('a', $definition->getArgument(1));
$this->assertEquals('foo', $definition->getArgument(2));
}

public function testDontTriggerAutowiring()
{
$container = new ContainerBuilder();

$container->register('foo', __NAMESPACE__.'\Foo');
$container->register('bar', __NAMESPACE__.'\Bar');

$pass = new AutowirePass();
$pass->process($container);

$this->assertCount(0, $container->getDefinition('bar')->getArguments());
}





public function testClassNotFoundThrowsException()
{
$container = new ContainerBuilder();

$aDefinition = $container->register('a', __NAMESPACE__.'\BadTypeHintedArgument');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}





public function testParentClassNotFoundThrowsException()
{
$container = new ContainerBuilder();

$aDefinition = $container->register('a', __NAMESPACE__.'\BadParentTypeHintedArgument');
$aDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}

public function testDontUseAbstractServices()
{
$container = new ContainerBuilder();

$container->register('abstract_foo', __NAMESPACE__.'\Foo')->setAbstract(true);
$container->register('foo', __NAMESPACE__.'\Foo');
$container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$arguments = $container->getDefinition('bar')->getArguments();
$this->assertSame('foo', (string) $arguments[0]);
}

public function testSomeSpecificArgumentsAreSet()
{
$container = new ContainerBuilder();

$container->register('foo', __NAMESPACE__.'\Foo');
$container->register('a', __NAMESPACE__.'\A');
$container->register('dunglas', __NAMESPACE__.'\Dunglas');
$container->register('multiple', __NAMESPACE__.'\MultipleArguments')
->setAutowired(true)

 
 ->setArguments(array(
1 => new Reference('foo'),
));

$pass = new AutowirePass();
$pass->process($container);

$definition = $container->getDefinition('multiple');
$this->assertEquals(
array(
new Reference('a'),
new Reference('foo'),
new Reference('dunglas'),
),
$definition->getArguments()
);
}





public function testScalarArgsCannotBeAutowired()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$container->register('dunglas', __NAMESPACE__.'\Dunglas');
$container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments')
->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$container->getDefinition('arg_no_type_hint');
}





public function testOptionalScalarNotReallyOptionalThrowException()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional')
->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}

public function testOptionalScalarArgsDontMessUpOrder()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('with_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalar')
->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$definition = $container->getDefinition('with_optional_scalar');
$this->assertEquals(
array(
new Reference('a'),

 'default_val',
new Reference('lille'),
),
$definition->getArguments()
);
}

public function testOptionalScalarArgsNotPassedIfLast()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('with_optional_scalar_last', __NAMESPACE__.'\MultipleArgumentsOptionalScalarLast')
->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$definition = $container->getDefinition('with_optional_scalar_last');
$this->assertEquals(
array(
new Reference('a'),
new Reference('lille'),

 
 
 'some_val',
),
$definition->getArguments()
);
}

public function testIgnoreServiceWithClassNotExisting()
{
$container = new ContainerBuilder();

$container->register('class_not_exist', __NAMESPACE__.'\OptionalServiceClass');

$barDefinition = $container->register('bar', __NAMESPACE__.'\Bar');
$barDefinition->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);

$this->assertTrue($container->hasDefinition('bar'));
}

public function testEmptyStringIsKept()
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('foo', __NAMESPACE__.'\MultipleArgumentsOptionalScalar')
->setAutowired(true)
->setArguments(array('', ''));

$pass = new AutowirePass();
$pass->process($container);

$this->assertEquals(array(new Reference('a'), '', new Reference('lille')), $container->getDefinition('foo')->getArguments());
}







public function testAutodiscoveredAutowiringOrder($class)
{
$container = new ContainerBuilder();

$container->register('a', __NAMESPACE__.'\\'.$class)
->setAutowired(true);

$pass = new AutowirePass();
$pass->process($container);
}

public function provideAutodiscoveredAutowiringOrder()
{
return array(
array('CannotBeAutowiredForwardOrder'),
array('CannotBeAutowiredReverseOrder'),
);
}
}

class Foo
{
}

class Bar
{
public function __construct(Foo $foo)
{
}
}

class A
{
}

class B extends A
{
}

class C
{
public function __construct(A $a)
{
}
}

interface DInterface
{
}

interface EInterface extends DInterface
{
}

interface IInterface
{
}

class I implements IInterface
{
}

class F extends I implements EInterface
{
}

class G
{
public function __construct(DInterface $d, EInterface $e, IInterface $i)
{
}
}

class H
{
public function __construct(B $b, DInterface $d)
{
}
}

interface CollisionInterface
{
}

class CollisionA implements CollisionInterface
{
}

class CollisionB implements CollisionInterface
{
}

class CannotBeAutowired
{
public function __construct(CollisionInterface $collision)
{
}
}

class CannotBeAutowiredForwardOrder
{
public function __construct(CollisionA $a, CollisionInterface $b, CollisionB $c)
{
}
}

class CannotBeAutowiredReverseOrder
{
public function __construct(CollisionA $a, CollisionB $c, CollisionInterface $b)
{
}
}

class Lille
{
}

class Dunglas
{
public function __construct(Lille $l)
{
}
}

class LesTilleuls
{
public function __construct(Dunglas $k)
{
}
}

class OptionalParameter
{
public function __construct(CollisionInterface $c = null, A $a, Foo $f = null)
{
}
}

class BadTypeHintedArgument
{
public function __construct(Dunglas $k, NotARealClass $r)
{
}
}
class BadParentTypeHintedArgument
{
public function __construct(Dunglas $k, OptionalServiceClass $r)
{
}
}
class NotGuessableArgument
{
public function __construct(Foo $k)
{
}
}
class NotGuessableArgumentForSubclass
{
public function __construct(A $k)
{
}
}
class MultipleArguments
{
public function __construct(A $k, $foo, Dunglas $dunglas)
{
}
}

class MultipleArgumentsOptionalScalar
{
public function __construct(A $a, $foo = 'default_val', Lille $lille = null)
{
}
}
class MultipleArgumentsOptionalScalarLast
{
public function __construct(A $a, Lille $lille, $foo = 'some_val')
{
}
}
class MultipleArgumentsOptionalScalarNotReallyOptional
{
public function __construct(A $a, $foo = 'default_val', Lille $lille)
{
}
}
<?php










namespace Symfony\Component\DependencyInjection\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Definition;




class LegacyDefinitionTest extends TestCase
{
public function testSetGetFactoryClass()
{
$def = new Definition('stdClass');
$this->assertNull($def->getFactoryClass());
$this->assertSame($def, $def->setFactoryClass('stdClass2'), '->setFactoryClass() implements a fluent interface.');
$this->assertEquals('stdClass2', $def->getFactoryClass(), '->getFactoryClass() returns current class to construct this service.');
}

public function testSetGetFactoryMethod()
{
$def = new Definition('stdClass');
$this->assertNull($def->getFactoryMethod());
$this->assertSame($def, $def->setFactoryMethod('foo'), '->setFactoryMethod() implements a fluent interface');
$this->assertEquals('foo', $def->getFactoryMethod(), '->getFactoryMethod() returns the factory method name');
}

public function testSetGetFactoryService()
{
$def = new Definition('stdClass');
$this->assertNull($def->getFactoryService());
$this->assertSame($def, $def->setFactoryService('foo.bar'), '->setFactoryService() implements a fluent interface.');
$this->assertEquals('foo.bar', $def->getFactoryService(), '->getFactoryService() returns current service to construct this service.');
}
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;






class Definition
{
private $class;
private $file;
private $factory;
private $factoryClass;
private $factoryMethod;
private $factoryService;
private $shared = true;
private $deprecated = false;
private $deprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.';
private $scope = ContainerInterface::SCOPE_CONTAINER;
private $properties = array();
private $calls = array();
private $configurator;
private $tags = array();
private $public = true;
private $synthetic = false;
private $abstract = false;
private $synchronized = false;
private $lazy = false;
private $decoratedService;
private $autowired = false;
private $autowiringTypes = array();

protected $arguments;





public function __construct($class = null, array $arguments = array())
{
$this->class = $class;
$this->arguments = $arguments;
}








public function setFactory($factory)
{
if (is_string($factory) && strpos($factory, '::') !== false) {
$factory = explode('::', $factory, 2);
}

$this->factory = $factory;

return $this;
}






public function getFactory()
{
return $this->factory;
}











public function setFactoryClass($factoryClass)
{
@trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryClass), E_USER_DEPRECATED);

$this->factoryClass = $factoryClass;

return $this;
}








public function getFactoryClass($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->factoryClass;
}










public function setFactoryMethod($factoryMethod)
{
@trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryMethod), E_USER_DEPRECATED);

$this->factoryMethod = $factoryMethod;

return $this;
}












public function setDecoratedService($id, $renamedId = null, $priority = 0)
{
if ($renamedId && $id == $renamedId) {
throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
}

if (null === $id) {
$this->decoratedService = null;
} else {
$this->decoratedService = array($id, $renamedId, (int) $priority);
}

return $this;
}






public function getDecoratedService()
{
return $this->decoratedService;
}








public function getFactoryMethod($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->factoryMethod;
}










public function setFactoryService($factoryService, $triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryService), E_USER_DEPRECATED);
}

$this->factoryService = $factoryService;

return $this;
}








public function getFactoryService($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->factoryService;
}








public function setClass($class)
{
$this->class = $class;

return $this;
}






public function getClass()
{
return $this->class;
}








public function setArguments(array $arguments)
{
$this->arguments = $arguments;

return $this;
}

public function setProperties(array $properties)
{
$this->properties = $properties;

return $this;
}

public function getProperties()
{
return $this->properties;
}

public function setProperty($name, $value)
{
$this->properties[$name] = $value;

return $this;
}








public function addArgument($argument)
{
$this->arguments[] = $argument;

return $this;
}











public function replaceArgument($index, $argument)
{
if (0 === count($this->arguments)) {
throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.');
}

if ($index < 0 || $index > count($this->arguments) - 1) {
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
}

$this->arguments[$index] = $argument;

return $this;
}






public function getArguments()
{
return $this->arguments;
}










public function getArgument($index)
{
if ($index < 0 || $index > count($this->arguments) - 1) {
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
}

return $this->arguments[$index];
}








public function setMethodCalls(array $calls = array())
{
$this->calls = array();
foreach ($calls as $call) {
$this->addMethodCall($call[0], $call[1]);
}

return $this;
}











public function addMethodCall($method, array $arguments = array())
{
if (empty($method)) {
throw new InvalidArgumentException(sprintf('Method name cannot be empty.'));
}
$this->calls[] = array($method, $arguments);

return $this;
}








public function removeMethodCall($method)
{
foreach ($this->calls as $i => $call) {
if ($call[0] === $method) {
unset($this->calls[$i]);
break;
}
}

return $this;
}








public function hasMethodCall($method)
{
foreach ($this->calls as $call) {
if ($call[0] === $method) {
return true;
}
}

return false;
}






public function getMethodCalls()
{
return $this->calls;
}








public function setTags(array $tags)
{
$this->tags = $tags;

return $this;
}






public function getTags()
{
return $this->tags;
}








public function getTag($name)
{
return isset($this->tags[$name]) ? $this->tags[$name] : array();
}









public function addTag($name, array $attributes = array())
{
$this->tags[$name][] = $attributes;

return $this;
}








public function hasTag($name)
{
return isset($this->tags[$name]);
}








public function clearTag($name)
{
unset($this->tags[$name]);

return $this;
}






public function clearTags()
{
$this->tags = array();

return $this;
}








public function setFile($file)
{
$this->file = $file;

return $this;
}






public function getFile()
{
return $this->file;
}








public function setShared($shared)
{
$this->shared = (bool) $shared;

return $this;
}






public function isShared()
{
return $this->shared;
}










public function setScope($scope, $triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

if (ContainerInterface::SCOPE_PROTOTYPE === $scope) {
$this->setShared(false);
}

$this->scope = $scope;

return $this;
}








public function getScope($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->scope;
}








public function setPublic($boolean)
{
$this->public = (bool) $boolean;

return $this;
}






public function isPublic()
{
return $this->public;
}










public function setSynchronized($boolean, $triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
}

$this->synchronized = (bool) $boolean;

return $this;
}








public function isSynchronized($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
}

return $this->synchronized;
}








public function setLazy($lazy)
{
$this->lazy = (bool) $lazy;

return $this;
}






public function isLazy()
{
return $this->lazy;
}









public function setSynthetic($boolean)
{
$this->synthetic = (bool) $boolean;

return $this;
}







public function isSynthetic()
{
return $this->synthetic;
}









public function setAbstract($boolean)
{
$this->abstract = (bool) $boolean;

return $this;
}







public function isAbstract()
{
return $this->abstract;
}












public function setDeprecated($status = true, $template = null)
{
if (null !== $template) {
if (preg_match('#[\r\n]|\*/#', $template)) {
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
}

if (false === strpos($template, '%service_id%')) {
throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
}

$this->deprecationTemplate = $template;
}

$this->deprecated = (bool) $status;

return $this;
}







public function isDeprecated()
{
return $this->deprecated;
}








public function getDeprecationMessage($id)
{
return str_replace('%service_id%', $id, $this->deprecationTemplate);
}








public function setConfigurator($callable)
{
$this->configurator = $callable;

return $this;
}






public function getConfigurator()
{
return $this->configurator;
}








public function setAutowiringTypes(array $types)
{
$this->autowiringTypes = array();

foreach ($types as $type) {
$this->autowiringTypes[$type] = true;
}

return $this;
}






public function isAutowired()
{
return $this->autowired;
}








public function setAutowired($autowired)
{
$this->autowired = $autowired;

return $this;
}






public function getAutowiringTypes()
{
return array_keys($this->autowiringTypes);
}








public function addAutowiringType($type)
{
$this->autowiringTypes[$type] = true;

return $this;
}








public function removeAutowiringType($type)
{
unset($this->autowiringTypes[$type]);

return $this;
}








public function hasAutowiringType($type)
{
return isset($this->autowiringTypes[$type]);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\DependencyInjection\ContainerBuilder;

interface PrependExtensionInterface
{





public function prepend(ContainerBuilder $container);
}
<?php










namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\DependencyInjection\ContainerBuilder;






interface ExtensionInterface
{








public function load(array $configs, ContainerBuilder $container);






public function getNamespace();






public function getXsdValidationBasePath();








public function getAlias();
}
<?php










namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\ConfigurationInterface;






abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface
{



public function getXsdValidationBasePath()
{
return false;
}




public function getNamespace()
{
return 'http://example.org/schema/dic/'.$this->getAlias();
}





















public function getAlias()
{
$className = get_class($this);
if (substr($className, -9) != 'Extension') {
throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.');
}
$classBaseName = substr(strrchr($className, '\\'), 1, -9);

return Container::underscore($classBaseName);
}




public function getConfiguration(array $config, ContainerBuilder $container)
{
$reflected = new \ReflectionClass($this);
$namespace = $reflected->getNamespaceName();

$class = $namespace.'\\Configuration';
if (class_exists($class)) {
$r = new \ReflectionClass($class);
$container->addResource(new FileResource($r->getFileName()));

if (!method_exists($class, '__construct')) {
return new $class();
}
}
}

final protected function processConfiguration(ConfigurationInterface $configuration, array $configs)
{
$processor = new Processor();

return $processor->processConfiguration($configuration, $configs);
}









protected function isConfigEnabled(ContainerBuilder $container, array $config)
{
if (!array_key_exists('enabled', $config)) {
throw new InvalidArgumentException("The config array has no 'enabled' key.");
}

return (bool) $container->getParameterBag()->resolveValue($config['enabled']);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Extension;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;






interface ConfigurationExtensionInterface
{








public function getConfiguration(array $config, ContainerBuilder $container);
}
<?php










namespace Symfony\Component\DependencyInjection;






trait ContainerAwareTrait
{



protected $container;






public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
<?php










namespace Symfony\Component\DependencyInjection;






class Parameter
{
private $id;




public function __construct($id)
{
$this->id = $id;
}




public function __toString()
{
return (string) $this->id;
}
}
<?php










namespace Symfony\Component\DependencyInjection;

use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;









class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return array(
new ExpressionFunction('service', function ($arg) {
return sprintf('$this->get(%s)', $arg);
}, function (array $variables, $value) {
return $variables['container']->get($value);
}),

new ExpressionFunction('parameter', function ($arg) {
return sprintf('$this->getParameter(%s)', $arg);
}, function (array $variables, $value) {
return $variables['container']->getParameter($value);
}),
);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;






interface CompilerPassInterface
{





public function process(ContainerBuilder $container);
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Alias;








class DecoratorServicePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definitions = new \SplPriorityQueue();
$order = PHP_INT_MAX;

foreach ($container->getDefinitions() as $id => $definition) {
if (!$decorated = $definition->getDecoratedService()) {
continue;
}
$definitions->insert(array($id, $definition), array($decorated[2], --$order));
}

foreach ($definitions as $arr) {
list($id, $definition) = $arr;
list($inner, $renamedId) = $definition->getDecoratedService();

$definition->setDecoratedService(null);

if (!$renamedId) {
$renamedId = $id.'.inner';
}


 
 if ($container->hasAlias($inner)) {
$alias = $container->getAlias($inner);
$public = $alias->isPublic();
$container->setAlias($renamedId, new Alias((string) $alias, false));
} else {
$decoratedDefinition = $container->getDefinition($inner);
$definition->setTags(array_merge($decoratedDefinition->getTags(), $definition->getTags()));
$definition->setAutowiringTypes(array_merge($decoratedDefinition->getAutowiringTypes(), $definition->getAutowiringTypes()));
$public = $decoratedDefinition->isPublic();
$decoratedDefinition->setPublic(false);
$decoratedDefinition->setTags(array());
$decoratedDefinition->setAutowiringTypes(array());
$container->setDefinition($renamedId, $decoratedDefinition);
}

$container->setAlias($inner, new Alias($id, $public));
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;







class ResolveInvalidReferencesPass implements CompilerPassInterface
{
private $container;






public function process(ContainerBuilder $container)
{
$this->container = $container;
foreach ($container->getDefinitions() as $definition) {
if ($definition->isSynthetic() || $definition->isAbstract()) {
continue;
}

$definition->setArguments(
$this->processArguments($definition->getArguments())
);

$calls = array();
foreach ($definition->getMethodCalls() as $call) {
try {
$calls[] = array($call[0], $this->processArguments($call[1], true));
} catch (RuntimeException $e) {

 }
}
$definition->setMethodCalls($calls);

$properties = array();
foreach ($definition->getProperties() as $name => $value) {
try {
$value = $this->processArguments(array($value), true);
$properties[$name] = reset($value);
} catch (RuntimeException $e) {

 }
}
$definition->setProperties($properties);
}
}











private function processArguments(array $arguments, $inMethodCall = false)
{
foreach ($arguments as $k => $argument) {
if (is_array($argument)) {
$arguments[$k] = $this->processArguments($argument, $inMethodCall);
} elseif ($argument instanceof Reference) {
$id = (string) $argument;

$invalidBehavior = $argument->getInvalidBehavior();
$exists = $this->container->has($id);


 if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
$arguments[$k] = null;
} elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
if ($inMethodCall) {
throw new RuntimeException('Method shouldn\'t be called.');
}

$arguments[$k] = null;
}
}
}

return $arguments;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;






class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
{







public function process(ContainerBuilder $container)
{
$parameterBag = $container->getParameterBag();

foreach ($container->getDefinitions() as $id => $definition) {
try {
$definition->setClass($parameterBag->resolveValue($definition->getClass()));
$definition->setFile($parameterBag->resolveValue($definition->getFile()));
$definition->setArguments($parameterBag->resolveValue($definition->getArguments()));
if ($definition->getFactoryClass(false)) {
$definition->setFactoryClass($parameterBag->resolveValue($definition->getFactoryClass(false)));
}

$factory = $definition->getFactory();

if (is_array($factory) && isset($factory[0])) {
$factory[0] = $parameterBag->resolveValue($factory[0]);
$definition->setFactory($factory);
}

$calls = array();
foreach ($definition->getMethodCalls() as $name => $arguments) {
$calls[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($arguments);
}
$definition->setMethodCalls($calls);

$definition->setProperties($parameterBag->resolveValue($definition->getProperties()));
} catch (ParameterNotFoundException $e) {
$e->setSourceId($id);

throw $e;
}
}

$aliases = array();
foreach ($container->getAliases() as $name => $target) {
$aliases[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($target);
}
$container->setAliases($aliases);

$parameterBag->resolve();
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Alias;








class ServiceReferenceGraphNode
{
private $id;
private $inEdges = array();
private $outEdges = array();
private $value;





public function __construct($id, $value)
{
$this->id = $id;
$this->value = $value;
}






public function addInEdge(ServiceReferenceGraphEdge $edge)
{
$this->inEdges[] = $edge;
}






public function addOutEdge(ServiceReferenceGraphEdge $edge)
{
$this->outEdges[] = $edge;
}






public function isAlias()
{
return $this->value instanceof Alias;
}






public function isDefinition()
{
return $this->value instanceof Definition;
}






public function getId()
{
return $this->id;
}






public function getInEdges()
{
return $this->inEdges;
}






public function getOutEdges()
{
return $this->outEdges;
}






public function getValue()
{
return $this->value;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;






class InlineServiceDefinitionsPass implements RepeatablePassInterface
{
private $repeatedPass;
private $graph;
private $compiler;
private $formatter;
private $currentId;




public function setRepeatedPass(RepeatedPass $repeatedPass)
{
$this->repeatedPass = $repeatedPass;
}






public function process(ContainerBuilder $container)
{
$this->compiler = $container->getCompiler();
$this->formatter = $this->compiler->getLoggingFormatter();
$this->graph = $this->compiler->getServiceReferenceGraph();

$container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true));
}










private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
{
foreach ($arguments as $k => $argument) {
if ($isRoot) {
$this->currentId = $k;
}
if (is_array($argument)) {
$arguments[$k] = $this->inlineArguments($container, $argument);
} elseif ($argument instanceof Reference) {
if (!$container->hasDefinition($id = (string) $argument)) {
continue;
}

if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));

if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false)) {
$arguments[$k] = $definition;
} else {
$arguments[$k] = clone $definition;
}
}
} elseif ($argument instanceof Definition) {
$argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
$argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
$argument->setProperties($this->inlineArguments($container, $argument->getProperties()));

$configurator = $this->inlineArguments($container, array($argument->getConfigurator()));
$argument->setConfigurator($configurator[0]);

$factory = $this->inlineArguments($container, array($argument->getFactory()));
$argument->setFactory($factory[0]);
}
}

return $arguments;
}










private function isInlineableDefinition(ContainerBuilder $container, $id, Definition $definition)
{
if (!$definition->isShared() || ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
return true;
}

if ($definition->isPublic() || $definition->isLazy()) {
return false;
}

if (!$this->graph->hasNode($id)) {
return true;
}

if ($this->currentId == $id) {
return false;
}

$ids = array();
foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
$ids[] = $edge->getSourceNode()->getId();
}

if (count(array_unique($ids)) > 1) {
return false;
}

if (count($ids) > 1 && is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) {
return false;
}

if (count($ids) > 1 && $definition->getFactoryService(false)) {
return false;
}

return $container->getDefinition(reset($ids))->getScope(false) === $definition->getScope(false);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;








class PassConfig
{
const TYPE_AFTER_REMOVING = 'afterRemoving';
const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization';
const TYPE_BEFORE_REMOVING = 'beforeRemoving';
const TYPE_OPTIMIZE = 'optimization';
const TYPE_REMOVE = 'removing';

private $mergePass;
private $afterRemovingPasses = array();
private $beforeOptimizationPasses = array();
private $beforeRemovingPasses = array();
private $optimizationPasses;
private $removingPasses;

public function __construct()
{
$this->mergePass = new MergeExtensionConfigurationPass();

$this->optimizationPasses = array(
new ExtensionCompilerPass(),
new ResolveDefinitionTemplatesPass(),
new DecoratorServicePass(),
new ResolveParameterPlaceHoldersPass(),
new CheckDefinitionValidityPass(),
new ResolveReferencesToAliasesPass(),
new ResolveInvalidReferencesPass(),
new AutowirePass(),
new AnalyzeServiceReferencesPass(true),
new CheckCircularReferencesPass(),
new CheckReferenceValidityPass(),
);

$this->removingPasses = array(
new RemovePrivateAliasesPass(),
new ReplaceAliasByActualDefinitionPass(),
new RemoveAbstractDefinitionsPass(),
new RepeatedPass(array(
new AnalyzeServiceReferencesPass(),
new InlineServiceDefinitionsPass(),
new AnalyzeServiceReferencesPass(),
new RemoveUnusedDefinitionsPass(),
)),
new CheckExceptionOnInvalidReferenceBehaviorPass(),
);
}






public function getPasses()
{
return array_merge(
array($this->mergePass),
$this->beforeOptimizationPasses,
$this->optimizationPasses,
$this->beforeRemovingPasses,
$this->removingPasses,
$this->afterRemovingPasses
);
}









public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION)
{
$property = $type.'Passes';
if (!isset($this->$property)) {
throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
}

$this->{$property}[] = $pass;
}






public function getAfterRemovingPasses()
{
return $this->afterRemovingPasses;
}






public function getBeforeOptimizationPasses()
{
return $this->beforeOptimizationPasses;
}






public function getBeforeRemovingPasses()
{
return $this->beforeRemovingPasses;
}






public function getOptimizationPasses()
{
return $this->optimizationPasses;
}






public function getRemovingPasses()
{
return $this->removingPasses;
}






public function getMergePass()
{
return $this->mergePass;
}






public function setMergePass(CompilerPassInterface $pass)
{
$this->mergePass = $pass;
}






public function setAfterRemovingPasses(array $passes)
{
$this->afterRemovingPasses = $passes;
}






public function setBeforeOptimizationPasses(array $passes)
{
$this->beforeOptimizationPasses = $passes;
}






public function setBeforeRemovingPasses(array $passes)
{
$this->beforeRemovingPasses = $passes;
}






public function setOptimizationPasses(array $passes)
{
$this->optimizationPasses = $passes;
}






public function setRemovingPasses(array $passes)
{
$this->removingPasses = $passes;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;







class ExtensionCompilerPass implements CompilerPassInterface
{



public function process(ContainerBuilder $container)
{
foreach ($container->getExtensions() as $extension) {
if (!$extension instanceof CompilerPassInterface) {
continue;
}

$extension->process($container);
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;






class RemoveUnusedDefinitionsPass implements RepeatablePassInterface
{
private $repeatedPass;




public function setRepeatedPass(RepeatedPass $repeatedPass)
{
$this->repeatedPass = $repeatedPass;
}






public function process(ContainerBuilder $container)
{
$compiler = $container->getCompiler();
$formatter = $compiler->getLoggingFormatter();
$graph = $compiler->getServiceReferenceGraph();

$hasChanged = false;
foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isPublic()) {
continue;
}

if ($graph->hasNode($id)) {
$edges = $graph->getNode($id)->getInEdges();
$referencingAliases = array();
$sourceIds = array();
foreach ($edges as $edge) {
$node = $edge->getSourceNode();
$sourceIds[] = $node->getId();

if ($node->isAlias()) {
$referencingAliases[] = $node->getValue();
}
}
$isReferenced = (count(array_unique($sourceIds)) - count($referencingAliases)) > 0;
} else {
$referencingAliases = array();
$isReferenced = false;
}

if (1 === count($referencingAliases) && false === $isReferenced) {
$container->setDefinition((string) reset($referencingAliases), $definition);
$definition->setPublic(true);
$container->removeDefinition($id);
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias '.reset($referencingAliases)));
} elseif (0 === count($referencingAliases) && false === $isReferenced) {
$container->removeDefinition($id);
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused'));
$hasChanged = true;
}
}

if ($hasChanged) {
$this->repeatedPass->setRepeat();
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;






class MergeExtensionConfigurationPass implements CompilerPassInterface
{



public function process(ContainerBuilder $container)
{
$parameters = $container->getParameterBag()->all();
$definitions = $container->getDefinitions();
$aliases = $container->getAliases();
$exprLangProviders = $container->getExpressionLanguageProviders();

foreach ($container->getExtensions() as $extension) {
if ($extension instanceof PrependExtensionInterface) {
$extension->prepend($container);
}
}

foreach ($container->getExtensions() as $name => $extension) {
if (!$config = $container->getExtensionConfig($name)) {

 continue;
}
$config = $container->getParameterBag()->resolveValue($config);

$tmpContainer = new ContainerBuilder($container->getParameterBag());
$tmpContainer->setResourceTracking($container->isTrackingResources());
$tmpContainer->addObjectResource($extension);
if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
$tmpContainer->addObjectResource($configuration);
}

foreach ($exprLangProviders as $provider) {
$tmpContainer->addExpressionLanguageProvider($provider);
}

$extension->load($config, $tmpContainer);

$container->merge($tmpContainer);
$container->getParameterBag()->add($parameters);
}

$container->addDefinitions($definitions);
$container->addAliases($aliases);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;




class RemoveAbstractDefinitionsPass implements CompilerPassInterface
{





public function process(ContainerBuilder $container)
{
$compiler = $container->getCompiler();
$formatter = $compiler->getLoggingFormatter();

foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isAbstract()) {
$container->removeDefinition($id);
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'abstract'));
}
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException;
use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException;











class CheckReferenceValidityPass implements CompilerPassInterface
{
private $container;
private $currentId;
private $currentScope;
private $currentScopeAncestors;
private $currentScopeChildren;






public function process(ContainerBuilder $container)
{
$this->container = $container;

$children = $this->container->getScopeChildren(false);
$ancestors = array();

$scopes = $this->container->getScopes(false);
foreach ($scopes as $name => $parent) {
$ancestors[$name] = array($parent);

while (isset($scopes[$parent])) {
$ancestors[$name][] = $parent = $scopes[$parent];
}
}

foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isSynthetic() || $definition->isAbstract()) {
continue;
}

$this->currentId = $id;
$this->currentScope = $scope = $definition->getScope(false);

if (ContainerInterface::SCOPE_CONTAINER === $scope) {
$this->currentScopeChildren = array_keys($scopes);
$this->currentScopeAncestors = array();
} elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
$this->currentScopeChildren = isset($children[$scope]) ? $children[$scope] : array();
$this->currentScopeAncestors = isset($ancestors[$scope]) ? $ancestors[$scope] : array();
}

$this->validateReferences($definition->getArguments());
$this->validateReferences($definition->getMethodCalls());
$this->validateReferences($definition->getProperties());
}
}








private function validateReferences(array $arguments)
{
foreach ($arguments as $argument) {
if (is_array($argument)) {
$this->validateReferences($argument);
} elseif ($argument instanceof Reference) {
$targetDefinition = $this->getDefinition((string) $argument);

if (null !== $targetDefinition && $targetDefinition->isAbstract()) {
throw new RuntimeException(sprintf(
'The definition "%s" has a reference to an abstract definition "%s". '
.'Abstract definitions cannot be the target of references.',
$this->currentId,
$argument
));
}

$this->validateScope($argument, $targetDefinition);
}
}
}










private function validateScope(Reference $reference, Definition $definition = null)
{
if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) {
return;
}

if (!$reference->isStrict(false)) {
return;
}

if (null === $definition) {
return;
}

if ($this->currentScope === $scope = $definition->getScope(false)) {
return;
}

$id = (string) $reference;

if (in_array($scope, $this->currentScopeChildren, true)) {
throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope);
}

if (!in_array($scope, $this->currentScopeAncestors, true)) {
throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope);
}
}








private function getDefinition($id)
{
if (!$this->container->hasDefinition($id)) {
return;
}

return $this->container->getDefinition($id);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;








class RemovePrivateAliasesPass implements CompilerPassInterface
{





public function process(ContainerBuilder $container)
{
$compiler = $container->getCompiler();
$formatter = $compiler->getLoggingFormatter();

foreach ($container->getAliases() as $id => $alias) {
if ($alias->isPublic()) {
continue;
}

$container->removeAlias($id);
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'private alias'));
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;






class ResolveReferencesToAliasesPass implements CompilerPassInterface
{
private $container;






public function process(ContainerBuilder $container)
{
$this->container = $container;

foreach ($container->getDefinitions() as $definition) {
if ($definition->isSynthetic() || $definition->isAbstract()) {
continue;
}

$definition->setArguments($this->processArguments($definition->getArguments()));
$definition->setMethodCalls($this->processArguments($definition->getMethodCalls()));
$definition->setProperties($this->processArguments($definition->getProperties()));
$definition->setFactory($this->processFactory($definition->getFactory()));
$definition->setFactoryService($this->processFactoryService($definition->getFactoryService(false)), false);
}

foreach ($container->getAliases() as $id => $alias) {
$aliasId = (string) $alias;
if ($aliasId !== $defId = $this->getDefinitionId($aliasId)) {
$container->setAlias($id, new Alias($defId, $alias->isPublic()));
}
}
}








private function processArguments(array $arguments)
{
foreach ($arguments as $k => $argument) {
if (is_array($argument)) {
$arguments[$k] = $this->processArguments($argument);
} elseif ($argument instanceof Reference) {
$defId = $this->getDefinitionId($id = (string) $argument);

if ($defId !== $id) {
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict(false));
}
}
}

return $arguments;
}

private function processFactoryService($factoryService)
{
if (null === $factoryService) {
return;
}

return $this->getDefinitionId($factoryService);
}

private function processFactory($factory)
{
if (null === $factory || !is_array($factory) || !$factory[0] instanceof Reference) {
return $factory;
}

$defId = $this->getDefinitionId($id = (string) $factory[0]);

if ($defId !== $id) {
$factory[0] = new Reference($defId, $factory[0]->getInvalidBehavior(), $factory[0]->isStrict(false));
}

return $factory;
}








private function getDefinitionId($id)
{
$seen = array();
while ($this->container->hasAlias($id)) {
if (isset($seen[$id])) {
throw new ServiceCircularReferenceException($id, array_keys($seen));
}
$seen[$id] = true;
$id = (string) $this->container->getAlias($id);
}

return $id;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;








class ResolveDefinitionTemplatesPass implements CompilerPassInterface
{
private $compiler;
private $formatter;
private $currentId;






public function process(ContainerBuilder $container)
{
$this->compiler = $container->getCompiler();
$this->formatter = $this->compiler->getLoggingFormatter();

$container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
}










private function resolveArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
{
foreach ($arguments as $k => $argument) {
if ($isRoot) {

 
 $arguments[$k] = $argument = $container->getDefinition($k);
$this->currentId = $k;
}
if (is_array($argument)) {
$arguments[$k] = $this->resolveArguments($container, $argument);
} elseif ($argument instanceof Definition) {
if ($argument instanceof DefinitionDecorator) {
$arguments[$k] = $argument = $this->resolveDefinition($container, $argument);
if ($isRoot) {
$container->setDefinition($k, $argument);
}
}
$argument->setArguments($this->resolveArguments($container, $argument->getArguments()));
$argument->setMethodCalls($this->resolveArguments($container, $argument->getMethodCalls()));
$argument->setProperties($this->resolveArguments($container, $argument->getProperties()));

$configurator = $this->resolveArguments($container, array($argument->getConfigurator()));
$argument->setConfigurator($configurator[0]);

$factory = $this->resolveArguments($container, array($argument->getFactory()));
$argument->setFactory($factory[0]);
}
}

return $arguments;
}











private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
{
if (!$container->hasDefinition($parent = $definition->getParent())) {
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId));
}

$parentDef = $container->getDefinition($parent);
if ($parentDef instanceof DefinitionDecorator) {
$id = $this->currentId;
$this->currentId = $parent;
$parentDef = $this->resolveDefinition($container, $parentDef);
$container->setDefinition($parent, $parentDef);
$this->currentId = $id;
}

$this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $this->currentId, $parent));
$def = new Definition();


 
 $def->setClass($parentDef->getClass());
$def->setArguments($parentDef->getArguments());
$def->setMethodCalls($parentDef->getMethodCalls());
$def->setProperties($parentDef->getProperties());
$def->setAutowiringTypes($parentDef->getAutowiringTypes());
if ($parentDef->getFactoryClass(false)) {
$def->setFactoryClass($parentDef->getFactoryClass(false));
}
if ($parentDef->getFactoryMethod(false)) {
$def->setFactoryMethod($parentDef->getFactoryMethod(false));
}
if ($parentDef->getFactoryService(false)) {
$def->setFactoryService($parentDef->getFactoryService(false));
}
if ($parentDef->isDeprecated()) {
$def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%'));
}
$def->setFactory($parentDef->getFactory());
$def->setConfigurator($parentDef->getConfigurator());
$def->setFile($parentDef->getFile());
$def->setPublic($parentDef->isPublic());
$def->setLazy($parentDef->isLazy());
$def->setAutowired($parentDef->isAutowired());


 $changes = $definition->getChanges();
if (isset($changes['class'])) {
$def->setClass($definition->getClass());
}
if (isset($changes['factory_class'])) {
$def->setFactoryClass($definition->getFactoryClass(false));
}
if (isset($changes['factory_method'])) {
$def->setFactoryMethod($definition->getFactoryMethod(false));
}
if (isset($changes['factory_service'])) {
$def->setFactoryService($definition->getFactoryService(false));
}
if (isset($changes['factory'])) {
$def->setFactory($definition->getFactory());
}
if (isset($changes['configurator'])) {
$def->setConfigurator($definition->getConfigurator());
}
if (isset($changes['file'])) {
$def->setFile($definition->getFile());
}
if (isset($changes['public'])) {
$def->setPublic($definition->isPublic());
}
if (isset($changes['lazy'])) {
$def->setLazy($definition->isLazy());
}
if (isset($changes['deprecated'])) {
$def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
}
if (isset($changes['autowire'])) {
$def->setAutowired($definition->isAutowired());
}
if (isset($changes['decorated_service'])) {
$decoratedService = $definition->getDecoratedService();
if (null === $decoratedService) {
$def->setDecoratedService($decoratedService);
} else {
$def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]);
}
}


 foreach ($definition->getArguments() as $k => $v) {
if (is_numeric($k)) {
$def->addArgument($v);
continue;
}

if (0 !== strpos($k, 'index_')) {
throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k));
}

$index = (int) substr($k, strlen('index_'));
$def->replaceArgument($index, $v);
}


 foreach ($definition->getProperties() as $k => $v) {
$def->setProperty($k, $v);
}


 if (count($calls = $definition->getMethodCalls()) > 0) {
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
}


 foreach ($definition->getAutowiringTypes() as $autowiringType) {
$def->addAutowiringType($autowiringType);
}


 $def->setAbstract($definition->isAbstract());
$def->setScope($definition->getScope(false), false);
$def->setShared($definition->isShared());
$def->setTags($definition->getTags());

return $def;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;








class ServiceReferenceGraphEdge
{
private $sourceNode;
private $destNode;
private $value;






public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null)
{
$this->sourceNode = $sourceNode;
$this->destNode = $destNode;
$this->value = $value;
}






public function getValue()
{
return $this->value;
}






public function getSourceNode()
{
return $this->sourceNode;
}






public function getDestNode()
{
return $this->destNode;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;






class CheckExceptionOnInvalidReferenceBehaviorPass implements CompilerPassInterface
{
private $container;
private $sourceId;

public function process(ContainerBuilder $container)
{
$this->container = $container;

foreach ($container->getDefinitions() as $id => $definition) {
$this->sourceId = $id;
$this->processDefinition($definition);
}
}

private function processDefinition(Definition $definition)
{
$this->processReferences($definition->getArguments());
$this->processReferences($definition->getMethodCalls());
$this->processReferences($definition->getProperties());
}

private function processReferences(array $arguments)
{
foreach ($arguments as $argument) {
if (is_array($argument)) {
$this->processReferences($argument);
} elseif ($argument instanceof Definition) {
$this->processDefinition($argument);
} elseif ($argument instanceof Reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $argument->getInvalidBehavior()) {
$destId = (string) $argument;

if (!$this->container->has($destId)) {
throw new ServiceNotFoundException($destId, $this->sourceId);
}
}
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;






class LoggingFormatter
{
public function formatRemoveService(CompilerPassInterface $pass, $id, $reason)
{
return $this->format($pass, sprintf('Removed service "%s"; reason: %s.', $id, $reason));
}

public function formatInlineService(CompilerPassInterface $pass, $id, $target)
{
return $this->format($pass, sprintf('Inlined service "%s" to "%s".', $id, $target));
}

public function formatUpdateReference(CompilerPassInterface $pass, $serviceId, $oldDestId, $newDestId)
{
return $this->format($pass, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $serviceId, $oldDestId, $newDestId));
}

public function formatResolveInheritance(CompilerPassInterface $pass, $childId, $parentId)
{
return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId));
}

public function format(CompilerPassInterface $pass, $message)
{
return sprintf('%s: %s', get_class($pass), $message);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;






class Compiler
{
private $passConfig;
private $log = array();
private $loggingFormatter;
private $serviceReferenceGraph;

public function __construct()
{
$this->passConfig = new PassConfig();
$this->serviceReferenceGraph = new ServiceReferenceGraph();
$this->loggingFormatter = new LoggingFormatter();
}






public function getPassConfig()
{
return $this->passConfig;
}






public function getServiceReferenceGraph()
{
return $this->serviceReferenceGraph;
}






public function getLoggingFormatter()
{
return $this->loggingFormatter;
}







public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
{
$this->passConfig->addPass($pass, $type);
}






public function addLogMessage($string)
{
$this->log[] = $string;
}






public function getLog()
{
return $this->log;
}






public function compile(ContainerBuilder $container)
{
foreach ($this->passConfig->getPasses() as $pass) {
$pass->process($container);
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;






class AutowirePass implements CompilerPassInterface
{
private $container;
private $reflectionClasses = array();
private $definedTypes = array();
private $types;
private $notGuessableTypes = array();
private $usedTypes = array();




public function process(ContainerBuilder $container)
{
$throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); };
spl_autoload_register($throwingAutoloader);

try {
$this->container = $container;
foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isAutowired()) {
$this->completeDefinition($id, $definition);
}
}

foreach ($this->usedTypes as $type => $id) {
if (isset($this->usedTypes[$type]) && isset($this->notGuessableTypes[$type])) {
$classOrInterface = class_exists($type) ? 'class' : 'interface';
$matchingServices = implode(', ', $this->types[$type]);

throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $type, $id, $classOrInterface, $matchingServices));
}
}
} catch (\Exception $e) {
} catch (\Throwable $e) {
}

spl_autoload_unregister($throwingAutoloader);


 $this->container = null;
$this->reflectionClasses = array();
$this->definedTypes = array();
$this->types = null;
$this->notGuessableTypes = array();
$this->usedTypes = array();

if (isset($e)) {
throw $e;
}
}









private function completeDefinition($id, Definition $definition)
{
if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {
return;
}

$this->container->addClassResource($reflectionClass);

if (!$constructor = $reflectionClass->getConstructor()) {
return;
}

$arguments = $definition->getArguments();
foreach ($constructor->getParameters() as $index => $parameter) {
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
continue;
}

try {
if (!$typeHint = $parameter->getClass()) {

 if (!$parameter->isOptional()) {
throw new RuntimeException(sprintf('Unable to autowire argument index %d ($%s) for the service "%s". If this is an object, give it a type-hint. Otherwise, specify this argument\'s value explicitly.', $index, $parameter->name, $id));
}

if (!array_key_exists($index, $arguments)) {

 $arguments[$index] = $parameter->getDefaultValue();
}

continue;
}

if (null === $this->types) {
$this->populateAvailableTypes();
}

if (isset($this->types[$typeHint->name]) && !isset($this->notGuessableTypes[$typeHint->name])) {
$value = new Reference($this->types[$typeHint->name]);
$this->usedTypes[$typeHint->name] = $id;
} else {
try {
$value = $this->createAutowiredDefinition($typeHint, $id);
$this->usedTypes[$typeHint->name] = $id;
} catch (RuntimeException $e) {
if ($parameter->allowsNull()) {
$value = null;
} elseif ($parameter->isDefaultValueAvailable()) {
$value = $parameter->getDefaultValue();
} else {
throw $e;
}
}
}
} catch (\ReflectionException $e) {


if (!$parameter->isDefaultValueAvailable()) {
throw new RuntimeException(sprintf('Cannot autowire argument %s for %s because the type-hinted class does not exist (%s).', $index + 1, $definition->getClass(), $e->getMessage()), 0, $e);
}

$value = $parameter->getDefaultValue();
}

$arguments[$index] = $value;
}


 
 ksort($arguments);
$definition->setArguments($arguments);
}




private function populateAvailableTypes()
{
$this->types = array();

foreach ($this->container->getDefinitions() as $id => $definition) {
$this->populateAvailableType($id, $definition);
}
}







private function populateAvailableType($id, Definition $definition)
{

 if ($definition->isAbstract()) {
return;
}

foreach ($definition->getAutowiringTypes() as $type) {
$this->definedTypes[$type] = true;
$this->types[$type] = $id;
unset($this->notGuessableTypes[$type]);
}

if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {
return;
}

foreach ($reflectionClass->getInterfaces() as $reflectionInterface) {
$this->set($reflectionInterface->name, $id);
}

do {
$this->set($reflectionClass->name, $id);
} while ($reflectionClass = $reflectionClass->getParentClass());
}







private function set($type, $id)
{
if (isset($this->definedTypes[$type])) {
return;
}

if (!isset($this->types[$type])) {
$this->types[$type] = $id;

return;
}

if ($this->types[$type] === $id) {
return;
}

if (!isset($this->notGuessableTypes[$type])) {
$this->notGuessableTypes[$type] = true;
$this->types[$type] = (array) $this->types[$type];
}

$this->types[$type][] = $id;
}











private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
{
if (isset($this->notGuessableTypes[$typeHint->name])) {
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
$matchingServices = implode(', ', $this->types[$typeHint->name]);

throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices));
}

if (!$typeHint->isInstantiable()) {
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface));
}

$argumentId = sprintf('autowired.%s', $typeHint->name);

$argumentDefinition = $this->container->register($argumentId, $typeHint->name);
$argumentDefinition->setPublic(false);

$this->populateAvailableType($argumentId, $argumentDefinition);

try {
$this->completeDefinition($argumentId, $argumentDefinition);
} catch (RuntimeException $e) {
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
$message = sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface);
throw new RuntimeException($message, 0, $e);
}

return new Reference($argumentId);
}









private function getReflectionClass($id, Definition $definition)
{
if (isset($this->reflectionClasses[$id])) {
return $this->reflectionClasses[$id];
}


 if (!$class = $definition->getClass()) {
return false;
}

$class = $this->container->getParameterBag()->resolveValue($class);

try {
$reflector = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
$reflector = false;
}

return $this->reflectionClasses[$id] = $reflector;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;






class RepeatedPass implements CompilerPassInterface
{



private $repeat = false;




private $passes;






public function __construct(array $passes)
{
foreach ($passes as $pass) {
if (!$pass instanceof RepeatablePassInterface) {
throw new InvalidArgumentException('$passes must be an array of RepeatablePassInterface.');
}

$pass->setRepeatedPass($this);
}

$this->passes = $passes;
}






public function process(ContainerBuilder $container)
{
do {
$this->repeat = false;
foreach ($this->passes as $pass) {
$pass->process($container);
}
} while ($this->repeat);
}




public function setRepeat()
{
$this->repeat = true;
}






public function getPasses()
{
return $this->passes;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;







class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
{
private $compiler;
private $formatter;








public function process(ContainerBuilder $container)
{

 $this->compiler = $container->getCompiler();
$this->formatter = $this->compiler->getLoggingFormatter();

 $seenAliasTargets = array();
$replacements = array();
foreach ($container->getAliases() as $definitionId => $target) {
$targetId = (string) $target;

 if ('service_container' === $targetId) {
continue;
}

 if (isset($replacements[$targetId])) {
$container->setAlias($definitionId, $replacements[$targetId]);
}

 if (isset($seenAliasTargets[$targetId])) {
continue;
}

 $seenAliasTargets[$targetId] = true;
try {
$definition = $container->getDefinition($targetId);
} catch (InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $definitionId, $targetId), null, $e);
}
if ($definition->isPublic()) {
continue;
}

 $definition->setPublic(true);
$container->setDefinition($definitionId, $definition);
$container->removeDefinition($targetId);
$replacements[$targetId] = $definitionId;
}


 foreach ($container->getDefinitions() as $definitionId => $definition) {
$definition->setArguments($this->updateArgumentReferences($replacements, $definitionId, $definition->getArguments()));
$definition->setMethodCalls($this->updateArgumentReferences($replacements, $definitionId, $definition->getMethodCalls()));
$definition->setProperties($this->updateArgumentReferences($replacements, $definitionId, $definition->getProperties()));
$definition->setFactoryService($this->updateFactoryReferenceId($replacements, $definition->getFactoryService(false)), false);
$definition->setFactory($this->updateFactoryReference($replacements, $definition->getFactory()));
}
}










private function updateArgumentReferences(array $replacements, $definitionId, array $arguments)
{
foreach ($arguments as $k => $argument) {

 if (is_array($argument)) {
$arguments[$k] = $this->updateArgumentReferences($replacements, $definitionId, $argument);
continue;
}

 if (!$argument instanceof Reference) {
continue;
}
$referenceId = (string) $argument;
if (!isset($replacements[$referenceId])) {
continue;
}

 $newId = $replacements[$referenceId];
$arguments[$k] = new Reference($newId, $argument->getInvalidBehavior());
$this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $definitionId, $referenceId, $newId));
}

return $arguments;
}









private function updateFactoryReferenceId(array $replacements, $referenceId)
{
if (null === $referenceId) {
return;
}

return isset($replacements[$referenceId]) ? $replacements[$referenceId] : $referenceId;
}

private function updateFactoryReference(array $replacements, $factory)
{
if (is_array($factory) && $factory[0] instanceof Reference && isset($replacements[$referenceId = (string) $factory[0]])) {
$factory[0] = new Reference($replacements[$referenceId], $factory[0]->getInvalidBehavior());
}

return $factory;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;







interface RepeatablePassInterface extends CompilerPassInterface
{





public function setRepeatedPass(RepeatedPass $repeatedPass);
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;










class AnalyzeServiceReferencesPass implements RepeatablePassInterface
{
private $graph;
private $container;
private $currentId;
private $currentDefinition;
private $repeatedPass;
private $onlyConstructorArguments;




public function __construct($onlyConstructorArguments = false)
{
$this->onlyConstructorArguments = (bool) $onlyConstructorArguments;
}




public function setRepeatedPass(RepeatedPass $repeatedPass)
{
$this->repeatedPass = $repeatedPass;
}






public function process(ContainerBuilder $container)
{
$this->container = $container;
$this->graph = $container->getCompiler()->getServiceReferenceGraph();
$this->graph->clear();

foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isSynthetic() || $definition->isAbstract()) {
continue;
}

$this->currentId = $id;
$this->currentDefinition = $definition;

$this->processArguments($definition->getArguments());
if ($definition->getFactoryService(false)) {
$this->processArguments(array(new Reference($definition->getFactoryService(false))));
}
if (is_array($definition->getFactory())) {
$this->processArguments($definition->getFactory());
}

if (!$this->onlyConstructorArguments) {
$this->processArguments($definition->getMethodCalls());
$this->processArguments($definition->getProperties());
if ($definition->getConfigurator()) {
$this->processArguments(array($definition->getConfigurator()));
}
}
}

foreach ($container->getAliases() as $id => $alias) {
$this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null);
}
}






private function processArguments(array $arguments)
{
foreach ($arguments as $argument) {
if (is_array($argument)) {
$this->processArguments($argument);
} elseif ($argument instanceof Reference) {
$this->graph->connect(
$this->currentId,
$this->currentDefinition,
$this->getDefinitionId((string) $argument),
$this->getDefinition((string) $argument),
$argument
);
} elseif ($argument instanceof Definition) {
$this->processArguments($argument->getArguments());
$this->processArguments($argument->getMethodCalls());
$this->processArguments($argument->getProperties());

if (is_array($argument->getFactory())) {
$this->processArguments($argument->getFactory());
}
if ($argument->getFactoryService(false)) {
$this->processArguments(array(new Reference($argument->getFactoryService(false))));
}
}
}
}








private function getDefinition($id)
{
$id = $this->getDefinitionId($id);

return null === $id ? null : $this->container->getDefinition($id);
}

private function getDefinitionId($id)
{
while ($this->container->hasAlias($id)) {
$id = (string) $this->container->getAlias($id);
}

if (!$this->container->hasDefinition($id)) {
return;
}

return $id;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;















class CheckDefinitionValidityPass implements CompilerPassInterface
{







public function process(ContainerBuilder $container)
{
foreach ($container->getDefinitions() as $id => $definition) {

 if ($definition->isSynthetic() && !$definition->isPublic()) {
throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id));
}


 if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
throw new RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id));
}


 if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
throw new RuntimeException(sprintf('A shared service ("%s") cannot be of scope "prototype".', $id));
}

if ($definition->getFactory() && ($definition->getFactoryClass(false) || $definition->getFactoryService(false) || $definition->getFactoryMethod(false))) {
throw new RuntimeException(sprintf('A service ("%s") can use either the old or the new factory syntax, not both.', $id));
}


 if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
if ($definition->getFactory() || $definition->getFactoryClass(false) || $definition->getFactoryService(false)) {
throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id));
}

throw new RuntimeException(sprintf(
'The definition for "%s" has no class. If you intend to inject '
.'this service dynamically at runtime, please mark it as synthetic=true. '
.'If this is an abstract definition solely used by child definitions, '
.'please add abstract=true, otherwise specify a class to get rid of this error.',
$id
));
}


 foreach ($definition->getTags() as $name => $tags) {
foreach ($tags as $attributes) {
foreach ($attributes as $attribute => $value) {
if (!is_scalar($value) && null !== $value) {
throw new RuntimeException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute));
}
}
}
}
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\ContainerBuilder;











class CheckCircularReferencesPass implements CompilerPassInterface
{
private $currentPath;
private $checkedNodes;






public function process(ContainerBuilder $container)
{
$graph = $container->getCompiler()->getServiceReferenceGraph();

$this->checkedNodes = array();
foreach ($graph->getNodes() as $id => $node) {
$this->currentPath = array($id);

$this->checkOutEdges($node->getOutEdges());
}
}








private function checkOutEdges(array $edges)
{
foreach ($edges as $edge) {
$node = $edge->getDestNode();
$id = $node->getId();

if (empty($this->checkedNodes[$id])) {

 if (!$node->getValue() || !$node->getValue()->isLazy()) {
$searchKey = array_search($id, $this->currentPath);
$this->currentPath[] = $id;

if (false !== $searchKey) {
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
}

$this->checkOutEdges($node->getOutEdges());
}

$this->checkedNodes[$id] = true;
array_pop($this->currentPath);
}
}
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;









class ServiceReferenceGraph
{



private $nodes = array();








public function hasNode($id)
{
return isset($this->nodes[$id]);
}










public function getNode($id)
{
if (!isset($this->nodes[$id])) {
throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id));
}

return $this->nodes[$id];
}






public function getNodes()
{
return $this->nodes;
}




public function clear()
{
$this->nodes = array();
}










public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null)
{
$sourceNode = $this->createNode($sourceId, $sourceValue);
$destNode = $this->createNode($destId, $destValue);
$edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference);

$sourceNode->addOutEdge($edge);
$destNode->addInEdge($edge);
}









private function createNode($id, $value)
{
if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) {
return $this->nodes[$id];
}

return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value);
}
}
<?php










namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;




class AutoAliasServicePass implements CompilerPassInterface
{



public function process(ContainerBuilder $container)
{
foreach ($container->findTaggedServiceIds('auto_alias') as $serviceId => $tags) {
foreach ($tags as $tag) {
if (!isset($tag['format'])) {
throw new InvalidArgumentException(sprintf('Missing tag information "format" on auto_alias service "%s".', $serviceId));
}

$aliasId = $container->getParameterBag()->resolveValue($tag['format']);
if ($container->hasDefinition($aliasId) || $container->hasAlias($aliasId)) {
$container->setAlias($serviceId, new Alias($aliasId));
}
}
}
}
}
<?php










namespace Symfony\Component\DependencyInjection;

class Alias
{
private $id;
private $public;





public function __construct($id, $public = true)
{
$this->id = strtolower($id);
$this->public = $public;
}






public function isPublic()
{
return $this->public;
}






public function setPublic($boolean)
{
$this->public = (bool) $boolean;
}






public function __toString()
{
return $this->id;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class ParameterCircularReferenceException extends RuntimeException
{
private $parameters;

public function __construct($parameters, \Exception $previous = null)
{
parent::__construct(sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], implode('" > "', $parameters), $parameters[0]), 0, $previous);

$this->parameters = $parameters;
}

public function getParameters()
{
return $this->parameters;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;




class LogicException extends \LogicException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class ServiceNotFoundException extends InvalidArgumentException
{
private $id;
private $sourceId;

public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = array())
{
if (null === $sourceId) {
$msg = sprintf('You have requested a non-existent service "%s".', $id);
} else {
$msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id);
}

if ($alternatives) {
if (1 == count($alternatives)) {
$msg .= ' Did you mean this: "';
} else {
$msg .= ' Did you mean one of these: "';
}
$msg .= implode('", "', $alternatives).'"?';
}

parent::__construct($msg, 0, $previous);

$this->id = $id;
$this->sourceId = $sourceId;
}

public function getId()
{
return $this->id;
}

public function getSourceId()
{
return $this->sourceId;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;







interface ExceptionInterface
{
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class ScopeWideningInjectionException extends RuntimeException
{
private $sourceServiceId;
private $sourceScope;
private $destServiceId;
private $destScope;

public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope, \Exception $previous = null)
{
parent::__construct(sprintf(
'Scope Widening Injection detected: The definition "%s" references the service "%s" which belongs to a narrower scope. '
.'Generally, it is safer to either move "%s" to scope "%s" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "%s" each time it is needed. '
.'In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.',
$sourceServiceId,
$destServiceId,
$sourceServiceId,
$destScope,
$destServiceId
), 0, $previous);

$this->sourceServiceId = $sourceServiceId;
$this->sourceScope = $sourceScope;
$this->destServiceId = $destServiceId;
$this->destScope = $destScope;
}

public function getSourceServiceId()
{
return $this->sourceServiceId;
}

public function getSourceScope()
{
return $this->sourceScope;
}

public function getDestServiceId()
{
return $this->destServiceId;
}

public function getDestScope()
{
return $this->destScope;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;




class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class InactiveScopeException extends RuntimeException
{
private $serviceId;
private $scope;

public function __construct($serviceId, $scope, \Exception $previous = null)
{
parent::__construct(sprintf('You cannot create a service ("%s") of an inactive scope ("%s").', $serviceId, $scope), 0, $previous);

$this->serviceId = $serviceId;
$this->scope = $scope;
}

public function getServiceId()
{
return $this->serviceId;
}

public function getScope()
{
return $this->scope;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class ScopeCrossingInjectionException extends RuntimeException
{
private $sourceServiceId;
private $sourceScope;
private $destServiceId;
private $destScope;

public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope, \Exception $previous = null)
{
parent::__construct(sprintf(
'Scope Crossing Injection detected: The definition "%s" references the service "%s" which belongs to another scope hierarchy. '
.'This service might not be available consistently. Generally, it is safer to either move the definition "%s" to scope "%s", or '
.'declare "%s" as a child scope of "%s". If you can be sure that the other scope is always active, you can set the reference to strict=false to get rid of this error.',
$sourceServiceId,
$destServiceId,
$sourceServiceId,
$destScope,
$sourceScope,
$destScope
), 0, $previous);

$this->sourceServiceId = $sourceServiceId;
$this->sourceScope = $sourceScope;
$this->destServiceId = $destServiceId;
$this->destScope = $destScope;
}

public function getSourceServiceId()
{
return $this->sourceServiceId;
}

public function getSourceScope()
{
return $this->sourceScope;
}

public function getDestServiceId()
{
return $this->destServiceId;
}

public function getDestScope()
{
return $this->destScope;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;




class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class ParameterNotFoundException extends InvalidArgumentException
{
private $key;
private $sourceId;
private $sourceKey;
private $alternatives;








public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array())
{
$this->key = $key;
$this->sourceId = $sourceId;
$this->sourceKey = $sourceKey;
$this->alternatives = $alternatives;

parent::__construct('', 0, $previous);

$this->updateRepr();
}

public function updateRepr()
{
if (null !== $this->sourceId) {
$this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key);
} elseif (null !== $this->sourceKey) {
$this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key);
} else {
$this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key);
}

if ($this->alternatives) {
if (1 == count($this->alternatives)) {
$this->message .= ' Did you mean this: "';
} else {
$this->message .= ' Did you mean one of these: "';
}
$this->message .= implode('", "', $this->alternatives).'"?';
}
}

public function getKey()
{
return $this->key;
}

public function getSourceId()
{
return $this->sourceId;
}

public function getSourceKey()
{
return $this->sourceKey;
}

public function setSourceId($sourceId)
{
$this->sourceId = $sourceId;

$this->updateRepr();
}

public function setSourceKey($sourceKey)
{
$this->sourceKey = $sourceKey;

$this->updateRepr();
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class ServiceCircularReferenceException extends RuntimeException
{
private $serviceId;
private $path;

public function __construct($serviceId, array $path, \Exception $previous = null)
{
parent::__construct(sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, implode(' -> ', $path)), 0, $previous);

$this->serviceId = $serviceId;
$this->path = $path;
}

public function getServiceId()
{
return $this->serviceId;
}

public function getPath()
{
return $this->path;
}
}
<?php










namespace Symfony\Component\DependencyInjection\Exception;






class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\DependencyInjection;






interface ContainerAwareInterface
{





public function setContainer(ContainerInterface $container = null);
}
<?php










namespace Symfony\Component\DependencyInjection;








interface ResettableContainerInterface extends ContainerInterface
{







public function reset();
}
<?php










namespace Symfony\Component\DependencyInjection;








abstract class ContainerAware implements ContainerAwareInterface
{



protected $container;




public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
<?php










namespace Symfony\Component\Process;







class PhpExecutableFinder
{
private $executableFinder;

public function __construct()
{
$this->executableFinder = new ExecutableFinder();
}








public function find($includeArgs = true)
{
$args = $this->findArguments();
$args = $includeArgs && $args ? ' '.implode(' ', $args) : '';


 if (defined('HHVM_VERSION')) {
return (getenv('PHP_BINARY') ?: PHP_BINARY).$args;
}


 if (defined('PHP_BINARY') && PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg')) && is_file(PHP_BINARY)) {
return PHP_BINARY.$args;
}

if ($php = getenv('PHP_PATH')) {
if (!is_executable($php)) {
return false;
}

return $php;
}

if ($php = getenv('PHP_PEAR_PHP_BIN')) {
if (is_executable($php)) {
return $php;
}
}

$dirs = array(PHP_BINDIR);
if ('\\' === DIRECTORY_SEPARATOR) {
$dirs[] = 'C:\xampp\php\\';
}

return $this->executableFinder->find('php', false, $dirs);
}






public function findArguments()
{
$arguments = array();

if (defined('HHVM_VERSION')) {
$arguments[] = '--php';
} elseif ('phpdbg' === PHP_SAPI) {
$arguments[] = '-qrr';
}

return $arguments;
}
}
<?php










namespace Symfony\Component\Process;







class ExecutableFinder
{
private $suffixes = array('.exe', '.bat', '.cmd', '.com');






public function setSuffixes(array $suffixes)
{
$this->suffixes = $suffixes;
}






public function addSuffix($suffix)
{
$this->suffixes[] = $suffix;
}










public function find($name, $default = null, array $extraDirs = array())
{
if (ini_get('open_basedir')) {
$searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
$dirs = array();
foreach ($searchPath as $path) {

 if (@is_dir($path)) {
$dirs[] = $path;
} else {
if (basename($path) == $name && @is_executable($path)) {
return $path;
}
}
}
} else {
$dirs = array_merge(
explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
$extraDirs
);
}

$suffixes = array('');
if ('\\' === DIRECTORY_SEPARATOR) {
$pathExt = getenv('PATHEXT');
$suffixes = array_merge($suffixes, $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes);
}
foreach ($suffixes as $suffix) {
foreach ($dirs as $dir) {
if (@is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === DIRECTORY_SEPARATOR || is_executable($file))) {
return $file;
}
}
}

return $default;
}
}
<?php










define('ERR_SELECT_FAILED', 1);
define('ERR_TIMEOUT', 2);
define('ERR_READ_FAILED', 3);
define('ERR_WRITE_FAILED', 4);

$read = array(STDIN);
$write = array(STDOUT, STDERR);

stream_set_blocking(STDIN, 0);
stream_set_blocking(STDOUT, 0);
stream_set_blocking(STDERR, 0);

$out = $err = '';
while ($read || $write) {
$r = $read;
$w = $write;
$e = null;
$n = stream_select($r, $w, $e, 5);

if (false === $n) {
die(ERR_SELECT_FAILED);
} elseif ($n < 1) {
die(ERR_TIMEOUT);
}

if (in_array(STDOUT, $w) && strlen($out) > 0) {
$written = fwrite(STDOUT, (binary) $out, 32768);
if (false === $written) {
die(ERR_WRITE_FAILED);
}
$out = (binary) substr($out, $written);
}
if (null === $read && '' === $out) {
$write = array_diff($write, array(STDOUT));
}

if (in_array(STDERR, $w) && strlen($err) > 0) {
$written = fwrite(STDERR, (binary) $err, 32768);
if (false === $written) {
die(ERR_WRITE_FAILED);
}
$err = (binary) substr($err, $written);
}
if (null === $read && '' === $err) {
$write = array_diff($write, array(STDERR));
}

if ($r) {
$str = fread(STDIN, 32768);
if (false !== $str) {
$out .= $str;
$err .= $str;
}
if (false === $str || feof(STDIN)) {
$read = null;
if (!feof(STDIN)) {
die(ERR_READ_FAILED);
}
}
}
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ProcessBuilder;

class ProcessBuilderTest extends TestCase
{
public function testInheritEnvironmentVars()
{
$_ENV['MY_VAR_1'] = 'foo';

$proc = ProcessBuilder::create()
->add('foo')
->getProcess();

unset($_ENV['MY_VAR_1']);

$env = $proc->getEnv();
$this->assertArrayHasKey('MY_VAR_1', $env);
$this->assertEquals('foo', $env['MY_VAR_1']);
}

public function testAddEnvironmentVariables()
{
$pb = new ProcessBuilder();
$env = array(
'foo' => 'bar',
'foo2' => 'bar2',
);
$proc = $pb
->add('command')
->setEnv('foo', 'bar2')
->addEnvironmentVariables($env)
->inheritEnvironmentVariables(false)
->getProcess()
;

$this->assertSame($env, $proc->getEnv());
}

public function testProcessShouldInheritAndOverrideEnvironmentVars()
{
$_ENV['MY_VAR_1'] = 'foo';

$proc = ProcessBuilder::create()
->setEnv('MY_VAR_1', 'bar')
->add('foo')
->getProcess();

unset($_ENV['MY_VAR_1']);

$env = $proc->getEnv();
$this->assertArrayHasKey('MY_VAR_1', $env);
$this->assertEquals('bar', $env['MY_VAR_1']);
}




public function testNegativeTimeoutFromSetter()
{
$pb = new ProcessBuilder();
$pb->setTimeout(-1);
}

public function testNullTimeout()
{
$pb = new ProcessBuilder();
$pb->setTimeout(10);
$pb->setTimeout(null);

$r = new \ReflectionObject($pb);
$p = $r->getProperty('timeout');
$p->setAccessible(true);

$this->assertNull($p->getValue($pb));
}

public function testShouldSetArguments()
{
$pb = new ProcessBuilder(array('initial'));
$pb->setArguments(array('second'));

$proc = $pb->getProcess();

$this->assertContains('second', $proc->getCommandLine());
}

public function testPrefixIsPrependedToAllGeneratedProcess()
{
$pb = new ProcessBuilder();
$pb->setPrefix('/usr/bin/php');

$proc = $pb->setArguments(array('-v'))->getProcess();
if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals('"/usr/bin/php" "-v"', $proc->getCommandLine());
} else {
$this->assertEquals("'/usr/bin/php' '-v'", $proc->getCommandLine());
}

$proc = $pb->setArguments(array('-i'))->getProcess();
if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals('"/usr/bin/php" "-i"', $proc->getCommandLine());
} else {
$this->assertEquals("'/usr/bin/php' '-i'", $proc->getCommandLine());
}
}

public function testArrayPrefixesArePrependedToAllGeneratedProcess()
{
$pb = new ProcessBuilder();
$pb->setPrefix(array('/usr/bin/php', 'composer.phar'));

$proc = $pb->setArguments(array('-v'))->getProcess();
if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals('"/usr/bin/php" "composer.phar" "-v"', $proc->getCommandLine());
} else {
$this->assertEquals("'/usr/bin/php' 'composer.phar' '-v'", $proc->getCommandLine());
}

$proc = $pb->setArguments(array('-i'))->getProcess();
if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals('"/usr/bin/php" "composer.phar" "-i"', $proc->getCommandLine());
} else {
$this->assertEquals("'/usr/bin/php' 'composer.phar' '-i'", $proc->getCommandLine());
}
}

public function testShouldEscapeArguments()
{
$pb = new ProcessBuilder(array('%path%', 'foo " bar', '%baz%baz'));
$proc = $pb->getProcess();

if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertSame('^%"path"^% "foo \\" bar" "%baz%baz"', $proc->getCommandLine());
} else {
$this->assertSame("'%path%' 'foo \" bar' '%baz%baz'", $proc->getCommandLine());
}
}

public function testShouldEscapeArgumentsAndPrefix()
{
$pb = new ProcessBuilder(array('arg'));
$pb->setPrefix('%prefix%');
$proc = $pb->getProcess();

if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertSame('^%"prefix"^% "arg"', $proc->getCommandLine());
} else {
$this->assertSame("'%prefix%' 'arg'", $proc->getCommandLine());
}
}




public function testShouldThrowALogicExceptionIfNoPrefixAndNoArgument()
{
ProcessBuilder::create()->getProcess();
}

public function testShouldNotThrowALogicExceptionIfNoArgument()
{
$process = ProcessBuilder::create()
->setPrefix('/usr/bin/php')
->getProcess();

if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
} else {
$this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
}
}

public function testShouldNotThrowALogicExceptionIfNoPrefix()
{
$process = ProcessBuilder::create(array('/usr/bin/php'))
->getProcess();

if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
} else {
$this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
}
}

public function testShouldReturnProcessWithDisabledOutput()
{
$process = ProcessBuilder::create(array('/usr/bin/php'))
->disableOutput()
->getProcess();

$this->assertTrue($process->isOutputDisabled());
}

public function testShouldReturnProcessWithEnabledOutput()
{
$process = ProcessBuilder::create(array('/usr/bin/php'))
->disableOutput()
->enableOutput()
->getProcess();

$this->assertFalse($process->isOutputDisabled());
}





public function testInvalidInput()
{
$builder = ProcessBuilder::create();
$builder->setInput(array());
}
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\PhpExecutableFinder;




class PhpExecutableFinderTest extends TestCase
{



public function testFindWithPhpPath()
{
if (defined('PHP_BINARY')) {
$this->markTestSkipped('The PHP binary is easily available as of PHP 5.4');
}

$f = new PhpExecutableFinder();

$current = $f->find();


 putenv('PHP_PATH=/not/executable/php');
$this->assertFalse($f->find(), '::find() returns false for not executable PHP');
$this->assertFalse($f->find(false), '::find() returns false for not executable PHP');


 putenv('PHP_PATH='.$current);
$this->assertEquals($f->find(), $current, '::find() returns the executable PHP');
$this->assertEquals($f->find(false), $current, '::find() returns the executable PHP');
}






public function testFind()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('Should not be executed in HHVM context.');
}

$f = new PhpExecutableFinder();

$current = PHP_BINARY;
$args = 'phpdbg' === PHP_SAPI ? ' -qrr' : '';

$this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP');
$this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
}




public function testFindWithHHVM()
{
if (!defined('HHVM_VERSION')) {
$this->markTestSkipped('Should be executed in HHVM context.');
}

$f = new PhpExecutableFinder();

$current = getenv('PHP_BINARY') ?: PHP_BINARY;

$this->assertEquals($current.' --php', $f->find(), '::find() returns the executable PHP');
$this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
}




public function testFindArguments()
{
$f = new PhpExecutableFinder();

if (defined('HHVM_VERSION')) {
$this->assertEquals($f->findArguments(), array('--php'), '::findArguments() returns HHVM arguments');
} elseif ('phpdbg' === PHP_SAPI) {
$this->assertEquals($f->findArguments(), array('-qrr'), '::findArguments() returns phpdbg arguments');
} else {
$this->assertEquals($f->findArguments(), array(), '::findArguments() returns no arguments');
}
}




public function testFindWithSuffix()
{
if (defined('PHP_BINARY')) {
$this->markTestSkipped('The PHP binary is easily available as of PHP 5.4');
}

putenv('PHP_PATH=');
putenv('PHP_PEAR_PHP_BIN=');
$f = new PhpExecutableFinder();

$current = $f->find();


 if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertTrue(is_executable($current));
$this->assertTrue((bool) preg_match('/'.addslashes(DIRECTORY_SEPARATOR).'php\.(exe|bat|cmd|com)$/i', $current), '::find() returns the executable PHP with suffixes');
}
}
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ExecutableFinder;




class ExecutableFinderTest extends TestCase
{
private $path;

protected function tearDown()
{
if ($this->path) {

 putenv('PATH='.$this->path);
}
}

private function setPath($path)
{
$this->path = getenv('PATH');
putenv('PATH='.$path);
}




public function testFind()
{
if (ini_get('open_basedir')) {
$this->markTestSkipped('Cannot test when open_basedir is set');
}

$this->setPath(dirname(PHP_BINARY));

$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName());

$this->assertSamePath(PHP_BINARY, $result);
}

public function testFindWithDefault()
{
if (ini_get('open_basedir')) {
$this->markTestSkipped('Cannot test when open_basedir is set');
}

$expected = 'defaultValue';

$this->setPath('');

$finder = new ExecutableFinder();
$result = $finder->find('foo', $expected);

$this->assertEquals($expected, $result);
}




public function testFindWithExtraDirs()
{
if (ini_get('open_basedir')) {
$this->markTestSkipped('Cannot test when open_basedir is set');
}

$this->setPath('');

$extraDirs = array(dirname(PHP_BINARY));

$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);

$this->assertSamePath(PHP_BINARY, $result);
}




public function testFindWithOpenBaseDir()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Cannot run test on windows');
}

if (ini_get('open_basedir')) {
$this->markTestSkipped('Cannot test when open_basedir is set');
}

$this->iniSet('open_basedir', dirname(PHP_BINARY).(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));

$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName());

$this->assertSamePath(PHP_BINARY, $result);
}




public function testFindProcessInOpenBasedir()
{
if (ini_get('open_basedir')) {
$this->markTestSkipped('Cannot test when open_basedir is set');
}
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Cannot run test on windows');
}

$this->setPath('');
$this->iniSet('open_basedir', PHP_BINARY.(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));

$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName(), false);

$this->assertSamePath(PHP_BINARY, $result);
}

private function assertSamePath($expected, $tested)
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->assertEquals(strtolower($expected), strtolower($tested));
} else {
$this->assertEquals($expected, $tested);
}
}

private function getPhpBinaryName()
{
return basename(PHP_BINARY, '\\' === DIRECTORY_SEPARATOR ? '.exe' : '');
}
}
<?php










pcntl_signal(SIGUSR1, function () { echo 'SIGUSR1'; exit; });

echo 'Caught ';

$n = 0;

while ($n++ < 400) {
usleep(10000);
pcntl_signal_dispatch();
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\ProcessUtils;

class ProcessUtilsTest extends TestCase
{



public function testEscapeArgument($result, $argument)
{
$this->assertSame($result, ProcessUtils::escapeArgument($argument));
}

public function dataArguments()
{
if ('\\' === DIRECTORY_SEPARATOR) {
return array(
array('"\"php\" \"-v\""', '"php" "-v"'),
array('"foo bar"', 'foo bar'),
array('^%"path"^%', '%path%'),
array('"<|>\\" \\"\'f"', '<|>" "\'f'),
array('""', ''),
array('"with\trailingbs\\\\"', 'with\trailingbs\\'),
);
}

return array(
array("'\"php\" \"-v\"'", '"php" "-v"'),
array("'foo bar'", 'foo bar'),
array("'%path%'", '%path%'),
array("'<|>\" \"'\\''f'", '<|>" "\'f'),
array("''", ''),
array("'with\\trailingbs\\'", 'with\trailingbs\\'),
array("'withNonAsciiAccentLikeéÉèÈàÀöä'", 'withNonAsciiAccentLikeéÉèÈàÀöä'),
);
}
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Exception\LogicException;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Exception\RuntimeException;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Pipes\PipesInterface;
use Symfony\Component\Process\Process;




class ProcessTest extends TestCase
{
private static $phpBin;
private static $process;
private static $sigchild;
private static $notEnhancedSigchild = false;

public static function setUpBeforeClass()
{
$phpBin = new PhpExecutableFinder();
self::$phpBin = getenv('SYMFONY_PROCESS_PHP_TEST_BINARY') ?: ('phpdbg' === PHP_SAPI ? 'php' : $phpBin->find());
if ('\\' !== DIRECTORY_SEPARATOR) {

 
 
 self::$phpBin = 'exec '.self::$phpBin;
}

ob_start();
phpinfo(INFO_GENERAL);
self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
}

protected function tearDown()
{
if (self::$process) {
self::$process->stop(0);
self::$process = null;
}
}

public function testThatProcessDoesNotThrowWarningDuringRun()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test is transient on Windows');
}
@trigger_error('Test Error', E_USER_NOTICE);
$process = $this->getProcess(self::$phpBin." -r 'sleep(3)'");
$process->run();
$actualError = error_get_last();
$this->assertEquals('Test Error', $actualError['message']);
$this->assertEquals(E_USER_NOTICE, $actualError['type']);
}




public function testNegativeTimeoutFromConstructor()
{
$this->getProcess('', null, null, null, -1);
}




public function testNegativeTimeoutFromSetter()
{
$p = $this->getProcess('');
$p->setTimeout(-1);
}

public function testFloatAndNullTimeout()
{
$p = $this->getProcess('');

$p->setTimeout(10);
$this->assertSame(10.0, $p->getTimeout());

$p->setTimeout(null);
$this->assertNull($p->getTimeout());

$p->setTimeout(0.0);
$this->assertNull($p->getTimeout());
}




public function testStopWithTimeoutIsActuallyWorking()
{
$p = $this->getProcess(self::$phpBin.' '.__DIR__.'/NonStopableProcess.php 30');
$p->start();

while (false === strpos($p->getOutput(), 'received')) {
usleep(1000);
}
$start = microtime(true);
$p->stop(0.1);

$p->wait();

$this->assertLessThan(15, microtime(true) - $start);
}

public function testAllOutputIsActuallyReadOnTermination()
{

 
 
 
 
 
 
 $expectedOutputSize = PipesInterface::CHUNK_SIZE * 2 + 2;

$code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize);
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));

$p->start();


 $h = new \ReflectionProperty($p, 'process');
$h->setAccessible(true);
$h = $h->getValue($p);
$s = @proc_get_status($h);

while (!empty($s['running'])) {
usleep(1000);
$s = proc_get_status($h);
}

$o = $p->getOutput();

$this->assertEquals($expectedOutputSize, strlen($o));
}

public function testCallbacksAreExecutedWithStart()
{
$process = $this->getProcess('echo foo');
$process->start(function ($type, $buffer) use (&$data) {
$data .= $buffer;
});

$process->wait();

$this->assertSame('foo'.PHP_EOL, $data);
}






public function testProcessResponses($expected, $getter, $code)
{
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->run();

$this->assertSame($expected, $p->$getter());
}






public function testProcessPipes($code, $size)
{
$expected = str_repeat(str_repeat('*', 1024), $size).'!';
$expectedLength = (1024 * $size) + 1;

$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->setInput($expected);
$p->run();

$this->assertEquals($expectedLength, strlen($p->getOutput()));
$this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
}




public function testSetStreamAsInput($code, $size)
{
$expected = str_repeat(str_repeat('*', 1024), $size).'!';
$expectedLength = (1024 * $size) + 1;

$stream = fopen('php://temporary', 'w+');
fwrite($stream, $expected);
rewind($stream);

$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->setInput($stream);
$p->run();

fclose($stream);

$this->assertEquals($expectedLength, strlen($p->getOutput()));
$this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
}

public function testLiveStreamAsInput()
{
$stream = fopen('php://memory', 'r+');
fwrite($stream, 'hello');
rewind($stream);

$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('stream_copy_to_stream(STDIN, STDOUT);')));
$p->setInput($stream);
$p->start(function ($type, $data) use ($stream) {
if ('hello' === $data) {
fclose($stream);
}
});
$p->wait();

$this->assertSame('hello', $p->getOutput());
}





public function testSetInputWhileRunningThrowsAnException()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(30);"');
$process->start();
try {
$process->setInput('foobar');
$process->stop();
$this->fail('A LogicException should have been raised.');
} catch (LogicException $e) {
}
$process->stop();

throw $e;
}






public function testInvalidInput($value)
{
$process = $this->getProcess('foo');
$process->setInput($value);
}

public function provideInvalidInputValues()
{
return array(
array(array()),
array(new NonStringifiable()),
);
}




public function testValidInput($expected, $value)
{
$process = $this->getProcess('foo');
$process->setInput($value);
$this->assertSame($expected, $process->getInput());
}

public function provideInputValues()
{
return array(
array(null, null),
array('24.5', 24.5),
array('input data', 'input data'),
);
}





public function testLegacyValidInput($expected, $value)
{
$process = $this->getProcess(self::$phpBin.' -v');
$process->setInput($value);
$this->assertSame($expected, $process->getInput());
}

public function provideLegacyInputValues()
{
return array(
array('stringifiable', new Stringifiable()),
);
}

public function chainedCommandsOutputProvider()
{
if ('\\' === DIRECTORY_SEPARATOR) {
return array(
array("2 \r\n2\r\n", '&&', '2'),
);
}

return array(
array("1\n1\n", ';', '1'),
array("2\n2\n", '&&', '2'),
);
}




public function testChainedCommandsOutput($expected, $operator, $input)
{
$process = $this->getProcess(sprintf('echo %s %s echo %s', $input, $operator, $input));
$process->run();
$this->assertEquals($expected, $process->getOutput());
}

public function testCallbackIsExecutedForOutput()
{
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('echo \'foo\';')));

$called = false;
$p->run(function ($type, $buffer) use (&$called) {
$called = $buffer === 'foo';
});

$this->assertTrue($called, 'The callback should be executed with the output');
}

public function testGetErrorOutput()
{
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }')));

$p->run();
$this->assertEquals(3, preg_match_all('/ERROR/', $p->getErrorOutput(), $matches));
}

public function testFlushErrorOutput()
{
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }')));

$p->run();
$p->clearErrorOutput();
$this->assertEmpty($p->getErrorOutput());
}




public function testIncrementalOutput($getOutput, $getIncrementalOutput, $uri)
{
$lock = tempnam(sys_get_temp_dir(), __FUNCTION__);

$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('file_put_contents($s = \''.$uri.'\', \'foo\'); flock(fopen('.var_export($lock, true).', \'r\'), LOCK_EX); file_put_contents($s, \'bar\');')));

$h = fopen($lock, 'w');
flock($h, LOCK_EX);

$p->start();

foreach (array('foo', 'bar') as $s) {
while (false === strpos($p->$getOutput(), $s)) {
usleep(1000);
}

$this->assertSame($s, $p->$getIncrementalOutput());
$this->assertSame('', $p->$getIncrementalOutput());

flock($h, LOCK_UN);
}

fclose($h);
}

public function provideIncrementalOutput()
{
return array(
array('getOutput', 'getIncrementalOutput', 'php://stdout'),
array('getErrorOutput', 'getIncrementalErrorOutput', 'php://stderr'),
);
}

public function testGetOutput()
{
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }')));

$p->run();
$this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches));
}

public function testFlushOutput()
{
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n=0;while ($n<3) {echo \' foo \';$n++;}')));

$p->run();
$p->clearOutput();
$this->assertEmpty($p->getOutput());
}

public function testZeroAsOutput()
{
if ('\\' === DIRECTORY_SEPARATOR) {

 $p = $this->getProcess('echo | set /p dummyName=0');
} else {
$p = $this->getProcess('printf 0');
}

$p->run();
$this->assertSame('0', $p->getOutput());
}

public function testExitCodeCommandFailed()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX exit code');
}
$this->skipIfNotEnhancedSigchild();


 $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis');
$process->run();

$this->assertGreaterThan(0, $process->getExitCode());
}

public function testTTYCommand()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not have /dev/tty support');
}

$process = $this->getProcess('echo "foo" >> /dev/null && '.self::$phpBin.' -r "usleep(100000);"');
$process->setTty(true);
$process->start();
$this->assertTrue($process->isRunning());
$process->wait();

$this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
}

public function testTTYCommandExitCode()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does have /dev/tty support');
}
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo "foo" >> /dev/null');
$process->setTty(true);
$process->run();

$this->assertTrue($process->isSuccessful());
}





public function testTTYInWindowsEnvironment()
{
if ('\\' !== DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test is for Windows platform only');
}

$process = $this->getProcess('echo "foo" >> /dev/null');
$process->setTty(false);
$process->setTty(true);
}

public function testExitCodeTextIsNullWhenExitCodeIsNull()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('');
$this->assertNull($process->getExitCodeText());
}

public function testPTYCommand()
{
if (!Process::isPtySupported()) {
$this->markTestSkipped('PTY is not supported on this operating system.');
}

$process = $this->getProcess('echo "foo"');
$process->setPty(true);
$process->run();

$this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
$this->assertEquals("foo\r\n", $process->getOutput());
}

public function testMustRun()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo foo');

$this->assertSame($process, $process->mustRun());
$this->assertEquals('foo'.PHP_EOL, $process->getOutput());
}

public function testSuccessfulMustRunHasCorrectExitCode()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo foo')->mustRun();
$this->assertEquals(0, $process->getExitCode());
}




public function testMustRunThrowsException()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('exit 1');
$process->mustRun();
}

public function testExitCodeText()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('');
$r = new \ReflectionObject($process);
$p = $r->getProperty('exitcode');
$p->setAccessible(true);

$p->setValue($process, 2);
$this->assertEquals('Misuse of shell builtins', $process->getExitCodeText());
}

public function testStartIsNonBlocking()
{
$process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$start = microtime(true);
$process->start();
$end = microtime(true);
$this->assertLessThan(0.4, $end - $start);
$process->stop();
}

public function testUpdateStatus()
{
$process = $this->getProcess('echo foo');
$process->run();
$this->assertTrue(strlen($process->getOutput()) > 0);
}

public function testGetExitCodeIsNullOnStart()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess(self::$phpBin.' -r "usleep(100000);"');
$this->assertNull($process->getExitCode());
$process->start();
$this->assertNull($process->getExitCode());
$process->wait();
$this->assertEquals(0, $process->getExitCode());
}

public function testGetExitCodeIsNullOnWhenStartingAgain()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess(self::$phpBin.' -r "usleep(100000);"');
$process->run();
$this->assertEquals(0, $process->getExitCode());
$process->start();
$this->assertNull($process->getExitCode());
$process->wait();
$this->assertEquals(0, $process->getExitCode());
}

public function testGetExitCode()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo foo');
$process->run();
$this->assertSame(0, $process->getExitCode());
}

public function testStatus()
{
$process = $this->getProcess(self::$phpBin.' -r "usleep(100000);"');
$this->assertFalse($process->isRunning());
$this->assertFalse($process->isStarted());
$this->assertFalse($process->isTerminated());
$this->assertSame(Process::STATUS_READY, $process->getStatus());
$process->start();
$this->assertTrue($process->isRunning());
$this->assertTrue($process->isStarted());
$this->assertFalse($process->isTerminated());
$this->assertSame(Process::STATUS_STARTED, $process->getStatus());
$process->wait();
$this->assertFalse($process->isRunning());
$this->assertTrue($process->isStarted());
$this->assertTrue($process->isTerminated());
$this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
}

public function testStop()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(31);"');
$process->start();
$this->assertTrue($process->isRunning());
$process->stop();
$this->assertFalse($process->isRunning());
}

public function testIsSuccessful()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo foo');
$process->run();
$this->assertTrue($process->isSuccessful());
}

public function testIsSuccessfulOnlyAfterTerminated()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess(self::$phpBin.' -r "usleep(100000);"');
$process->start();

$this->assertFalse($process->isSuccessful());

$process->wait();

$this->assertTrue($process->isSuccessful());
}

public function testIsNotSuccessful()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess(self::$phpBin.' -r "throw new \Exception(\'BOUM\');"');
$process->run();
$this->assertFalse($process->isSuccessful());
}

public function testProcessIsNotSignaled()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX signals');
}
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo foo');
$process->run();
$this->assertFalse($process->hasBeenSignaled());
}

public function testProcessWithoutTermSignal()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX signals');
}
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('echo foo');
$process->run();
$this->assertEquals(0, $process->getTermSignal());
}

public function testProcessIsSignaledIfStopped()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX signals');
}
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess(self::$phpBin.' -r "sleep(32);"');
$process->start();
$process->stop();
$this->assertTrue($process->hasBeenSignaled());
$this->assertEquals(15, $process->getTermSignal()); 
 }





public function testProcessThrowsExceptionWhenExternallySignaled()
{
if (!function_exists('posix_kill')) {
$this->markTestSkipped('Function posix_kill is required.');
}
$this->skipIfNotEnhancedSigchild(false);

$process = $this->getProcess(self::$phpBin.' -r "sleep(32.1)"');
$process->start();
posix_kill($process->getPid(), 9); 

$process->wait();
}

public function testRestart()
{
$process1 = $this->getProcess(self::$phpBin.' -r "echo getmypid();"');
$process1->run();
$process2 = $process1->restart();

$process2->wait(); 


 $this->assertFalse($process1->isRunning());
$this->assertFalse($process2->isRunning());
$this->assertTrue(is_numeric($process1->getOutput()));
$this->assertTrue(is_numeric($process2->getOutput()));


 $this->assertNotEquals($process1->getOutput(), $process2->getOutput());
}





public function testRunProcessWithTimeout()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(30);"');
$process->setTimeout(0.1);
$start = microtime(true);
try {
$process->run();
$this->fail('A RuntimeException should have been raised');
} catch (RuntimeException $e) {
}

$this->assertLessThan(15, microtime(true) - $start);

throw $e;
}

public function testCheckTimeoutOnNonStartedProcess()
{
$process = $this->getProcess('echo foo');
$this->assertNull($process->checkTimeout());
}

public function testCheckTimeoutOnTerminatedProcess()
{
$process = $this->getProcess('echo foo');
$process->run();
$this->assertNull($process->checkTimeout());
}





public function testCheckTimeoutOnStartedProcess()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(33);"');
$process->setTimeout(0.1);

$process->start();
$start = microtime(true);

try {
while ($process->isRunning()) {
$process->checkTimeout();
usleep(100000);
}
$this->fail('A ProcessTimedOutException should have been raised');
} catch (ProcessTimedOutException $e) {
}

$this->assertLessThan(15, microtime(true) - $start);

throw $e;
}

public function testIdleTimeout()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(34);"');
$process->setTimeout(60);
$process->setIdleTimeout(0.1);

try {
$process->run();

$this->fail('A timeout exception was expected.');
} catch (ProcessTimedOutException $e) {
$this->assertTrue($e->isIdleTimeout());
$this->assertFalse($e->isGeneralTimeout());
$this->assertEquals(0.1, $e->getExceededTimeout());
}
}

public function testIdleTimeoutNotExceededWhenOutputIsSent()
{
$process = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('while (true) {echo \'foo \'; usleep(1000);}')));
$process->setTimeout(1);
$process->start();

while (false === strpos($process->getOutput(), 'foo')) {
usleep(1000);
}

$process->setIdleTimeout(0.5);

try {
$process->wait();
$this->fail('A timeout exception was expected.');
} catch (ProcessTimedOutException $e) {
$this->assertTrue($e->isGeneralTimeout(), 'A general timeout is expected.');
$this->assertFalse($e->isIdleTimeout(), 'No idle timeout is expected.');
$this->assertEquals(1, $e->getExceededTimeout());
}
}





public function testStartAfterATimeout()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(35);"');
$process->setTimeout(0.1);

try {
$process->run();
$this->fail('A ProcessTimedOutException should have been raised.');
} catch (ProcessTimedOutException $e) {
}
$this->assertFalse($process->isRunning());
$process->start();
$this->assertTrue($process->isRunning());
$process->stop(0);

throw $e;
}

public function testGetPid()
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(36);"');
$process->start();
$this->assertGreaterThan(0, $process->getPid());
$process->stop(0);
}

public function testGetPidIsNullBeforeStart()
{
$process = $this->getProcess('foo');
$this->assertNull($process->getPid());
}

public function testGetPidIsNullAfterRun()
{
$process = $this->getProcess('echo foo');
$process->run();
$this->assertNull($process->getPid());
}




public function testSignal()
{
$process = $this->getProcess(self::$phpBin.' '.__DIR__.'/SignalListener.php');
$process->start();

while (false === strpos($process->getOutput(), 'Caught')) {
usleep(1000);
}
$process->signal(SIGUSR1);
$process->wait();

$this->assertEquals('Caught SIGUSR1', $process->getOutput());
}




public function testExitCodeIsAvailableAfterSignal()
{
$this->skipIfNotEnhancedSigchild();

$process = $this->getProcess('sleep 4');
$process->start();
$process->signal(SIGKILL);

while ($process->isRunning()) {
usleep(10000);
}

$this->assertFalse($process->isRunning());
$this->assertTrue($process->hasBeenSignaled());
$this->assertFalse($process->isSuccessful());
$this->assertEquals(137, $process->getExitCode());
}





public function testSignalProcessNotRunning()
{
$process = $this->getProcess('foo');
$process->signal(1); 
 }




public function testMethodsThatNeedARunningProcess($method)
{
$process = $this->getProcess('foo');

if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Process\Exception\LogicException');
$this->expectExceptionMessage(sprintf('Process must be started before calling %s.', $method));
} else {
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method));
}

$process->{$method}();
}

public function provideMethodsThatNeedARunningProcess()
{
return array(
array('getOutput'),
array('getIncrementalOutput'),
array('getErrorOutput'),
array('getIncrementalErrorOutput'),
array('wait'),
);
}






public function testMethodsThatNeedATerminatedProcess($method)
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(37);"');
$process->start();
try {
$process->{$method}();
$process->stop(0);
$this->fail('A LogicException must have been thrown');
} catch (\Exception $e) {
}
$process->stop(0);

throw $e;
}

public function provideMethodsThatNeedATerminatedProcess()
{
return array(
array('hasBeenSignaled'),
array('getTermSignal'),
array('hasBeenStopped'),
array('getStopSignal'),
);
}





public function testWrongSignal($signal)
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('POSIX signals do not work on Windows');
}

$process = $this->getProcess(self::$phpBin.' -r "sleep(38);"');
$process->start();
try {
$process->signal($signal);
$this->fail('A RuntimeException must have been thrown');
} catch (RuntimeException $e) {
$process->stop(0);
}

throw $e;
}

public function provideWrongSignal()
{
return array(
array(-4),
array('Céphalopodes'),
);
}

public function testDisableOutputDisablesTheOutput()
{
$p = $this->getProcess('foo');
$this->assertFalse($p->isOutputDisabled());
$p->disableOutput();
$this->assertTrue($p->isOutputDisabled());
$p->enableOutput();
$this->assertFalse($p->isOutputDisabled());
}





public function testDisableOutputWhileRunningThrowsException()
{
$p = $this->getProcess(self::$phpBin.' -r "sleep(39);"');
$p->start();
$p->disableOutput();
}





public function testEnableOutputWhileRunningThrowsException()
{
$p = $this->getProcess(self::$phpBin.' -r "sleep(40);"');
$p->disableOutput();
$p->start();
$p->enableOutput();
}

public function testEnableOrDisableOutputAfterRunDoesNotThrowException()
{
$p = $this->getProcess('echo foo');
$p->disableOutput();
$p->run();
$p->enableOutput();
$p->disableOutput();
$this->assertTrue($p->isOutputDisabled());
}





public function testDisableOutputWhileIdleTimeoutIsSet()
{
$process = $this->getProcess('foo');
$process->setIdleTimeout(1);
$process->disableOutput();
}





public function testSetIdleTimeoutWhileOutputIsDisabled()
{
$process = $this->getProcess('foo');
$process->disableOutput();
$process->setIdleTimeout(1);
}

public function testSetNullIdleTimeoutWhileOutputIsDisabled()
{
$process = $this->getProcess('foo');
$process->disableOutput();
$this->assertSame($process, $process->setIdleTimeout(null));
}




public function testStartWithACallbackAndDisabledOutput($startMethod, $exception, $exceptionMessage)
{
$p = $this->getProcess('foo');
$p->disableOutput();

if (method_exists($this, 'expectException')) {
$this->expectException($exception);
$this->expectExceptionMessage($exceptionMessage);
} else {
$this->setExpectedException($exception, $exceptionMessage);
}

if ('mustRun' === $startMethod) {
$this->skipIfNotEnhancedSigchild();
}
$p->{$startMethod}(function () {});
}

public function provideStartMethods()
{
return array(
array('start', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'),
array('run', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'),
array('mustRun', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'),
);
}






public function testGetOutputWhileDisabled($fetchMethod)
{
$p = $this->getProcess(self::$phpBin.' -r "sleep(41);"');
$p->disableOutput();
$p->start();
$p->{$fetchMethod}();
}

public function provideOutputFetchingMethods()
{
return array(
array('getOutput'),
array('getIncrementalOutput'),
array('getErrorOutput'),
array('getIncrementalErrorOutput'),
);
}

public function testStopTerminatesProcessCleanly()
{
$process = $this->getProcess(self::$phpBin.' -r "echo 123; sleep(42);"');
$process->run(function () use ($process) {
$process->stop();
});
$this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException');
}

public function testKillSignalTerminatesProcessCleanly()
{
$process = $this->getProcess(self::$phpBin.' -r "echo 123; sleep(43);"');
$process->run(function () use ($process) {
$process->signal(9); 
 });
$this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
}

public function testTermSignalTerminatesProcessCleanly()
{
$process = $this->getProcess(self::$phpBin.' -r "echo 123; sleep(44);"');
$process->run(function () use ($process) {
$process->signal(15); 
 });
$this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
}

public function responsesCodeProvider()
{
return array(

 
 
 array('output', 'getOutput', 'echo \'output\';'),
);
}

public function pipesCodeProvider()
{
$variations = array(
'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);',
'include \''.__DIR__.'/PipeStdinInStdoutStdErrStreamSelect.php\';',
);

if ('\\' === DIRECTORY_SEPARATOR) {

 $sizes = array(1, 2, 4, 8);
} else {
$sizes = array(1, 16, 64, 1024, 4096);
}

$codes = array();
foreach ($sizes as $size) {
foreach ($variations as $code) {
$codes[] = array($code, $size);
}
}

return $codes;
}




public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method)
{
$process = $this->getProcess(self::$phpBin.' -r '.escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }'), null, null, null, null);
$process->start();
$result = '';
$limit = microtime(true) + 3;
$expected = '012';

while ($result !== $expected && microtime(true) < $limit) {
$result .= $process->$method();
}

$this->assertSame($expected, $result);
$process->stop();
}

public function provideVariousIncrementals()
{
return array(
array('php://stdout', 'getIncrementalOutput'),
array('php://stderr', 'getIncrementalErrorOutput'),
);
}











private function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array())
{
$process = new Process($commandline, $cwd, $env, $input, $timeout, $options);

if (false !== $enhance = getenv('ENHANCE_SIGCHLD')) {
try {
$process->setEnhanceSigchildCompatibility(false);
$process->getExitCode();
$this->fail('ENHANCE_SIGCHLD must be used together with a sigchild-enabled PHP.');
} catch (RuntimeException $e) {
$this->assertSame('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.', $e->getMessage());
if ($enhance) {
$process->setEnhanceSigchildCompatibility(true);
} else {
self::$notEnhancedSigchild = true;
}
}
}

if (self::$process) {
self::$process->stop(0);
}

return self::$process = $process;
}

private function skipIfNotEnhancedSigchild($expectException = true)
{
if (self::$sigchild) {
if (!$expectException) {
$this->markTestSkipped('PHP is compiled with --enable-sigchild.');
} elseif (self::$notEnhancedSigchild) {
if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Process\Exception\RuntimeException');
$this->expectExceptionMessage('This PHP has been compiled with --enable-sigchild.');
} else {
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild.');
}
}
}
}
}

class Stringifiable
{
public function __toString()
{
return 'stringifiable';
}
}

class NonStringifiable
{
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Exception\ProcessFailedException;




class ProcessFailedExceptionTest extends TestCase
{



public function testProcessFailedExceptionThrowsException()
{
$process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful'))->setConstructorArgs(array('php'))->getMock();
$process->expects($this->once())
->method('isSuccessful')
->will($this->returnValue(true));

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(
'\InvalidArgumentException',
'Expected a failed process, but the given process was successful.'
);

new ProcessFailedException($process);
}





public function testProcessFailedExceptionPopulatesInformationFromProcessOutput()
{
$cmd = 'php';
$exitCode = 1;
$exitText = 'General error';
$output = 'Command output';
$errorOutput = 'FATAL: Unexpected error';
$workingDirectory = getcwd();

$process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
$process->expects($this->once())
->method('isSuccessful')
->will($this->returnValue(false));

$process->expects($this->once())
->method('getOutput')
->will($this->returnValue($output));

$process->expects($this->once())
->method('getErrorOutput')
->will($this->returnValue($errorOutput));

$process->expects($this->once())
->method('getExitCode')
->will($this->returnValue($exitCode));

$process->expects($this->once())
->method('getExitCodeText')
->will($this->returnValue($exitText));

$process->expects($this->once())
->method('isOutputDisabled')
->will($this->returnValue(false));

$process->expects($this->once())
->method('getWorkingDirectory')
->will($this->returnValue($workingDirectory));

$exception = new ProcessFailedException($process);

$this->assertEquals(
"The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
$exception->getMessage()
);
}





public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
{
$cmd = 'php';
$exitCode = 1;
$exitText = 'General error';
$workingDirectory = getcwd();

$process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
$process->expects($this->once())
->method('isSuccessful')
->will($this->returnValue(false));

$process->expects($this->never())
->method('getOutput');

$process->expects($this->never())
->method('getErrorOutput');

$process->expects($this->once())
->method('getExitCode')
->will($this->returnValue($exitCode));

$process->expects($this->once())
->method('getExitCodeText')
->will($this->returnValue($exitText));

$process->expects($this->once())
->method('isOutputDisabled')
->will($this->returnValue(true));

$process->expects($this->once())
->method('getWorkingDirectory')
->will($this->returnValue($workingDirectory));

$exception = new ProcessFailedException($process);

$this->assertEquals(
"The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
$exception->getMessage()
);
}
}
<?php










namespace Symfony\Component\Process\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\PhpProcess;

class PhpProcessTest extends TestCase
{
public function testNonBlockingWorks()
{
$expected = 'hello world!';
$process = new PhpProcess(<<<PHP
<?php echo '$expected';
PHP
);
$process->start();
$process->wait();
$this->assertEquals($expected, $process->getOutput());
}

public function testCommandLine()
{
$process = new PhpProcess(<<<'PHP'
<?php echo 'foobar';
PHP
);

$commandLine = $process->getCommandLine();

$f = new PhpExecutableFinder();
$this->assertContains($f->find(), $commandLine, '::getCommandLine() returns the command line of PHP before start');

$process->start();
$this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start');

$process->wait();
$this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait');
}
}
<?php

















function handleSignal($signal)
{
switch ($signal) {
case SIGTERM:
$name = 'SIGTERM';
break;
case SIGINT:
$name = 'SIGINT';
break;
default:
$name = $signal.' (unknown)';
break;
}

echo "signal $name\n";
}

pcntl_signal(SIGTERM, 'handleSignal');
pcntl_signal(SIGINT, 'handleSignal');

echo 'received ';

$duration = isset($argv[1]) ? (int) $argv[1] : 3;
$start = microtime(true);

while ($duration > (microtime(true) - $start)) {
usleep(10000);
pcntl_signal_dispatch();
}
<?php










namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\RuntimeException;










class PhpProcess extends Process
{









public function __construct($script, $cwd = null, array $env = null, $timeout = 60, array $options = array())
{
$executableFinder = new PhpExecutableFinder();
if (false === $php = $executableFinder->find()) {
$php = null;
}
if ('phpdbg' === PHP_SAPI) {
$file = tempnam(sys_get_temp_dir(), 'dbg');
file_put_contents($file, $script);
register_shutdown_function('unlink', $file);
$php .= ' '.ProcessUtils::escapeArgument($file);
$script = null;
}
if ('\\' !== DIRECTORY_SEPARATOR && null !== $php) {

 
 
 $php = 'exec '.$php;
}

parent::__construct($php, $cwd, $env, $script, $timeout, $options);
}




public function setPhpBinary($php)
{
$this->setCommandLine($php);
}




public function start($callback = null)
{
if (null === $this->getCommandLine()) {
throw new RuntimeException('Unable to find the PHP executable.');
}

parent::start($callback);
}
}
<?php










namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\InvalidArgumentException;
use Symfony\Component\Process\Exception\LogicException;






class ProcessBuilder
{
private $arguments;
private $cwd;
private $env = array();
private $input;
private $timeout = 60;
private $options = array();
private $inheritEnv = true;
private $prefix = array();
private $outputDisabled = false;






public function __construct(array $arguments = array())
{
$this->arguments = $arguments;
}








public static function create(array $arguments = array())
{
return new static($arguments);
}








public function add($argument)
{
$this->arguments[] = $argument;

return $this;
}










public function setPrefix($prefix)
{
$this->prefix = is_array($prefix) ? $prefix : array($prefix);

return $this;
}











public function setArguments(array $arguments)
{
$this->arguments = $arguments;

return $this;
}








public function setWorkingDirectory($cwd)
{
$this->cwd = $cwd;

return $this;
}








public function inheritEnvironmentVariables($inheritEnv = true)
{
$this->inheritEnv = $inheritEnv;

return $this;
}












public function setEnv($name, $value)
{
$this->env[$name] = $value;

return $this;
}












public function addEnvironmentVariables(array $variables)
{
$this->env = array_replace($this->env, $variables);

return $this;
}












public function setInput($input)
{
$this->input = ProcessUtils::validateInput(__METHOD__, $input);

return $this;
}












public function setTimeout($timeout)
{
if (null === $timeout) {
$this->timeout = null;

return $this;
}

$timeout = (float) $timeout;

if ($timeout < 0) {
throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
}

$this->timeout = $timeout;

return $this;
}









public function setOption($name, $value)
{
$this->options[$name] = $value;

return $this;
}






public function disableOutput()
{
$this->outputDisabled = true;

return $this;
}






public function enableOutput()
{
$this->outputDisabled = false;

return $this;
}








public function getProcess()
{
if (0 === count($this->prefix) && 0 === count($this->arguments)) {
throw new LogicException('You must add() command arguments before calling getProcess().');
}

$options = $this->options;

$arguments = array_merge($this->prefix, $this->arguments);
$script = implode(' ', array_map(array(__NAMESPACE__.'\\ProcessUtils', 'escapeArgument'), $arguments));

if ($this->inheritEnv) {

 $env = array_replace($_ENV, $_SERVER, $this->env);
} else {
$env = $this->env;
}

$process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options);

if ($this->outputDisabled) {
$process->disableOutput();
}

return $process;
}
}
<?php










namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\InvalidArgumentException;
use Symfony\Component\Process\Exception\LogicException;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Exception\RuntimeException;
use Symfony\Component\Process\Pipes\PipesInterface;
use Symfony\Component\Process\Pipes\UnixPipes;
use Symfony\Component\Process\Pipes\WindowsPipes;








class Process
{
const ERR = 'err';
const OUT = 'out';

const STATUS_READY = 'ready';
const STATUS_STARTED = 'started';
const STATUS_TERMINATED = 'terminated';

const STDIN = 0;
const STDOUT = 1;
const STDERR = 2;


 const TIMEOUT_PRECISION = 0.2;

private $callback;
private $commandline;
private $cwd;
private $env;
private $input;
private $starttime;
private $lastOutputTime;
private $timeout;
private $idleTimeout;
private $options;
private $exitcode;
private $fallbackStatus = array();
private $processInformation;
private $outputDisabled = false;
private $stdout;
private $stderr;
private $enhanceWindowsCompatibility = true;
private $enhanceSigchildCompatibility;
private $process;
private $status = self::STATUS_READY;
private $incrementalOutputOffset = 0;
private $incrementalErrorOutputOffset = 0;
private $tty;
private $pty;

private $useFileHandles = false;

private $processPipes;

private $latestSignal;

private static $sigchild;








public static $exitCodes = array(
0 => 'OK',
1 => 'General error',
2 => 'Misuse of shell builtins',

126 => 'Invoked command cannot execute',
127 => 'Command not found',
128 => 'Invalid exit argument',


 129 => 'Hangup',
130 => 'Interrupt',
131 => 'Quit and dump core',
132 => 'Illegal instruction',
133 => 'Trace/breakpoint trap',
134 => 'Process aborted',
135 => 'Bus error: "access to undefined portion of memory object"',
136 => 'Floating point exception: "erroneous arithmetic operation"',
137 => 'Kill (terminate immediately)',
138 => 'User-defined 1',
139 => 'Segmentation violation',
140 => 'User-defined 2',
141 => 'Write to pipe with no one reading',
142 => 'Signal raised by alarm',
143 => 'Termination (request to terminate)',

 145 => 'Child process terminated, stopped (or continued*)',
146 => 'Continue if stopped',
147 => 'Stop executing temporarily',
148 => 'Terminal stop signal',
149 => 'Background process attempting to read from tty ("in")',
150 => 'Background process attempting to write to tty ("out")',
151 => 'Urgent data available on socket',
152 => 'CPU time limit exceeded',
153 => 'File size limit exceeded',
154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
155 => 'Profiling timer expired',

 157 => 'Pollable event',

 159 => 'Bad syscall',
);













public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array())
{
if (!function_exists('proc_open')) {
throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
}

$this->commandline = $commandline;
$this->cwd = $cwd;


 
 
 
 if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DIRECTORY_SEPARATOR)) {
$this->cwd = getcwd();
}
if (null !== $env) {
$this->setEnv($env);
}

$this->setInput($input);
$this->setTimeout($timeout);
$this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
$this->pty = false;
$this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
$this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options);
}

public function __destruct()
{
$this->stop(0);
}

public function __clone()
{
$this->resetProcessData();
}




















public function run($callback = null)
{
$this->start($callback);

return $this->wait();
}














public function mustRun($callback = null)
{
if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
}

if (0 !== $this->run($callback)) {
throw new ProcessFailedException($this);
}

return $this;
}




















public function start($callback = null)
{
if ($this->isRunning()) {
throw new RuntimeException('Process is already running');
}
if ($this->outputDisabled && null !== $callback) {
throw new LogicException('Output has been disabled, enable it to allow the use of a callback.');
}

$this->resetProcessData();
$this->starttime = $this->lastOutputTime = microtime(true);
$this->callback = $this->buildCallback($callback);
$descriptors = $this->getDescriptors();

$commandline = $this->commandline;

if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
$commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')';
foreach ($this->processPipes->getFiles() as $offset => $filename) {
$commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename);
}
$commandline .= '"';

if (!isset($this->options['bypass_shell'])) {
$this->options['bypass_shell'] = true;
}
} elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {

 $descriptors[3] = array('pipe', 'w');


 $commandline = '{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
$commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';


 
 $ptsWorkaround = fopen(__FILE__, 'r');
}

$this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options);

if (!is_resource($this->process)) {
throw new RuntimeException('Unable to launch a new process.');
}
$this->status = self::STATUS_STARTED;

if (isset($descriptors[3])) {
$this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
}

if ($this->tty) {
return;
}

$this->updateStatus(false);
$this->checkTimeout();
}
















public function restart($callback = null)
{
if ($this->isRunning()) {
throw new RuntimeException('Process is already running');
}

$process = clone $this;
$process->start($callback);

return $process;
}
















public function wait($callback = null)
{
$this->requireProcessIsStarted(__FUNCTION__);

$this->updateStatus(false);
if (null !== $callback) {
$this->callback = $this->buildCallback($callback);
}

do {
$this->checkTimeout();
$running = '\\' === DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
$this->readPipes($running, '\\' !== DIRECTORY_SEPARATOR || !$running);
} while ($running);

while ($this->isRunning()) {
usleep(1000);
}

if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
}

return $this->exitcode;
}






public function getPid()
{
return $this->isRunning() ? $this->processInformation['pid'] : null;
}












public function signal($signal)
{
$this->doSignal($signal, true);

return $this;
}









public function disableOutput()
{
if ($this->isRunning()) {
throw new RuntimeException('Disabling output while the process is running is not possible.');
}
if (null !== $this->idleTimeout) {
throw new LogicException('Output can not be disabled while an idle timeout is set.');
}

$this->outputDisabled = true;

return $this;
}








public function enableOutput()
{
if ($this->isRunning()) {
throw new RuntimeException('Enabling output while the process is running is not possible.');
}

$this->outputDisabled = false;

return $this;
}






public function isOutputDisabled()
{
return $this->outputDisabled;
}









public function getOutput()
{
$this->readPipesForOutput(__FUNCTION__);

if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
return '';
}

return $ret;
}












public function getIncrementalOutput()
{
$this->readPipesForOutput(__FUNCTION__);

$latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
$this->incrementalOutputOffset = ftell($this->stdout);

if (false === $latest) {
return '';
}

return $latest;
}






public function clearOutput()
{
ftruncate($this->stdout, 0);
fseek($this->stdout, 0);
$this->incrementalOutputOffset = 0;

return $this;
}









public function getErrorOutput()
{
$this->readPipesForOutput(__FUNCTION__);

if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
return '';
}

return $ret;
}













public function getIncrementalErrorOutput()
{
$this->readPipesForOutput(__FUNCTION__);

$latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
$this->incrementalErrorOutputOffset = ftell($this->stderr);

if (false === $latest) {
return '';
}

return $latest;
}






public function clearErrorOutput()
{
ftruncate($this->stderr, 0);
fseek($this->stderr, 0);
$this->incrementalErrorOutputOffset = 0;

return $this;
}








public function getExitCode()
{
if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
}

$this->updateStatus(false);

return $this->exitcode;
}












public function getExitCodeText()
{
if (null === $exitcode = $this->getExitCode()) {
return;
}

return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
}






public function isSuccessful()
{
return 0 === $this->getExitCode();
}











public function hasBeenSignaled()
{
$this->requireProcessIsTerminated(__FUNCTION__);

if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
}

return $this->processInformation['signaled'];
}











public function getTermSignal()
{
$this->requireProcessIsTerminated(__FUNCTION__);

if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
}

return $this->processInformation['termsig'];
}










public function hasBeenStopped()
{
$this->requireProcessIsTerminated(__FUNCTION__);

return $this->processInformation['stopped'];
}










public function getStopSignal()
{
$this->requireProcessIsTerminated(__FUNCTION__);

return $this->processInformation['stopsig'];
}






public function isRunning()
{
if (self::STATUS_STARTED !== $this->status) {
return false;
}

$this->updateStatus(false);

return $this->processInformation['running'];
}






public function isStarted()
{
return $this->status != self::STATUS_READY;
}






public function isTerminated()
{
$this->updateStatus(false);

return $this->status == self::STATUS_TERMINATED;
}








public function getStatus()
{
$this->updateStatus(false);

return $this->status;
}









public function stop($timeout = 10, $signal = null)
{
$timeoutMicro = microtime(true) + $timeout;
if ($this->isRunning()) {

 $this->doSignal(15, false);
do {
usleep(1000);
} while ($this->isRunning() && microtime(true) < $timeoutMicro);

if ($this->isRunning()) {

 
 $this->doSignal($signal ?: 9, false);
}
}

if ($this->isRunning()) {
if (isset($this->fallbackStatus['pid'])) {
unset($this->fallbackStatus['pid']);

return $this->stop(0, $signal);
}
$this->close();
}

return $this->exitcode;
}








public function addOutput($line)
{
$this->lastOutputTime = microtime(true);

fseek($this->stdout, 0, SEEK_END);
fwrite($this->stdout, $line);
fseek($this->stdout, $this->incrementalOutputOffset);
}








public function addErrorOutput($line)
{
$this->lastOutputTime = microtime(true);

fseek($this->stderr, 0, SEEK_END);
fwrite($this->stderr, $line);
fseek($this->stderr, $this->incrementalErrorOutputOffset);
}






public function getCommandLine()
{
return $this->commandline;
}








public function setCommandLine($commandline)
{
$this->commandline = $commandline;

return $this;
}






public function getTimeout()
{
return $this->timeout;
}






public function getIdleTimeout()
{
return $this->idleTimeout;
}












public function setTimeout($timeout)
{
$this->timeout = $this->validateTimeout($timeout);

return $this;
}













public function setIdleTimeout($timeout)
{
if (null !== $timeout && $this->outputDisabled) {
throw new LogicException('Idle timeout can not be set while the output is disabled.');
}

$this->idleTimeout = $this->validateTimeout($timeout);

return $this;
}










public function setTty($tty)
{
if ('\\' === DIRECTORY_SEPARATOR && $tty) {
throw new RuntimeException('TTY mode is not supported on Windows platform.');
}
if ($tty) {
static $isTtySupported;

if (null === $isTtySupported) {
$isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
}

if (!$isTtySupported) {
throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
}
}

$this->tty = (bool) $tty;

return $this;
}






public function isTty()
{
return $this->tty;
}








public function setPty($bool)
{
$this->pty = (bool) $bool;

return $this;
}






public function isPty()
{
return $this->pty;
}






public function getWorkingDirectory()
{
if (null === $this->cwd) {

 
 return getcwd() ?: null;
}

return $this->cwd;
}








public function setWorkingDirectory($cwd)
{
$this->cwd = $cwd;

return $this;
}






public function getEnv()
{
return $this->env;
}














public function setEnv(array $env)
{

 $env = array_filter($env, function ($value) {
return !is_array($value);
});

$this->env = array();
foreach ($env as $key => $value) {
$this->env[$key] = (string) $value;
}

return $this;
}










public function getStdin()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getInput() method instead.', E_USER_DEPRECATED);

return $this->getInput();
}






public function getInput()
{
return $this->input;
}














public function setStdin($stdin)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the setInput() method instead.', E_USER_DEPRECATED);

return $this->setInput($stdin);
}














public function setInput($input)
{
if ($this->isRunning()) {
throw new LogicException('Input can not be set while the process is running.');
}

$this->input = ProcessUtils::validateInput(__METHOD__, $input);

return $this;
}






public function getOptions()
{
return $this->options;
}








public function setOptions(array $options)
{
$this->options = $options;

return $this;
}








public function getEnhanceWindowsCompatibility()
{
return $this->enhanceWindowsCompatibility;
}








public function setEnhanceWindowsCompatibility($enhance)
{
$this->enhanceWindowsCompatibility = (bool) $enhance;

return $this;
}






public function getEnhanceSigchildCompatibility()
{
return $this->enhanceSigchildCompatibility;
}












public function setEnhanceSigchildCompatibility($enhance)
{
$this->enhanceSigchildCompatibility = (bool) $enhance;

return $this;
}









public function checkTimeout()
{
if ($this->status !== self::STATUS_STARTED) {
return;
}

if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
$this->stop(0);

throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL);
}

if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
$this->stop(0);

throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE);
}
}






public static function isPtySupported()
{
static $result;

if (null !== $result) {
return $result;
}

if ('\\' === DIRECTORY_SEPARATOR) {
return $result = false;
}

return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes);
}






private function getDescriptors()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->processPipes = WindowsPipes::create($this, $this->input);
} else {
$this->processPipes = UnixPipes::create($this, $this->input);
}

return $this->processPipes->getDescriptors();
}











protected function buildCallback($callback)
{
$that = $this;
$out = self::OUT;
$callback = function ($type, $data) use ($that, $callback, $out) {
if ($out == $type) {
$that->addOutput($data);
} else {
$that->addErrorOutput($data);
}

if (null !== $callback) {
call_user_func($callback, $type, $data);
}
};

return $callback;
}






protected function updateStatus($blocking)
{
if (self::STATUS_STARTED !== $this->status) {
return;
}

$this->processInformation = proc_get_status($this->process);
$running = $this->processInformation['running'];

$this->readPipes($running && $blocking, '\\' !== DIRECTORY_SEPARATOR || !$running);

if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
$this->processInformation = $this->fallbackStatus + $this->processInformation;
}

if (!$running) {
$this->close();
}
}






protected function isSigchildEnabled()
{
if (null !== self::$sigchild) {
return self::$sigchild;
}

if (!function_exists('phpinfo') || defined('HHVM_VERSION')) {
return self::$sigchild = false;
}

ob_start();
phpinfo(INFO_GENERAL);

return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
}








private function readPipesForOutput($caller)
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
}

$this->requireProcessIsStarted($caller);

$this->updateStatus(false);
}










private function validateTimeout($timeout)
{
$timeout = (float) $timeout;

if (0.0 === $timeout) {
$timeout = null;
} elseif ($timeout < 0) {
throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
}

return $timeout;
}







private function readPipes($blocking, $close)
{
$result = $this->processPipes->readAndWrite($blocking, $close);

$callback = $this->callback;
foreach ($result as $type => $data) {
if (3 !== $type) {
$callback($type === self::STDOUT ? self::OUT : self::ERR, $data);
} elseif (!isset($this->fallbackStatus['signaled'])) {
$this->fallbackStatus['exitcode'] = (int) $data;
}
}
}






private function close()
{
$this->processPipes->close();
if (is_resource($this->process)) {
proc_close($this->process);
}
$this->exitcode = $this->processInformation['exitcode'];
$this->status = self::STATUS_TERMINATED;

if (-1 === $this->exitcode) {
if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {

 $this->exitcode = 128 + $this->processInformation['termsig'];
} elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
$this->processInformation['signaled'] = true;
$this->processInformation['termsig'] = -1;
}
}


 
 
 $this->callback = null;

return $this->exitcode;
}




private function resetProcessData()
{
$this->starttime = null;
$this->callback = null;
$this->exitcode = null;
$this->fallbackStatus = array();
$this->processInformation = null;
$this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
$this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
$this->process = null;
$this->latestSignal = null;
$this->status = self::STATUS_READY;
$this->incrementalOutputOffset = 0;
$this->incrementalErrorOutputOffset = 0;
}













private function doSignal($signal, $throwException)
{
if (null === $pid = $this->getPid()) {
if ($throwException) {
throw new LogicException('Can not send signal on a non running process.');
}

return false;
}

if ('\\' === DIRECTORY_SEPARATOR) {
exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
if ($exitCode && $this->isRunning()) {
if ($throwException) {
throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
}

return false;
}
} else {
if (!$this->enhanceSigchildCompatibility || !$this->isSigchildEnabled()) {
$ok = @proc_terminate($this->process, $signal);
} elseif (function_exists('posix_kill')) {
$ok = @posix_kill($pid, $signal);
} elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), array(2 => array('pipe', 'w')), $pipes)) {
$ok = false === fgets($pipes[2]);
}
if (!$ok) {
if ($throwException) {
throw new RuntimeException(sprintf('Error while sending signal `%s`.', $signal));
}

return false;
}
}

$this->latestSignal = (int) $signal;
$this->fallbackStatus['signaled'] = true;
$this->fallbackStatus['exitcode'] = -1;
$this->fallbackStatus['termsig'] = $this->latestSignal;

return true;
}








private function requireProcessIsStarted($functionName)
{
if (!$this->isStarted()) {
throw new LogicException(sprintf('Process must be started before calling %s.', $functionName));
}
}








private function requireProcessIsTerminated($functionName)
{
if (!$this->isTerminated()) {
throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
}
}
}
<?php










namespace Symfony\Component\Process\Pipes;

use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\RuntimeException;











class WindowsPipes extends AbstractPipes
{

private $files = array();

private $fileHandles = array();

private $readBytes = array(
Process::STDOUT => 0,
Process::STDERR => 0,
);

private $disableOutput;

public function __construct($disableOutput, $input)
{
$this->disableOutput = (bool) $disableOutput;

if (!$this->disableOutput) {

 
 
 
 $pipes = array(
Process::STDOUT => Process::OUT,
Process::STDERR => Process::ERR,
);
$tmpCheck = false;
$tmpDir = sys_get_temp_dir();
$lastError = 'unknown reason';
set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
for ($i = 0;; ++$i) {
foreach ($pipes as $pipe => $name) {
$file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
if (file_exists($file) && !unlink($file)) {
continue 2;
}
$h = fopen($file, 'xb');
if (!$h) {
$error = $lastError;
if ($tmpCheck || $tmpCheck = unlink(tempnam(false, 'sf_check_'))) {
continue;
}
restore_error_handler();
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
}
if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
continue 2;
}
if (isset($this->files[$pipe])) {
unlink($this->files[$pipe]);
}
$this->files[$pipe] = $file;
}
break;
}
restore_error_handler();
}

parent::__construct($input);
}

public function __destruct()
{
$this->close();
$this->removeFiles();
}




public function getDescriptors()
{
if ($this->disableOutput) {
$nullstream = fopen('NUL', 'c');

return array(
array('pipe', 'r'),
$nullstream,
$nullstream,
);
}


 
 
 return array(
array('pipe', 'r'),
array('file', 'NUL', 'w'),
array('file', 'NUL', 'w'),
);
}




public function getFiles()
{
return $this->files;
}




public function readAndWrite($blocking, $close = false)
{
$this->unblock();
$w = $this->write();
$read = $r = $e = array();

if ($blocking) {
if ($w) {
@stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
} elseif ($this->fileHandles) {
usleep(Process::TIMEOUT_PRECISION * 1E6);
}
}
foreach ($this->fileHandles as $type => $fileHandle) {
$data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]);

if (isset($data[0])) {
$this->readBytes[$type] += strlen($data);
$read[$type] = $data;
}
if ($close) {
fclose($fileHandle);
unset($this->fileHandles[$type]);
}
}

return $read;
}




public function areOpen()
{
return $this->pipes && $this->fileHandles;
}




public function close()
{
parent::close();
foreach ($this->fileHandles as $handle) {
fclose($handle);
}
$this->fileHandles = array();
}









public static function create(Process $process, $input)
{
return new static($process->isOutputDisabled(), $input);
}




private function removeFiles()
{
foreach ($this->files as $filename) {
if (file_exists($filename)) {
@unlink($filename);
}
}
$this->files = array();
}
}
<?php










namespace Symfony\Component\Process\Pipes;






abstract class AbstractPipes implements PipesInterface
{

public $pipes = array();


private $inputBuffer = '';

private $input;

private $blocked = true;

public function __construct($input)
{
if (is_resource($input)) {
$this->input = $input;
} elseif (is_string($input)) {
$this->inputBuffer = $input;
} else {
$this->inputBuffer = (string) $input;
}
}




public function close()
{
foreach ($this->pipes as $pipe) {
fclose($pipe);
}
$this->pipes = array();
}






protected function hasSystemCallBeenInterrupted()
{
$lastError = error_get_last();


 return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call');
}




protected function unblock()
{
if (!$this->blocked) {
return;
}

foreach ($this->pipes as $pipe) {
stream_set_blocking($pipe, 0);
}
if (null !== $this->input) {
stream_set_blocking($this->input, 0);
}

$this->blocked = false;
}




protected function write()
{
if (!isset($this->pipes[0])) {
return;
}
$input = $this->input;
$r = $e = array();
$w = array($this->pipes[0]);


 if (false === $n = @stream_select($r, $w, $e, 0, 0)) {
return;
}

foreach ($w as $stdin) {
if (isset($this->inputBuffer[0])) {
$written = fwrite($stdin, $this->inputBuffer);
$this->inputBuffer = substr($this->inputBuffer, $written);
if (isset($this->inputBuffer[0])) {
return array($this->pipes[0]);
}
}

if ($input) {
for (;;) {
$data = fread($input, self::CHUNK_SIZE);
if (!isset($data[0])) {
break;
}
$written = fwrite($stdin, $data);
$data = substr($data, $written);
if (isset($data[0])) {
$this->inputBuffer = $data;

return array($this->pipes[0]);
}
}
if (feof($input)) {

 
 $this->input = null;
}
}
}


 if (null === $this->input && !isset($this->inputBuffer[0])) {
fclose($this->pipes[0]);
unset($this->pipes[0]);
} elseif (!$w) {
return array($this->pipes[0]);
}
}
}
<?php










namespace Symfony\Component\Process\Pipes;

use Symfony\Component\Process\Process;








class UnixPipes extends AbstractPipes
{

private $ttyMode;

private $ptyMode;

private $disableOutput;

public function __construct($ttyMode, $ptyMode, $input, $disableOutput)
{
$this->ttyMode = (bool) $ttyMode;
$this->ptyMode = (bool) $ptyMode;
$this->disableOutput = (bool) $disableOutput;

parent::__construct($input);
}

public function __destruct()
{
$this->close();
}




public function getDescriptors()
{
if ($this->disableOutput) {
$nullstream = fopen('/dev/null', 'c');

return array(
array('pipe', 'r'),
$nullstream,
$nullstream,
);
}

if ($this->ttyMode) {
return array(
array('file', '/dev/tty', 'r'),
array('file', '/dev/tty', 'w'),
array('file', '/dev/tty', 'w'),
);
}

if ($this->ptyMode && Process::isPtySupported()) {
return array(
array('pty'),
array('pty'),
array('pty'),
);
}

return array(
array('pipe', 'r'),
array('pipe', 'w'), 
 array('pipe', 'w'), 
 );
}




public function getFiles()
{
return array();
}




public function readAndWrite($blocking, $close = false)
{
$this->unblock();
$w = $this->write();

$read = $e = array();
$r = $this->pipes;
unset($r[0]);


 if (($r || $w) && false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {

 
 if (!$this->hasSystemCallBeenInterrupted()) {
$this->pipes = array();
}

return $read;
}

foreach ($r as $pipe) {

 
 $read[$type = array_search($pipe, $this->pipes, true)] = '';

do {
$data = fread($pipe, self::CHUNK_SIZE);
$read[$type] .= $data;
} while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));

if (!isset($read[$type][0])) {
unset($read[$type]);
}

if ($close && feof($pipe)) {
fclose($pipe);
unset($this->pipes[$type]);
}
}

return $read;
}




public function areOpen()
{
return (bool) $this->pipes;
}









public static function create(Process $process, $input)
{
return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled());
}
}
<?php










namespace Symfony\Component\Process\Pipes;








interface PipesInterface
{
const CHUNK_SIZE = 16384;






public function getDescriptors();






public function getFiles();









public function readAndWrite($blocking, $close = false);






public function areOpen();




public function close();
}
<?php










namespace Symfony\Component\Process;

use Symfony\Component\Process\Exception\InvalidArgumentException;








class ProcessUtils
{



private function __construct()
{
}








public static function escapeArgument($argument)
{

 
 
 
 if ('\\' === DIRECTORY_SEPARATOR) {
if ('' === $argument) {
return escapeshellarg($argument);
}

$escapedArgument = '';
$quote = false;
foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
if ('"' === $part) {
$escapedArgument .= '\\"';
} elseif (self::isSurroundedBy($part, '%')) {

 $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
} else {

 if ('\\' === substr($part, -1)) {
$part .= '\\';
}
$quote = true;
$escapedArgument .= $part;
}
}
if ($quote) {
$escapedArgument = '"'.$escapedArgument.'"';
}

return $escapedArgument;
}

return "'".str_replace("'", "'\\''", $argument)."'";
}













public static function validateInput($caller, $input)
{
if (null !== $input) {
if (is_resource($input)) {
return $input;
}
if (is_string($input)) {
return $input;
}
if (is_scalar($input)) {
return (string) $input;
}

 if (is_object($input) && method_exists($input, '__toString')) {
@trigger_error('Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);

return (string) $input;
}

throw new InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller));
}

return $input;
}

private static function isSurroundedBy($arg, $char)
{
return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
}
}
<?php










namespace Symfony\Component\Process\Exception;






class LogicException extends \LogicException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Process\Exception;

use Symfony\Component\Process\Process;






class ProcessTimedOutException extends RuntimeException
{
const TYPE_GENERAL = 1;
const TYPE_IDLE = 2;

private $process;
private $timeoutType;

public function __construct(Process $process, $timeoutType)
{
$this->process = $process;
$this->timeoutType = $timeoutType;

parent::__construct(sprintf(
'The process "%s" exceeded the timeout of %s seconds.',
$process->getCommandLine(),
$this->getExceededTimeout()
));
}

public function getProcess()
{
return $this->process;
}

public function isGeneralTimeout()
{
return $this->timeoutType === self::TYPE_GENERAL;
}

public function isIdleTimeout()
{
return $this->timeoutType === self::TYPE_IDLE;
}

public function getExceededTimeout()
{
switch ($this->timeoutType) {
case self::TYPE_GENERAL:
return $this->process->getTimeout();

case self::TYPE_IDLE:
return $this->process->getIdleTimeout();

default:
throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
}
}
}
<?php










namespace Symfony\Component\Process\Exception;






interface ExceptionInterface
{
}
<?php










namespace Symfony\Component\Process\Exception;






class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Process\Exception;

use Symfony\Component\Process\Process;






class ProcessFailedException extends RuntimeException
{
private $process;

public function __construct(Process $process)
{
if ($process->isSuccessful()) {
throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
}

$error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
$process->getCommandLine(),
$process->getExitCode(),
$process->getExitCodeText(),
$process->getWorkingDirectory()
);

if (!$process->isOutputDisabled()) {
$error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
$process->getOutput(),
$process->getErrorOutput()
);
}

parent::__construct($error);

$this->process = $process;
}

public function getProcess()
{
return $this->process;
}
}
<?php










namespace Symfony\Component\Process\Exception;






class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Console\Logger;

use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;








class ConsoleLogger extends AbstractLogger
{
const INFO = 'info';
const ERROR = 'error';




private $output;



private $verbosityLevelMap = array(
LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
);



private $formatLevelMap = array(
LogLevel::EMERGENCY => self::ERROR,
LogLevel::ALERT => self::ERROR,
LogLevel::CRITICAL => self::ERROR,
LogLevel::ERROR => self::ERROR,
LogLevel::WARNING => self::INFO,
LogLevel::NOTICE => self::INFO,
LogLevel::INFO => self::INFO,
LogLevel::DEBUG => self::INFO,
);






public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
{
$this->output = $output;
$this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
$this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
}




public function log($level, $message, array $context = array())
{
if (!isset($this->verbosityLevelMap[$level])) {
throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
}


 if ($this->formatLevelMap[$level] === self::ERROR && $this->output instanceof ConsoleOutputInterface) {
$output = $this->output->getErrorOutput();
} else {
$output = $this->output;
}

if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
$output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)));
}
}











private function interpolate($message, array $context)
{

 $replace = array();
foreach ($context as $key => $val) {
if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
$replace[sprintf('{%s}', $key)] = $val;
}
}


 return strtr($message, $replace);
}
}
<?php










namespace Symfony\Component\Console\Style;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\OutputInterface;






abstract class OutputStyle implements OutputInterface, StyleInterface
{
private $output;




public function __construct(OutputInterface $output)
{
$this->output = $output;
}




public function newLine($count = 1)
{
$this->output->write(str_repeat(PHP_EOL, $count));
}






public function createProgressBar($max = 0)
{
return new ProgressBar($this->output, $max);
}




public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
$this->output->write($messages, $newline, $type);
}




public function writeln($messages, $type = self::OUTPUT_NORMAL)
{
$this->output->writeln($messages, $type);
}




public function setVerbosity($level)
{
$this->output->setVerbosity($level);
}




public function getVerbosity()
{
return $this->output->getVerbosity();
}




public function setDecorated($decorated)
{
$this->output->setDecorated($decorated);
}




public function isDecorated()
{
return $this->output->isDecorated();
}




public function setFormatter(OutputFormatterInterface $formatter)
{
$this->output->setFormatter($formatter);
}




public function getFormatter()
{
return $this->output->getFormatter();
}
}
<?php










namespace Symfony\Component\Console\Style;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;






class SymfonyStyle extends OutputStyle
{
const MAX_LINE_LENGTH = 120;

private $input;
private $questionHelper;
private $progressBar;
private $lineLength;
private $bufferedOutput;





public function __construct(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());

 $this->lineLength = min($this->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);

parent::__construct($output);
}










public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
{
$messages = is_array($messages) ? array_values($messages) : array($messages);

$this->autoPrependBlock();
$this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, true));
$this->newLine();
}




public function title($message)
{
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
sprintf('<comment>%s</>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
));
$this->newLine();
}




public function section($message)
{
$this->autoPrependBlock();
$this->writeln(array(
sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
sprintf('<comment>%s</>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
));
$this->newLine();
}




public function listing(array $elements)
{
$this->autoPrependText();
$elements = array_map(function ($element) {
return sprintf(' * %s', $element);
}, $elements);

$this->writeln($elements);
$this->newLine();
}




public function text($message)
{
$this->autoPrependText();

$messages = is_array($message) ? array_values($message) : array($message);
foreach ($messages as $message) {
$this->writeln(sprintf(' %s', $message));
}
}






public function comment($message)
{
$messages = is_array($message) ? array_values($message) : array($message);

$this->autoPrependBlock();
$this->writeln($this->createBlock($messages, null, null, '<fg=default;bg=default> // </>'));
$this->newLine();
}




public function success($message)
{
$this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
}




public function error($message)
{
$this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
}




public function warning($message)
{
$this->block($message, 'WARNING', 'fg=white;bg=red', ' ', true);
}




public function note($message)
{
$this->block($message, 'NOTE', 'fg=yellow', ' ! ');
}




public function caution($message)
{
$this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
}




public function table(array $headers, array $rows)
{
$style = clone Table::getStyleDefinition('symfony-style-guide');
$style->setCellHeaderFormat('<info>%s</info>');

$table = new Table($this);
$table->setHeaders($headers);
$table->setRows($rows);
$table->setStyle($style);

$table->render();
$this->newLine();
}




public function ask($question, $default = null, $validator = null)
{
$question = new Question($question, $default);
$question->setValidator($validator);

return $this->askQuestion($question);
}




public function askHidden($question, $validator = null)
{
$question = new Question($question);

$question->setHidden(true);
$question->setValidator($validator);

return $this->askQuestion($question);
}




public function confirm($question, $default = true)
{
return $this->askQuestion(new ConfirmationQuestion($question, $default));
}




public function choice($question, array $choices, $default = null)
{
if (null !== $default) {
$values = array_flip($choices);
$default = $values[$default];
}

return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
}




public function progressStart($max = 0)
{
$this->progressBar = $this->createProgressBar($max);
$this->progressBar->start();
}




public function progressAdvance($step = 1)
{
$this->getProgressBar()->advance($step);
}




public function progressFinish()
{
$this->getProgressBar()->finish();
$this->newLine(2);
$this->progressBar = null;
}




public function createProgressBar($max = 0)
{
$progressBar = parent::createProgressBar($max);

if ('\\' !== DIRECTORY_SEPARATOR) {
$progressBar->setEmptyBarCharacter('░'); 
 $progressBar->setProgressCharacter('');
$progressBar->setBarCharacter('▓'); 
 }

return $progressBar;
}






public function askQuestion(Question $question)
{
if ($this->input->isInteractive()) {
$this->autoPrependBlock();
}

if (!$this->questionHelper) {
$this->questionHelper = new SymfonyQuestionHelper();
}

$answer = $this->questionHelper->ask($this->input, $this, $question);

if ($this->input->isInteractive()) {
$this->newLine();
$this->bufferedOutput->write("\n");
}

return $answer;
}




public function writeln($messages, $type = self::OUTPUT_NORMAL)
{
parent::writeln($messages, $type);
$this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
}




public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
parent::write($messages, $newline, $type);
$this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
}




public function newLine($count = 1)
{
parent::newLine($count);
$this->bufferedOutput->write(str_repeat("\n", $count));
}




private function getProgressBar()
{
if (!$this->progressBar) {
throw new RuntimeException('The ProgressBar is not started.');
}

return $this->progressBar;
}

private function getTerminalWidth()
{
$application = new Application();
$dimensions = $application->getTerminalDimensions();

return $dimensions[0] ?: self::MAX_LINE_LENGTH;
}

private function autoPrependBlock()
{
$chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);

if (!isset($chars[0])) {
return $this->newLine(); 
 }

 $this->newLine(2 - substr_count($chars, "\n"));
}

private function autoPrependText()
{
$fetched = $this->bufferedOutput->fetch();

 if ("\n" !== substr($fetched, -1)) {
$this->newLine();
}
}

private function reduceBuffer($messages)
{

 
 return array_map(function ($value) {
return substr($value, -4);
}, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
}

private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
{
$indentLength = 0;
$prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
$lines = array();

if (null !== $type) {
$type = sprintf('[%s] ', $type);
$indentLength = strlen($type);
$lineIndentation = str_repeat(' ', $indentLength);
}


 foreach ($messages as $key => $message) {
if ($escape) {
$message = OutputFormatter::escape($message);
}

$lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true)));

if (count($messages) > 1 && $key < count($messages) - 1) {
$lines[] = '';
}
}

$firstLineIndex = 0;
if ($padding && $this->isDecorated()) {
$firstLineIndex = 1;
array_unshift($lines, '');
$lines[] = '';
}

foreach ($lines as $i => &$line) {
if (null !== $type) {
$line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
}

$line = $prefix.$line;
$line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));

if ($style) {
$line = sprintf('<%s>%s</>', $style, $line);
}
}

return $lines;
}
}
<?php










namespace Symfony\Component\Console\Style;






interface StyleInterface
{





public function title($message);






public function section($message);






public function listing(array $elements);






public function text($message);






public function success($message);






public function error($message);






public function warning($message);






public function note($message);






public function caution($message);







public function table(array $headers, array $rows);










public function ask($question, $default = null, $validator = null);









public function askHidden($question, $validator = null);









public function confirm($question, $default = true);










public function choice($question, array $choices, $default = null);






public function newLine($count = 1);






public function progressStart($max = 0);






public function progressAdvance($step = 1);




public function progressFinish();
}
<?php










namespace Symfony\Component\Console;






final class ConsoleEvents
{












const COMMAND = 'console.command';












const TERMINATE = 'console.terminate';













const EXCEPTION = 'console.exception';
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\CommandNotFoundException;






class ApplicationDescription
{
const GLOBAL_NAMESPACE = '_global';




private $application;




private $namespace;




private $namespaces;




private $commands;




private $aliases;







public function __construct(Application $application, $namespace = null)
{
$this->application = $application;
$this->namespace = $namespace;
}




public function getNamespaces()
{
if (null === $this->namespaces) {
$this->inspectApplication();
}

return $this->namespaces;
}




public function getCommands()
{
if (null === $this->commands) {
$this->inspectApplication();
}

return $this->commands;
}








public function getCommand($name)
{
if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
throw new CommandNotFoundException(sprintf('Command %s does not exist.', $name));
}

return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
}

private function inspectApplication()
{
$this->commands = array();
$this->namespaces = array();

$all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
foreach ($this->sortCommands($all) as $namespace => $commands) {
$names = array();


foreach ($commands as $name => $command) {
if (!$command->getName()) {
continue;
}

if ($command->getName() === $name) {
$this->commands[$name] = $command;
} else {
$this->aliases[$name] = $command;
}

$names[] = $name;
}

$this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
}
}






private function sortCommands(array $commands)
{
$namespacedCommands = array();
$globalCommands = array();
foreach ($commands as $name => $command) {
$key = $this->application->extractNamespace($name, 1);
if (!$key) {
$globalCommands['_global'][$name] = $command;
} else {
$namespacedCommands[$key][$name] = $command;
}
}
ksort($namespacedCommands);
$namespacedCommands = array_merge($globalCommands, $namespacedCommands);

foreach ($namespacedCommands as &$commandsSet) {
ksort($commandsSet);
}

 unset($commandsSet);

return $namespacedCommands;
}
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;








class TextDescriptor extends Descriptor
{



protected function describeInputArgument(InputArgument $argument, array $options = array())
{
if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
$default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
} else {
$default = '';
}

$totalWidth = isset($options['total_width']) ? $options['total_width'] : Helper::strlen($argument->getName());
$spacingWidth = $totalWidth - strlen($argument->getName());

$this->writeText(sprintf('  <info>%s</info>  %s%s%s',
$argument->getName(),
str_repeat(' ', $spacingWidth),

 preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
$default
), $options);
}




protected function describeInputOption(InputOption $option, array $options = array())
{
if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
$default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
} else {
$default = '';
}

$value = '';
if ($option->acceptValue()) {
$value = '='.strtoupper($option->getName());

if ($option->isValueOptional()) {
$value = '['.$value.']';
}
}

$totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions(array($option));
$synopsis = sprintf('%s%s',
$option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ',
sprintf('--%s%s', $option->getName(), $value)
);

$spacingWidth = $totalWidth - Helper::strlen($synopsis);

$this->writeText(sprintf('  <info>%s</info>  %s%s%s%s',
$synopsis,
str_repeat(' ', $spacingWidth),

 preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
$default,
$option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
), $options);
}




protected function describeInputDefinition(InputDefinition $definition, array $options = array())
{
$totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
foreach ($definition->getArguments() as $argument) {
$totalWidth = max($totalWidth, Helper::strlen($argument->getName()));
}

if ($definition->getArguments()) {
$this->writeText('<comment>Arguments:</comment>', $options);
$this->writeText("\n");
foreach ($definition->getArguments() as $argument) {
$this->describeInputArgument($argument, array_merge($options, array('total_width' => $totalWidth)));
$this->writeText("\n");
}
}

if ($definition->getArguments() && $definition->getOptions()) {
$this->writeText("\n");
}

if ($definition->getOptions()) {
$laterOptions = array();

$this->writeText('<comment>Options:</comment>', $options);
foreach ($definition->getOptions() as $option) {
if (strlen($option->getShortcut()) > 1) {
$laterOptions[] = $option;
continue;
}
$this->writeText("\n");
$this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
}
foreach ($laterOptions as $option) {
$this->writeText("\n");
$this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
}
}
}




protected function describeCommand(Command $command, array $options = array())
{
$command->getSynopsis(true);
$command->getSynopsis(false);
$command->mergeApplicationDefinition(false);

$this->writeText('<comment>Usage:</comment>', $options);
foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
$this->writeText("\n");
$this->writeText('  '.$usage, $options);
}
$this->writeText("\n");

$definition = $command->getNativeDefinition();
if ($definition->getOptions() || $definition->getArguments()) {
$this->writeText("\n");
$this->describeInputDefinition($definition, $options);
$this->writeText("\n");
}

if ($help = $command->getProcessedHelp()) {
$this->writeText("\n");
$this->writeText('<comment>Help:</comment>', $options);
$this->writeText("\n");
$this->writeText('  '.str_replace("\n", "\n  ", $help), $options);
$this->writeText("\n");
}
}




protected function describeApplication(Application $application, array $options = array())
{
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace);

if (isset($options['raw_text']) && $options['raw_text']) {
$width = $this->getColumnWidth($description->getCommands());

foreach ($description->getCommands() as $command) {
$this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
$this->writeText("\n");
}
} else {
if ('' != $help = $application->getHelp()) {
$this->writeText("$help\n\n", $options);
}

$this->writeText("<comment>Usage:</comment>\n", $options);
$this->writeText("  command [options] [arguments]\n\n", $options);

$this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);

$this->writeText("\n");
$this->writeText("\n");

$width = $this->getColumnWidth($description->getCommands());

if ($describedNamespace) {
$this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
} else {
$this->writeText('<comment>Available commands:</comment>', $options);
}


 foreach ($description->getNamespaces() as $namespace) {
if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
$this->writeText("\n");
$this->writeText(' <comment>'.$namespace['id'].'</comment>', $options);
}

foreach ($namespace['commands'] as $name) {
$this->writeText("\n");
$spacingWidth = $width - Helper::strlen($name);
$this->writeText(sprintf('  <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
}
}

$this->writeText("\n");
}
}




private function writeText($content, array $options = array())
{
$this->write(
isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
isset($options['raw_output']) ? !$options['raw_output'] : true
);
}








private function formatDefaultValue($default)
{
if (is_string($default)) {
$default = OutputFormatter::escape($default);
} elseif (is_array($default)) {
foreach ($default as $key => $value) {
if (is_string($value)) {
$default[$key] = OutputFormatter::escape($value);
}
}
}

if (PHP_VERSION_ID < 50400) {
return str_replace(array('\/', '\\\\'), array('/', '\\'), json_encode($default));
}

return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
}






private function getColumnWidth(array $commands)
{
$widths = array();

foreach ($commands as $command) {
$widths[] = Helper::strlen($command->getName());
foreach ($command->getAliases() as $alias) {
$widths[] = Helper::strlen($alias);
}
}

return max($widths) + 2;
}






private function calculateTotalWidthForOptions($options)
{
$totalWidth = 0;
foreach ($options as $option) {

 $nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName());

if ($option->acceptValue()) {
$valueLength = 1 + Helper::strlen($option->getName()); 
 $valueLength += $option->isValueOptional() ? 2 : 0; 

$nameLength += $valueLength;
}
$totalWidth = max($totalWidth, $nameLength);
}

return $totalWidth;
}
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;








class JsonDescriptor extends Descriptor
{



protected function describeInputArgument(InputArgument $argument, array $options = array())
{
$this->writeData($this->getInputArgumentData($argument), $options);
}




protected function describeInputOption(InputOption $option, array $options = array())
{
$this->writeData($this->getInputOptionData($option), $options);
}




protected function describeInputDefinition(InputDefinition $definition, array $options = array())
{
$this->writeData($this->getInputDefinitionData($definition), $options);
}




protected function describeCommand(Command $command, array $options = array())
{
$this->writeData($this->getCommandData($command), $options);
}




protected function describeApplication(Application $application, array $options = array())
{
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace);
$commands = array();

foreach ($description->getCommands() as $command) {
$commands[] = $this->getCommandData($command);
}

$data = $describedNamespace
? array('commands' => $commands, 'namespace' => $describedNamespace)
: array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));

$this->writeData($data, $options);
}









private function writeData(array $data, array $options)
{
$this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0));
}






private function getInputArgumentData(InputArgument $argument)
{
return array(
'name' => $argument->getName(),
'is_required' => $argument->isRequired(),
'is_array' => $argument->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
'default' => $argument->getDefault(),
);
}






private function getInputOptionData(InputOption $option)
{
return array(
'name' => '--'.$option->getName(),
'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
'accept_value' => $option->acceptValue(),
'is_value_required' => $option->isValueRequired(),
'is_multiple' => $option->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
'default' => $option->getDefault(),
);
}






private function getInputDefinitionData(InputDefinition $definition)
{
$inputArguments = array();
foreach ($definition->getArguments() as $name => $argument) {
$inputArguments[$name] = $this->getInputArgumentData($argument);
}

$inputOptions = array();
foreach ($definition->getOptions() as $name => $option) {
$inputOptions[$name] = $this->getInputOptionData($option);
}

return array('arguments' => $inputArguments, 'options' => $inputOptions);
}






private function getCommandData(Command $command)
{
$command->getSynopsis();
$command->mergeApplicationDefinition(false);

return array(
'name' => $command->getName(),
'usage' => array_merge(array($command->getSynopsis()), $command->getUsages(), $command->getAliases()),
'description' => $command->getDescription(),
'help' => $command->getProcessedHelp(),
'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
);
}
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Output\OutputInterface;






interface DescriptorInterface
{







public function describe(OutputInterface $output, $object, array $options = array());
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;








class MarkdownDescriptor extends Descriptor
{



protected function describeInputArgument(InputArgument $argument, array $options = array())
{
$this->write(
'**'.$argument->getName().':**'."\n\n"
.'* Name: '.($argument->getName() ?: '<none>')."\n"
.'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
.'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
.'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n  ", $argument->getDescription() ?: '<none>')."\n"
.'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
);
}




protected function describeInputOption(InputOption $option, array $options = array())
{
$this->write(
'**'.$option->getName().':**'."\n\n"
.'* Name: `--'.$option->getName().'`'."\n"
.'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '<none>')."\n"
.'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
.'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
.'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
.'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n  ", $option->getDescription() ?: '<none>')."\n"
.'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
);
}




protected function describeInputDefinition(InputDefinition $definition, array $options = array())
{
if ($showArguments = count($definition->getArguments()) > 0) {
$this->write('### Arguments:');
foreach ($definition->getArguments() as $argument) {
$this->write("\n\n");
$this->write($this->describeInputArgument($argument));
}
}

if (count($definition->getOptions()) > 0) {
if ($showArguments) {
$this->write("\n\n");
}

$this->write('### Options:');
foreach ($definition->getOptions() as $option) {
$this->write("\n\n");
$this->write($this->describeInputOption($option));
}
}
}




protected function describeCommand(Command $command, array $options = array())
{
$command->getSynopsis();
$command->mergeApplicationDefinition(false);

$this->write(
$command->getName()."\n"
.str_repeat('-', Helper::strlen($command->getName()))."\n\n"
.'* Description: '.($command->getDescription() ?: '<none>')."\n"
.'* Usage:'."\n\n"
.array_reduce(array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
return $carry.'  * `'.$usage.'`'."\n";
})
);

if ($help = $command->getProcessedHelp()) {
$this->write("\n");
$this->write($help);
}

if ($command->getNativeDefinition()) {
$this->write("\n\n");
$this->describeInputDefinition($command->getNativeDefinition());
}
}




protected function describeApplication(Application $application, array $options = array())
{
$describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
$description = new ApplicationDescription($application, $describedNamespace);

$this->write($application->getName()."\n".str_repeat('=', Helper::strlen($application->getName())));

foreach ($description->getNamespaces() as $namespace) {
if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
$this->write("\n\n");
$this->write('**'.$namespace['id'].':**');
}

$this->write("\n\n");
$this->write(implode("\n", array_map(function ($commandName) {
return '* '.$commandName;
}, $namespace['commands'])));
}

foreach ($description->getCommands() as $command) {
$this->write("\n\n");
$this->write($this->describeCommand($command));
}
}
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;








class XmlDescriptor extends Descriptor
{





public function getInputDefinitionDocument(InputDefinition $definition)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($definitionXML = $dom->createElement('definition'));

$definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
foreach ($definition->getArguments() as $argument) {
$this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
}

$definitionXML->appendChild($optionsXML = $dom->createElement('options'));
foreach ($definition->getOptions() as $option) {
$this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
}

return $dom;
}






public function getCommandDocument(Command $command)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($commandXML = $dom->createElement('command'));

$command->getSynopsis();
$command->mergeApplicationDefinition(false);

$commandXML->setAttribute('id', $command->getName());
$commandXML->setAttribute('name', $command->getName());

$commandXML->appendChild($usagesXML = $dom->createElement('usages'));

foreach (array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()) as $usage) {
$usagesXML->appendChild($dom->createElement('usage', $usage));
}

$commandXML->appendChild($descriptionXML = $dom->createElement('description'));
$descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));

$commandXML->appendChild($helpXML = $dom->createElement('help'));
$helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));

$definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition());
$this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));

return $dom;
}







public function getApplicationDocument(Application $application, $namespace = null)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($rootXml = $dom->createElement('symfony'));

if ($application->getName() !== 'UNKNOWN') {
$rootXml->setAttribute('name', $application->getName());
if ($application->getVersion() !== 'UNKNOWN') {
$rootXml->setAttribute('version', $application->getVersion());
}
}

$rootXml->appendChild($commandsXML = $dom->createElement('commands'));

$description = new ApplicationDescription($application, $namespace);

if ($namespace) {
$commandsXML->setAttribute('namespace', $namespace);
}

foreach ($description->getCommands() as $command) {
$this->appendDocument($commandsXML, $this->getCommandDocument($command));
}

if (!$namespace) {
$rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));

foreach ($description->getNamespaces() as $namespaceDescription) {
$namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
$namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);

foreach ($namespaceDescription['commands'] as $name) {
$namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
$commandXML->appendChild($dom->createTextNode($name));
}
}
}

return $dom;
}




protected function describeInputArgument(InputArgument $argument, array $options = array())
{
$this->writeDocument($this->getInputArgumentDocument($argument));
}




protected function describeInputOption(InputOption $option, array $options = array())
{
$this->writeDocument($this->getInputOptionDocument($option));
}




protected function describeInputDefinition(InputDefinition $definition, array $options = array())
{
$this->writeDocument($this->getInputDefinitionDocument($definition));
}




protected function describeCommand(Command $command, array $options = array())
{
$this->writeDocument($this->getCommandDocument($command));
}




protected function describeApplication(Application $application, array $options = array())
{
$this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null));
}







private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
{
foreach ($importedParent->childNodes as $childNode) {
$parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
}
}








private function writeDocument(\DOMDocument $dom)
{
$dom->formatOutput = true;
$this->write($dom->saveXML());
}






private function getInputArgumentDocument(InputArgument $argument)
{
$dom = new \DOMDocument('1.0', 'UTF-8');

$dom->appendChild($objectXML = $dom->createElement('argument'));
$objectXML->setAttribute('name', $argument->getName());
$objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
$objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
$objectXML->appendChild($descriptionXML = $dom->createElement('description'));
$descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));

$objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
$defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
foreach ($defaults as $default) {
$defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
$defaultXML->appendChild($dom->createTextNode($default));
}

return $dom;
}






private function getInputOptionDocument(InputOption $option)
{
$dom = new \DOMDocument('1.0', 'UTF-8');

$dom->appendChild($objectXML = $dom->createElement('option'));
$objectXML->setAttribute('name', '--'.$option->getName());
$pos = strpos($option->getShortcut(), '|');
if (false !== $pos) {
$objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
$objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
} else {
$objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
}
$objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
$objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
$objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
$objectXML->appendChild($descriptionXML = $dom->createElement('description'));
$descriptionXML->appendChild($dom->createTextNode($option->getDescription()));

if ($option->acceptValue()) {
$defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
$objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));

if (!empty($defaults)) {
foreach ($defaults as $default) {
$defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
$defaultXML->appendChild($dom->createTextNode($default));
}
}
}

return $dom;
}
}
<?php










namespace Symfony\Component\Console\Descriptor;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;






abstract class Descriptor implements DescriptorInterface
{



private $output;




public function describe(OutputInterface $output, $object, array $options = array())
{
$this->output = $output;

switch (true) {
case $object instanceof InputArgument:
$this->describeInputArgument($object, $options);
break;
case $object instanceof InputOption:
$this->describeInputOption($object, $options);
break;
case $object instanceof InputDefinition:
$this->describeInputDefinition($object, $options);
break;
case $object instanceof Command:
$this->describeCommand($object, $options);
break;
case $object instanceof Application:
$this->describeApplication($object, $options);
break;
default:
throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
}
}







protected function write($content, $decorated = false)
{
$this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
}









abstract protected function describeInputArgument(InputArgument $argument, array $options = array());









abstract protected function describeInputOption(InputOption $option, array $options = array());









abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());









abstract protected function describeCommand(Command $command, array $options = array());









abstract protected function describeApplication(Application $application, array $options = array());
}
<?php










namespace Symfony\Component\Console;

use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Process\ProcessBuilder;
use Symfony\Component\Process\PhpExecutableFinder;












class Shell
{
private $application;
private $history;
private $output;
private $hasReadline;
private $processIsolation = false;









public function __construct(Application $application)
{
@trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

$this->hasReadline = function_exists('readline');
$this->application = $application;
$this->history = getenv('HOME').'/.history_'.$application->getName();
$this->output = new ConsoleOutput();
}




public function run()
{
$this->application->setAutoExit(false);
$this->application->setCatchExceptions(true);

if ($this->hasReadline) {
readline_read_history($this->history);
readline_completion_function(array($this, 'autocompleter'));
}

$this->output->writeln($this->getHeader());
$php = null;
if ($this->processIsolation) {
$finder = new PhpExecutableFinder();
$php = $finder->find();
$this->output->writeln(<<<'EOF'
<info>Running with process isolation, you should consider this:</info>
  * each command is executed as separate process,
  * commands don't support interactivity, all params must be passed explicitly,
  * commands output is not colorized.

EOF
);
}

while (true) {
$command = $this->readline();

if (false === $command) {
$this->output->writeln("\n");

break;
}

if ($this->hasReadline) {
readline_add_history($command);
readline_write_history($this->history);
}

if ($this->processIsolation) {
$pb = new ProcessBuilder();

$process = $pb
->add($php)
->add($_SERVER['argv'][0])
->add($command)
->inheritEnvironmentVariables(true)
->getProcess()
;

$output = $this->output;
$process->run(function ($type, $data) use ($output) {
$output->writeln($data);
});

$ret = $process->getExitCode();
} else {
$ret = $this->application->run(new StringInput($command), $this->output);
}

if (0 !== $ret) {
$this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
}
}
}






protected function getHeader()
{
return <<<EOF

Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).

At the prompt, type <comment>help</comment> for some help,
or <comment>list</comment> to get a list of available commands.

To exit the shell, type <comment>^D</comment>.

EOF;
}






protected function getPrompt()
{

 return $this->output->getFormatter()->format($this->application->getName().' > ');
}

protected function getOutput()
{
return $this->output;
}

protected function getApplication()
{
return $this->application;
}








private function autocompleter($text)
{
$info = readline_info();
$text = substr($info['line_buffer'], 0, $info['end']);

if ($info['point'] !== $info['end']) {
return true;
}


 if (false === strpos($text, ' ') || !$text) {
return array_keys($this->application->all());
}


 try {
$command = $this->application->find(substr($text, 0, strpos($text, ' ')));
} catch (\Exception $e) {
return true;
}

$list = array('--help');
foreach ($command->getDefinition()->getOptions() as $option) {
$list[] = '--'.$option->getName();
}

return $list;
}






private function readline()
{
if ($this->hasReadline) {
$line = readline($this->getPrompt());
} else {
$this->output->write($this->getPrompt());
$line = fgets(STDIN, 1024);
$line = (false === $line || '' === $line) ? false : rtrim($line);
}

return $line;
}

public function getProcessIsolation()
{
return $this->processIsolation;
}

public function setProcessIsolation($processIsolation)
{
$this->processIsolation = (bool) $processIsolation;

if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
throw new RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
}
}
}
<?php










namespace Symfony\Component\Console\Question;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;






class Question
{
private $question;
private $attempts;
private $hidden = false;
private $hiddenFallback = true;
private $autocompleterValues;
private $validator;
private $default;
private $normalizer;







public function __construct($question, $default = null)
{
$this->question = $question;
$this->default = $default;
}






public function getQuestion()
{
return $this->question;
}






public function getDefault()
{
return $this->default;
}






public function isHidden()
{
return $this->hidden;
}










public function setHidden($hidden)
{
if ($this->autocompleterValues) {
throw new LogicException('A hidden question cannot use the autocompleter.');
}

$this->hidden = (bool) $hidden;

return $this;
}






public function isHiddenFallback()
{
return $this->hiddenFallback;
}








public function setHiddenFallback($fallback)
{
$this->hiddenFallback = (bool) $fallback;

return $this;
}






public function getAutocompleterValues()
{
return $this->autocompleterValues;
}











public function setAutocompleterValues($values)
{
if (is_array($values)) {
$values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
}

if (null !== $values && !is_array($values)) {
if (!$values instanceof \Traversable || !$values instanceof \Countable) {
throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
}
}

if ($this->hidden) {
throw new LogicException('A hidden question cannot use the autocompleter.');
}

$this->autocompleterValues = $values;

return $this;
}








public function setValidator($validator)
{
$this->validator = $validator;

return $this;
}






public function getValidator()
{
return $this->validator;
}












public function setMaxAttempts($attempts)
{
if (null !== $attempts && $attempts < 1) {
throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
}

$this->attempts = $attempts;

return $this;
}








public function getMaxAttempts()
{
return $this->attempts;
}










public function setNormalizer($normalizer)
{
$this->normalizer = $normalizer;

return $this;
}








public function getNormalizer()
{
return $this->normalizer;
}

protected function isAssoc($array)
{
return (bool) count(array_filter(array_keys($array), 'is_string'));
}
}
<?php










namespace Symfony\Component\Console\Question;






class ConfirmationQuestion extends Question
{
private $trueAnswerRegex;








public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')
{
parent::__construct($question, (bool) $default);

$this->trueAnswerRegex = $trueAnswerRegex;
$this->setNormalizer($this->getDefaultNormalizer());
}






private function getDefaultNormalizer()
{
$default = $this->getDefault();
$regex = $this->trueAnswerRegex;

return function ($answer) use ($default, $regex) {
if (is_bool($answer)) {
return $answer;
}

$answerIsTrue = (bool) preg_match($regex, $answer);
if (false === $default) {
return $answer && $answerIsTrue;
}

return !$answer || $answerIsTrue;
};
}
}
<?php










namespace Symfony\Component\Console\Question;

use Symfony\Component\Console\Exception\InvalidArgumentException;






class ChoiceQuestion extends Question
{
private $choices;
private $multiselect = false;
private $prompt = ' > ';
private $errorMessage = 'Value "%s" is invalid';








public function __construct($question, array $choices, $default = null)
{
parent::__construct($question, $default);

$this->choices = $choices;
$this->setValidator($this->getDefaultValidator());
$this->setAutocompleterValues($choices);
}






public function getChoices()
{
return $this->choices;
}










public function setMultiselect($multiselect)
{
$this->multiselect = $multiselect;
$this->setValidator($this->getDefaultValidator());

return $this;
}






public function isMultiselect()
{
return $this->multiselect;
}






public function getPrompt()
{
return $this->prompt;
}








public function setPrompt($prompt)
{
$this->prompt = $prompt;

return $this;
}










public function setErrorMessage($errorMessage)
{
$this->errorMessage = $errorMessage;
$this->setValidator($this->getDefaultValidator());

return $this;
}






private function getDefaultValidator()
{
$choices = $this->choices;
$errorMessage = $this->errorMessage;
$multiselect = $this->multiselect;
$isAssoc = $this->isAssoc($choices);

return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {

 $selectedChoices = str_replace(' ', '', $selected);

if ($multiselect) {

 if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
throw new InvalidArgumentException(sprintf($errorMessage, $selected));
}
$selectedChoices = explode(',', $selectedChoices);
} else {
$selectedChoices = array($selected);
}

$multiselectChoices = array();
foreach ($selectedChoices as $value) {
$results = array();
foreach ($choices as $key => $choice) {
if ($choice === $value) {
$results[] = $key;
}
}

if (count($results) > 1) {
throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
}

$result = array_search($value, $choices);

if (!$isAssoc) {
if (false !== $result) {
$result = $choices[$result];
} elseif (isset($choices[$value])) {
$result = $choices[$value];
}
} elseif (false === $result && isset($choices[$value])) {
$result = $value;
}

if (false === $result) {
throw new InvalidArgumentException(sprintf($errorMessage, $value));
}

$multiselectChoices[] = (string) $result;
}

if ($multiselect) {
return $multiselectChoices;
}

return current($multiselectChoices);
};
}
}
<?php










namespace Symfony\Component\Console\Tester;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;






class CommandTester
{
private $command;
private $input;
private $output;
private $statusCode;






public function __construct(Command $command)
{
$this->command = $command;
}















public function execute(array $input, array $options = array())
{

 
 if (!isset($input['command'])
&& (null !== $application = $this->command->getApplication())
&& $application->getDefinition()->hasArgument('command')
) {
$input = array_merge(array('command' => $this->command->getName()), $input);
}

$this->input = new ArrayInput($input);
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}

$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated'])) {
$this->output->setDecorated($options['decorated']);
}
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}

return $this->statusCode = $this->command->run($this->input, $this->output);
}








public function getDisplay($normalize = false)
{
rewind($this->output->getStream());

$display = stream_get_contents($this->output->getStream());

if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}

return $display;
}






public function getInput()
{
return $this->input;
}






public function getOutput()
{
return $this->output;
}






public function getStatusCode()
{
return $this->statusCode;
}
}
<?php










namespace Symfony\Component\Console\Tester;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;











class ApplicationTester
{
private $application;
private $input;
private $output;
private $statusCode;






public function __construct(Application $application)
{
$this->application = $application;
}















public function run(array $input, $options = array())
{
$this->input = new ArrayInput($input);
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}

$this->output = new StreamOutput(fopen('php://memory', 'w', false));
if (isset($options['decorated'])) {
$this->output->setDecorated($options['decorated']);
}
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}

return $this->statusCode = $this->application->run($this->input, $this->output);
}








public function getDisplay($normalize = false)
{
rewind($this->output->getStream());

$display = stream_get_contents($this->output->getStream());

if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}

return $display;
}






public function getInput()
{
return $this->input;
}






public function getOutput()
{
return $this->output;
}






public function getStatusCode()
{
return $this->statusCode;
}
}
<?php










namespace Symfony\Component\Console;

use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Helper\ProgressHelper;
use Symfony\Component\Console\Helper\TableHelper;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
















class Application
{
private $commands = array();
private $wantHelps = false;
private $runningCommand;
private $name;
private $version;
private $catchExceptions = true;
private $autoExit = true;
private $definition;
private $helperSet;
private $dispatcher;
private $terminalDimensions;
private $defaultCommand;







public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
{
$this->name = $name;
$this->version = $version;
$this->defaultCommand = 'list';
$this->helperSet = $this->getDefaultHelperSet();
$this->definition = $this->getDefaultInputDefinition();

foreach ($this->getDefaultCommands() as $command) {
$this->add($command);
}
}

public function setDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}









public function run(InputInterface $input = null, OutputInterface $output = null)
{
if (null === $input) {
$input = new ArgvInput();
}

if (null === $output) {
$output = new ConsoleOutput();
}

$this->configureIO($input, $output);

try {
$exitCode = $this->doRun($input, $output);
} catch (\Exception $e) {
if (!$this->catchExceptions) {
throw $e;
}

if ($output instanceof ConsoleOutputInterface) {
$this->renderException($e, $output->getErrorOutput());
} else {
$this->renderException($e, $output);
}

$exitCode = $e->getCode();
if (is_numeric($exitCode)) {
$exitCode = (int) $exitCode;
if (0 === $exitCode) {
$exitCode = 1;
}
} else {
$exitCode = 1;
}
}

if ($this->autoExit) {
if ($exitCode > 255) {
$exitCode = 255;
}

exit($exitCode);
}

return $exitCode;
}









public function doRun(InputInterface $input, OutputInterface $output)
{
if (true === $input->hasParameterOption(array('--version', '-V'))) {
$output->writeln($this->getLongVersion());

return 0;
}

$name = $this->getCommandName($input);
if (true === $input->hasParameterOption(array('--help', '-h'))) {
if (!$name) {
$name = 'help';
$input = new ArrayInput(array('command' => 'help'));
} else {
$this->wantHelps = true;
}
}

if (!$name) {
$name = $this->defaultCommand;
$input = new ArrayInput(array('command' => $this->defaultCommand));
}


 $command = $this->find($name);

$this->runningCommand = $command;
$exitCode = $this->doRunCommand($command, $input, $output);
$this->runningCommand = null;

return $exitCode;
}






public function setHelperSet(HelperSet $helperSet)
{
$this->helperSet = $helperSet;
}






public function getHelperSet()
{
return $this->helperSet;
}






public function setDefinition(InputDefinition $definition)
{
$this->definition = $definition;
}






public function getDefinition()
{
return $this->definition;
}






public function getHelp()
{
return $this->getLongVersion();
}






public function setCatchExceptions($boolean)
{
$this->catchExceptions = (bool) $boolean;
}






public function setAutoExit($boolean)
{
$this->autoExit = (bool) $boolean;
}






public function getName()
{
return $this->name;
}






public function setName($name)
{
$this->name = $name;
}






public function getVersion()
{
return $this->version;
}






public function setVersion($version)
{
$this->version = $version;
}






public function getLongVersion()
{
if ('UNKNOWN' !== $this->getName()) {
if ('UNKNOWN' !== $this->getVersion()) {
return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
}

return sprintf('<info>%s</info>', $this->getName());
}

return '<info>Console Tool</info>';
}








public function register($name)
{
return $this->add(new Command($name));
}








public function addCommands(array $commands)
{
foreach ($commands as $command) {
$this->add($command);
}
}











public function add(Command $command)
{
$command->setApplication($this);

if (!$command->isEnabled()) {
$command->setApplication(null);

return;
}

if (null === $command->getDefinition()) {
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
}

$this->commands[$command->getName()] = $command;

foreach ($command->getAliases() as $alias) {
$this->commands[$alias] = $command;
}

return $command;
}










public function get($name)
{
if (!isset($this->commands[$name])) {
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
}

$command = $this->commands[$name];

if ($this->wantHelps) {
$this->wantHelps = false;

$helpCommand = $this->get('help');
$helpCommand->setCommand($command);

return $helpCommand;
}

return $command;
}








public function has($name)
{
return isset($this->commands[$name]);
}








public function getNamespaces()
{
$namespaces = array();
foreach ($this->all() as $command) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));

foreach ($command->getAliases() as $alias) {
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
}
}

return array_values(array_unique(array_filter($namespaces)));
}










public function findNamespace($namespace)
{
$allNamespaces = $this->getNamespaces();
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace);
$namespaces = preg_grep('{^'.$expr.'}', $allNamespaces);

if (empty($namespaces)) {
$message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);

if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
if (1 == count($alternatives)) {
$message .= "\n\nDid you mean this?\n    ";
} else {
$message .= "\n\nDid you mean one of these?\n    ";
}

$message .= implode("\n    ", $alternatives);
}

throw new CommandNotFoundException($message, $alternatives);
}

$exact = in_array($namespace, $namespaces, true);
if (count($namespaces) > 1 && !$exact) {
throw new CommandNotFoundException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
}

return $exact ? $namespace : reset($namespaces);
}













public function find($name)
{
$allCommands = array_keys($this->commands);
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
$commands = preg_grep('{^'.$expr.'}', $allCommands);

if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) {
if (false !== $pos = strrpos($name, ':')) {

 $this->findNamespace(substr($name, 0, $pos));
}

$message = sprintf('Command "%s" is not defined.', $name);

if ($alternatives = $this->findAlternatives($name, $allCommands)) {
if (1 == count($alternatives)) {
$message .= "\n\nDid you mean this?\n    ";
} else {
$message .= "\n\nDid you mean one of these?\n    ";
}
$message .= implode("\n    ", $alternatives);
}

throw new CommandNotFoundException($message, $alternatives);
}


 if (count($commands) > 1) {
$commandList = $this->commands;
$commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
$commandName = $commandList[$nameOrAlias]->getName();

return $commandName === $nameOrAlias || !in_array($commandName, $commands);
});
}

$exact = in_array($name, $commands, true);
if (count($commands) > 1 && !$exact) {
$suggestions = $this->getAbbreviationSuggestions(array_values($commands));

throw new CommandNotFoundException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions), array_values($commands));
}

return $this->get($exact ? $name : reset($commands));
}










public function all($namespace = null)
{
if (null === $namespace) {
return $this->commands;
}

$commands = array();
foreach ($this->commands as $name => $command) {
if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
$commands[$name] = $command;
}
}

return $commands;
}








public static function getAbbreviations($names)
{
$abbrevs = array();
foreach ($names as $name) {
for ($len = strlen($name); $len > 0; --$len) {
$abbrev = substr($name, 0, $len);
$abbrevs[$abbrev][] = $name;
}
}

return $abbrevs;
}











public function asText($namespace = null, $raw = false)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);

$descriptor = new TextDescriptor();
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw);
$descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true));

return $output->fetch();
}











public function asXml($namespace = null, $asDom = false)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);

$descriptor = new XmlDescriptor();

if ($asDom) {
return $descriptor->getApplicationDocument($this, $namespace);
}

$output = new BufferedOutput();
$descriptor->describe($output, $this, array('namespace' => $namespace));

return $output->fetch();
}







public function renderException($e, $output)
{
$output->writeln('', OutputInterface::VERBOSITY_QUIET);

do {
$title = sprintf('  [%s]  ', get_class($e));

$len = $this->stringWidth($title);

$width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;

 if (defined('HHVM_VERSION') && $width > 1 << 31) {
$width = 1 << 31;
}
$formatter = $output->getFormatter();
$lines = array();
foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
foreach ($this->splitStringByWidth($line, $width - 4) as $line) {

 $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
$lines[] = array($line, $lineLength);

$len = max($lineLength, $len);
}
}

$messages = array();
$messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
foreach ($lines as $line) {
$messages[] = $formatter->format(sprintf('<error>  %s  %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
}
$messages[] = $emptyLine;
$messages[] = '';

$output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET);

if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
$output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);


 $trace = $e->getTrace();
array_unshift($trace, array(
'function' => '',
'file' => $e->getFile() !== null ? $e->getFile() : 'n/a',
'line' => $e->getLine() !== null ? $e->getLine() : 'n/a',
'args' => array(),
));

for ($i = 0, $count = count($trace); $i < $count; ++$i) {
$class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
$type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
$function = $trace[$i]['function'];
$file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
$line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';

$output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line), OutputInterface::VERBOSITY_QUIET);
}

$output->writeln('', OutputInterface::VERBOSITY_QUIET);
}
} while ($e = $e->getPrevious());

if (null !== $this->runningCommand) {
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
}
}






protected function getTerminalWidth()
{
$dimensions = $this->getTerminalDimensions();

return $dimensions[0];
}






protected function getTerminalHeight()
{
$dimensions = $this->getTerminalDimensions();

return $dimensions[1];
}






public function getTerminalDimensions()
{
if ($this->terminalDimensions) {
return $this->terminalDimensions;
}

if ('\\' === DIRECTORY_SEPARATOR) {

 if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
return array((int) $matches[1], (int) $matches[2]);
}

 if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
return array((int) $matches[1], (int) $matches[2]);
}
}

if ($sttyString = $this->getSttyColumns()) {

 if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
return array((int) $matches[2], (int) $matches[1]);
}

 if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
return array((int) $matches[2], (int) $matches[1]);
}
}

return array(null, null);
}











public function setTerminalDimensions($width, $height)
{
$this->terminalDimensions = array($width, $height);

return $this;
}







protected function configureIO(InputInterface $input, OutputInterface $output)
{
if (true === $input->hasParameterOption(array('--ansi'))) {
$output->setDecorated(true);
} elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
$output->setDecorated(false);
}

if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
$input->setInteractive(false);
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
$inputStream = $this->getHelperSet()->get('question')->getInputStream();
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
$input->setInteractive(false);
}
}

if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
$input->setInteractive(false);
} else {
if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
} elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {
$output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
} elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
}
}
}













protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
{
foreach ($command->getHelperSet() as $helper) {
if ($helper instanceof InputAwareInterface) {
$helper->setInput($input);
}
}

if (null === $this->dispatcher) {
try {
return $command->run($input, $output);
} catch (\Exception $e) {
throw $e;
} catch (\Throwable $e) {
throw new FatalThrowableError($e);
}
}


 try {
$command->mergeApplicationDefinition();
$input->bind($command->getDefinition());
} catch (ExceptionInterface $e) {

 }


 
 $command->setInputBound(true);

$event = new ConsoleCommandEvent($command, $input, $output);
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);

if ($event->commandShouldRun()) {
try {
$e = null;
$exitCode = $command->run($input, $output);
} catch (\Exception $x) {
$e = $x;
} catch (\Throwable $x) {
$e = new FatalThrowableError($x);
}
if (null !== $e) {
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);

if ($e !== $event->getException()) {
$x = $e = $event->getException();
}

$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);

throw $x;
}
} else {
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
}

$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);

return $event->getExitCode();
}








protected function getCommandName(InputInterface $input)
{
return $input->getFirstArgument();
}






protected function getDefaultInputDefinition()
{
return new InputDefinition(array(
new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),

new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
));
}






protected function getDefaultCommands()
{
return array(new HelpCommand(), new ListCommand());
}






protected function getDefaultHelperSet()
{
return new HelperSet(array(
new FormatterHelper(),
new DialogHelper(false),
new ProgressHelper(false),
new TableHelper(false),
new DebugFormatterHelper(),
new ProcessHelper(),
new QuestionHelper(),
));
}






private function getSttyColumns()
{
if (!function_exists('proc_open')) {
return;
}

$descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
$process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
if (is_resource($process)) {
$info = stream_get_contents($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

return $info;
}
}






private function getConsoleMode()
{
if (!function_exists('proc_open')) {
return;
}

$descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
$process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
if (is_resource($process)) {
$info = stream_get_contents($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
return $matches[2].'x'.$matches[1];
}
}
}








private function getAbbreviationSuggestions($abbrevs)
{
return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
}











public function extractNamespace($name, $limit = null)
{
$parts = explode(':', $name);
array_pop($parts);

return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
}










private function findAlternatives($name, $collection)
{
$threshold = 1e3;
$alternatives = array();

$collectionParts = array();
foreach ($collection as $item) {
$collectionParts[$item] = explode(':', $item);
}

foreach (explode(':', $name) as $i => $subname) {
foreach ($collectionParts as $collectionName => $parts) {
$exists = isset($alternatives[$collectionName]);
if (!isset($parts[$i]) && $exists) {
$alternatives[$collectionName] += $threshold;
continue;
} elseif (!isset($parts[$i])) {
continue;
}

$lev = levenshtein($subname, $parts[$i]);
if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
$alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
} elseif ($exists) {
$alternatives[$collectionName] += $threshold;
}
}
}

foreach ($collection as $item) {
$lev = levenshtein($name, $item);
if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
$alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
}
}

$alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
asort($alternatives);

return array_keys($alternatives);
}






public function setDefaultCommand($commandName)
{
$this->defaultCommand = $commandName;
}

private function stringWidth($string)
{
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return strlen($string);
}

return mb_strwidth($string, $encoding);
}

private function splitStringByWidth($string, $width)
{

 
 
 if (false === $encoding = mb_detect_encoding($string, null, true)) {
return str_split($string, $width);
}

$utf8String = mb_convert_encoding($string, 'utf8', $encoding);
$lines = array();
$line = '';
foreach (preg_split('//u', $utf8String) as $char) {

 if (mb_strwidth($line.$char, 'utf8') <= $width) {
$line .= $char;
continue;
}

 $lines[] = str_pad($line, $width);
$line = $char;
}
if ('' !== $line) {
$lines[] = count($lines) ? str_pad($line, $width) : $line;
}

mb_convert_variables($encoding, 'utf8', $lines);

return $lines;
}








private function extractAllNamespaces($name)
{

 $parts = explode(':', $name, -1);
$namespaces = array();

foreach ($parts as $part) {
if (count($namespaces)) {
$namespaces[] = end($namespaces).':'.$part;
} else {
$namespaces[] = $part;
}
}

return $namespaces;
}
}
<?php










namespace Symfony\Component\Console\Formatter;

use Symfony\Component\Console\Exception\InvalidArgumentException;






class OutputFormatterStyle implements OutputFormatterStyleInterface
{
private static $availableForegroundColors = array(
'black' => array('set' => 30, 'unset' => 39),
'red' => array('set' => 31, 'unset' => 39),
'green' => array('set' => 32, 'unset' => 39),
'yellow' => array('set' => 33, 'unset' => 39),
'blue' => array('set' => 34, 'unset' => 39),
'magenta' => array('set' => 35, 'unset' => 39),
'cyan' => array('set' => 36, 'unset' => 39),
'white' => array('set' => 37, 'unset' => 39),
'default' => array('set' => 39, 'unset' => 39),
);
private static $availableBackgroundColors = array(
'black' => array('set' => 40, 'unset' => 49),
'red' => array('set' => 41, 'unset' => 49),
'green' => array('set' => 42, 'unset' => 49),
'yellow' => array('set' => 43, 'unset' => 49),
'blue' => array('set' => 44, 'unset' => 49),
'magenta' => array('set' => 45, 'unset' => 49),
'cyan' => array('set' => 46, 'unset' => 49),
'white' => array('set' => 47, 'unset' => 49),
'default' => array('set' => 49, 'unset' => 49),
);
private static $availableOptions = array(
'bold' => array('set' => 1, 'unset' => 22),
'underscore' => array('set' => 4, 'unset' => 24),
'blink' => array('set' => 5, 'unset' => 25),
'reverse' => array('set' => 7, 'unset' => 27),
'conceal' => array('set' => 8, 'unset' => 28),
);

private $foreground;
private $background;
private $options = array();








public function __construct($foreground = null, $background = null, array $options = array())
{
if (null !== $foreground) {
$this->setForeground($foreground);
}
if (null !== $background) {
$this->setBackground($background);
}
if (count($options)) {
$this->setOptions($options);
}
}








public function setForeground($color = null)
{
if (null === $color) {
$this->foreground = null;

return;
}

if (!isset(static::$availableForegroundColors[$color])) {
throw new InvalidArgumentException(sprintf(
'Invalid foreground color specified: "%s". Expected one of (%s)',
$color,
implode(', ', array_keys(static::$availableForegroundColors))
));
}

$this->foreground = static::$availableForegroundColors[$color];
}








public function setBackground($color = null)
{
if (null === $color) {
$this->background = null;

return;
}

if (!isset(static::$availableBackgroundColors[$color])) {
throw new InvalidArgumentException(sprintf(
'Invalid background color specified: "%s". Expected one of (%s)',
$color,
implode(', ', array_keys(static::$availableBackgroundColors))
));
}

$this->background = static::$availableBackgroundColors[$color];
}








public function setOption($option)
{
if (!isset(static::$availableOptions[$option])) {
throw new InvalidArgumentException(sprintf(
'Invalid option specified: "%s". Expected one of (%s)',
$option,
implode(', ', array_keys(static::$availableOptions))
));
}

if (!in_array(static::$availableOptions[$option], $this->options)) {
$this->options[] = static::$availableOptions[$option];
}
}








public function unsetOption($option)
{
if (!isset(static::$availableOptions[$option])) {
throw new InvalidArgumentException(sprintf(
'Invalid option specified: "%s". Expected one of (%s)',
$option,
implode(', ', array_keys(static::$availableOptions))
));
}

$pos = array_search(static::$availableOptions[$option], $this->options);
if (false !== $pos) {
unset($this->options[$pos]);
}
}






public function setOptions(array $options)
{
$this->options = array();

foreach ($options as $option) {
$this->setOption($option);
}
}








public function apply($text)
{
$setCodes = array();
$unsetCodes = array();

if (null !== $this->foreground) {
$setCodes[] = $this->foreground['set'];
$unsetCodes[] = $this->foreground['unset'];
}
if (null !== $this->background) {
$setCodes[] = $this->background['set'];
$unsetCodes[] = $this->background['unset'];
}
if (count($this->options)) {
foreach ($this->options as $option) {
$setCodes[] = $option['set'];
$unsetCodes[] = $option['unset'];
}
}

if (0 === count($setCodes)) {
return $text;
}

return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
}
}
<?php










namespace Symfony\Component\Console\Formatter;

use Symfony\Component\Console\Exception\InvalidArgumentException;




class OutputFormatterStyleStack
{



private $styles;




private $emptyStyle;






public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
{
$this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
$this->reset();
}




public function reset()
{
$this->styles = array();
}






public function push(OutputFormatterStyleInterface $style)
{
$this->styles[] = $style;
}










public function pop(OutputFormatterStyleInterface $style = null)
{
if (empty($this->styles)) {
return $this->emptyStyle;
}

if (null === $style) {
return array_pop($this->styles);
}

foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
if ($style->apply('') === $stackedStyle->apply('')) {
$this->styles = array_slice($this->styles, 0, $index);

return $stackedStyle;
}
}

throw new InvalidArgumentException('Incorrectly nested style tag found.');
}






public function getCurrent()
{
if (empty($this->styles)) {
return $this->emptyStyle;
}

return $this->styles[count($this->styles) - 1];
}






public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
{
$this->emptyStyle = $emptyStyle;

return $this;
}




public function getEmptyStyle()
{
return $this->emptyStyle;
}
}
<?php










namespace Symfony\Component\Console\Formatter;

use Symfony\Component\Console\Exception\InvalidArgumentException;






class OutputFormatter implements OutputFormatterInterface
{
private $decorated;
private $styles = array();
private $styleStack;








public static function escape($text)
{
$text = preg_replace('/([^\\\\]?)</', '$1\\<', $text);

return self::escapeTrailingBackslash($text);
}










public static function escapeTrailingBackslash($text)
{
if ('\\' === substr($text, -1)) {
$len = strlen($text);
$text = rtrim($text, '\\');
$text .= str_repeat('<<', $len - strlen($text));
}

return $text;
}







public function __construct($decorated = false, array $styles = array())
{
$this->decorated = (bool) $decorated;

$this->setStyle('error', new OutputFormatterStyle('white', 'red'));
$this->setStyle('info', new OutputFormatterStyle('green'));
$this->setStyle('comment', new OutputFormatterStyle('yellow'));
$this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));

foreach ($styles as $name => $style) {
$this->setStyle($name, $style);
}

$this->styleStack = new OutputFormatterStyleStack();
}






public function setDecorated($decorated)
{
$this->decorated = (bool) $decorated;
}






public function isDecorated()
{
return $this->decorated;
}







public function setStyle($name, OutputFormatterStyleInterface $style)
{
$this->styles[strtolower($name)] = $style;
}








public function hasStyle($name)
{
return isset($this->styles[strtolower($name)]);
}










public function getStyle($name)
{
if (!$this->hasStyle($name)) {
throw new InvalidArgumentException(sprintf('Undefined style: %s', $name));
}

return $this->styles[strtolower($name)];
}








public function format($message)
{
$message = (string) $message;
$offset = 0;
$output = '';
$tagRegex = '[a-z][a-z0-9_=;-]*+';
preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
foreach ($matches[0] as $i => $match) {
$pos = $match[1];
$text = $match[0];

if (0 != $pos && '\\' == $message[$pos - 1]) {
continue;
}


 $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
$offset = $pos + strlen($text);


 if ($open = '/' != $text[1]) {
$tag = $matches[1][$i][0];
} else {
$tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
}

if (!$open && !$tag) {

 $this->styleStack->pop();
} elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
$output .= $this->applyCurrentStyle($text);
} elseif ($open) {
$this->styleStack->push($style);
} else {
$this->styleStack->pop($style);
}
}

$output .= $this->applyCurrentStyle(substr($message, $offset));

if (false !== strpos($output, '<<')) {
return strtr($output, array('\\<' => '<', '<<' => '\\'));
}

return str_replace('\\<', '<', $output);
}




public function getStyleStack()
{
return $this->styleStack;
}








private function createStyleFromString($string)
{
if (isset($this->styles[$string])) {
return $this->styles[$string];
}

if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
return false;
}

$style = new OutputFormatterStyle();
foreach ($matches as $match) {
array_shift($match);

if ('fg' == $match[0]) {
$style->setForeground($match[1]);
} elseif ('bg' == $match[0]) {
$style->setBackground($match[1]);
} else {
try {
$style->setOption($match[1]);
} catch (\InvalidArgumentException $e) {
return false;
}
}
}

return $style;
}








private function applyCurrentStyle($text)
{
return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
}
}
<?php










namespace Symfony\Component\Console\Formatter;






interface OutputFormatterStyleInterface
{





public function setForeground($color = null);






public function setBackground($color = null);






public function setOption($option);






public function unsetOption($option);






public function setOptions(array $options);








public function apply($text);
}
<?php










namespace Symfony\Component\Console\Formatter;






interface OutputFormatterInterface
{





public function setDecorated($decorated);






public function isDecorated();







public function setStyle($name, OutputFormatterStyleInterface $style);








public function hasStyle($name);








public function getStyle($name);








public function format($message);
}
<?php










namespace Symfony\Component\Console\Helper;








class DebugFormatterHelper extends Helper
{
private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default');
private $started = array();
private $count = -1;










public function start($id, $message, $prefix = 'RUN')
{
$this->started[$id] = array('border' => ++$this->count % count($this->colors));

return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
}












public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR')
{
$message = '';

if ($error) {
if (isset($this->started[$id]['out'])) {
$message .= "\n";
unset($this->started[$id]['out']);
}
if (!isset($this->started[$id]['err'])) {
$message .= sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix);
$this->started[$id]['err'] = true;
}

$message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
} else {
if (isset($this->started[$id]['err'])) {
$message .= "\n";
unset($this->started[$id]['err']);
}
if (!isset($this->started[$id]['out'])) {
$message .= sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix);
$this->started[$id]['out'] = true;
}

$message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
}

return $message;
}











public function stop($id, $message, $successful, $prefix = 'RES')
{
$trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';

if ($successful) {
return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
}

$message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);

unset($this->started[$id]['out'], $this->started[$id]['err']);

return $message;
}






private function getBorder($id)
{
return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]);
}




public function getName()
{
return 'debug_formatter';
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Descriptor\DescriptorInterface;
use Symfony\Component\Console\Descriptor\JsonDescriptor;
use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;






class DescriptorHelper extends Helper
{



private $descriptors = array();




public function __construct()
{
$this
->register('txt', new TextDescriptor())
->register('xml', new XmlDescriptor())
->register('json', new JsonDescriptor())
->register('md', new MarkdownDescriptor())
;
}














public function describe(OutputInterface $output, $object, array $options = array())
{
$options = array_merge(array(
'raw_text' => false,
'format' => 'txt',
), $options);

if (!isset($this->descriptors[$options['format']])) {
throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
}

$descriptor = $this->descriptors[$options['format']];
$descriptor->describe($output, $object, $options);
}









public function register($format, DescriptorInterface $descriptor)
{
$this->descriptors[$format] = $descriptor;

return $this;
}




public function getName()
{
return 'descriptor';
}
}
<?php










namespace Symfony\Component\Console\Helper;






interface HelperInterface
{





public function setHelperSet(HelperSet $helperSet = null);






public function getHelperSet();






public function getName();
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputAwareInterface;






abstract class InputAwareHelper extends Helper implements InputAwareInterface
{
protected $input;




public function setInput(InputInterface $input)
{
$this->input = $input;
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;






class HelperSet implements \IteratorAggregate
{



private $helpers = array();
private $command;






public function __construct(array $helpers = array())
{
foreach ($helpers as $alias => $helper) {
$this->set($helper, is_int($alias) ? null : $alias);
}
}







public function set(HelperInterface $helper, $alias = null)
{
$this->helpers[$helper->getName()] = $helper;
if (null !== $alias) {
$this->helpers[$alias] = $helper;
}

$helper->setHelperSet($this);
}








public function has($name)
{
return isset($this->helpers[$name]);
}










public function get($name)
{
if (!$this->has($name)) {
throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
}

if ('dialog' === $name && $this->helpers[$name] instanceof DialogHelper) {
@trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
} elseif ('progress' === $name && $this->helpers[$name] instanceof ProgressHelper) {
@trigger_error('"Symfony\Component\Console\Helper\ProgressHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\ProgressBar" instead.', E_USER_DEPRECATED);
} elseif ('table' === $name && $this->helpers[$name] instanceof TableHelper) {
@trigger_error('"Symfony\Component\Console\Helper\TableHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\Table" instead.', E_USER_DEPRECATED);
}

return $this->helpers[$name];
}






public function setCommand(Command $command = null)
{
$this->command = $command;
}






public function getCommand()
{
return $this->command;
}




public function getIterator()
{
return new \ArrayIterator($this->helpers);
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\LogicException;










class ProgressHelper extends Helper
{
const FORMAT_QUIET = ' %percent%%';
const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
const FORMAT_QUIET_NOMAX = ' %current%';
const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';


 private $barWidth = 28;
private $barChar = '=';
private $emptyBarChar = '-';
private $progressChar = '>';
private $format = null;
private $redrawFreq = 1;

private $lastMessagesLength;
private $barCharOriginal;




private $output;






private $current;






private $max;






private $startTime;






private $defaultFormatVars = array(
'current',
'max',
'bar',
'percent',
'elapsed',
);






private $formatVars;






private $widths = array(
'current' => 4,
'max' => 4,
'percent' => 3,
'elapsed' => 6,
);






private $timeFormats = array(
array(0, '???'),
array(2, '1 sec'),
array(59, 'secs', 1),
array(60, '1 min'),
array(3600, 'mins', 60),
array(5400, '1 hr'),
array(86400, 'hrs', 3600),
array(129600, '1 day'),
array(604800, 'days', 86400),
);

public function __construct($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\ProgressBar class instead.', E_USER_DEPRECATED);
}
}






public function setBarWidth($size)
{
$this->barWidth = (int) $size;
}






public function setBarCharacter($char)
{
$this->barChar = $char;
}






public function setEmptyBarCharacter($char)
{
$this->emptyBarChar = $char;
}






public function setProgressCharacter($char)
{
$this->progressChar = $char;
}






public function setFormat($format)
{
$this->format = $format;
}






public function setRedrawFrequency($freq)
{
$this->redrawFreq = (int) $freq;
}







public function start(OutputInterface $output, $max = null)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$this->startTime = time();
$this->current = 0;
$this->max = (int) $max;


 $this->output = $output->isDecorated() ? $output : new NullOutput();
$this->lastMessagesLength = 0;
$this->barCharOriginal = '';

if (null === $this->format) {
switch ($output->getVerbosity()) {
case OutputInterface::VERBOSITY_QUIET:
$this->format = self::FORMAT_QUIET_NOMAX;
if ($this->max > 0) {
$this->format = self::FORMAT_QUIET;
}
break;
case OutputInterface::VERBOSITY_VERBOSE:
case OutputInterface::VERBOSITY_VERY_VERBOSE:
case OutputInterface::VERBOSITY_DEBUG:
$this->format = self::FORMAT_VERBOSE_NOMAX;
if ($this->max > 0) {
$this->format = self::FORMAT_VERBOSE;
}
break;
default:
$this->format = self::FORMAT_NORMAL_NOMAX;
if ($this->max > 0) {
$this->format = self::FORMAT_NORMAL;
}
break;
}
}

$this->initialize();
}









public function advance($step = 1, $redraw = false)
{
$this->setCurrent($this->current + $step, $redraw);
}









public function setCurrent($current, $redraw = false)
{
if (null === $this->startTime) {
throw new LogicException('You must start the progress bar before calling setCurrent().');
}

$current = (int) $current;

if ($current < $this->current) {
throw new LogicException('You can\'t regress the progress bar');
}

if (0 === $this->current) {
$redraw = true;
}

$prevPeriod = (int) ($this->current / $this->redrawFreq);

$this->current = $current;

$currPeriod = (int) ($this->current / $this->redrawFreq);
if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
$this->display();
}
}








public function display($finish = false)
{
if (null === $this->startTime) {
throw new LogicException('You must start the progress bar before calling display().');
}

$message = $this->format;
foreach ($this->generate($finish) as $name => $value) {
$message = str_replace("%{$name}%", $value, $message);
}
$this->overwrite($this->output, $message);
}








public function clear()
{
$this->overwrite($this->output, '');
}




public function finish()
{
if (null === $this->startTime) {
throw new LogicException('You must start the progress bar before calling finish().');
}

if (null !== $this->startTime) {
if (!$this->max) {
$this->barChar = $this->barCharOriginal;
$this->display(true);
}
$this->startTime = null;
$this->output->writeln('');
$this->output = null;
}
}




private function initialize()
{
$this->formatVars = array();
foreach ($this->defaultFormatVars as $var) {
if (false !== strpos($this->format, "%{$var}%")) {
$this->formatVars[$var] = true;
}
}

if ($this->max > 0) {
$this->widths['max'] = $this->strlen($this->max);
$this->widths['current'] = $this->widths['max'];
} else {
$this->barCharOriginal = $this->barChar;
$this->barChar = $this->emptyBarChar;
}
}








private function generate($finish = false)
{
$vars = array();
$percent = 0;
if ($this->max > 0) {
$percent = (float) $this->current / $this->max;
}

if (isset($this->formatVars['bar'])) {
if ($this->max > 0) {
$completeBars = floor($percent * $this->barWidth);
} else {
if (!$finish) {
$completeBars = floor($this->current % $this->barWidth);
} else {
$completeBars = $this->barWidth;
}
}

$emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
$bar = str_repeat($this->barChar, $completeBars);
if ($completeBars < $this->barWidth) {
$bar .= $this->progressChar;
$bar .= str_repeat($this->emptyBarChar, $emptyBars);
}

$vars['bar'] = $bar;
}

if (isset($this->formatVars['elapsed'])) {
$elapsed = time() - $this->startTime;
$vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
}

if (isset($this->formatVars['current'])) {
$vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
}

if (isset($this->formatVars['max'])) {
$vars['max'] = $this->max;
}

if (isset($this->formatVars['percent'])) {
$vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
}

return $vars;
}








private function humaneTime($secs)
{
$text = '';
foreach ($this->timeFormats as $format) {
if ($secs < $format[0]) {
if (count($format) == 2) {
$text = $format[1];
break;
} else {
$text = ceil($secs / $format[2]).' '.$format[1];
break;
}
}
}

return $text;
}







private function overwrite(OutputInterface $output, $message)
{
$length = $this->strlen($message);


 if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
$message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
}


 $output->write("\x0D");
$output->write($message);

$this->lastMessagesLength = $this->strlen($message);
}




public function getName()
{
return 'progress';
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Exception\InvalidArgumentException;










class TableHelper extends Helper
{
const LAYOUT_DEFAULT = 0;
const LAYOUT_BORDERLESS = 1;
const LAYOUT_COMPACT = 2;




private $table;

public function __construct($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\Table class instead.', E_USER_DEPRECATED);
}

$this->table = new Table(new NullOutput());
}










public function setLayout($layout)
{
switch ($layout) {
case self::LAYOUT_BORDERLESS:
$this->table->setStyle('borderless');
break;

case self::LAYOUT_COMPACT:
$this->table->setStyle('compact');
break;

case self::LAYOUT_DEFAULT:
$this->table->setStyle('default');
break;

default:
throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
}

return $this;
}

public function setHeaders(array $headers)
{
$this->table->setHeaders($headers);

return $this;
}

public function setRows(array $rows)
{
$this->table->setRows($rows);

return $this;
}

public function addRows(array $rows)
{
$this->table->addRows($rows);

return $this;
}

public function addRow(array $row)
{
$this->table->addRow($row);

return $this;
}

public function setRow($column, array $row)
{
$this->table->setRow($column, $row);

return $this;
}








public function setPaddingChar($paddingChar)
{
$this->table->getStyle()->setPaddingChar($paddingChar);

return $this;
}








public function setHorizontalBorderChar($horizontalBorderChar)
{
$this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar);

return $this;
}








public function setVerticalBorderChar($verticalBorderChar)
{
$this->table->getStyle()->setVerticalBorderChar($verticalBorderChar);

return $this;
}








public function setCrossingChar($crossingChar)
{
$this->table->getStyle()->setCrossingChar($crossingChar);

return $this;
}








public function setCellHeaderFormat($cellHeaderFormat)
{
$this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat);

return $this;
}








public function setCellRowFormat($cellRowFormat)
{
$this->table->getStyle()->setCellHeaderFormat($cellRowFormat);

return $this;
}








public function setCellRowContentFormat($cellRowContentFormat)
{
$this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat);

return $this;
}








public function setBorderFormat($borderFormat)
{
$this->table->getStyle()->setBorderFormat($borderFormat);

return $this;
}








public function setPadType($padType)
{
$this->table->getStyle()->setPadType($padType);

return $this;
}















public function render(OutputInterface $output)
{
$p = new \ReflectionProperty($this->table, 'output');
$p->setAccessible(true);
$p->setValue($this->table, $output);

$this->table->render();
}




public function getName()
{
return 'table';
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\ProcessBuilder;






class ProcessHelper extends Helper
{












public function run(OutputInterface $output, $cmd, $error = null, $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$formatter = $this->getHelperSet()->get('debug_formatter');

if (is_array($cmd)) {
$process = ProcessBuilder::create($cmd)->getProcess();
} elseif ($cmd instanceof Process) {
$process = $cmd;
} else {
$process = new Process($cmd);
}

if ($verbosity <= $output->getVerbosity()) {
$output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine())));
}

if ($output->isDebug()) {
$callback = $this->wrapCallback($output, $process, $callback);
}

$process->run($callback);

if ($verbosity <= $output->getVerbosity()) {
$message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
$output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
}

if (!$process->isSuccessful() && null !== $error) {
$output->writeln(sprintf('<error>%s</error>', $this->escapeString($error)));
}

return $process;
}



















public function mustRun(OutputInterface $output, $cmd, $error = null, $callback = null)
{
$process = $this->run($output, $cmd, $error, $callback);

if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}

return $process;
}










public function wrapCallback(OutputInterface $output, Process $process, $callback = null)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$formatter = $this->getHelperSet()->get('debug_formatter');

$that = $this;

return function ($type, $buffer) use ($output, $process, $callback, $formatter, $that) {
$output->write($formatter->progress(spl_object_hash($process), $that->escapeString($buffer), Process::ERR === $type));

if (null !== $callback) {
call_user_func($callback, $type, $buffer);
}
};
}






public function escapeString($str)
{
return str_replace('<', '\\<', $str);
}




public function getName()
{
return 'process';
}
}
<?php










namespace Symfony\Component\Console\Helper;






class TableSeparator extends TableCell
{



public function __construct(array $options = array())
{
parent::__construct('', $options);
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Question\ChoiceQuestion;






class QuestionHelper extends Helper
{
private $inputStream;
private static $shell;
private static $stty;












public function ask(InputInterface $input, OutputInterface $output, Question $question)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

if (!$input->isInteractive()) {
return $question->getDefault();
}

if (!$question->getValidator()) {
return $this->doAsk($output, $question);
}

$that = $this;

$interviewer = function () use ($output, $question, $that) {
return $that->doAsk($output, $question);
};

return $this->validateAttempts($interviewer, $output, $question);
}










public function setInputStream($stream)
{
if (!is_resource($stream)) {
throw new InvalidArgumentException('Input stream must be a valid resource.');
}

$this->inputStream = $stream;
}






public function getInputStream()
{
return $this->inputStream;
}




public function getName()
{
return 'question';
}














public function doAsk(OutputInterface $output, Question $question)
{
$this->writePrompt($output, $question);

$inputStream = $this->inputStream ?: STDIN;
$autocomplete = $question->getAutocompleterValues();

if (null === $autocomplete || !$this->hasSttyAvailable()) {
$ret = false;
if ($question->isHidden()) {
try {
$ret = trim($this->getHiddenResponse($output, $inputStream));
} catch (\RuntimeException $e) {
if (!$question->isHiddenFallback()) {
throw $e;
}
}
}

if (false === $ret) {
$ret = fgets($inputStream, 4096);
if (false === $ret) {
throw new RuntimeException('Aborted');
}
$ret = trim($ret);
}
} else {
$ret = trim($this->autocomplete($output, $question, $inputStream));
}

$ret = strlen($ret) > 0 ? $ret : $question->getDefault();

if ($normalizer = $question->getNormalizer()) {
return $normalizer($ret);
}

return $ret;
}







protected function writePrompt(OutputInterface $output, Question $question)
{
$message = $question->getQuestion();

if ($question instanceof ChoiceQuestion) {
$maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));

$messages = (array) $question->getQuestion();
foreach ($question->getChoices() as $key => $value) {
$width = $maxWidth - $this->strlen($key);
$messages[] = '  [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
}

$output->writeln($messages);

$message = $question->getPrompt();
}

$output->write($message);
}







protected function writeError(OutputInterface $output, \Exception $error)
{
if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
$message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
} else {
$message = '<error>'.$error->getMessage().'</error>';
}

$output->writeln($message);
}










private function autocomplete(OutputInterface $output, Question $question, $inputStream)
{
$autocomplete = $question->getAutocompleterValues();
$ret = '';

$i = 0;
$ofs = -1;
$matches = $autocomplete;
$numMatches = count($matches);

$sttyMode = shell_exec('stty -g');


 shell_exec('stty -icanon -echo');


 $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));


 while (!feof($inputStream)) {
$c = fread($inputStream, 1);


 if ("\177" === $c) {
if (0 === $numMatches && 0 !== $i) {
--$i;

 $output->write("\033[1D");
}

if ($i === 0) {
$ofs = -1;
$matches = $autocomplete;
$numMatches = count($matches);
} else {
$numMatches = 0;
}


 $ret = substr($ret, 0, $i);
} elseif ("\033" === $c) {

 $c .= fread($inputStream, 2);


 if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
if ('A' === $c[2] && -1 === $ofs) {
$ofs = 0;
}

if (0 === $numMatches) {
continue;
}

$ofs += ('A' === $c[2]) ? -1 : 1;
$ofs = ($numMatches + $ofs) % $numMatches;
}
} elseif (ord($c) < 32) {
if ("\t" === $c || "\n" === $c) {
if ($numMatches > 0 && -1 !== $ofs) {
$ret = $matches[$ofs];

 $output->write(substr($ret, $i));
$i = strlen($ret);
}

if ("\n" === $c) {
$output->write($c);
break;
}

$numMatches = 0;
}

continue;
} else {
$output->write($c);
$ret .= $c;
++$i;

$numMatches = 0;
$ofs = 0;

foreach ($autocomplete as $value) {

 if (0 === strpos($value, $ret) && $i !== strlen($value)) {
$matches[$numMatches++] = $value;
}
}
}


 $output->write("\033[K");

if ($numMatches > 0 && -1 !== $ofs) {

 $output->write("\0337");

 $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');

 $output->write("\0338");
}
}


 shell_exec(sprintf('stty %s', $sttyMode));

return $ret;
}











private function getHiddenResponse(OutputInterface $output, $inputStream)
{
if ('\\' === DIRECTORY_SEPARATOR) {
$exe = __DIR__.'/../Resources/bin/hiddeninput.exe';


 if ('phar:' === substr(__FILE__, 0, 5)) {
$tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
copy($exe, $tmpExe);
$exe = $tmpExe;
}

$value = rtrim(shell_exec($exe));
$output->writeln('');

if (isset($tmpExe)) {
unlink($tmpExe);
}

return $value;
}

if ($this->hasSttyAvailable()) {
$sttyMode = shell_exec('stty -g');

shell_exec('stty -echo');
$value = fgets($inputStream, 4096);
shell_exec(sprintf('stty %s', $sttyMode));

if (false === $value) {
throw new RuntimeException('Aborted');
}

$value = trim($value);
$output->writeln('');

return $value;
}

if (false !== $shell = $this->getShell()) {
$readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
$value = rtrim(shell_exec($command));
$output->writeln('');

return $value;
}

throw new RuntimeException('Unable to hide the response.');
}












private function validateAttempts($interviewer, OutputInterface $output, Question $question)
{
$error = null;
$attempts = $question->getMaxAttempts();
while (null === $attempts || $attempts--) {
if (null !== $error) {
$this->writeError($output, $error);
}

try {
return call_user_func($question->getValidator(), $interviewer());
} catch (RuntimeException $e) {
throw $e;
} catch (\Exception $error) {
}
}

throw $error;
}






private function getShell()
{
if (null !== self::$shell) {
return self::$shell;
}

self::$shell = false;

if (file_exists('/usr/bin/env')) {

 $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
self::$shell = $sh;
break;
}
}
}

return self::$shell;
}






private function hasSttyAvailable()
{
if (null !== self::$stty) {
return self::$stty;
}

exec('stty 2>&1', $output, $exitcode);

return self::$stty = $exitcode === 0;
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\InvalidArgumentException;









class Table
{





private $headers = array();






private $rows = array();






private $columnWidths = array();






private $numberOfColumns;




private $output;




private $style;




private $columnStyles = array();

private static $styles;

public function __construct(OutputInterface $output)
{
$this->output = $output;

if (!self::$styles) {
self::$styles = self::initStyles();
}

$this->setStyle('default');
}







public static function setStyleDefinition($name, TableStyle $style)
{
if (!self::$styles) {
self::$styles = self::initStyles();
}

self::$styles[$name] = $style;
}








public static function getStyleDefinition($name)
{
if (!self::$styles) {
self::$styles = self::initStyles();
}

if (isset(self::$styles[$name])) {
return self::$styles[$name];
}

throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
}








public function setStyle($name)
{
$this->style = $this->resolveStyle($name);

return $this;
}






public function getStyle()
{
return $this->style;
}









public function setColumnStyle($columnIndex, $name)
{
$columnIndex = intval($columnIndex);

$this->columnStyles[$columnIndex] = $this->resolveStyle($name);

return $this;
}










public function getColumnStyle($columnIndex)
{
if (isset($this->columnStyles[$columnIndex])) {
return $this->columnStyles[$columnIndex];
}

return $this->getStyle();
}

public function setHeaders(array $headers)
{
$headers = array_values($headers);
if (!empty($headers) && !is_array($headers[0])) {
$headers = array($headers);
}

$this->headers = $headers;

return $this;
}

public function setRows(array $rows)
{
$this->rows = array();

return $this->addRows($rows);
}

public function addRows(array $rows)
{
foreach ($rows as $row) {
$this->addRow($row);
}

return $this;
}

public function addRow($row)
{
if ($row instanceof TableSeparator) {
$this->rows[] = $row;

return $this;
}

if (!is_array($row)) {
throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
}

$this->rows[] = array_values($row);

return $this;
}

public function setRow($column, array $row)
{
$this->rows[$column] = $row;

return $this;
}













public function render()
{
$this->calculateNumberOfColumns();
$rows = $this->buildTableRows($this->rows);
$headers = $this->buildTableRows($this->headers);

$this->calculateColumnsWidth(array_merge($headers, $rows));

$this->renderRowSeparator();
if (!empty($headers)) {
foreach ($headers as $header) {
$this->renderRow($header, $this->style->getCellHeaderFormat());
$this->renderRowSeparator();
}
}
foreach ($rows as $row) {
if ($row instanceof TableSeparator) {
$this->renderRowSeparator();
} else {
$this->renderRow($row, $this->style->getCellRowFormat());
}
}
if (!empty($rows)) {
$this->renderRowSeparator();
}

$this->cleanup();
}






private function renderRowSeparator()
{
if (0 === $count = $this->numberOfColumns) {
return;
}

if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
return;
}

$markup = $this->style->getCrossingChar();
for ($column = 0; $column < $count; ++$column) {
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
}

$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
}




private function renderColumnSeparator()
{
return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
}









private function renderRow(array $row, $cellFormat)
{
if (empty($row)) {
return;
}

$rowContent = $this->renderColumnSeparator();
foreach ($this->getRowColumns($row) as $column) {
$rowContent .= $this->renderCell($row, $column, $cellFormat);
$rowContent .= $this->renderColumnSeparator();
}
$this->output->writeln($rowContent);
}








private function renderCell(array $row, $column, $cellFormat)
{
$cell = isset($row[$column]) ? $row[$column] : '';
$width = $this->columnWidths[$column];
if ($cell instanceof TableCell && $cell->getColspan() > 1) {

 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
$width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
}
}


 if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
$width += strlen($cell) - mb_strwidth($cell, $encoding);
}

$style = $this->getColumnStyle($column);

if ($cell instanceof TableSeparator) {
return sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width));
}

$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
$content = sprintf($style->getCellRowContentFormat(), $cell);

return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType()));
}




private function calculateNumberOfColumns()
{
if (null !== $this->numberOfColumns) {
return;
}

$columns = array(0);
foreach (array_merge($this->headers, $this->rows) as $row) {
if ($row instanceof TableSeparator) {
continue;
}

$columns[] = $this->getNumberOfColumns($row);
}

$this->numberOfColumns = max($columns);
}

private function buildTableRows($rows)
{
$unmergedRows = array();
for ($rowKey = 0; $rowKey < count($rows); ++$rowKey) {
$rows = $this->fillNextRows($rows, $rowKey);


 foreach ($rows[$rowKey] as $column => $cell) {
if (!strstr($cell, "\n")) {
continue;
}
$lines = explode("\n", $cell);
foreach ($lines as $lineKey => $line) {
if ($cell instanceof TableCell) {
$line = new TableCell($line, array('colspan' => $cell->getColspan()));
}
if (0 === $lineKey) {
$rows[$rowKey][$column] = $line;
} else {
$unmergedRows[$rowKey][$lineKey][$column] = $line;
}
}
}
}

$tableRows = array();
foreach ($rows as $rowKey => $row) {
$tableRows[] = $this->fillCells($row);
if (isset($unmergedRows[$rowKey])) {
$tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
}
}

return $tableRows;
}









private function fillNextRows($rows, $line)
{
$unmergedRows = array();
foreach ($rows[$line] as $column => $cell) {
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
$nbLines = $cell->getRowspan() - 1;
$lines = array($cell);
if (strstr($cell, "\n")) {
$lines = explode("\n", $cell);
$nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;

$rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
unset($lines[0]);
}


 $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows);
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
$value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
$unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
if ($nbLines === $unmergedRowKey - $line) {
break;
}
}
}
}

foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {

 if (isset($rows[$unmergedRowKey]) && is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
foreach ($unmergedRow as $cellKey => $cell) {

 array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell));
}
} else {
$row = $this->copyRow($rows, $unmergedRowKey - 1);
foreach ($unmergedRow as $column => $cell) {
if (!empty($cell)) {
$row[$column] = $unmergedRow[$column];
}
}
array_splice($rows, $unmergedRowKey, 0, array($row));
}
}

return $rows;
}








private function fillCells($row)
{
$newRow = array();
foreach ($row as $column => $cell) {
$newRow[] = $cell;
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {

 $newRow[] = '';
}
}
}

return $newRow ?: $row;
}







private function copyRow($rows, $line)
{
$row = $rows[$line];
foreach ($row as $cellKey => $cellValue) {
$row[$cellKey] = '';
if ($cellValue instanceof TableCell) {
$row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan()));
}
}

return $row;
}








private function getNumberOfColumns(array $row)
{
$columns = count($row);
foreach ($row as $column) {
$columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0;
}

return $columns;
}








private function getRowColumns($row)
{
$columns = range(0, $this->numberOfColumns - 1);
foreach ($row as $cellKey => $cell) {
if ($cell instanceof TableCell && $cell->getColspan() > 1) {

 $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
}
}

return $columns;
}






private function calculateColumnsWidth($rows)
{
for ($column = 0; $column < $this->numberOfColumns; ++$column) {
$lengths = array();
foreach ($rows as $row) {
if ($row instanceof TableSeparator) {
continue;
}

foreach ($row as $i => $cell) {
if ($cell instanceof TableCell) {
$textLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
if ($textLength > 0) {
$contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
foreach ($contentColumns as $position => $content) {
$row[$i + $position] = $content;
}
}
}
}

$lengths[] = $this->getCellWidth($row, $column);
}

$this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
}
}






private function getColumnSeparatorWidth()
{
return strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
}









private function getCellWidth(array $row, $column)
{
if (isset($row[$column])) {
$cell = $row[$column];
$cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);

return $cellWidth;
}

return 0;
}




private function cleanup()
{
$this->columnWidths = array();
$this->numberOfColumns = null;
}

private static function initStyles()
{
$borderless = new TableStyle();
$borderless
->setHorizontalBorderChar('=')
->setVerticalBorderChar(' ')
->setCrossingChar(' ')
;

$compact = new TableStyle();
$compact
->setHorizontalBorderChar('')
->setVerticalBorderChar(' ')
->setCrossingChar('')
->setCellRowContentFormat('%s')
;

$styleGuide = new TableStyle();
$styleGuide
->setHorizontalBorderChar('-')
->setVerticalBorderChar(' ')
->setCrossingChar(' ')
->setCellHeaderFormat('%s')
;

return array(
'default' => new TableStyle(),
'borderless' => $borderless,
'compact' => $compact,
'symfony-style-guide' => $styleGuide,
);
}

private function resolveStyle($name)
{
if ($name instanceof TableStyle) {
return $name;
}

if (isset(self::$styles[$name])) {
return self::$styles[$name];
}

throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Formatter\OutputFormatter;






class FormatterHelper extends Helper
{









public function formatSection($section, $message, $style = 'info')
{
return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
}










public function formatBlock($messages, $style, $large = false)
{
if (!is_array($messages)) {
$messages = array($messages);
}

$len = 0;
$lines = array();
foreach ($messages as $message) {
$message = OutputFormatter::escape($message);
$lines[] = sprintf($large ? '  %s  ' : ' %s ', $message);
$len = max($this->strlen($message) + ($large ? 4 : 2), $len);
}

$messages = $large ? array(str_repeat(' ', $len)) : array();
for ($i = 0; isset($lines[$i]); ++$i) {
$messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
}
if ($large) {
$messages[] = str_repeat(' ', $len);
}

for ($i = 0; isset($messages[$i]); ++$i) {
$messages[$i] = sprintf('<%s>%s</%s>', $style, $messages[$i], $style);
}

return implode("\n", $messages);
}




public function getName()
{
return 'formatter';
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;









class DialogHelper extends InputAwareHelper
{
private $inputStream;
private static $shell;
private static $stty;

public function __construct($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
}
}
















public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$width = max(array_map('strlen', array_keys($choices)));

$messages = (array) $question;
foreach ($choices as $key => $value) {
$messages[] = sprintf("  [<info>%-{$width}s</info>] %s", $key, $value);
}

$output->writeln($messages);

$result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) {

 $selectedChoices = str_replace(' ', '', $picked);

if ($multiselect) {

 if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
throw new InvalidArgumentException(sprintf($errorMessage, $picked));
}
$selectedChoices = explode(',', $selectedChoices);
} else {
$selectedChoices = array($picked);
}

$multiselectChoices = array();

foreach ($selectedChoices as $value) {
if (empty($choices[$value])) {
throw new InvalidArgumentException(sprintf($errorMessage, $value));
}
$multiselectChoices[] = $value;
}

if ($multiselect) {
return $multiselectChoices;
}

return $picked;
}, $attempts, $default);

return $result;
}













public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null)
{
if ($this->input && !$this->input->isInteractive()) {
return $default;
}

if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$output->write($question);

$inputStream = $this->inputStream ?: STDIN;

if (null === $autocomplete || !$this->hasSttyAvailable()) {
$ret = fgets($inputStream, 4096);
if (false === $ret) {
throw new RuntimeException('Aborted');
}
$ret = trim($ret);
} else {
$ret = '';

$i = 0;
$ofs = -1;
$matches = $autocomplete;
$numMatches = count($matches);

$sttyMode = shell_exec('stty -g');


 shell_exec('stty -icanon -echo');


 $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));


 while (!feof($inputStream)) {
$c = fread($inputStream, 1);


 if ("\177" === $c) {
if (0 === $numMatches && 0 !== $i) {
--$i;

 $output->write("\033[1D");
}

if ($i === 0) {
$ofs = -1;
$matches = $autocomplete;
$numMatches = count($matches);
} else {
$numMatches = 0;
}


 $ret = substr($ret, 0, $i);
} elseif ("\033" === $c) {

 $c .= fread($inputStream, 2);


 if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
if ('A' === $c[2] && -1 === $ofs) {
$ofs = 0;
}

if (0 === $numMatches) {
continue;
}

$ofs += ('A' === $c[2]) ? -1 : 1;
$ofs = ($numMatches + $ofs) % $numMatches;
}
} elseif (ord($c) < 32) {
if ("\t" === $c || "\n" === $c) {
if ($numMatches > 0 && -1 !== $ofs) {
$ret = $matches[$ofs];

 $output->write(substr($ret, $i));
$i = strlen($ret);
}

if ("\n" === $c) {
$output->write($c);
break;
}

$numMatches = 0;
}

continue;
} else {
$output->write($c);
$ret .= $c;
++$i;

$numMatches = 0;
$ofs = 0;

foreach ($autocomplete as $value) {

 if (0 === strpos($value, $ret) && $i !== strlen($value)) {
$matches[$numMatches++] = $value;
}
}
}


 $output->write("\033[K");

if ($numMatches > 0 && -1 !== $ofs) {

 $output->write("\0337");

 $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');

 $output->write("\0338");
}
}


 shell_exec(sprintf('stty %s', $sttyMode));
}

return strlen($ret) > 0 ? $ret : $default;
}












public function askConfirmation(OutputInterface $output, $question, $default = true)
{
$answer = 'z';
while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
$answer = $this->ask($output, $question);
}

if (false === $default) {
return $answer && 'y' == strtolower($answer[0]);
}

return !$answer || 'y' == strtolower($answer[0]);
}












public function askHiddenResponse(OutputInterface $output, $question, $fallback = true)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

if ('\\' === DIRECTORY_SEPARATOR) {
$exe = __DIR__.'/../Resources/bin/hiddeninput.exe';


 if ('phar:' === substr(__FILE__, 0, 5)) {
$tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
copy($exe, $tmpExe);
$exe = $tmpExe;
}

$output->write($question);
$value = rtrim(shell_exec($exe));
$output->writeln('');

if (isset($tmpExe)) {
unlink($tmpExe);
}

return $value;
}

if ($this->hasSttyAvailable()) {
$output->write($question);

$sttyMode = shell_exec('stty -g');

shell_exec('stty -echo');
$value = fgets($this->inputStream ?: STDIN, 4096);
shell_exec(sprintf('stty %s', $sttyMode));

if (false === $value) {
throw new RuntimeException('Aborted');
}

$value = trim($value);
$output->writeln('');

return $value;
}

if (false !== $shell = $this->getShell()) {
$output->write($question);
$readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
$value = rtrim(shell_exec($command));
$output->writeln('');

return $value;
}

if ($fallback) {
return $this->ask($output, $question);
}

throw new RuntimeException('Unable to hide the response');
}



















public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null)
{
$that = $this;

$interviewer = function () use ($output, $question, $default, $autocomplete, $that) {
return $that->ask($output, $question, $default, $autocomplete);
};

return $this->validateAttempts($interviewer, $output, $validator, $attempts);
}



















public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true)
{
$that = $this;

$interviewer = function () use ($output, $question, $fallback, $that) {
return $that->askHiddenResponse($output, $question, $fallback);
};

return $this->validateAttempts($interviewer, $output, $validator, $attempts);
}








public function setInputStream($stream)
{
$this->inputStream = $stream;
}






public function getInputStream()
{
return $this->inputStream;
}




public function getName()
{
return 'dialog';
}






private function getShell()
{
if (null !== self::$shell) {
return self::$shell;
}

self::$shell = false;

if (file_exists('/usr/bin/env')) {

 $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
self::$shell = $sh;
break;
}
}
}

return self::$shell;
}

private function hasSttyAvailable()
{
if (null !== self::$stty) {
return self::$stty;
}

exec('stty 2>&1', $output, $exitcode);

return self::$stty = $exitcode === 0;
}













private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$e = null;
while (false === $attempts || $attempts--) {
if (null !== $e) {
$output->writeln($this->getHelperSet()->get('formatter')->formatBlock($e->getMessage(), 'error'));
}

try {
return call_user_func($validator, $interviewer());
} catch (\Exception $e) {
}
}

throw $e;
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Formatter\OutputFormatter;






class SymfonyQuestionHelper extends QuestionHelper
{



public function ask(InputInterface $input, OutputInterface $output, Question $question)
{
$validator = $question->getValidator();
$question->setValidator(function ($value) use ($validator) {
if (null !== $validator) {
$value = $validator($value);
} else {

 if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
throw new LogicException('A value is required.');
}
}

return $value;
});

return parent::ask($input, $output, $question);
}




protected function writePrompt(OutputInterface $output, Question $question)
{
$text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
$default = $question->getDefault();

switch (true) {
case null === $default:
$text = sprintf(' <info>%s</info>:', $text);

break;

case $question instanceof ConfirmationQuestion:
$text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');

break;

case $question instanceof ChoiceQuestion && $question->isMultiselect():
$choices = $question->getChoices();
$default = explode(',', $default);

foreach ($default as $key => $value) {
$default[$key] = $choices[trim($value)];
}

$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(implode(', ', $default)));

break;

case $question instanceof ChoiceQuestion:
$choices = $question->getChoices();
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($choices[$default]));

break;

default:
$text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default));
}

$output->writeln($text);

if ($question instanceof ChoiceQuestion) {
$width = max(array_map('strlen', array_keys($question->getChoices())));

foreach ($question->getChoices() as $key => $value) {
$output->writeln(sprintf("  [<comment>%-${width}s</comment>] %s", $key, $value));
}
}

$output->write(' > ');
}




protected function writeError(OutputInterface $output, \Exception $error)
{
if ($output instanceof SymfonyStyle) {
$output->newLine();
$output->error($error->getMessage());

return;
}

parent::writeError($output, $error);
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\LogicException;







class ProgressBar
{

 private $barWidth = 28;
private $barChar;
private $emptyBarChar = '-';
private $progressChar = '>';
private $format;
private $internalFormat;
private $redrawFreq = 1;




private $output;
private $step = 0;
private $max;
private $startTime;
private $stepWidth;
private $percent = 0.0;
private $formatLineCount;
private $messages = array();
private $overwrite = true;
private $firstRun = true;

private static $formatters;
private static $formats;







public function __construct(OutputInterface $output, $max = 0)
{
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}

$this->output = $output;
$this->setMaxSteps($max);

if (!$this->output->isDecorated()) {

 $this->overwrite = false;


 $this->setRedrawFrequency($max / 10);
}

$this->startTime = time();
}









public static function setPlaceholderFormatterDefinition($name, $callable)
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
}

self::$formatters[$name] = $callable;
}








public static function getPlaceholderFormatterDefinition($name)
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
}

return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
}









public static function setFormatDefinition($name, $format)
{
if (!self::$formats) {
self::$formats = self::initFormats();
}

self::$formats[$name] = $format;
}








public static function getFormatDefinition($name)
{
if (!self::$formats) {
self::$formats = self::initFormats();
}

return isset(self::$formats[$name]) ? self::$formats[$name] : null;
}











public function setMessage($message, $name = 'message')
{
$this->messages[$name] = $message;
}

public function getMessage($name = 'message')
{
return $this->messages[$name];
}






public function getStartTime()
{
return $this->startTime;
}






public function getMaxSteps()
{
return $this->max;
}








public function getStep()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED);

return $this->getProgress();
}






public function getProgress()
{
return $this->step;
}








public function getStepWidth()
{
return $this->stepWidth;
}






public function getProgressPercent()
{
return $this->percent;
}






public function setBarWidth($size)
{
$this->barWidth = (int) $size;
}






public function getBarWidth()
{
return $this->barWidth;
}






public function setBarCharacter($char)
{
$this->barChar = $char;
}






public function getBarCharacter()
{
if (null === $this->barChar) {
return $this->max ? '=' : $this->emptyBarChar;
}

return $this->barChar;
}






public function setEmptyBarCharacter($char)
{
$this->emptyBarChar = $char;
}






public function getEmptyBarCharacter()
{
return $this->emptyBarChar;
}






public function setProgressCharacter($char)
{
$this->progressChar = $char;
}






public function getProgressCharacter()
{
return $this->progressChar;
}






public function setFormat($format)
{
$this->format = null;
$this->internalFormat = $format;
}






public function setRedrawFrequency($freq)
{
$this->redrawFreq = max((int) $freq, 1);
}






public function start($max = null)
{
$this->startTime = time();
$this->step = 0;
$this->percent = 0.0;

if (null !== $max) {
$this->setMaxSteps($max);
}

$this->display();
}








public function advance($step = 1)
{
$this->setProgress($this->step + $step);
}










public function setCurrent($step)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED);

$this->setProgress($step);
}






public function setOverwrite($overwrite)
{
$this->overwrite = (bool) $overwrite;
}








public function setProgress($step)
{
$step = (int) $step;
if ($step < $this->step) {
throw new LogicException('You can\'t regress the progress bar.');
}

if ($this->max && $step > $this->max) {
$this->max = $step;
}

$prevPeriod = (int) ($this->step / $this->redrawFreq);
$currPeriod = (int) ($step / $this->redrawFreq);
$this->step = $step;
$this->percent = $this->max ? (float) $this->step / $this->max : 0;
if ($prevPeriod !== $currPeriod || $this->max === $step) {
$this->display();
}
}




public function finish()
{
if (!$this->max) {
$this->max = $this->step;
}

if ($this->step === $this->max && !$this->overwrite) {

 return;
}

$this->setProgress($this->max);
}




public function display()
{
if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
return;
}

if (null === $this->format) {
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
}


 $self = $this;
$output = $this->output;
$messages = $this->messages;
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) {
if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
$text = call_user_func($formatter, $self, $output);
} elseif (isset($messages[$matches[1]])) {
$text = $messages[$matches[1]];
} else {
return $matches[0];
}

if (isset($matches[2])) {
$text = sprintf('%'.$matches[2], $text);
}

return $text;
}, $this->format));
}








public function clear()
{
if (!$this->overwrite) {
return;
}

if (null === $this->format) {
$this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
}

$this->overwrite('');
}






private function setRealFormat($format)
{

 if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
$this->format = self::getFormatDefinition($format.'_nomax');
} elseif (null !== self::getFormatDefinition($format)) {
$this->format = self::getFormatDefinition($format);
} else {
$this->format = $format;
}

$this->formatLineCount = substr_count($this->format, "\n");
}






private function setMaxSteps($max)
{
$this->max = max(0, (int) $max);
$this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
}






private function overwrite($message)
{
if ($this->overwrite) {
if (!$this->firstRun) {

 $this->output->write("\x0D");


 $this->output->write("\x1B[2K");


 if ($this->formatLineCount > 0) {
$this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
}
}
} elseif ($this->step > 0) {
$this->output->writeln('');
}

$this->firstRun = false;

$this->output->write($message);
}

private function determineBestFormat()
{
switch ($this->output->getVerbosity()) {

 case OutputInterface::VERBOSITY_VERBOSE:
return $this->max ? 'verbose' : 'verbose_nomax';
case OutputInterface::VERBOSITY_VERY_VERBOSE:
return $this->max ? 'very_verbose' : 'very_verbose_nomax';
case OutputInterface::VERBOSITY_DEBUG:
return $this->max ? 'debug' : 'debug_nomax';
default:
return $this->max ? 'normal' : 'normal_nomax';
}
}

private static function initPlaceholderFormatters()
{
return array(
'bar' => function (ProgressBar $bar, OutputInterface $output) {
$completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
$display = str_repeat($bar->getBarCharacter(), $completeBars);
if ($completeBars < $bar->getBarWidth()) {
$emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
$display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
}

return $display;
},
'elapsed' => function (ProgressBar $bar) {
return Helper::formatTime(time() - $bar->getStartTime());
},
'remaining' => function (ProgressBar $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
}

if (!$bar->getProgress()) {
$remaining = 0;
} else {
$remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
}

return Helper::formatTime($remaining);
},
'estimated' => function (ProgressBar $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
}

if (!$bar->getProgress()) {
$estimated = 0;
} else {
$estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
}

return Helper::formatTime($estimated);
},
'memory' => function (ProgressBar $bar) {
return Helper::formatMemory(memory_get_usage(true));
},
'current' => function (ProgressBar $bar) {
return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
},
'max' => function (ProgressBar $bar) {
return $bar->getMaxSteps();
},
'percent' => function (ProgressBar $bar) {
return floor($bar->getProgressPercent() * 100);
},
);
}

private static function initFormats()
{
return array(
'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
'normal_nomax' => ' %current% [%bar%]',

'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',

'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',

'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
);
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;






abstract class Helper implements HelperInterface
{
protected $helperSet = null;






public function setHelperSet(HelperSet $helperSet = null)
{
$this->helperSet = $helperSet;
}






public function getHelperSet()
{
return $this->helperSet;
}








public static function strlen($string)
{
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return strlen($string);
}

return mb_strwidth($string, $encoding);
}

public static function formatTime($secs)
{
static $timeFormats = array(
array(0, '< 1 sec'),
array(1, '1 sec'),
array(2, 'secs', 1),
array(60, '1 min'),
array(120, 'mins', 60),
array(3600, '1 hr'),
array(7200, 'hrs', 3600),
array(86400, '1 day'),
array(172800, 'days', 86400),
);

foreach ($timeFormats as $index => $format) {
if ($secs >= $format[0]) {
if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
|| $index == count($timeFormats) - 1
) {
if (2 == count($format)) {
return $format[1];
}

return floor($secs / $format[2]).' '.$format[1];
}
}
}
}

public static function formatMemory($memory)
{
if ($memory >= 1024 * 1024 * 1024) {
return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
}

if ($memory >= 1024 * 1024) {
return sprintf('%.1f MiB', $memory / 1024 / 1024);
}

if ($memory >= 1024) {
return sprintf('%d KiB', $memory / 1024);
}

return sprintf('%d B', $memory);
}

public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string)
{
$isDecorated = $formatter->isDecorated();
$formatter->setDecorated(false);

 $string = $formatter->format($string);

 $string = preg_replace("/\033\[[^m]*m/", '', $string);
$formatter->setDecorated($isDecorated);

return self::strlen($string);
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Output\OutputInterface;




class ProgressIndicator
{
private $output;
private $startTime;
private $format;
private $message;
private $indicatorValues;
private $indicatorCurrent;
private $indicatorChangeInterval;
private $indicatorUpdateTime;
private $started = false;

private static $formatters;
private static $formats;







public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
{
$this->output = $output;

if (null === $format) {
$format = $this->determineBestFormat();
}

if (null === $indicatorValues) {
$indicatorValues = array('-', '\\', '|', '/');
}

$indicatorValues = array_values($indicatorValues);

if (2 > count($indicatorValues)) {
throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
}

$this->format = self::getFormatDefinition($format);
$this->indicatorChangeInterval = $indicatorChangeInterval;
$this->indicatorValues = $indicatorValues;
$this->startTime = time();
}






public function setMessage($message)
{
$this->message = $message;

$this->display();
}








public function getMessage()
{
return $this->message;
}








public function getStartTime()
{
return $this->startTime;
}








public function getCurrentValue()
{
return $this->indicatorValues[$this->indicatorCurrent % count($this->indicatorValues)];
}






public function start($message)
{
if ($this->started) {
throw new LogicException('Progress indicator already started.');
}

$this->message = $message;
$this->started = true;
$this->startTime = time();
$this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
$this->indicatorCurrent = 0;

$this->display();
}




public function advance()
{
if (!$this->started) {
throw new LogicException('Progress indicator has not yet been started.');
}

if (!$this->output->isDecorated()) {
return;
}

$currentTime = $this->getCurrentTimeInMilliseconds();

if ($currentTime < $this->indicatorUpdateTime) {
return;
}

$this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
++$this->indicatorCurrent;

$this->display();
}






public function finish($message)
{
if (!$this->started) {
throw new LogicException('Progress indicator has not yet been started.');
}

$this->message = $message;
$this->display();
$this->output->writeln('');
$this->started = false;
}








public static function getFormatDefinition($name)
{
if (!self::$formats) {
self::$formats = self::initFormats();
}

return isset(self::$formats[$name]) ? self::$formats[$name] : null;
}









public static function setPlaceholderFormatterDefinition($name, $callable)
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
}

self::$formatters[$name] = $callable;
}








public static function getPlaceholderFormatterDefinition($name)
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
}

return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
}

private function display()
{
if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
return;
}

$self = $this;

$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
return call_user_func($formatter, $self);
}

return $matches[0];
}, $this->format));
}

private function determineBestFormat()
{
switch ($this->output->getVerbosity()) {

 case OutputInterface::VERBOSITY_VERBOSE:
return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
case OutputInterface::VERBOSITY_VERY_VERBOSE:
case OutputInterface::VERBOSITY_DEBUG:
return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
default:
return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
}
}






private function overwrite($message)
{
if ($this->output->isDecorated()) {
$this->output->write("\x0D\x1B[2K");
$this->output->write($message);
} else {
$this->output->writeln($message);
}
}

private function getCurrentTimeInMilliseconds()
{
return round(microtime(true) * 1000);
}

private static function initPlaceholderFormatters()
{
return array(
'indicator' => function (ProgressIndicator $indicator) {
return $indicator->getCurrentValue();
},
'message' => function (ProgressIndicator $indicator) {
return $indicator->getMessage();
},
'elapsed' => function (ProgressIndicator $indicator) {
return Helper::formatTime(time() - $indicator->getStartTime());
},
'memory' => function () {
return Helper::formatMemory(memory_get_usage(true));
},
);
}

private static function initFormats()
{
return array(
'normal' => ' %indicator% %message%',
'normal_no_ansi' => ' %message%',

'verbose' => ' %indicator% %message% (%elapsed:6s%)',
'verbose_no_ansi' => ' %message% (%elapsed:6s%)',

'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
);
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;







class TableStyle
{
private $paddingChar = ' ';
private $horizontalBorderChar = '-';
private $verticalBorderChar = '|';
private $crossingChar = '+';
private $cellHeaderFormat = '<info>%s</info>';
private $cellRowFormat = '%s';
private $cellRowContentFormat = ' %s ';
private $borderFormat = '%s';
private $padType = STR_PAD_RIGHT;








public function setPaddingChar($paddingChar)
{
if (!$paddingChar) {
throw new LogicException('The padding char must not be empty');
}

$this->paddingChar = $paddingChar;

return $this;
}






public function getPaddingChar()
{
return $this->paddingChar;
}








public function setHorizontalBorderChar($horizontalBorderChar)
{
$this->horizontalBorderChar = $horizontalBorderChar;

return $this;
}






public function getHorizontalBorderChar()
{
return $this->horizontalBorderChar;
}








public function setVerticalBorderChar($verticalBorderChar)
{
$this->verticalBorderChar = $verticalBorderChar;

return $this;
}






public function getVerticalBorderChar()
{
return $this->verticalBorderChar;
}








public function setCrossingChar($crossingChar)
{
$this->crossingChar = $crossingChar;

return $this;
}






public function getCrossingChar()
{
return $this->crossingChar;
}








public function setCellHeaderFormat($cellHeaderFormat)
{
$this->cellHeaderFormat = $cellHeaderFormat;

return $this;
}






public function getCellHeaderFormat()
{
return $this->cellHeaderFormat;
}








public function setCellRowFormat($cellRowFormat)
{
$this->cellRowFormat = $cellRowFormat;

return $this;
}






public function getCellRowFormat()
{
return $this->cellRowFormat;
}








public function setCellRowContentFormat($cellRowContentFormat)
{
$this->cellRowContentFormat = $cellRowContentFormat;

return $this;
}






public function getCellRowContentFormat()
{
return $this->cellRowContentFormat;
}








public function setBorderFormat($borderFormat)
{
$this->borderFormat = $borderFormat;

return $this;
}






public function getBorderFormat()
{
return $this->borderFormat;
}








public function setPadType($padType)
{
if (!in_array($padType, array(STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH), true)) {
throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
}

$this->padType = $padType;

return $this;
}






public function getPadType()
{
return $this->padType;
}
}
<?php










namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Exception\InvalidArgumentException;




class TableCell
{



private $value;




private $options = array(
'rowspan' => 1,
'colspan' => 1,
);





public function __construct($value = '', array $options = array())
{
if (is_numeric($value) && !is_string($value)) {
$value = (string) $value;
}

$this->value = $value;


 if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff)));
}

$this->options = array_merge($this->options, $options);
}






public function __toString()
{
return $this->value;
}






public function getColspan()
{
return (int) $this->options['colspan'];
}






public function getRowspan()
{
return (int) $this->options['rowspan'];
}
}
<?php










namespace Symfony\Component\Console\Output;







interface ConsoleOutputInterface extends OutputInterface
{





public function getErrorOutput();






public function setErrorOutput(OutputInterface $error);
}
<?php










namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;














class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{



private $stderr;








public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
{
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);

$actualDecorated = $this->isDecorated();
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());

if (null === $decorated) {
$this->setDecorated($actualDecorated && $this->stderr->isDecorated());
}
}




public function setDecorated($decorated)
{
parent::setDecorated($decorated);
$this->stderr->setDecorated($decorated);
}




public function setFormatter(OutputFormatterInterface $formatter)
{
parent::setFormatter($formatter);
$this->stderr->setFormatter($formatter);
}




public function setVerbosity($level)
{
parent::setVerbosity($level);
$this->stderr->setVerbosity($level);
}




public function getErrorOutput()
{
return $this->stderr;
}




public function setErrorOutput(OutputInterface $error)
{
$this->stderr = $error;
}







protected function hasStdoutSupport()
{
return false === $this->isRunningOS400();
}







protected function hasStderrSupport()
{
return false === $this->isRunningOS400();
}







private function isRunningOS400()
{
$checks = array(
function_exists('php_uname') ? php_uname('s') : '',
getenv('OSTYPE'),
PHP_OS,
);

return false !== stripos(implode(';', $checks), 'OS400');
}




private function openOutputStream()
{
$outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output';

return @fopen($outputStream, 'w') ?: fopen('php://output', 'w');
}




private function openErrorStream()
{
$errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output';

return fopen($errorStream, 'w');
}
}
<?php










namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;









class NullOutput implements OutputInterface
{



public function setFormatter(OutputFormatterInterface $formatter)
{

 }




public function getFormatter()
{

 return new OutputFormatter();
}




public function setDecorated($decorated)
{

 }




public function isDecorated()
{
return false;
}




public function setVerbosity($level)
{

 }




public function getVerbosity()
{
return self::VERBOSITY_QUIET;
}




public function isQuiet()
{
return true;
}




public function isVerbose()
{
return false;
}




public function isVeryVerbose()
{
return false;
}




public function isDebug()
{
return false;
}




public function writeln($messages, $options = self::OUTPUT_NORMAL)
{

 }




public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
{

 }
}
<?php










namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;














class StreamOutput extends Output
{
private $stream;











public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
{
if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
}

$this->stream = $stream;

if (null === $decorated) {
$decorated = $this->hasColorSupport();
}

parent::__construct($verbosity, $decorated, $formatter);
}






public function getStream()
{
return $this->stream;
}




protected function doWrite($message, $newline)
{
if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {

 throw new RuntimeException('Unable to write output.');
}

fflush($this->stream);
}











protected function hasColorSupport()
{
if (DIRECTORY_SEPARATOR === '\\') {
return
'10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
}

return function_exists('posix_isatty') && @posix_isatty($this->stream);
}
}
<?php










namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Formatter\OutputFormatter;














abstract class Output implements OutputInterface
{
private $verbosity;
private $formatter;








public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
{
$this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
$this->formatter = $formatter ?: new OutputFormatter();
$this->formatter->setDecorated($decorated);
}




public function setFormatter(OutputFormatterInterface $formatter)
{
$this->formatter = $formatter;
}




public function getFormatter()
{
return $this->formatter;
}




public function setDecorated($decorated)
{
$this->formatter->setDecorated($decorated);
}




public function isDecorated()
{
return $this->formatter->isDecorated();
}




public function setVerbosity($level)
{
$this->verbosity = (int) $level;
}




public function getVerbosity()
{
return $this->verbosity;
}




public function isQuiet()
{
return self::VERBOSITY_QUIET === $this->verbosity;
}




public function isVerbose()
{
return self::VERBOSITY_VERBOSE <= $this->verbosity;
}




public function isVeryVerbose()
{
return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
}




public function isDebug()
{
return self::VERBOSITY_DEBUG <= $this->verbosity;
}




public function writeln($messages, $options = self::OUTPUT_NORMAL)
{
$this->write($messages, true, $options);
}




public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
{
$messages = (array) $messages;

$types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
$type = $types & $options ?: self::OUTPUT_NORMAL;

$verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
$verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;

if ($verbosity > $this->getVerbosity()) {
return;
}

foreach ($messages as $message) {
switch ($type) {
case OutputInterface::OUTPUT_NORMAL:
$message = $this->formatter->format($message);
break;
case OutputInterface::OUTPUT_RAW:
break;
case OutputInterface::OUTPUT_PLAIN:
$message = strip_tags($this->formatter->format($message));
break;
}

$this->doWrite($message, $newline);
}
}







abstract protected function doWrite($message, $newline);
}
<?php










namespace Symfony\Component\Console\Output;




class BufferedOutput extends Output
{



private $buffer = '';






public function fetch()
{
$content = $this->buffer;
$this->buffer = '';

return $content;
}




protected function doWrite($message, $newline)
{
$this->buffer .= $message;

if ($newline) {
$this->buffer .= "\n";
}
}
}
<?php










namespace Symfony\Component\Console\Output;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;






interface OutputInterface
{
const VERBOSITY_QUIET = 16;
const VERBOSITY_NORMAL = 32;
const VERBOSITY_VERBOSE = 64;
const VERBOSITY_VERY_VERBOSE = 128;
const VERBOSITY_DEBUG = 256;

const OUTPUT_NORMAL = 1;
const OUTPUT_RAW = 2;
const OUTPUT_PLAIN = 4;








public function write($messages, $newline = false, $options = 0);







public function writeln($messages, $options = 0);






public function setVerbosity($level);






public function getVerbosity();






public function setDecorated($decorated);






public function isDecorated();






public function setFormatter(OutputFormatterInterface $formatter);






public function getFormatter();
}
<?php










namespace Symfony\Component\Console\Event;






class ConsoleCommandEvent extends ConsoleEvent
{



const RETURN_CODE_DISABLED = 113;






private $commandShouldRun = true;






public function disableCommand()
{
return $this->commandShouldRun = false;
}






public function enableCommand()
{
return $this->commandShouldRun = true;
}






public function commandShouldRun()
{
return $this->commandShouldRun;
}
}
<?php










namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;






class ConsoleTerminateEvent extends ConsoleEvent
{





private $exitCode;

public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
{
parent::__construct($command, $input, $output);

$this->setExitCode($exitCode);
}






public function setExitCode($exitCode)
{
$this->exitCode = (int) $exitCode;
}






public function getExitCode()
{
return $this->exitCode;
}
}
<?php










namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\Event;






class ConsoleEvent extends Event
{
protected $command;

private $input;
private $output;

public function __construct(Command $command, InputInterface $input, OutputInterface $output)
{
$this->command = $command;
$this->input = $input;
$this->output = $output;
}






public function getCommand()
{
return $this->command;
}






public function getInput()
{
return $this->input;
}






public function getOutput()
{
return $this->output;
}
}
<?php










namespace Symfony\Component\Console\Event;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;






class ConsoleExceptionEvent extends ConsoleEvent
{
private $exception;
private $exitCode;

public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
{
parent::__construct($command, $input, $output);

$this->setException($exception);
$this->exitCode = (int) $exitCode;
}






public function getException()
{
return $this->exception;
}








public function setException(\Exception $exception)
{
$this->exception = $exception;
}






public function getExitCode()
{
return $this->exitCode;
}
}
<?php










namespace Symfony\Component\Console\Tests\Logger;

use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Logger\ConsoleLogger;
use Symfony\Component\Console\Tests\Fixtures\DummyOutput;
use Symfony\Component\Console\Output\OutputInterface;







class ConsoleLoggerTest extends TestCase
{



protected $output;




public function getLogger()
{
$this->output = new DummyOutput(OutputInterface::VERBOSITY_VERBOSE);

return new ConsoleLogger($this->output, array(
LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL,
LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL,
LogLevel::DEBUG => OutputInterface::VERBOSITY_NORMAL,
));
}






public function getLogs()
{
return $this->output->getLogs();
}

public function testImplements()
{
$this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
}




public function testLogsAtAllLevels($level, $message)
{
$logger = $this->getLogger();
$logger->{$level}($message, array('user' => 'Bob'));
$logger->log($level, $message, array('user' => 'Bob'));

$expected = array(
$level.' message of level '.$level.' with context: Bob',
$level.' message of level '.$level.' with context: Bob',
);
$this->assertEquals($expected, $this->getLogs());
}

public function provideLevelsAndMessages()
{
return array(
LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
);
}




public function testThrowsOnInvalidLevel()
{
$logger = $this->getLogger();
$logger->log('invalid level', 'Foo');
}

public function testContextReplacement()
{
$logger = $this->getLogger();
$logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));

$expected = array('info {Message {nothing} Bob Bar a}');
$this->assertEquals($expected, $this->getLogs());
}

public function testObjectCastToString()
{
if (method_exists($this, 'createPartialMock')) {
$dummy = $this->createPartialMock('Symfony\Component\Console\Tests\Logger\DummyTest', array('__toString'));
} else {
$dummy = $this->getMock('Symfony\Component\Console\Tests\Logger\DummyTest', array('__toString'));
}
$dummy->expects($this->once())
->method('__toString')
->will($this->returnValue('DUMMY'));

$this->getLogger()->warning($dummy);

$expected = array('warning DUMMY');
$this->assertEquals($expected, $this->getLogs());
}

public function testContextCanContainAnything()
{
$context = array(
'bool' => true,
'null' => null,
'string' => 'Foo',
'int' => 0,
'float' => 0.5,
'nested' => array('with object' => new DummyTest()),
'object' => new \DateTime(),
'resource' => fopen('php://memory', 'r'),
);

$this->getLogger()->warning('Crazy context data', $context);

$expected = array('warning Crazy context data');
$this->assertEquals($expected, $this->getLogs());
}

public function testContextExceptionKeyCanBeExceptionOrOtherValues()
{
$logger = $this->getLogger();
$logger->warning('Random message', array('exception' => 'oops'));
$logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));

$expected = array(
'warning Random message',
'critical Uncaught Exception!',
);
$this->assertEquals($expected, $this->getLogs());
}
}

class DummyTest
{
public function __toString()
{
}
}
<?php










namespace Symfony\Component\Console\Tests\Style;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Tester\CommandTester;

class SymfonyStyleTest extends TestCase
{

protected $command;

protected $tester;

protected function setUp()
{
$this->command = new Command('sfstyle');
$this->tester = new CommandTester($this->command);
}

protected function tearDown()
{
$this->command = null;
$this->tester = null;
}




public function testOutputs($inputCommandFilepath, $outputFilepath)
{
$code = require $inputCommandFilepath;
$this->command->setCode($code);
$this->tester->execute(array(), array('interactive' => false, 'decorated' => false));
$this->assertStringEqualsFile($outputFilepath, $this->tester->getDisplay(true));
}

public function inputCommandToOutputFilesProvider()
{
$baseDir = __DIR__.'/../Fixtures/Style/SymfonyStyle';

return array_map(null, glob($baseDir.'/command/command_*.php'), glob($baseDir.'/output/output_*.txt'));
}
}





class SymfonyStyleWithForcedLineLength extends SymfonyStyle
{
public function __construct(InputInterface $input, OutputInterface $output)
{
parent::__construct($input, $output);

$ref = new \ReflectionProperty(get_parent_class($this), 'lineLength');
$ref->setAccessible(true);
$ref->setValue($this, 120);
}
}
<?php










namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplicationMbString;
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommandMbString;

class TextDescriptorTest extends AbstractDescriptorTest
{
public function getDescribeCommandTestData()
{
return $this->getDescriptionTestData(array_merge(
ObjectsProvider::getCommands(),
array('command_mbstring' => new DescriptorCommandMbString())
));
}

public function getDescribeApplicationTestData()
{
return $this->getDescriptionTestData(array_merge(
ObjectsProvider::getApplications(),
array('application_mbstring' => new DescriptorApplicationMbString())
));
}

protected function getDescriptor()
{
return new TextDescriptor();
}

protected function getFormat()
{
return 'txt';
}
}
<?php










namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\XmlDescriptor;

class XmlDescriptorTest extends AbstractDescriptorTest
{
protected function getDescriptor()
{
return new XmlDescriptor();
}

protected function getFormat()
{
return 'xml';
}
}
<?php










namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplicationMbString;
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommandMbString;

class MarkdownDescriptorTest extends AbstractDescriptorTest
{
public function getDescribeCommandTestData()
{
return $this->getDescriptionTestData(array_merge(
ObjectsProvider::getCommands(),
array('command_mbstring' => new DescriptorCommandMbString())
));
}

public function getDescribeApplicationTestData()
{
return $this->getDescriptionTestData(array_merge(
ObjectsProvider::getApplications(),
array('application_mbstring' => new DescriptorApplicationMbString())
));
}

protected function getDescriptor()
{
return new MarkdownDescriptor();
}

protected function getFormat()
{
return 'md';
}
}
<?php










namespace Symfony\Component\Console\Tests\Descriptor;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\BufferedOutput;

abstract class AbstractDescriptorTest extends TestCase
{

public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
{
$this->assertDescription($expectedDescription, $argument);
}


public function testDescribeInputOption(InputOption $option, $expectedDescription)
{
$this->assertDescription($expectedDescription, $option);
}


public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription)
{
$this->assertDescription($expectedDescription, $definition);
}


public function testDescribeCommand(Command $command, $expectedDescription)
{
$this->assertDescription($expectedDescription, $command);
}


public function testDescribeApplication(Application $application, $expectedDescription)
{

 
 
 foreach ($application->all() as $command) {
$command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
}

$this->assertDescription($expectedDescription, $application);
}

public function getDescribeInputArgumentTestData()
{
return $this->getDescriptionTestData(ObjectsProvider::getInputArguments());
}

public function getDescribeInputOptionTestData()
{
return $this->getDescriptionTestData(ObjectsProvider::getInputOptions());
}

public function getDescribeInputDefinitionTestData()
{
return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions());
}

public function getDescribeCommandTestData()
{
return $this->getDescriptionTestData(ObjectsProvider::getCommands());
}

public function getDescribeApplicationTestData()
{
return $this->getDescriptionTestData(ObjectsProvider::getApplications());
}

abstract protected function getDescriptor();

abstract protected function getFormat();

protected function getDescriptionTestData(array $objects)
{
$data = array();
foreach ($objects as $name => $object) {
$description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat()));
$data[] = array($object, $description);
}

return $data;
}

protected function assertDescription($expectedDescription, $describedObject)
{
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
$this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
$this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch())));
}
}
<?php










namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Descriptor\JsonDescriptor;
use Symfony\Component\Console\Output\BufferedOutput;

class JsonDescriptorTest extends AbstractDescriptorTest
{
protected function getDescriptor()
{
return new JsonDescriptor();
}

protected function getFormat()
{
return 'json';
}

protected function assertDescription($expectedDescription, $describedObject)
{
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
$this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
$this->assertEquals(json_decode(trim($expectedDescription), true), json_decode(trim(str_replace(PHP_EOL, "\n", $output->fetch())), true));
}
}
<?php










namespace Symfony\Component\Console\Tests\Descriptor;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1;
use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1;
use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2;




class ObjectsProvider
{
public static function getInputArguments()
{
return array(
'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED),
'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"),
'input_argument_with_style' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', '<comment>style</>'),
);
}

public static function getInputOptions()
{
return array(
'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE),
'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'),
'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
'input_option_5' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, "multiline\noption description"),
'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
'input_option_with_style' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description', '<comment>style</>'),
'input_option_with_style_array' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'option description', array('<comment>Hello</comment>', '<info>world</info>')),
);
}

public static function getInputDefinitions()
{
return array(
'input_definition_1' => new InputDefinition(),
'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))),
'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))),
'input_definition_4' => new InputDefinition(array(
new InputArgument('argument_name', InputArgument::REQUIRED),
new InputOption('option_name', 'o', InputOption::VALUE_NONE),
)),
);
}

public static function getCommands()
{
return array(
'command_1' => new DescriptorCommand1(),
'command_2' => new DescriptorCommand2(),
);
}

public static function getApplications()
{
return array(
'application_1' => new DescriptorApplication1(),
'application_2' => new DescriptorApplication2(),
);
}
}
<?php










namespace Symfony\Component\Console\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Tester\ApplicationTester;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;

class ApplicationTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
require_once self::$fixturesPath.'/FooCommand.php';
require_once self::$fixturesPath.'/Foo1Command.php';
require_once self::$fixturesPath.'/Foo2Command.php';
require_once self::$fixturesPath.'/Foo3Command.php';
require_once self::$fixturesPath.'/Foo4Command.php';
require_once self::$fixturesPath.'/Foo5Command.php';
require_once self::$fixturesPath.'/FoobarCommand.php';
require_once self::$fixturesPath.'/BarBucCommand.php';
require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
}

protected function normalizeLineBreaks($text)
{
return str_replace(PHP_EOL, "\n", $text);
}






protected function ensureStaticCommandHelp(Application $application)
{
foreach ($application->all() as $command) {
$command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
}
}

public function testConstructor()
{
$application = new Application('foo', 'bar');
$this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument');
$this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument');
$this->assertEquals(array('help', 'list'), array_keys($application->all()), '__construct() registered the help and list commands by default');
}

public function testSetGetName()
{
$application = new Application();
$application->setName('foo');
$this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application');
}

public function testSetGetVersion()
{
$application = new Application();
$application->setVersion('bar');
$this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application');
}

public function testGetLongVersion()
{
$application = new Application('foo', 'bar');
$this->assertEquals('<info>foo</info> version <comment>bar</comment>', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
}

public function testHelp()
{
$application = new Application();
$this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->getHelp() returns a help message');
}

public function testAll()
{
$application = new Application();
$commands = $application->all();
$this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands');

$application->add(new \FooCommand());
$commands = $application->all('foo');
$this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
}

public function testRegister()
{
$application = new Application();
$command = $application->register('foo');
$this->assertEquals('foo', $command->getName(), '->register() registers a new command');
}

public function testAdd()
{
$application = new Application();
$application->add($foo = new \FooCommand());
$commands = $application->all();
$this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command');

$application = new Application();
$application->addCommands(array($foo = new \FooCommand(), $foo1 = new \Foo1Command()));
$commands = $application->all();
$this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands');
}





public function testAddCommandWithEmptyConstructor()
{
$application = new Application();
$application->add(new \Foo5Command());
}

public function testHasGet()
{
$application = new Application();
$this->assertTrue($application->has('list'), '->has() returns true if a named command is registered');
$this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered');

$application->add($foo = new \FooCommand());
$this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered');
$this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
$this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');

$application = new Application();
$application->add($foo = new \FooCommand());

 $r = new \ReflectionObject($application);
$p = $r->getProperty('wantHelps');
$p->setAccessible(true);
$p->setValue($application, true);
$command = $application->get('foo:bar');
$this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input');
}

public function testSilentHelp()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$tester = new ApplicationTester($application);
$tester->run(array('-h' => true, '-q' => true), array('decorated' => false));

$this->assertEmpty($tester->getDisplay(true));
}





public function testGetInvalidCommand()
{
$application = new Application();
$application->get('foofoo');
}

public function testGetNamespaces()
{
$application = new Application();
$application->add(new \FooCommand());
$application->add(new \Foo1Command());
$this->assertEquals(array('foo'), $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces');
}

public function testFindNamespace()
{
$application = new Application();
$application->add(new \FooCommand());
$this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
$this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation');
$application->add(new \Foo2Command());
$this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
}

public function testFindNamespaceWithSubnamespaces()
{
$application = new Application();
$application->add(new \FooSubnamespaced1Command());
$application->add(new \FooSubnamespaced2Command());
$this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces');
}





public function testFindAmbiguousNamespace()
{
$application = new Application();
$application->add(new \BarBucCommand());
$application->add(new \FooCommand());
$application->add(new \Foo2Command());
$application->findNamespace('f');
}





public function testFindInvalidNamespace()
{
$application = new Application();
$application->findNamespace('bar');
}





public function testFindUniqueNameButNamespaceName()
{
$application = new Application();
$application->add(new \FooCommand());
$application->add(new \Foo1Command());
$application->add(new \Foo2Command());

$application->find($commandName = 'foo1');
}

public function testFind()
{
$application = new Application();
$application->add(new \FooCommand());

$this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
$this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
$this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists');
$this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist');
$this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
}




public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
{
if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Console\Exception\CommandNotFoundException');
$this->expectExceptionMessage($expectedExceptionMessage);
} else {
$this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage);
}

$application = new Application();
$application->add(new \FooCommand());
$application->add(new \Foo1Command());
$application->add(new \Foo2Command());

$application->find($abbreviation);
}

public function provideAmbiguousAbbreviations()
{
return array(
array('f', 'Command "f" is not defined.'),
array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'),
);
}

public function testFindCommandEqualNamespace()
{
$application = new Application();
$application->add(new \Foo3Command());
$application->add(new \Foo4Command());

$this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name');
$this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name');
}

public function testFindCommandWithAmbiguousNamespacesButUniqueName()
{
$application = new Application();
$application->add(new \FooCommand());
$application->add(new \FoobarCommand());

$this->assertInstanceOf('FoobarCommand', $application->find('f:f'));
}

public function testFindCommandWithMissingNamespace()
{
$application = new Application();
$application->add(new \Foo4Command());

$this->assertInstanceOf('Foo4Command', $application->find('f::t'));
}






public function testFindAlternativeExceptionMessageSingle($name)
{
$application = new Application();
$application->add(new \Foo3Command());
$application->find($name);
}

public function provideInvalidCommandNamesSingle()
{
return array(
array('foo3:baR'),
array('foO3:bar'),
);
}

public function testFindAlternativeExceptionMessageMultiple()
{
$application = new Application();
$application->add(new \FooCommand());
$application->add(new \Foo1Command());
$application->add(new \Foo2Command());


 try {
$application->find('foo:baR');
$this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
$this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
$this->assertRegExp('/foo1:bar/', $e->getMessage());
$this->assertRegExp('/foo:bar/', $e->getMessage());
}


 try {
$application->find('foo2:bar');
$this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
$this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
$this->assertRegExp('/foo1/', $e->getMessage());
}

$application->add(new \Foo3Command());
$application->add(new \Foo4Command());


 try {
$a = $application->find('foo3:');
$this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e);
$this->assertRegExp('/foo3:bar/', $e->getMessage());
$this->assertRegExp('/foo3:bar:toh/', $e->getMessage());
}
}

public function testFindAlternativeCommands()
{
$application = new Application();

$application->add(new \FooCommand());
$application->add(new \Foo1Command());
$application->add(new \Foo2Command());

try {
$application->find($commandName = 'Unknown command');
$this->fail('->find() throws a CommandNotFoundException if command does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist');
$this->assertSame(array(), $e->getAlternatives());
$this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without alternatives');
}


 
 try {
$application->find($commandName = 'bar1');
$this->fail('->find() throws a CommandNotFoundException if command does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist');
$this->assertSame(array('afoobar1', 'foo:bar1'), $e->getAlternatives());
$this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
$this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"');
$this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"');
$this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative');
}
}

public function testFindAlternativeCommandsWithAnAlias()
{
$fooCommand = new \FooCommand();
$fooCommand->setAliases(array('foo2'));

$application = new Application();
$application->add($fooCommand);

$result = $application->find('foo');

$this->assertSame($fooCommand, $result);
}

public function testFindAlternativeNamespace()
{
$application = new Application();

$application->add(new \FooCommand());
$application->add(new \Foo1Command());
$application->add(new \Foo2Command());
$application->add(new \Foo3Command());

try {
$application->find('Unknown-namespace:Unknown-command');
$this->fail('->find() throws a CommandNotFoundException if namespace does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist');
$this->assertSame(array(), $e->getAlternatives());
$this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, without alternatives');
}

try {
$application->find('foo2:command');
$this->fail('->find() throws a CommandNotFoundException if namespace does not exist');
} catch (\Exception $e) {
$this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist');
$this->assertCount(3, $e->getAlternatives());
$this->assertContains('foo', $e->getAlternatives());
$this->assertContains('foo1', $e->getAlternatives());
$this->assertContains('foo3', $e->getAlternatives());
$this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative');
$this->assertRegExp('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"');
$this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"');
$this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"');
}
}

public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces()
{
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getNamespaces'))->getMock();
$application->expects($this->once())
->method('getNamespaces')
->will($this->returnValue(array('foo:sublong', 'bar:sub')));

$this->assertEquals('foo:sublong', $application->findNamespace('f:sub'));
}





public function testFindWithDoubleColonInNameThrowsException()
{
$application = new Application();
$application->add(new \FooCommand());
$application->add(new \Foo4Command());
$application->find('foo::bar');
}

public function testSetCatchExceptions()
{
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock();
$application->setAutoExit(false);
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(120));
$tester = new ApplicationTester($application);

$application->setCatchExceptions(true);
$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag');

$application->setCatchExceptions(false);
try {
$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->fail('->setCatchExceptions() sets the catch exception flag');
} catch (\Exception $e) {
$this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag');
$this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag');
}
}




public function testLegacyAsText()
{
$application = new Application();
$application->add(new \FooCommand());
$this->ensureStaticCommandHelp($application);
$this->assertStringEqualsFile(self::$fixturesPath.'/application_astext1.txt', $this->normalizeLineBreaks($application->asText()), '->asText() returns a text representation of the application');
$this->assertStringEqualsFile(self::$fixturesPath.'/application_astext2.txt', $this->normalizeLineBreaks($application->asText('foo')), '->asText() returns a text representation of the application');
}




public function testLegacyAsXml()
{
$application = new Application();
$application->add(new \FooCommand());
$this->ensureStaticCommandHelp($application);
$this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml1.txt', $application->asXml(), '->asXml() returns an XML representation of the application');
$this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml2.txt', $application->asXml('foo'), '->asXml() returns an XML representation of the application');
}

public function testRenderException()
{
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock();
$application->setAutoExit(false);
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(120));
$tester = new ApplicationTester($application);

$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exception');

$tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
$this->assertContains('Exception trace', $tester->getDisplay(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose');

$tester->run(array('command' => 'list', '--foo' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getDisplay(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command');

$application->add(new \Foo3Command());
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo3:bar'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

$tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock();
$application->setAutoExit(false);
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(32));
$tester = new ApplicationTester($application);

$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
}

public function testRenderExceptionWithDoubleWidthCharacters()
{
$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock();
$application->setAutoExit(false);
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(120));
$application->register('foo')->setCode(function () {
throw new \Exception('エラーメッセージ');
});
$tester = new ApplicationTester($application);

$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

$tester->run(array('command' => 'foo'), array('decorated' => true));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');

$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock();
$application->setAutoExit(false);
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(32));
$application->register('foo')->setCode(function () {
throw new \Exception('コマンドの実行中にエラーが発生しました。');
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
}

public function testRun()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);
$application->add($command = new \Foo1Command());
$_SERVER['argv'] = array('cli.php', 'foo:bar1');

ob_start();
$application->run();
ob_end_clean();

$this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given');
$this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given');

$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$this->ensureStaticCommandHelp($application);
$tester = new ApplicationTester($application);

$tester->run(array(), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed');

$tester->run(array('--help' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed');

$tester->run(array('-h' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed');

$tester->run(array('command' => 'list', '--help' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed');

$tester->run(array('command' => 'list', '-h' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed');

$tester->run(array('--ansi' => true));
$this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed');

$tester->run(array('--no-ansi' => true));
$this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed');

$tester->run(array('--version' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed');

$tester->run(array('-V' => true), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed');

$tester->run(array('command' => 'list', '--quiet' => true));
$this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed');
$this->assertFalse($tester->getInput()->isInteractive(), '->run() sets off the interactive mode if --quiet is passed');

$tester->run(array('command' => 'list', '-q' => true));
$this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed');
$this->assertFalse($tester->getInput()->isInteractive(), '->run() sets off the interactive mode if -q is passed');

$tester->run(array('command' => 'list', '--verbose' => true));
$this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed');

$tester->run(array('command' => 'list', '--verbose' => 1));
$this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed');

$tester->run(array('command' => 'list', '--verbose' => 2));
$this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed');

$tester->run(array('command' => 'list', '--verbose' => 3));
$this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed');

$tester->run(array('command' => 'list', '--verbose' => 4));
$this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed');

$tester->run(array('command' => 'list', '-v' => true));
$this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');

$tester->run(array('command' => 'list', '-vv' => true));
$this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');

$tester->run(array('command' => 'list', '-vvv' => true));
$this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');

$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);
$application->add(new \FooCommand());
$tester = new ApplicationTester($application);

$tester->run(array('command' => 'foo:bar', '--no-interaction' => true), array('decorated' => false));
$this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed');

$tester->run(array('command' => 'foo:bar', '-n' => true), array('decorated' => false));
$this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed');
}








public function testVerboseValueNotBreakArguments()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);
$application->add(new \FooCommand());

$output = new StreamOutput(fopen('php://memory', 'w', false));

$input = new ArgvInput(array('cli.php', '-v', 'foo:bar'));
$application->run($input, $output);

$input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar'));
$application->run($input, $output);
}

public function testRunReturnsIntegerExitCode()
{
$exception = new \Exception('', 4);

$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('doRun'))->getMock();
$application->setAutoExit(false);
$application->expects($this->once())
->method('doRun')
->will($this->throwException($exception));

$exitCode = $application->run(new ArrayInput(array()), new NullOutput());

$this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception');
}

public function testRunReturnsExitCodeOneForExceptionCodeZero()
{
$exception = new \Exception('', 0);

$application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('doRun'))->getMock();
$application->setAutoExit(false);
$application->expects($this->once())
->method('doRun')
->will($this->throwException($exception));

$exitCode = $application->run(new ArrayInput(array()), new NullOutput());

$this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
}





public function testAddingOptionWithDuplicateShortcut()
{
$dispatcher = new EventDispatcher();
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);
$application->setDispatcher($dispatcher);

$application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'Environment'));

$application
->register('foo')
->setAliases(array('f'))
->setDefinition(array(new InputOption('survey', 'e', InputOption::VALUE_REQUIRED, 'My option with a shortcut.')))
->setCode(function (InputInterface $input, OutputInterface $output) {})
;

$input = new ArrayInput(array('command' => 'foo'));
$output = new NullOutput();

$application->run($input, $output);
}





public function testAddingAlreadySetDefinitionElementData($def)
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);
$application
->register('foo')
->setDefinition(array($def))
->setCode(function (InputInterface $input, OutputInterface $output) {})
;

$input = new ArrayInput(array('command' => 'foo'));
$output = new NullOutput();
$application->run($input, $output);
}

public function getAddingAlreadySetDefinitionElementData()
{
return array(
array(new InputArgument('command', InputArgument::REQUIRED)),
array(new InputOption('quiet', '', InputOption::VALUE_NONE)),
array(new InputOption('query', 'q', InputOption::VALUE_NONE)),
);
}

public function testGetDefaultHelperSetReturnsDefaultValues()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$helperSet = $application->getHelperSet();

$this->assertTrue($helperSet->has('formatter'));
$this->assertTrue($helperSet->has('dialog'));
$this->assertTrue($helperSet->has('progress'));
}

public function testAddingSingleHelperSetOverwritesDefaultValues()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$application->setHelperSet(new HelperSet(array(new FormatterHelper())));

$helperSet = $application->getHelperSet();

$this->assertTrue($helperSet->has('formatter'));


 $this->assertFalse($helperSet->has('dialog'));
$this->assertFalse($helperSet->has('progress'));
}

public function testOverwritingDefaultHelperSetOverwritesDefaultValues()
{
$application = new CustomApplication();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$application->setHelperSet(new HelperSet(array(new FormatterHelper())));

$helperSet = $application->getHelperSet();

$this->assertTrue($helperSet->has('formatter'));


 $this->assertFalse($helperSet->has('dialog'));
$this->assertFalse($helperSet->has('progress'));
}

public function testGetDefaultInputDefinitionReturnsDefaultValues()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$inputDefinition = $application->getDefinition();

$this->assertTrue($inputDefinition->hasArgument('command'));

$this->assertTrue($inputDefinition->hasOption('help'));
$this->assertTrue($inputDefinition->hasOption('quiet'));
$this->assertTrue($inputDefinition->hasOption('verbose'));
$this->assertTrue($inputDefinition->hasOption('version'));
$this->assertTrue($inputDefinition->hasOption('ansi'));
$this->assertTrue($inputDefinition->hasOption('no-ansi'));
$this->assertTrue($inputDefinition->hasOption('no-interaction'));
}

public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues()
{
$application = new CustomApplication();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$inputDefinition = $application->getDefinition();


 $this->assertFalse($inputDefinition->hasArgument('command'));

$this->assertFalse($inputDefinition->hasOption('help'));
$this->assertFalse($inputDefinition->hasOption('quiet'));
$this->assertFalse($inputDefinition->hasOption('verbose'));
$this->assertFalse($inputDefinition->hasOption('version'));
$this->assertFalse($inputDefinition->hasOption('ansi'));
$this->assertFalse($inputDefinition->hasOption('no-ansi'));
$this->assertFalse($inputDefinition->hasOption('no-interaction'));

$this->assertTrue($inputDefinition->hasOption('custom'));
}

public function testSettingCustomInputDefinitionOverwritesDefaultValues()
{
$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$application->setDefinition(new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.'))));

$inputDefinition = $application->getDefinition();


 $this->assertFalse($inputDefinition->hasArgument('command'));

$this->assertFalse($inputDefinition->hasOption('help'));
$this->assertFalse($inputDefinition->hasOption('quiet'));
$this->assertFalse($inputDefinition->hasOption('verbose'));
$this->assertFalse($inputDefinition->hasOption('version'));
$this->assertFalse($inputDefinition->hasOption('ansi'));
$this->assertFalse($inputDefinition->hasOption('no-ansi'));
$this->assertFalse($inputDefinition->hasOption('no-interaction'));

$this->assertTrue($inputDefinition->hasOption('custom'));
}

public function testRunWithDispatcher()
{
$application = new Application();
$application->setAutoExit(false);
$application->setDispatcher($this->getDispatcher());

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'));
$this->assertEquals('before.foo.after.'.PHP_EOL, $tester->getDisplay());
}





public function testRunWithExceptionAndDispatcher()
{
$application = new Application();
$application->setDispatcher($this->getDispatcher());
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
throw new \RuntimeException('foo');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'));
}

public function testRunDispatchesAllEventsWithException()
{
$application = new Application();
$application->setDispatcher($this->getDispatcher());
$application->setAutoExit(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');

throw new \RuntimeException('foo');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'));
$this->assertContains('before.foo.caught.after.', $tester->getDisplay());
}

public function testRunWithError()
{
if (method_exists($this, 'expectException')) {
$this->expectException('Exception');
$this->expectExceptionMessage('dymerr');
} else {
$this->setExpectedException('Exception', 'dymerr');
}

$application = new Application();
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('dym.');

throw new \Error('dymerr');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'dym'));
}





public function testRunWithErrorAndDispatcher()
{
$application = new Application();
$application->setDispatcher($this->getDispatcher());
$application->setAutoExit(false);
$application->setCatchExceptions(false);

$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('dym.');

throw new \Error('dymerr');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'dym'));
$this->assertContains('before.dym.caught.after.', $tester->getDisplay(), 'The PHP Error did not dispached events');
}

public function testRunDispatchesAllEventsWithError()
{
$application = new Application();
$application->setDispatcher($this->getDispatcher());
$application->setAutoExit(false);

$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('dym.');

throw new \Error('dymerr');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'dym'));
$this->assertContains('before.dym.caught.after.', $tester->getDisplay(), 'The PHP Error did not dispached events');
}

public function testRunWithErrorFailingStatusCode()
{
$application = new Application();
$application->setDispatcher($this->getDispatcher());
$application->setAutoExit(false);

$application->register('dus')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('dus.');

throw new \Error('duserr');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'dus'));
$this->assertSame(1, $tester->getStatusCode(), 'Status code should be 1');
}

public function testRunWithDispatcherSkippingCommand()
{
$application = new Application();
$application->setDispatcher($this->getDispatcher(true));
$application->setAutoExit(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});

$tester = new ApplicationTester($application);
$exitCode = $tester->run(array('command' => 'foo'));
$this->assertContains('before.after.', $tester->getDisplay());
$this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
}

public function testRunWithDispatcherAccessingInputOptions()
{
$noInteractionValue = null;
$quietValue = null;

$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) {
$input = $event->getInput();

$noInteractionValue = $input->getOption('no-interaction');
$quietValue = $input->getOption('quiet');
});

$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo', '--no-interaction' => true));

$this->assertTrue($noInteractionValue);
$this->assertFalse($quietValue);
}

public function testRunWithDispatcherAddingInputOptions()
{
$extraValue = null;

$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) {
$definition = $event->getCommand()->getDefinition();
$input = $event->getInput();

$definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED));
$input->bind($definition);

$extraValue = $input->getOption('extra');
});

$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);

$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
});

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo', '--extra' => 'some test value'));

$this->assertEquals('some test value', $extraValue);
}

public function testUpdateInputFromConsoleCommandEvent()
{
$dispatcher = $this->getDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) {
$event->getInput()->setOption('extra', 'overriden');
});

$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);

$application
->register('foo')
->addOption('extra', null, InputOption::VALUE_REQUIRED)
->setCode(function (InputInterface $input, OutputInterface $output) {
$output->write('foo.');
})
;

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo', '--extra' => 'original'));

$this->assertEquals('overriden', $tester->getInput()->getOption('extra'));
}

public function testTerminalDimensions()
{
$application = new Application();
$originalDimensions = $application->getTerminalDimensions();
$this->assertCount(2, $originalDimensions);

$width = 80;
if ($originalDimensions[0] == $width) {
$width = 100;
}

$application->setTerminalDimensions($width, 80);
$this->assertSame(array($width, 80), $application->getTerminalDimensions());
}

protected function getDispatcher($skipCommand = false)
{
$dispatcher = new EventDispatcher();
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use ($skipCommand) {
$event->getOutput()->write('before.');

if ($skipCommand) {
$event->disableCommand();
}
});
$dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($skipCommand) {
$event->getOutput()->writeln('after.');

if (!$skipCommand) {
$event->setExitCode(113);
}
});
$dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
$event->getOutput()->write('caught.');

$event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException()));
});

return $dispatcher;
}

public function testSetRunCustomDefaultCommand()
{
$command = new \FooCommand();

$application = new Application();
$application->setAutoExit(false);
$application->add($command);
$application->setDefaultCommand($command->getName());

$tester = new ApplicationTester($application);
$tester->run(array());
$this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');

$application = new CustomDefaultCommandApplication();
$application->setAutoExit(false);

$tester = new ApplicationTester($application);
$tester->run(array());

$this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
}




public function testCanCheckIfTerminalIsInteractive()
{
$application = new CustomDefaultCommandApplication();
$application->setAutoExit(false);

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'help'));

$this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n')));

$inputStream = $application->getHelperSet()->get('question')->getInputStream();
$this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream));
}
}

class CustomApplication extends Application
{





protected function getDefaultInputDefinition()
{
return new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')));
}






protected function getDefaultHelperSet()
{
return new HelperSet(array(new FormatterHelper()));
}
}

class CustomDefaultCommandApplication extends Application
{



public function __construct()
{
parent::__construct();

$command = new \FooCommand();
$this->add($command);
$this->setDefaultCommand($command->getName());
}
}
<?php










namespace Symfony\Component\Console\Tests\Tester;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Tester\CommandTester;

class CommandTesterTest extends TestCase
{
protected $command;
protected $tester;

protected function setUp()
{
$this->command = new Command('foo');
$this->command->addArgument('command');
$this->command->addArgument('foo');
$this->command->setCode(function ($input, $output) { $output->writeln('foo'); });

$this->tester = new CommandTester($this->command);
$this->tester->execute(array('foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
}

protected function tearDown()
{
$this->command = null;
$this->tester = null;
}

public function testExecute()
{
$this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
$this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
$this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
}

public function testGetInput()
{
$this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
}

public function testGetOutput()
{
rewind($this->tester->getOutput()->getStream());
$this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
}

public function testGetDisplay()
{
$this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
}

public function testGetStatusCode()
{
$this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
}

public function testCommandFromApplication()
{
$application = new Application();
$application->setAutoExit(false);

$command = new Command('foo');
$command->setCode(function ($input, $output) { $output->writeln('foo'); });

$application->add($command);

$tester = new CommandTester($application->find('foo'));


 $this->assertEquals(0, $tester->execute(array()));
}
}
<?php










namespace Symfony\Component\Console\Tests\Tester;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Tester\ApplicationTester;

class ApplicationTesterTest extends TestCase
{
protected $application;
protected $tester;

protected function setUp()
{
$this->application = new Application();
$this->application->setAutoExit(false);
$this->application->register('foo')
->addArgument('foo')
->setCode(function ($input, $output) { $output->writeln('foo'); })
;

$this->tester = new ApplicationTester($this->application);
$this->tester->run(array('command' => 'foo', 'foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
}

protected function tearDown()
{
$this->application = null;
$this->tester = null;
}

public function testRun()
{
$this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option');
$this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option');
$this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option');
}

public function testGetInput()
{
$this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance');
}

public function testGetOutput()
{
rewind($this->tester->getOutput()->getStream());
$this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance');
}

public function testGetDisplay()
{
$this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution');
}

public function testGetStatusCode()
{
$this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code');
}
}
<?php










namespace Symfony\Component\Console\Tests\Formatter;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatterStyleStack;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputFormatterStyleStackTest extends TestCase
{
public function testPush()
{
$stack = new OutputFormatterStyleStack();
$stack->push($s1 = new OutputFormatterStyle('white', 'black'));
$stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));

$this->assertEquals($s2, $stack->getCurrent());

$stack->push($s3 = new OutputFormatterStyle('green', 'red'));

$this->assertEquals($s3, $stack->getCurrent());
}

public function testPop()
{
$stack = new OutputFormatterStyleStack();
$stack->push($s1 = new OutputFormatterStyle('white', 'black'));
$stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));

$this->assertEquals($s2, $stack->pop());
$this->assertEquals($s1, $stack->pop());
}

public function testPopEmpty()
{
$stack = new OutputFormatterStyleStack();
$style = new OutputFormatterStyle();

$this->assertEquals($style, $stack->pop());
}

public function testPopNotLast()
{
$stack = new OutputFormatterStyleStack();
$stack->push($s1 = new OutputFormatterStyle('white', 'black'));
$stack->push($s2 = new OutputFormatterStyle('yellow', 'blue'));
$stack->push($s3 = new OutputFormatterStyle('green', 'red'));

$this->assertEquals($s2, $stack->pop($s2));
$this->assertEquals($s1, $stack->pop());
}




public function testInvalidPop()
{
$stack = new OutputFormatterStyleStack();
$stack->push(new OutputFormatterStyle('white', 'black'));
$stack->pop(new OutputFormatterStyle('yellow', 'blue'));
}
}
<?php










namespace Symfony\Component\Console\Tests\Formatter;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputFormatterStyleTest extends TestCase
{
public function testConstructor()
{
$style = new OutputFormatterStyle('green', 'black', array('bold', 'underscore'));
$this->assertEquals("\033[32;40;1;4mfoo\033[39;49;22;24m", $style->apply('foo'));

$style = new OutputFormatterStyle('red', null, array('blink'));
$this->assertEquals("\033[31;5mfoo\033[39;25m", $style->apply('foo'));

$style = new OutputFormatterStyle(null, 'white');
$this->assertEquals("\033[47mfoo\033[49m", $style->apply('foo'));
}

public function testForeground()
{
$style = new OutputFormatterStyle();

$style->setForeground('black');
$this->assertEquals("\033[30mfoo\033[39m", $style->apply('foo'));

$style->setForeground('blue');
$this->assertEquals("\033[34mfoo\033[39m", $style->apply('foo'));

$style->setForeground('default');
$this->assertEquals("\033[39mfoo\033[39m", $style->apply('foo'));

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException');
$style->setForeground('undefined-color');
}

public function testBackground()
{
$style = new OutputFormatterStyle();

$style->setBackground('black');
$this->assertEquals("\033[40mfoo\033[49m", $style->apply('foo'));

$style->setBackground('yellow');
$this->assertEquals("\033[43mfoo\033[49m", $style->apply('foo'));

$style->setBackground('default');
$this->assertEquals("\033[49mfoo\033[49m", $style->apply('foo'));

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException');
$style->setBackground('undefined-color');
}

public function testOptions()
{
$style = new OutputFormatterStyle();

$style->setOptions(array('reverse', 'conceal'));
$this->assertEquals("\033[7;8mfoo\033[27;28m", $style->apply('foo'));

$style->setOption('bold');
$this->assertEquals("\033[7;8;1mfoo\033[27;28;22m", $style->apply('foo'));

$style->unsetOption('reverse');
$this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo'));

$style->setOption('bold');
$this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo'));

$style->setOptions(array('bold'));
$this->assertEquals("\033[1mfoo\033[22m", $style->apply('foo'));

try {
$style->setOption('foo');
$this->fail('->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
$this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options');
}

try {
$style->unsetOption('foo');
$this->fail('->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
$this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options');
}
}
}
<?php










namespace Symfony\Component\Console\Tests\Formatter;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputFormatterTest extends TestCase
{
public function testEmptyTag()
{
$formatter = new OutputFormatter(true);
$this->assertEquals('foo<>bar', $formatter->format('foo<>bar'));
}

public function testLGCharEscaping()
{
$formatter = new OutputFormatter(true);

$this->assertEquals('foo<bar', $formatter->format('foo\\<bar'));
$this->assertEquals('<info>some info</info>', $formatter->format('\\<info>some info\\</info>'));
$this->assertEquals('\\<info>some info\\</info>', OutputFormatter::escape('<info>some info</info>'));

$this->assertEquals(
"\033[33mSymfony\\Component\\Console does work very well!\033[39m",
$formatter->format('<comment>Symfony\Component\Console does work very well!</comment>')
);
}

public function testBundledStyles()
{
$formatter = new OutputFormatter(true);

$this->assertTrue($formatter->hasStyle('error'));
$this->assertTrue($formatter->hasStyle('info'));
$this->assertTrue($formatter->hasStyle('comment'));
$this->assertTrue($formatter->hasStyle('question'));

$this->assertEquals(
"\033[37;41msome error\033[39;49m",
$formatter->format('<error>some error</error>')
);
$this->assertEquals(
"\033[32msome info\033[39m",
$formatter->format('<info>some info</info>')
);
$this->assertEquals(
"\033[33msome comment\033[39m",
$formatter->format('<comment>some comment</comment>')
);
$this->assertEquals(
"\033[30;46msome question\033[39;49m",
$formatter->format('<question>some question</question>')
);
}

public function testNestedStyles()
{
$formatter = new OutputFormatter(true);

$this->assertEquals(
"\033[37;41msome \033[39;49m\033[32msome info\033[39m\033[37;41m error\033[39;49m",
$formatter->format('<error>some <info>some info</info> error</error>')
);
}

public function testAdjacentStyles()
{
$formatter = new OutputFormatter(true);

$this->assertEquals(
"\033[37;41msome error\033[39;49m\033[32msome info\033[39m",
$formatter->format('<error>some error</error><info>some info</info>')
);
}

public function testStyleMatchingNotGreedy()
{
$formatter = new OutputFormatter(true);

$this->assertEquals(
"(\033[32m>=2.0,<2.3\033[39m)",
$formatter->format('(<info>>=2.0,<2.3</info>)')
);
}

public function testStyleEscaping()
{
$formatter = new OutputFormatter(true);

$this->assertEquals(
"(\033[32mz>=2.0,<<<a2.3\\\033[39m)",
$formatter->format('(<info>'.$formatter->escape('z>=2.0,<\\<<a2.3\\').'</info>)')
);

$this->assertEquals(
"\033[32m<error>some error</error>\033[39m",
$formatter->format('<info>'.$formatter->escape('<error>some error</error>').'</info>')
);
}

public function testDeepNestedStyles()
{
$formatter = new OutputFormatter(true);

$this->assertEquals(
"\033[37;41merror\033[39;49m\033[32minfo\033[39m\033[33mcomment\033[39m\033[37;41merror\033[39;49m",
$formatter->format('<error>error<info>info<comment>comment</info>error</error>')
);
}

public function testNewStyle()
{
$formatter = new OutputFormatter(true);

$style = new OutputFormatterStyle('blue', 'white');
$formatter->setStyle('test', $style);

$this->assertEquals($style, $formatter->getStyle('test'));
$this->assertNotEquals($style, $formatter->getStyle('info'));

$style = new OutputFormatterStyle('blue', 'white');
$formatter->setStyle('b', $style);

$this->assertEquals("\033[34;47msome \033[39;49m\033[34;47mcustom\033[39;49m\033[34;47m msg\033[39;49m", $formatter->format('<test>some <b>custom</b> msg</test>'));
}

public function testRedefineStyle()
{
$formatter = new OutputFormatter(true);

$style = new OutputFormatterStyle('blue', 'white');
$formatter->setStyle('info', $style);

$this->assertEquals("\033[34;47msome custom msg\033[39;49m", $formatter->format('<info>some custom msg</info>'));
}

public function testInlineStyle()
{
$formatter = new OutputFormatter(true);

$this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('<fg=blue;bg=red>some text</>'));
$this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('<fg=blue;bg=red>some text</fg=blue;bg=red>'));
}

public function testNonStyleTag()
{
$formatter = new OutputFormatter(true);

$this->assertEquals("\033[32msome \033[39m\033[32m<tag>\033[39m\033[32m \033[39m\033[32m<setting=value>\033[39m\033[32m styled \033[39m\033[32m<p>\033[39m\033[32msingle-char tag\033[39m\033[32m</p>\033[39m", $formatter->format('<info>some <tag> <setting=value> styled <p>single-char tag</p></info>'));
}

public function testFormatLongString()
{
$formatter = new OutputFormatter(true);
$long = str_repeat('\\', 14000);
$this->assertEquals("\033[37;41msome error\033[39;49m".$long, $formatter->format('<error>some error</error>'.$long));
}

public function testFormatToStringObject()
{
$formatter = new OutputFormatter(false);
$this->assertEquals(
'some info', $formatter->format(new TableCell())
);
}

public function testNotDecoratedFormatter()
{
$formatter = new OutputFormatter(false);

$this->assertTrue($formatter->hasStyle('error'));
$this->assertTrue($formatter->hasStyle('info'));
$this->assertTrue($formatter->hasStyle('comment'));
$this->assertTrue($formatter->hasStyle('question'));

$this->assertEquals(
'some error', $formatter->format('<error>some error</error>')
);
$this->assertEquals(
'some info', $formatter->format('<info>some info</info>')
);
$this->assertEquals(
'some comment', $formatter->format('<comment>some comment</comment>')
);
$this->assertEquals(
'some question', $formatter->format('<question>some question</question>')
);
$this->assertEquals(
'some text with inline style', $formatter->format('<fg=red>some text with inline style</>')
);

$formatter->setDecorated(true);

$this->assertEquals(
"\033[37;41msome error\033[39;49m", $formatter->format('<error>some error</error>')
);
$this->assertEquals(
"\033[32msome info\033[39m", $formatter->format('<info>some info</info>')
);
$this->assertEquals(
"\033[33msome comment\033[39m", $formatter->format('<comment>some comment</comment>')
);
$this->assertEquals(
"\033[30;46msome question\033[39;49m", $formatter->format('<question>some question</question>')
);
$this->assertEquals(
"\033[31msome text with inline style\033[39m", $formatter->format('<fg=red>some text with inline style</>')
);
}

public function testContentWithLineBreaks()
{
$formatter = new OutputFormatter(true);

$this->assertEquals(<<<EOF
\033[32m
some text\033[39m
EOF
, $formatter->format(<<<'EOF'
<info>
some text</info>
EOF
));

$this->assertEquals(<<<EOF
\033[32msome text
\033[39m
EOF
, $formatter->format(<<<'EOF'
<info>some text
</info>
EOF
));

$this->assertEquals(<<<EOF
\033[32m
some text
\033[39m
EOF
, $formatter->format(<<<'EOF'
<info>
some text
</info>
EOF
));

$this->assertEquals(<<<EOF
\033[32m
some text
more text
\033[39m
EOF
, $formatter->format(<<<'EOF'
<info>
some text
more text
</info>
EOF
));
}
}

class TableCell
{
public function __toString()
{
return '<info>some info</info>';
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\Helper;

class HelperTest extends TestCase
{
public function formatTimeProvider()
{
return array(
array(0, '< 1 sec'),
array(1, '1 sec'),
array(2, '2 secs'),
array(59, '59 secs'),
array(60, '1 min'),
array(61, '1 min'),
array(119, '1 min'),
array(120, '2 mins'),
array(121, '2 mins'),
array(3599, '59 mins'),
array(3600, '1 hr'),
array(7199, '1 hr'),
array(7200, '2 hrs'),
array(7201, '2 hrs'),
array(86399, '23 hrs'),
array(86400, '1 day'),
array(86401, '1 day'),
array(172799, '1 day'),
array(172800, '2 days'),
array(172801, '2 days'),
);
}







public function testFormatTime($secs, $expectedFormat)
{
$this->assertEquals($expectedFormat, Helper::formatTime($secs));
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;




class QuestionHelperTest extends TestCase
{
public function testAskChoice()
{
$questionHelper = new QuestionHelper();

$helperSet = new HelperSet(array(new FormatterHelper()));
$questionHelper->setHelperSet($helperSet);

$heroes = array('Superman', 'Batman', 'Spiderman');

$questionHelper->setInputStream($this->getInputStream("\n1\n  1  \nFabien\n1\nFabien\n1\n0,2\n 0 , 2  \n\n\n"));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
$question->setMaxAttempts(1);

 $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
$question->setMaxAttempts(1);
$this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
$question->setErrorMessage('Input "%s" is not a superhero!');
$question->setMaxAttempts(2);
$this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));

rewind($output->getStream());
$stream = stream_get_contents($output->getStream());
$this->assertContains('Input "Fabien" is not a superhero!', $stream);

try {
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
$question->setMaxAttempts(1);
$questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question);
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
}

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
$question->setMaxAttempts(1);
$question->setMultiselect(true);

$this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
$question->setMaxAttempts(1);
$question->setMultiselect(true);

$this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
$question->setMaxAttempts(1);
$question->setMultiselect(true);

$this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}

public function testAsk()
{
$dialog = new QuestionHelper();

$dialog->setInputStream($this->getInputStream("\n8AM\n"));

$question = new Question('What time is it?', '2PM');
$this->assertEquals('2PM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new Question('What time is it?', '2PM');
$this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));

rewind($output->getStream());
$this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
}

public function testAskWithAutocomplete()
{
if (!$this->hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
}


 
 
 
 
 
 
 
 $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");

$dialog = new QuestionHelper();
$dialog->setInputStream($inputStream);
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = new Question('Please select a bundle', 'FrameworkBundle');
$question->setAutocompleterValues(array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle'));

$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}

public function testAskWithAutocompleteWithNonSequentialKeys()
{
if (!$this->hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
}


 $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n");

$dialog = new QuestionHelper();
$dialog->setInputStream($inputStream);
$dialog->setHelperSet(new HelperSet(array(new FormatterHelper())));

$question = new ChoiceQuestion('Please select a bundle', array(1 => 'AcmeDemoBundle', 4 => 'AsseticBundle'));
$question->setMaxAttempts(1);

$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}

public function testAskHiddenResponse()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test is not supported on Windows');
}

$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream("8AM\n"));

$question = new Question('What time is it?');
$question->setHidden(true);

$this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}




public function testAskConfirmation($question, $expected, $default = true)
{
$dialog = new QuestionHelper();

$dialog->setInputStream($this->getInputStream($question."\n"));
$question = new ConfirmationQuestion('Do you like French fries?', $default);
$this->assertEquals($expected, $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel'));
}

public function getAskConfirmationData()
{
return array(
array('', true),
array('', false, false),
array('y', true),
array('yes', true),
array('n', false),
array('no', false),
);
}

public function testAskConfirmationWithCustomTrueAnswer()
{
$dialog = new QuestionHelper();

$dialog->setInputStream($this->getInputStream("j\ny\n"));
$question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
$this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i');
$this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}

public function testAskAndValidate()
{
$dialog = new QuestionHelper();
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$error = 'This is not a color!';
$validator = function ($color) use ($error) {
if (!in_array($color, array('white', 'black'))) {
throw new \InvalidArgumentException($error);
}

return $color;
};

$question = new Question('What color was the white horse of Henry IV?', 'white');
$question->setValidator($validator);
$question->setMaxAttempts(2);

$dialog->setInputStream($this->getInputStream("\nblack\n"));
$this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('black', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
try {
$dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertEquals($error, $e->getMessage());
}
}




public function testSelectChoiceFromSimpleChoices($providedAnswer, $expectedValue)
{
$possibleChoices = array(
'My environment 1',
'My environment 2',
'My environment 3',
);

$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
$question->setMaxAttempts(1);
$answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);

$this->assertSame($expectedValue, $answer);
}

public function simpleAnswerProvider()
{
return array(
array(0, 'My environment 1'),
array(1, 'My environment 2'),
array(2, 'My environment 3'),
array('My environment 1', 'My environment 1'),
array('My environment 2', 'My environment 2'),
array('My environment 3', 'My environment 3'),
);
}




public function testChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue)
{
$possibleChoices = array(
'0' => 'No environment',
'1' => 'My environment 1',
'env_2' => 'My environment 2',
3 => 'My environment 3',
);

$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
$question->setMaxAttempts(1);
$answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);

$this->assertSame($expectedValue, $answer);
}

public function mixedKeysChoiceListAnswerProvider()
{
return array(
array('0', '0'),
array('No environment', '0'),
array('1', '1'),
array('env_2', 'env_2'),
array(3, '3'),
array('My environment 1', '1'),
);
}




public function testSelectChoiceFromChoiceList($providedAnswer, $expectedValue)
{
$possibleChoices = array(
'env_1' => 'My environment 1',
'env_2' => 'My environment',
'env_3' => 'My environment',
);

$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream($providedAnswer."\n"));
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
$question->setMaxAttempts(1);
$answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);

$this->assertSame($expectedValue, $answer);
}





public function testAmbiguousChoiceFromChoicelist()
{
$possibleChoices = array(
'env_1' => 'My first environment',
'env_2' => 'My environment',
'env_3' => 'My environment',
);

$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream("My environment\n"));
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = new ChoiceQuestion('Please select the environment to load', $possibleChoices);
$question->setMaxAttempts(1);

$dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
}

public function answerProvider()
{
return array(
array('env_1', 'env_1'),
array('env_2', 'env_2'),
array('env_3', 'env_3'),
array('My environment 1', 'env_1'),
);
}

public function testNoInteraction()
{
$dialog = new QuestionHelper();
$question = new Question('Do you have a job?', 'not yet');
$this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question));
}




public function testChoiceOutputFormattingQuestionForUtf8Keys()
{
$question = 'Lorem ipsum?';
$possibleChoices = array(
'foo' => 'foo',
'żółw' => 'bar',
'łabądź' => 'baz',
);
$outputShown = array(
$question,
'  [<info>foo   </info>] foo',
'  [<info>żółw  </info>] bar',
'  [<info>łabądź</info>] baz',
);
$output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock();
$output->method('getFormatter')->willReturn(new OutputFormatter());

$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream("\n"));
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));

$question = new ChoiceQuestion($question, $possibleChoices, 'foo');
$dialog->ask($this->createInputInterfaceMock(), $output, $question);
}





public function testAskThrowsExceptionOnMissingInput()
{
$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream(''));

$dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), new Question('What\'s your name?'));
}





public function testAskThrowsExceptionOnMissingInputWithValidator()
{
$dialog = new QuestionHelper();
$dialog->setInputStream($this->getInputStream(''));

$question = new Question('What\'s your name?');
$question->setValidator(function () {
if (!$value) {
throw new \Exception('A value is required.');
}
});

$dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question);
}

protected function getInputStream($input)
{
$stream = fopen('php://memory', 'r+', false);
fwrite($stream, $input);
rewind($stream);

return $stream;
}

protected function createOutputInterface()
{
return new StreamOutput(fopen('php://memory', 'r+', false));
}

protected function createInputInterfaceMock($interactive = true)
{
$mock = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')->getMock();
$mock->expects($this->any())
->method('isInteractive')
->will($this->returnValue($interactive));

return $mock;
}

private function hasSttyAvailable()
{
exec('stty 2>&1', $output, $exitcode);

return $exitcode === 0;
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableStyle;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Helper\TableCell;
use Symfony\Component\Console\Output\StreamOutput;

class TableTest extends TestCase
{
protected $stream;

protected function setUp()
{
$this->stream = fopen('php://memory', 'r+');
}

protected function tearDown()
{
fclose($this->stream);
$this->stream = null;
}




public function testRender($headers, $rows, $style, $expected, $decorated = false)
{
$table = new Table($output = $this->getOutputStream($decorated));
$table
->setHeaders($headers)
->setRows($rows)
->setStyle($style)
;
$table->render();

$this->assertEquals($expected, $this->getOutputContent($output));
}




public function testRenderAddRows($headers, $rows, $style, $expected, $decorated = false)
{
$table = new Table($output = $this->getOutputStream($decorated));
$table
->setHeaders($headers)
->addRows($rows)
->setStyle($style)
;
$table->render();

$this->assertEquals($expected, $this->getOutputContent($output));
}




public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected, $decorated = false)
{
$table = new Table($output = $this->getOutputStream($decorated));
$table
->setHeaders($headers)
->setStyle($style)
;
foreach ($rows as $row) {
$table->addRow($row);
}
$table->render();

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testRenderProvider()
{
$books = array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
);

return array(
array(
array('ISBN', 'Title', 'Author'),
$books,
'default',
<<<'TABLE'
+---------------+--------------------------+------------------+
| ISBN          | Title                    | Author           |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 | A Tale of Two Cities     | Charles Dickens  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
),
array(
array('ISBN', 'Title', 'Author'),
$books,
'compact',
<<<'TABLE'
 ISBN          Title                    Author           
 99921-58-10-7 Divine Comedy            Dante Alighieri  
 9971-5-0210-0 A Tale of Two Cities     Charles Dickens  
 960-425-059-0 The Lord of the Rings    J. R. R. Tolkien 
 80-902734-1-6 And Then There Were None Agatha Christie  

TABLE
),
array(
array('ISBN', 'Title', 'Author'),
$books,
'borderless',
<<<'TABLE'
 =============== ========================== ================== 
  ISBN            Title                      Author            
 =============== ========================== ================== 
  99921-58-10-7   Divine Comedy              Dante Alighieri   
  9971-5-0210-0   A Tale of Two Cities       Charles Dickens   
  960-425-059-0   The Lord of the Rings      J. R. R. Tolkien  
  80-902734-1-6   And Then There Were None   Agatha Christie   
 =============== ========================== ================== 

TABLE
),
array(
array('ISBN', 'Title'),
array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
array('9971-5-0210-0'),
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
),
'default',
<<<'TABLE'
+---------------+--------------------------+------------------+
| ISBN          | Title                    |                  |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
),
array(
array(),
array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
array('9971-5-0210-0'),
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
),
'default',
<<<'TABLE'
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
),
array(
array('ISBN', 'Title', 'Author'),
array(
array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
),
'default',
<<<'TABLE'
+---------------+----------------------------+-----------------+
| ISBN          | Title                      | Author          |
+---------------+----------------------------+-----------------+
| 99921-58-10-7 | Divine                     | Dante Alighieri |
|               | Comedy                     |                 |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 960-425-059-0 | The Lord of the Rings      | J. R. R.        |
|               |                            | Tolkien         |
+---------------+----------------------------+-----------------+

TABLE
),
array(
array('ISBN', 'Title'),
array(),
'default',
<<<'TABLE'
+------+-------+
| ISBN | Title |
+------+-------+

TABLE
),
array(
array(),
array(),
'default',
'',
),
'Cell text with tags used for Output styling' => array(
array('ISBN', 'Title', 'Author'),
array(
array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
),
'default',
<<<'TABLE'
+---------------+----------------------+-----------------+
| ISBN          | Title                | Author          |
+---------------+----------------------+-----------------+
| 99921-58-10-7 | Divine Comedy        | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+----------------------+-----------------+

TABLE
),
'Cell text with tags not used for Output styling' => array(
array('ISBN', 'Title', 'Author'),
array(
array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
),
'default',
<<<'TABLE'
+----------------------------------+----------------------+-----------------+
| ISBN                             | Title                | Author          |
+----------------------------------+----------------------+-----------------+
| <strong>99921-58-10-700</strong> | <f>Divine Com</f>    | Dante Alighieri |
| 9971-5-0210-0                    | A Tale of Two Cities | Charles Dickens |
+----------------------------------+----------------------+-----------------+

TABLE
),
'Cell with colspan' => array(
array('ISBN', 'Title', 'Author'),
array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
new TableSeparator(),
array(new TableCell('Divine Comedy(Dante Alighieri)', array('colspan' => 3))),
new TableSeparator(),
array(
new TableCell('Arduino: A Quick-Start Guide', array('colspan' => 2)),
'Mark Schmidt',
),
new TableSeparator(),
array(
'9971-5-0210-0',
new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)),
),
new TableSeparator(),
array(
new TableCell('Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!', array('colspan' => 3)),
),
),
'default',
<<<'TABLE'
+-------------------------------+-------------------------------+-----------------------------+
| ISBN                          | Title                         | Author                      |
+-------------------------------+-------------------------------+-----------------------------+
| 99921-58-10-7                 | Divine Comedy                 | Dante Alighieri             |
+-------------------------------+-------------------------------+-----------------------------+
| Divine Comedy(Dante Alighieri)                                                              |
+-------------------------------+-------------------------------+-----------------------------+
| Arduino: A Quick-Start Guide                                  | Mark Schmidt                |
+-------------------------------+-------------------------------+-----------------------------+
| 9971-5-0210-0                 | A Tale of                                                   |
|                               | Two Cities                                                  |
+-------------------------------+-------------------------------+-----------------------------+
| Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!       |
+-------------------------------+-------------------------------+-----------------------------+

TABLE
),
'Cell with rowspan' => array(
array('ISBN', 'Title', 'Author'),
array(
array(
new TableCell('9971-5-0210-0', array('rowspan' => 3)),
new TableCell('Divine Comedy', array('rowspan' => 2)),
'Dante Alighieri',
),
array(),
array("The Lord of \nthe Rings", "J. R. \nR. Tolkien"),
new TableSeparator(),
array('80-902734-1-6', new TableCell("And Then \nThere \nWere None", array('rowspan' => 3)), 'Agatha Christie'),
array('80-902734-1-7', 'Test'),
),
'default',
<<<'TABLE'
+---------------+---------------+-----------------+
| ISBN          | Title         | Author          |
+---------------+---------------+-----------------+
| 9971-5-0210-0 | Divine Comedy | Dante Alighieri |
|               |               |                 |
|               | The Lord of   | J. R.           |
|               | the Rings     | R. Tolkien      |
+---------------+---------------+-----------------+
| 80-902734-1-6 | And Then      | Agatha Christie |
| 80-902734-1-7 | There         | Test            |
|               | Were None     |                 |
+---------------+---------------+-----------------+

TABLE
),
'Cell with rowspan and colspan' => array(
array('ISBN', 'Title', 'Author'),
array(
array(
new TableCell('9971-5-0210-0', array('rowspan' => 2, 'colspan' => 2)),
'Dante Alighieri',
),
array('Charles Dickens'),
new TableSeparator(),
array(
'Dante Alighieri',
new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 2)),
),
array('J. R. R. Tolkien'),
array('J. R. R'),
),
'default',
<<<'TABLE'
+------------------+---------+-----------------+
| ISBN             | Title   | Author          |
+------------------+---------+-----------------+
| 9971-5-0210-0              | Dante Alighieri |
|                            | Charles Dickens |
+------------------+---------+-----------------+
| Dante Alighieri  | 9971-5-0210-0             |
| J. R. R. Tolkien |                           |
| J. R. R          |                           |
+------------------+---------+-----------------+

TABLE
),
'Cell with rowspan and colspan contains new line break' => array(
array('ISBN', 'Title', 'Author'),
array(
array(
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
'Dante Alighieri',
),
array('Charles Dickens'),
new TableSeparator(),
array(
'Dante Alighieri',
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
),
array('Charles Dickens'),
new TableSeparator(),
array(
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
new TableCell("Dante \nAlighieri", array('rowspan' => 2, 'colspan' => 1)),
),
),
'default',
<<<'TABLE'
+-----------------+-------+-----------------+
| ISBN            | Title | Author          |
+-----------------+-------+-----------------+
| 9971                    | Dante Alighieri |
| -5-                     | Charles Dickens |
| 021                     |                 |
| 0-0                     |                 |
+-----------------+-------+-----------------+
| Dante Alighieri | 9971                    |
| Charles Dickens | -5-                     |
|                 | 021                     |
|                 | 0-0                     |
+-----------------+-------+-----------------+
| 9971                    | Dante           |
| -5-                     | Alighieri       |
| 021                     |                 |
| 0-0                     |                 |
+-----------------+-------+-----------------+

TABLE
),
'Cell with rowspan and colspan without using TableSeparator' => array(
array('ISBN', 'Title', 'Author'),
array(
array(
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
'Dante Alighieri',
),
array('Charles Dickens'),
array(
'Dante Alighieri',
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
),
array('Charles Dickens'),
),
'default',
<<<'TABLE'
+-----------------+-------+-----------------+
| ISBN            | Title | Author          |
+-----------------+-------+-----------------+
| 9971                    | Dante Alighieri |
| -5-                     | Charles Dickens |
| 021                     |                 |
| 0-0                     |                 |
| Dante Alighieri | 9971                    |
| Charles Dickens | -5-                     |
|                 | 021                     |
|                 | 0-0                     |
+-----------------+-------+-----------------+

TABLE
),
'Cell with rowspan and colspan with separator inside a rowspan' => array(
array('ISBN', 'Author'),
array(
array(
new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)),
'Dante Alighieri',
),
array(new TableSeparator()),
array('Charles Dickens'),
),
'default',
<<<'TABLE'
+---------------+-----------------+
| ISBN          | Author          |
+---------------+-----------------+
| 9971-5-0210-0 | Dante Alighieri |
|               |-----------------|
|               | Charles Dickens |
+---------------+-----------------+

TABLE
),
'Multiple header lines' => array(
array(
array(new TableCell('Main title', array('colspan' => 3))),
array('ISBN', 'Title', 'Author'),
),
array(),
'default',
<<<'TABLE'
+------+-------+--------+
| Main title            |
+------+-------+--------+
| ISBN | Title | Author |
+------+-------+--------+

TABLE
),
'Row with multiple cells' => array(
array(),
array(
array(
new TableCell('1', array('colspan' => 3)),
new TableCell('2', array('colspan' => 2)),
new TableCell('3', array('colspan' => 2)),
new TableCell('4', array('colspan' => 2)),
),
),
'default',
<<<'TABLE'
+---+--+--+---+--+---+--+---+--+
| 1       | 2    | 3    | 4    |
+---+--+--+---+--+---+--+---+--+

TABLE
),
'Coslpan and table cells with comment style' => array(
array(
new TableCell('<comment>Long Title</comment>', array('colspan' => 3)),
),
array(
array(
new TableCell('9971-5-0210-0', array('colspan' => 3)),
),
new TableSeparator(),
array(
'Dante Alighieri',
'J. R. R. Tolkien',
'J. R. R',
),
),
'default',
<<<TABLE
+-----------------+------------------+---------+
|\033[32m \033[39m\033[33mLong Title\033[39m\033[32m                                   \033[39m|
+-----------------+------------------+---------+
| 9971-5-0210-0                                |
+-----------------+------------------+---------+
| Dante Alighieri | J. R. R. Tolkien | J. R. R |
+-----------------+------------------+---------+

TABLE
,
true,
),
);
}

public function testRenderMultiByte()
{
$table = new Table($output = $this->getOutputStream());
$table
->setHeaders(array('■■'))
->setRows(array(array(1234)))
->setStyle('default')
;
$table->render();

$expected =
<<<'TABLE'
+------+
| ■■   |
+------+
| 1234 |
+------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testTableCellWithNumericIntValue()
{
$table = new Table($output = $this->getOutputStream());

$table->setRows(array(array(new TableCell(12345))));
$table->render();

$expected =
<<<'TABLE'
+-------+
| 12345 |
+-------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testTableCellWithNumericFloatValue()
{
$table = new Table($output = $this->getOutputStream());

$table->setRows(array(array(new TableCell(12345.01))));
$table->render();

$expected =
<<<'TABLE'
+----------+
| 12345.01 |
+----------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testStyle()
{
$style = new TableStyle();
$style
->setHorizontalBorderChar('.')
->setVerticalBorderChar('.')
->setCrossingChar('.')
;

Table::setStyleDefinition('dotfull', $style);
$table = new Table($output = $this->getOutputStream());
$table
->setHeaders(array('Foo'))
->setRows(array(array('Bar')))
->setStyle('dotfull');
$table->render();

$expected =
<<<'TABLE'
.......
. Foo .
.......
. Bar .
.......

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testRowSeparator()
{
$table = new Table($output = $this->getOutputStream());
$table
->setHeaders(array('Foo'))
->setRows(array(
array('Bar1'),
new TableSeparator(),
array('Bar2'),
new TableSeparator(),
array('Bar3'),
));
$table->render();

$expected =
<<<'TABLE'
+------+
| Foo  |
+------+
| Bar1 |
+------+
| Bar2 |
+------+
| Bar3 |
+------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));

$this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
}

public function testRenderMultiCalls()
{
$table = new Table($output = $this->getOutputStream());
$table->setRows(array(
array(new TableCell('foo', array('colspan' => 2))),
));
$table->render();
$table->render();
$table->render();

$expected =
<<<TABLE
+----+---+
| foo    |
+----+---+
+----+---+
| foo    |
+----+---+
+----+---+
| foo    |
+----+---+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testColumnStyle()
{
$table = new Table($output = $this->getOutputStream());
$table
->setHeaders(array('ISBN', 'Title', 'Author', 'Price'))
->setRows(array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'),
));

$style = new TableStyle();
$style->setPadType(STR_PAD_LEFT);
$table->setColumnStyle(3, $style);

$table->render();

$expected =
<<<TABLE
+---------------+----------------------+-----------------+--------+
| ISBN          | Title                | Author          |  Price |
+---------------+----------------------+-----------------+--------+
| 99921-58-10-7 | Divine Comedy        | Dante Alighieri |   9.95 |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | 139.25 |
+---------------+----------------------+-----------------+--------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}





public function testIsNotDefinedStyleException()
{
$table = new Table($this->getOutputStream());
$table->setStyle('absent');
}





public function testGetStyleDefinition()
{
Table::getStyleDefinition('absent');
}

protected function getOutputStream($decorated = false)
{
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, $decorated);
}

protected function getOutputContent(StreamOutput $output)
{
rewind($output->getStream());

return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
}
}
<?php

namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Question\ChoiceQuestion;




class SymfonyQuestionHelperTest extends TestCase
{
public function testAskChoice()
{
$questionHelper = new SymfonyQuestionHelper();

$helperSet = new HelperSet(array(new FormatterHelper()));
$questionHelper->setHelperSet($helperSet);

$heroes = array('Superman', 'Batman', 'Spiderman');

$questionHelper->setInputStream($this->getInputStream("\n1\n  1  \nFabien\n1\nFabien\n1\n0,2\n 0 , 2  \n\n\n"));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2');
$question->setMaxAttempts(1);

 $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
$this->assertOutputContains('What is your favorite superhero? [Spiderman]', $output);

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
$question->setMaxAttempts(1);
$this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes);
$question->setErrorMessage('Input "%s" is not a superhero!');
$question->setMaxAttempts(2);
$this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
$this->assertOutputContains('Input "Fabien" is not a superhero!', $output);

try {
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1');
$question->setMaxAttempts(1);
$questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question);
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
}

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
$question->setMaxAttempts(1);
$question->setMultiselect(true);

$this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
$this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1');
$question->setMaxAttempts(1);
$question->setMultiselect(true);

$this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
$this->assertOutputContains('What is your favorite superhero? [Superman, Batman]', $output);

$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 ');
$question->setMaxAttempts(1);
$question->setMultiselect(true);

$this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question));
$this->assertOutputContains('What is your favorite superhero? [Superman, Batman]', $output);
}

public function testAskReturnsNullIfValidatorAllowsIt()
{
$questionHelper = new SymfonyQuestionHelper();
$questionHelper->setInputStream($this->getInputStream("\n"));
$question = new Question('What is your favorite superhero?');
$question->setValidator(function ($value) { return $value; });
$this->assertNull($questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}

public function testAskEscapeDefaultValue()
{
$helper = new SymfonyQuestionHelper();
$helper->setInputStream($this->getInputStream('\\'));
$helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Can I have a backslash?', '\\'));

$this->assertOutputContains('Can I have a backslash? [\]', $output);
}

public function testAskEscapeAndFormatLabel()
{
$helper = new SymfonyQuestionHelper();
$helper->setInputStream($this->getInputStream('Foo\\Bar'));
$helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Do you want to use Foo\\Bar <comment>or</comment> Foo\\Baz\\?', 'Foo\\Baz'));

$this->assertOutputContains('Do you want to use Foo\\Bar or Foo\\Baz\\? [Foo\\Baz]:', $output);
}

public function testLabelTrailingBackslash()
{
$helper = new SymfonyQuestionHelper();
$helper->setInputStream($this->getInputStream('sure'));
$helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Question with a trailing \\'));

$this->assertOutputContains('Question with a trailing \\', $output);
}





public function testAskThrowsExceptionOnMissingInput()
{
$dialog = new SymfonyQuestionHelper();

$dialog->setInputStream($this->getInputStream(''));
$dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), new Question('What\'s your name?'));
}

protected function getInputStream($input)
{
$stream = fopen('php://memory', 'r+', false);
fwrite($stream, $input);
rewind($stream);

return $stream;
}

protected function createOutputInterface()
{
$output = new StreamOutput(fopen('php://memory', 'r+', false));
$output->setDecorated(false);

return $output;
}

protected function createInputInterfaceMock($interactive = true)
{
$mock = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')->getMock();
$mock->expects($this->any())
->method('isInteractive')
->will($this->returnValue($interactive));

return $mock;
}

private function assertOutputContains($expected, StreamOutput $output)
{
rewind($output->getStream());
$stream = stream_get_contents($output->getStream());
$this->assertContains($expected, $stream);
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Command\Command;

class HelperSetTest extends TestCase
{
public function testConstructor()
{
$mock_helper = $this->getGenericMockHelper('fake_helper');
$helperset = new HelperSet(array('fake_helper_alias' => $mock_helper));

$this->assertEquals($mock_helper, $helperset->get('fake_helper_alias'), '__construct sets given helper to helpers');
$this->assertTrue($helperset->has('fake_helper_alias'), '__construct sets helper alias for given helper');
}

public function testSet()
{
$helperset = new HelperSet();
$helperset->set($this->getGenericMockHelper('fake_helper', $helperset));
$this->assertTrue($helperset->has('fake_helper'), '->set() adds helper to helpers');

$helperset = new HelperSet();
$helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
$helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
$this->assertTrue($helperset->has('fake_helper_01'), '->set() will set multiple helpers on consecutive calls');
$this->assertTrue($helperset->has('fake_helper_02'), '->set() will set multiple helpers on consecutive calls');

$helperset = new HelperSet();
$helperset->set($this->getGenericMockHelper('fake_helper', $helperset), 'fake_helper_alias');
$this->assertTrue($helperset->has('fake_helper'), '->set() adds helper alias when set');
$this->assertTrue($helperset->has('fake_helper_alias'), '->set() adds helper alias when set');
}

public function testHas()
{
$helperset = new HelperSet(array('fake_helper_alias' => $this->getGenericMockHelper('fake_helper')));
$this->assertTrue($helperset->has('fake_helper'), '->has() finds set helper');
$this->assertTrue($helperset->has('fake_helper_alias'), '->has() finds set helper by alias');
}

public function testGet()
{
$helper_01 = $this->getGenericMockHelper('fake_helper_01');
$helper_02 = $this->getGenericMockHelper('fake_helper_02');
$helperset = new HelperSet(array('fake_helper_01_alias' => $helper_01, 'fake_helper_02_alias' => $helper_02));
$this->assertEquals($helper_01, $helperset->get('fake_helper_01'), '->get() returns correct helper by name');
$this->assertEquals($helper_01, $helperset->get('fake_helper_01_alias'), '->get() returns correct helper by alias');
$this->assertEquals($helper_02, $helperset->get('fake_helper_02'), '->get() returns correct helper by name');
$this->assertEquals($helper_02, $helperset->get('fake_helper_02_alias'), '->get() returns correct helper by alias');

$helperset = new HelperSet();
try {
$helperset->get('foo');
$this->fail('->get() throws InvalidArgumentException when helper not found');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws InvalidArgumentException when helper not found');
$this->assertInstanceOf('Symfony\Component\Console\Exception\ExceptionInterface', $e, '->get() throws domain specific exception when helper not found');
$this->assertContains('The helper "foo" is not defined.', $e->getMessage(), '->get() throws InvalidArgumentException when helper not found');
}
}

public function testSetCommand()
{
$cmd_01 = new Command('foo');
$cmd_02 = new Command('bar');

$helperset = new HelperSet();
$helperset->setCommand($cmd_01);
$this->assertEquals($cmd_01, $helperset->getCommand(), '->setCommand() stores given command');

$helperset = new HelperSet();
$helperset->setCommand($cmd_01);
$helperset->setCommand($cmd_02);
$this->assertEquals($cmd_02, $helperset->getCommand(), '->setCommand() overwrites stored command with consecutive calls');
}

public function testGetCommand()
{
$cmd = new Command('foo');
$helperset = new HelperSet();
$helperset->setCommand($cmd);
$this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command');
}

public function testIteration()
{
$helperset = new HelperSet();
$helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
$helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));

$helpers = array('fake_helper_01', 'fake_helper_02');
$i = 0;

foreach ($helperset as $helper) {
$this->assertEquals($helpers[$i++], $helper->getName());
}
}

private function getGenericMockHelper($name, HelperSet $helperset = null)
{
$mock_helper = $this->getMockBuilder('\Symfony\Component\Console\Helper\HelperInterface')->getMock();
$mock_helper->expects($this->any())
->method('getName')
->will($this->returnValue($name));

if ($helperset) {
$mock_helper->expects($this->any())
->method('setHelperSet')
->with($this->equalTo($helperset));
}

return $mock_helper;
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\FormatterHelper;

class FormatterHelperTest extends TestCase
{
public function testFormatSection()
{
$formatter = new FormatterHelper();

$this->assertEquals(
'<info>[cli]</info> Some text to display',
$formatter->formatSection('cli', 'Some text to display'),
'::formatSection() formats a message in a section'
);
}

public function testFormatBlock()
{
$formatter = new FormatterHelper();

$this->assertEquals(
'<error> Some text to display </error>',
$formatter->formatBlock('Some text to display', 'error'),
'::formatBlock() formats a message in a block'
);

$this->assertEquals(
'<error> Some text to display </error>'."\n".
'<error> foo bar              </error>',
$formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'),
'::formatBlock() formats a message in a block'
);

$this->assertEquals(
'<error>                        </error>'."\n".
'<error>  Some text to display  </error>'."\n".
'<error>                        </error>',
$formatter->formatBlock('Some text to display', 'error', true),
'::formatBlock() formats a message in a block'
);
}

public function testFormatBlockWithDiacriticLetters()
{
$formatter = new FormatterHelper();

$this->assertEquals(
'<error>                       </error>'."\n".
'<error>  Du texte à afficher  </error>'."\n".
'<error>                       </error>',
$formatter->formatBlock('Du texte à afficher', 'error', true),
'::formatBlock() formats a message in a block'
);
}

public function testFormatBlockWithDoubleWidthDiacriticLetters()
{
$formatter = new FormatterHelper();
$this->assertEquals(
'<error>                    </error>'."\n".
'<error>  表示するテキスト  </error>'."\n".
'<error>                    </error>',
$formatter->formatBlock('表示するテキスト', 'error', true),
'::formatBlock() formats a message in a block'
);
}

public function testFormatBlockLGEscaping()
{
$formatter = new FormatterHelper();

$this->assertEquals(
'<error>                            </error>'."\n".
'<error>  \<info>some info\</info>  </error>'."\n".
'<error>                            </error>',
$formatter->formatBlock('<info>some info</info>', 'error', true),
'::formatBlock() escapes \'<\' chars'
);
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\TableHelper;
use Symfony\Component\Console\Output\StreamOutput;




class LegacyTableHelperTest extends TestCase
{
protected $stream;

protected function setUp()
{
$this->stream = fopen('php://memory', 'r+');
}

protected function tearDown()
{
fclose($this->stream);
$this->stream = null;
}




public function testRender($headers, $rows, $layout, $expected)
{
$table = new TableHelper();
$table
->setHeaders($headers)
->setRows($rows)
->setLayout($layout)
;
$table->render($output = $this->getOutputStream());

$this->assertEquals($expected, $this->getOutputContent($output));
}




public function testRenderAddRows($headers, $rows, $layout, $expected)
{
$table = new TableHelper();
$table
->setHeaders($headers)
->addRows($rows)
->setLayout($layout)
;
$table->render($output = $this->getOutputStream());

$this->assertEquals($expected, $this->getOutputContent($output));
}




public function testRenderAddRowsOneByOne($headers, $rows, $layout, $expected)
{
$table = new TableHelper();
$table
->setHeaders($headers)
->setLayout($layout)
;
foreach ($rows as $row) {
$table->addRow($row);
}
$table->render($output = $this->getOutputStream());

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testRenderProvider()
{
$books = array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
);

return array(
array(
array('ISBN', 'Title', 'Author'),
$books,
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+--------------------------+------------------+
| ISBN          | Title                    | Author           |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 | A Tale of Two Cities     | Charles Dickens  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
),
array(
array('ISBN', 'Title', 'Author'),
$books,
TableHelper::LAYOUT_COMPACT,
<<<'TABLE'
 ISBN          Title                    Author           
 99921-58-10-7 Divine Comedy            Dante Alighieri  
 9971-5-0210-0 A Tale of Two Cities     Charles Dickens  
 960-425-059-0 The Lord of the Rings    J. R. R. Tolkien 
 80-902734-1-6 And Then There Were None Agatha Christie  

TABLE
),
array(
array('ISBN', 'Title', 'Author'),
$books,
TableHelper::LAYOUT_BORDERLESS,
<<<'TABLE'
 =============== ========================== ================== 
  ISBN            Title                      Author            
 =============== ========================== ================== 
  99921-58-10-7   Divine Comedy              Dante Alighieri   
  9971-5-0210-0   A Tale of Two Cities       Charles Dickens   
  960-425-059-0   The Lord of the Rings      J. R. R. Tolkien  
  80-902734-1-6   And Then There Were None   Agatha Christie   
 =============== ========================== ================== 

TABLE
),
array(
array('ISBN', 'Title'),
array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
array('9971-5-0210-0'),
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
),
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+--------------------------+------------------+
| ISBN          | Title                    |                  |
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
),
array(
array(),
array(
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
array('9971-5-0210-0'),
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
),
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+--------------------------+------------------+
| 99921-58-10-7 | Divine Comedy            | Dante Alighieri  |
| 9971-5-0210-0 |                          |                  |
| 960-425-059-0 | The Lord of the Rings    | J. R. R. Tolkien |
| 80-902734-1-6 | And Then There Were None | Agatha Christie  |
+---------------+--------------------------+------------------+

TABLE
),
array(
array('ISBN', 'Title', 'Author'),
array(
array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'),
array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"),
),
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+----------------------------+-----------------+
| ISBN          | Title                      | Author          |
+---------------+----------------------------+-----------------+
| 99921-58-10-7 | Divine                     | Dante Alighieri |
|               | Comedy                     |                 |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 9971-5-0210-2 | Harry Potter               | Rowling         |
|               | and the Chamber of Secrets | Joanne K.       |
| 960-425-059-0 | The Lord of the Rings      | J. R. R.        |
|               |                            | Tolkien         |
+---------------+----------------------------+-----------------+

TABLE
),
array(
array('ISBN', 'Title'),
array(),
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+------+-------+
| ISBN | Title |
+------+-------+

TABLE
),
array(
array(),
array(),
TableHelper::LAYOUT_DEFAULT,
'',
),
'Cell text with tags used for Output styling' => array(
array('ISBN', 'Title', 'Author'),
array(
array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
),
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+---------------+----------------------+-----------------+
| ISBN          | Title                | Author          |
+---------------+----------------------+-----------------+
| 99921-58-10-7 | Divine Comedy        | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+---------------+----------------------+-----------------+

TABLE
),
'Cell text with tags not used for Output styling' => array(
array('ISBN', 'Title', 'Author'),
array(
array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
),
TableHelper::LAYOUT_DEFAULT,
<<<'TABLE'
+----------------------------------+----------------------+-----------------+
| ISBN                             | Title                | Author          |
+----------------------------------+----------------------+-----------------+
| <strong>99921-58-10-700</strong> | <f>Divine Com</f>    | Dante Alighieri |
| 9971-5-0210-0                    | A Tale of Two Cities | Charles Dickens |
+----------------------------------+----------------------+-----------------+

TABLE
),
);
}

public function testRenderMultiByte()
{
$table = new TableHelper();
$table
->setHeaders(array('■■'))
->setRows(array(array(1234)))
->setLayout(TableHelper::LAYOUT_DEFAULT)
;
$table->render($output = $this->getOutputStream());

$expected =
<<<'TABLE'
+------+
| ■■   |
+------+
| 1234 |
+------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

public function testRenderFullWidthCharacters()
{
$table = new TableHelper();
$table
->setHeaders(array('あいうえお'))
->setRows(array(array(1234567890)))
->setLayout(TableHelper::LAYOUT_DEFAULT)
;
$table->render($output = $this->getOutputStream());

$expected =
<<<'TABLE'
+------------+
| あいうえお |
+------------+
| 1234567890 |
+------------+

TABLE;

$this->assertEquals($expected, $this->getOutputContent($output));
}

protected function getOutputStream()
{
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
}

protected function getOutputContent(StreamOutput $output)
{
rewind($output->getStream());

return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\ProcessBuilder;

class ProcessHelperTest extends TestCase
{



public function testVariousProcessRuns($expected, $cmd, $verbosity, $error)
{
$helper = new ProcessHelper();
$helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
$output = $this->getOutputStream($verbosity);
$helper->run($output, $cmd, $error);
$this->assertEquals($expected, $this->getOutput($output));
}

public function testPassedCallbackIsExecuted()
{
$helper = new ProcessHelper();
$helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper())));
$output = $this->getOutputStream(StreamOutput::VERBOSITY_NORMAL);

$executed = false;
$callback = function () use (&$executed) { $executed = true; };

$helper->run($output, 'php -r "echo 42;"', null, $callback);
$this->assertTrue($executed);
}

public function provideCommandsAndOutput()
{
$successOutputVerbose = <<<'EOT'
  RUN  php -r "echo 42;"
  RES  Command ran successfully

EOT;
$successOutputDebug = <<<'EOT'
  RUN  php -r "echo 42;"
  OUT  42
  RES  Command ran successfully

EOT;
$successOutputDebugWithTags = <<<'EOT'
  RUN  php -r "echo '<info>42</info>';"
  OUT  <info>42</info>
  RES  Command ran successfully

EOT;
$successOutputProcessDebug = <<<'EOT'
  RUN  'php' '-r' 'echo 42;'
  OUT  42
  RES  Command ran successfully

EOT;
$syntaxErrorOutputVerbose = <<<'EOT'
  RUN  php -r "fwrite(STDERR, 'error message');usleep(50000);fwrite(STDOUT, 'out message');exit(252);"
  RES  252 Command did not run successfully

EOT;
$syntaxErrorOutputDebug = <<<'EOT'
  RUN  php -r "fwrite(STDERR, 'error message');usleep(500000);fwrite(STDOUT, 'out message');exit(252);"
  ERR  error message
  OUT  out message
  RES  252 Command did not run successfully

EOT;

$errorMessage = 'An error occurred';
$args = new ProcessBuilder(array('php', '-r', 'echo 42;'));
$args = $args->getProcess()->getCommandLine();
$successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug);

return array(
array('', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null),
array($successOutputVerbose, 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
array($successOutputDebug, 'php -r "echo 42;"', StreamOutput::VERBOSITY_DEBUG, null),
array($successOutputDebugWithTags, 'php -r "echo \'<info>42</info>\';"', StreamOutput::VERBOSITY_DEBUG, null),
array('', 'php -r "syntax error"', StreamOutput::VERBOSITY_VERBOSE, null),
array($syntaxErrorOutputVerbose, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
array($syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null),
array($errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERBOSE, $errorMessage),
array($syntaxErrorOutputVerbose.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage),
array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage),
array($successOutputProcessDebug, array('php', '-r', 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null),
array($successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null),
);
}

private function getOutputStream($verbosity)
{
return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, false);
}

private function getOutput(StreamOutput $output)
{
rewind($output->getStream());

return stream_get_contents($output->getStream());
}
}
<?php

namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\ProgressIndicator;
use Symfony\Component\Console\Output\StreamOutput;




class ProgressIndicatorTest extends TestCase
{
public function testDefaultIndicator()
{
$bar = new ProgressIndicator($output = $this->getOutputStream());
$bar->start('Starting...');
usleep(101000);
$bar->advance();
usleep(101000);
$bar->advance();
usleep(101000);
$bar->advance();
usleep(101000);
$bar->advance();
usleep(101000);
$bar->advance();
usleep(101000);
$bar->setMessage('Advancing...');
$bar->advance();
$bar->finish('Done...');
$bar->start('Starting Again...');
usleep(101000);
$bar->advance();
$bar->finish('Done Again...');

rewind($output->getStream());

$this->assertEquals(
$this->generateOutput(' - Starting...').
$this->generateOutput(' \\ Starting...').
$this->generateOutput(' | Starting...').
$this->generateOutput(' / Starting...').
$this->generateOutput(' - Starting...').
$this->generateOutput(' \\ Starting...').
$this->generateOutput(' \\ Advancing...').
$this->generateOutput(' | Advancing...').
$this->generateOutput(' | Done...').
PHP_EOL.
$this->generateOutput(' - Starting Again...').
$this->generateOutput(' \\ Starting Again...').
$this->generateOutput(' \\ Done Again...').
PHP_EOL,
stream_get_contents($output->getStream())
);
}

public function testNonDecoratedOutput()
{
$bar = new ProgressIndicator($output = $this->getOutputStream(false));

$bar->start('Starting...');
$bar->advance();
$bar->advance();
$bar->setMessage('Midway...');
$bar->advance();
$bar->advance();
$bar->finish('Done...');

rewind($output->getStream());

$this->assertEquals(
' Starting...'.PHP_EOL.
' Midway...'.PHP_EOL.
' Done...'.PHP_EOL.PHP_EOL,
stream_get_contents($output->getStream())
);
}

public function testCustomIndicatorValues()
{
$bar = new ProgressIndicator($output = $this->getOutputStream(), null, 100, array('a', 'b', 'c'));

$bar->start('Starting...');
usleep(101000);
$bar->advance();
usleep(101000);
$bar->advance();
usleep(101000);
$bar->advance();

rewind($output->getStream());

$this->assertEquals(
$this->generateOutput(' a Starting...').
$this->generateOutput(' b Starting...').
$this->generateOutput(' c Starting...').
$this->generateOutput(' a Starting...'),
stream_get_contents($output->getStream())
);
}





public function testCannotSetInvalidIndicatorCharacters()
{
$bar = new ProgressIndicator($this->getOutputStream(), null, 100, array('1'));
}





public function testCannotStartAlreadyStartedIndicator()
{
$bar = new ProgressIndicator($this->getOutputStream());
$bar->start('Starting...');
$bar->start('Starting Again.');
}





public function testCannotAdvanceUnstartedIndicator()
{
$bar = new ProgressIndicator($this->getOutputStream());
$bar->advance();
}





public function testCannotFinishUnstartedIndicator()
{
$bar = new ProgressIndicator($this->getOutputStream());
$bar->finish('Finished');
}




public function testFormats($format)
{
$bar = new ProgressIndicator($output = $this->getOutputStream(), $format);
$bar->start('Starting...');
$bar->advance();

rewind($output->getStream());

$this->assertNotEmpty(stream_get_contents($output->getStream()));
}






public function provideFormat()
{
return array(
array('normal'),
array('verbose'),
array('very_verbose'),
array('debug'),
);
}

protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
{
return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
}

protected function generateOutput($expected)
{
$count = substr_count($expected, "\n");

return "\x0D\x1B[2K".($count ? sprintf("\033[%dA", $count) : '').$expected;
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\TableStyle;

class TableStyleTest extends TestCase
{




public function testSetPadTypeWithInvalidType()
{
$style = new TableStyle();
$style->setPadType('TEST');
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Exception\InvalidArgumentException;




class LegacyDialogHelperTest extends TestCase
{
public function testSelect()
{
$dialog = new DialogHelper();

$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$heroes = array('Superman', 'Batman', 'Spiderman');

$dialog->setInputStream($this->getInputStream("\n1\n  1  \nFabien\n1\nFabien\n1\n0,2\n 0 , 2  \n\n\n"));
$this->assertEquals('2', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '2'));
$this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
$this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes));
$this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false));

rewind($output->getStream());
$this->assertContains('Input "Fabien" is not a superhero!', stream_get_contents($output->getStream()));

try {
$this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, 1));
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertEquals('Value "Fabien" is invalid', $e->getMessage());
}

$this->assertEquals(array('1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
$this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
$this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true));
$this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '0,1', false, 'Input "%s" is not a superhero!', true));
$this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, ' 0 , 1 ', false, 'Input "%s" is not a superhero!', true));
}

public function testSelectOnErrorOutput()
{
$dialog = new DialogHelper();

$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$heroes = array('Superman', 'Batman', 'Spiderman');

$dialog->setInputStream($this->getInputStream("Stdout\n1\n"));
$this->assertEquals('1', $dialog->select($output = $this->getConsoleOutput($this->getOutputStream()), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false));

rewind($output->getErrorOutput()->getStream());
$this->assertContains('Input "Stdout" is not a superhero!', stream_get_contents($output->getErrorOutput()->getStream()));
}

public function testAsk()
{
$dialog = new DialogHelper();

$dialog->setInputStream($this->getInputStream("\n8AM\n"));

$this->assertEquals('2PM', $dialog->ask($this->getOutputStream(), 'What time is it?', '2PM'));
$this->assertEquals('8AM', $dialog->ask($output = $this->getOutputStream(), 'What time is it?', '2PM'));

rewind($output->getStream());
$this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
}

public function testAskOnErrorOutput()
{
if (!$this->hasSttyAvailable()) {
$this->markTestSkipped('`stderr` is required to test stderr output functionality');
}

$dialog = new DialogHelper();

$dialog->setInputStream($this->getInputStream("not stdout\n"));

$this->assertEquals('not stdout', $dialog->ask($output = $this->getConsoleOutput($this->getOutputStream()), 'Where should output go?', 'stderr'));

rewind($output->getErrorOutput()->getStream());
$this->assertEquals('Where should output go?', stream_get_contents($output->getErrorOutput()->getStream()));
}

public function testAskWithAutocomplete()
{
if (!$this->hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
}


 
 
 
 
 
 
 
 $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");

$dialog = new DialogHelper();
$dialog->setInputStream($inputStream);

$bundles = array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle');

$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('FrameworkBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('SecurityBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('FooBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('AsseticBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
$this->assertEquals('FooBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles));
}




public function testAskHiddenResponse()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test is not supported on Windows');
}

$dialog = new DialogHelper();

$dialog->setInputStream($this->getInputStream("8AM\n"));

$this->assertEquals('8AM', $dialog->askHiddenResponse($this->getOutputStream(), 'What time is it?'));
}




public function testAskHiddenResponseOnErrorOutput()
{
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test is not supported on Windows');
}

$dialog = new DialogHelper();

$dialog->setInputStream($this->getInputStream("8AM\n"));

$this->assertEquals('8AM', $dialog->askHiddenResponse($output = $this->getConsoleOutput($this->getOutputStream()), 'What time is it?'));

rewind($output->getErrorOutput()->getStream());
$this->assertContains('What time is it?', stream_get_contents($output->getErrorOutput()->getStream()));
}

public function testAskConfirmation()
{
$dialog = new DialogHelper();

$dialog->setInputStream($this->getInputStream("\n\n"));
$this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?'));
$this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));

$dialog->setInputStream($this->getInputStream("y\nyes\n"));
$this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));
$this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false));

$dialog->setInputStream($this->getInputStream("n\nno\n"));
$this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
$this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true));
}

public function testAskAndValidate()
{
$dialog = new DialogHelper();
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = 'What color was the white horse of Henry IV?';
$error = 'This is not a color!';
$validator = function ($color) use ($error) {
if (!in_array($color, array('white', 'black'))) {
throw new InvalidArgumentException($error);
}

return $color;
};

$dialog->setInputStream($this->getInputStream("\nblack\n"));
$this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));
$this->assertEquals('black', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white'));

$dialog->setInputStream($this->getInputStream("green\nyellow\norange\n"));
try {
$this->assertEquals('white', $dialog->askAndValidate($output = $this->getConsoleOutput($this->getOutputStream()), $question, $validator, 2, 'white'));
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertEquals($error, $e->getMessage());
rewind($output->getErrorOutput()->getStream());
$this->assertContains('What color was the white horse of Henry IV?', stream_get_contents($output->getErrorOutput()->getStream()));
}
}

public function testNoInteraction()
{
$dialog = new DialogHelper();

$input = new ArrayInput(array());
$input->setInteractive(false);

$dialog->setInput($input);

$this->assertEquals('not yet', $dialog->ask($this->getOutputStream(), 'Do you have a job?', 'not yet'));
}

protected function getInputStream($input)
{
$stream = fopen('php://memory', 'r+', false);
fwrite($stream, $input);
rewind($stream);

return $stream;
}

protected function getOutputStream()
{
return new StreamOutput(fopen('php://memory', 'r+', false));
}

protected function getConsoleOutput($stderr)
{
$output = new ConsoleOutput();
$output->setErrorOutput($stderr);

return $output;
}

private function hasSttyAvailable()
{
exec('stty 2>&1', $output, $exitcode);

return $exitcode === 0;
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\ProgressHelper;
use Symfony\Component\Console\Output\StreamOutput;





class LegacyProgressHelperTest extends TestCase
{
public function testAdvance()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream());
$progress->advance();

rewind($output->getStream());
$this->assertEquals($this->generateOutput('    1 [->--------------------------]'), stream_get_contents($output->getStream()));
}

public function testAdvanceWithStep()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream());
$progress->advance(5);

rewind($output->getStream());
$this->assertEquals($this->generateOutput('    5 [----->----------------------]'), stream_get_contents($output->getStream()));
}

public function testAdvanceMultipleTimes()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream());
$progress->advance(3);
$progress->advance(2);

rewind($output->getStream());
$this->assertEquals($this->generateOutput('    3 [--->------------------------]').$this->generateOutput('    5 [----->----------------------]'), stream_get_contents($output->getStream()));
}

public function testCustomizations()
{
$progress = new ProgressHelper();
$progress->setBarWidth(10);
$progress->setBarCharacter('_');
$progress->setEmptyBarCharacter(' ');
$progress->setProgressCharacter('/');
$progress->setFormat(' %current%/%max% [%bar%] %percent%%');
$progress->start($output = $this->getOutputStream(), 10);
$progress->advance();

rewind($output->getStream());
$this->assertEquals($this->generateOutput('  1/10 [_/        ]  10%'), stream_get_contents($output->getStream()));
}

public function testPercent()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream(), 50);
$progress->display();
$progress->advance();
$progress->advance();

rewind($output->getStream());
$this->assertEquals($this->generateOutput('  0/50 [>---------------------------]   0%').$this->generateOutput('  1/50 [>---------------------------]   2%').$this->generateOutput('  2/50 [=>--------------------------]   4%'), stream_get_contents($output->getStream()));
}

public function testOverwriteWithShorterLine()
{
$progress = new ProgressHelper();
$progress->setFormat(' %current%/%max% [%bar%] %percent%%');
$progress->start($output = $this->getOutputStream(), 50);
$progress->display();
$progress->advance();


 $progress->setFormat(' %current%/%max% [%bar%]');
$progress->advance();

rewind($output->getStream());
$this->assertEquals(
$this->generateOutput('  0/50 [>---------------------------]   0%').
$this->generateOutput('  1/50 [>---------------------------]   2%').
$this->generateOutput('  2/50 [=>--------------------------]     '),
stream_get_contents($output->getStream())
);
}

public function testSetCurrentProgress()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream(), 50);
$progress->display();
$progress->advance();
$progress->setCurrent(15);
$progress->setCurrent(25);

rewind($output->getStream());
$this->assertEquals(
$this->generateOutput('  0/50 [>---------------------------]   0%').
$this->generateOutput('  1/50 [>---------------------------]   2%').
$this->generateOutput(' 15/50 [========>-------------------]  30%').
$this->generateOutput(' 25/50 [==============>-------------]  50%'),
stream_get_contents($output->getStream())
);
}





public function testSetCurrentBeforeStarting()
{
$progress = new ProgressHelper();
$progress->setCurrent(15);
}





public function testRegressProgress()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream(), 50);
$progress->setCurrent(15);
$progress->setCurrent(10);
}

public function testRedrawFrequency()
{
$progress = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressHelper')->setMethods(array('display'))->getMock();
$progress->expects($this->exactly(4))
->method('display');

$progress->setRedrawFrequency(2);

$progress->start($output = $this->getOutputStream(), 6);
$progress->setCurrent(1);
$progress->advance(2);
$progress->advance(2);
$progress->advance(1);
}

public function testMultiByteSupport()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream());
$progress->setBarCharacter('■');
$progress->advance(3);

rewind($output->getStream());
$this->assertEquals($this->generateOutput('    3 [■■■>------------------------]'), stream_get_contents($output->getStream()));
}

public function testClear()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream(), 50);
$progress->setCurrent(25);
$progress->clear();

rewind($output->getStream());
$this->assertEquals(
$this->generateOutput(' 25/50 [==============>-------------]  50%').$this->generateOutput(''),
stream_get_contents($output->getStream())
);
}

public function testPercentNotHundredBeforeComplete()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream(), 200);
$progress->display();
$progress->advance(199);
$progress->advance();

rewind($output->getStream());
$this->assertEquals($this->generateOutput('   0/200 [>---------------------------]   0%').$this->generateOutput(' 199/200 [===========================>]  99%').$this->generateOutput(' 200/200 [============================] 100%'), stream_get_contents($output->getStream()));
}

public function testNonDecoratedOutput()
{
$progress = new ProgressHelper();
$progress->start($output = $this->getOutputStream(false));
$progress->advance();

rewind($output->getStream());
$this->assertEquals('', stream_get_contents($output->getStream()));
}

protected function getOutputStream($decorated = true)
{
return new StreamOutput(fopen('php://memory', 'r+', false), StreamOutput::VERBOSITY_NORMAL, $decorated);
}

protected $lastMessagesLength;

protected function generateOutput($expected)
{
$expectedout = $expected;

if ($this->lastMessagesLength !== null) {
$expectedout = str_pad($expected, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
}

$this->lastMessagesLength = strlen($expectedout);

return "\x0D".$expectedout;
}
}
<?php










namespace Symfony\Component\Console\Tests\Helper;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Output\StreamOutput;




class ProgressBarTest extends TestCase
{
public function testMultipleStart()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->start();
$bar->advance();
$bar->start();

rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]'.
$this->generateOutput('    1 [->--------------------------]').
$this->generateOutput('    0 [>---------------------------]'),
stream_get_contents($output->getStream())
);
}

public function testAdvance()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->start();
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]'.
$this->generateOutput('    1 [->--------------------------]'),
stream_get_contents($output->getStream())
);
}

public function testAdvanceWithStep()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->start();
$bar->advance(5);

rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]'.
$this->generateOutput('    5 [----->----------------------]'),
stream_get_contents($output->getStream())
);
}

public function testAdvanceMultipleTimes()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->start();
$bar->advance(3);
$bar->advance(2);

rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]'.
$this->generateOutput('    3 [--->------------------------]').
$this->generateOutput('    5 [----->----------------------]'),
stream_get_contents($output->getStream())
);
}

public function testAdvanceOverMax()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->setProgress(9);
$bar->advance();
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'  9/10 [=========================>--]  90%'.
$this->generateOutput(' 10/10 [============================] 100%').
$this->generateOutput(' 11/11 [============================] 100%'),
stream_get_contents($output->getStream())
);
}

public function testFormat()
{
$expected =
'  0/10 [>---------------------------]   0%'.
$this->generateOutput(' 10/10 [============================] 100%').
$this->generateOutput(' 10/10 [============================] 100%')
;


 $bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->start();
$bar->advance(10);
$bar->finish();

rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));


 $bar = new ProgressBar($output = $this->getOutputStream());
$bar->start(10);
$bar->advance(10);
$bar->finish();

rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));


 $bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->setFormat('normal');
$bar->start();
$bar->advance(10);
$bar->finish();

rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));


 $bar = new ProgressBar($output = $this->getOutputStream());
$bar->setFormat('normal');
$bar->start(10);
$bar->advance(10);
$bar->finish();

rewind($output->getStream());
$this->assertEquals($expected, stream_get_contents($output->getStream()));
}

public function testCustomizations()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->setBarWidth(10);
$bar->setBarCharacter('_');
$bar->setEmptyBarCharacter(' ');
$bar->setProgressCharacter('/');
$bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
$bar->start();
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'  0/10 [/         ]   0%'.
$this->generateOutput('  1/10 [_/        ]  10%'),
stream_get_contents($output->getStream())
);
}

public function testDisplayWithoutStart()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->display();

rewind($output->getStream());
$this->assertEquals(
'  0/50 [>---------------------------]   0%',
stream_get_contents($output->getStream())
);
}

public function testDisplayWithQuietVerbosity()
{
$bar = new ProgressBar($output = $this->getOutputStream(true, StreamOutput::VERBOSITY_QUIET), 50);
$bar->display();

rewind($output->getStream());
$this->assertEquals(
'',
stream_get_contents($output->getStream())
);
}

public function testFinishWithoutStart()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->finish();

rewind($output->getStream());
$this->assertEquals(
' 50/50 [============================] 100%',
stream_get_contents($output->getStream())
);
}

public function testPercent()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->start();
$bar->display();
$bar->advance();
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'  0/50 [>---------------------------]   0%'.
$this->generateOutput('  0/50 [>---------------------------]   0%').
$this->generateOutput('  1/50 [>---------------------------]   2%').
$this->generateOutput('  2/50 [=>--------------------------]   4%'),
stream_get_contents($output->getStream())
);
}

public function testOverwriteWithShorterLine()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%');
$bar->start();
$bar->display();
$bar->advance();


 $bar->setFormat(' %current%/%max% [%bar%]');
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'  0/50 [>---------------------------]   0%'.
$this->generateOutput('  0/50 [>---------------------------]   0%').
$this->generateOutput('  1/50 [>---------------------------]   2%').
$this->generateOutput('  2/50 [=>--------------------------]'),
stream_get_contents($output->getStream())
);
}

public function testStartWithMax()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->setFormat('%current%/%max% [%bar%]');
$bar->start(50);
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
' 0/50 [>---------------------------]'.
$this->generateOutput(' 1/50 [>---------------------------]'),
stream_get_contents($output->getStream())
);
}

public function testSetCurrentProgress()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->start();
$bar->display();
$bar->advance();
$bar->setProgress(15);
$bar->setProgress(25);

rewind($output->getStream());
$this->assertEquals(
'  0/50 [>---------------------------]   0%'.
$this->generateOutput('  0/50 [>---------------------------]   0%').
$this->generateOutput('  1/50 [>---------------------------]   2%').
$this->generateOutput(' 15/50 [========>-------------------]  30%').
$this->generateOutput(' 25/50 [==============>-------------]  50%'),
stream_get_contents($output->getStream())
);
}

public function testSetCurrentBeforeStarting()
{
$bar = new ProgressBar($this->getOutputStream());
$bar->setProgress(15);
$this->assertNotNull($bar->getStartTime());
}





public function testRegressProgress()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->start();
$bar->setProgress(15);
$bar->setProgress(10);
}

public function testRedrawFrequency()
{
$bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream(), 6))->getMock();
$bar->expects($this->exactly(4))->method('display');

$bar->setRedrawFrequency(2);
$bar->start();
$bar->setProgress(1);
$bar->advance(2);
$bar->advance(2);
$bar->advance(1);
}

public function testRedrawFrequencyIsAtLeastOneIfZeroGiven()
{
$bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream()))->getMock();

$bar->expects($this->exactly(2))->method('display');
$bar->setRedrawFrequency(0);
$bar->start();
$bar->advance();
}

public function testRedrawFrequencyIsAtLeastOneIfSmallerOneGiven()
{
$bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream()))->getMock();

$bar->expects($this->exactly(2))->method('display');
$bar->setRedrawFrequency(0.9);
$bar->start();
$bar->advance();
}

public function testMultiByteSupport()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->start();
$bar->setBarCharacter('■');
$bar->advance(3);

rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]'.
$this->generateOutput('    3 [■■■>------------------------]'),
stream_get_contents($output->getStream())
);
}

public function testClear()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 50);
$bar->start();
$bar->setProgress(25);
$bar->clear();

rewind($output->getStream());
$this->assertEquals(
'  0/50 [>---------------------------]   0%'.
$this->generateOutput(' 25/50 [==============>-------------]  50%').
$this->generateOutput(''),
stream_get_contents($output->getStream())
);
}

public function testPercentNotHundredBeforeComplete()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 200);
$bar->start();
$bar->display();
$bar->advance(199);
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'   0/200 [>---------------------------]   0%'.
$this->generateOutput('   0/200 [>---------------------------]   0%').
$this->generateOutput(' 199/200 [===========================>]  99%').
$this->generateOutput(' 200/200 [============================] 100%'),
stream_get_contents($output->getStream())
);
}

public function testNonDecoratedOutput()
{
$bar = new ProgressBar($output = $this->getOutputStream(false), 200);
$bar->start();

for ($i = 0; $i < 200; ++$i) {
$bar->advance();
}

$bar->finish();

rewind($output->getStream());
$this->assertEquals(
'   0/200 [>---------------------------]   0%'.PHP_EOL.
'  20/200 [==>-------------------------]  10%'.PHP_EOL.
'  40/200 [=====>----------------------]  20%'.PHP_EOL.
'  60/200 [========>-------------------]  30%'.PHP_EOL.
'  80/200 [===========>----------------]  40%'.PHP_EOL.
' 100/200 [==============>-------------]  50%'.PHP_EOL.
' 120/200 [================>-----------]  60%'.PHP_EOL.
' 140/200 [===================>--------]  70%'.PHP_EOL.
' 160/200 [======================>-----]  80%'.PHP_EOL.
' 180/200 [=========================>--]  90%'.PHP_EOL.
' 200/200 [============================] 100%',
stream_get_contents($output->getStream())
);
}

public function testNonDecoratedOutputWithClear()
{
$bar = new ProgressBar($output = $this->getOutputStream(false), 50);
$bar->start();
$bar->setProgress(25);
$bar->clear();
$bar->setProgress(50);
$bar->finish();

rewind($output->getStream());
$this->assertEquals(
'  0/50 [>---------------------------]   0%'.PHP_EOL.
' 25/50 [==============>-------------]  50%'.PHP_EOL.
' 50/50 [============================] 100%',
stream_get_contents($output->getStream())
);
}

public function testNonDecoratedOutputWithoutMax()
{
$bar = new ProgressBar($output = $this->getOutputStream(false));
$bar->start();
$bar->advance();

rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]'.PHP_EOL.
'    1 [->--------------------------]',
stream_get_contents($output->getStream())
);
}

public function testParallelBars()
{
$output = $this->getOutputStream();
$bar1 = new ProgressBar($output, 2);
$bar2 = new ProgressBar($output, 3);
$bar2->setProgressCharacter('#');
$bar3 = new ProgressBar($output);

$bar1->start();
$output->write("\n");
$bar2->start();
$output->write("\n");
$bar3->start();

for ($i = 1; $i <= 3; ++$i) {

 $output->write("\033[2A");
if ($i <= 2) {
$bar1->advance();
}
$output->write("\n");
$bar2->advance();
$output->write("\n");
$bar3->advance();
}
$output->write("\033[2A");
$output->write("\n");
$output->write("\n");
$bar3->finish();

rewind($output->getStream());
$this->assertEquals(
' 0/2 [>---------------------------]   0%'."\n".
' 0/3 [#---------------------------]   0%'."\n".
rtrim('    0 [>---------------------------]').

"\033[2A".
$this->generateOutput(' 1/2 [==============>-------------]  50%')."\n".
$this->generateOutput(' 1/3 [=========#------------------]  33%')."\n".
rtrim($this->generateOutput('    1 [->--------------------------]')).

"\033[2A".
$this->generateOutput(' 2/2 [============================] 100%')."\n".
$this->generateOutput(' 2/3 [==================#---------]  66%')."\n".
rtrim($this->generateOutput('    2 [-->-------------------------]')).

"\033[2A".
"\n".
$this->generateOutput(' 3/3 [============================] 100%')."\n".
rtrim($this->generateOutput('    3 [--->------------------------]')).

"\033[2A".
"\n".
"\n".
rtrim($this->generateOutput('    3 [============================]')),
stream_get_contents($output->getStream())
);
}

public function testWithoutMax()
{
$output = $this->getOutputStream();

$bar = new ProgressBar($output);
$bar->start();
$bar->advance();
$bar->advance();
$bar->advance();
$bar->finish();

rewind($output->getStream());
$this->assertEquals(
rtrim('    0 [>---------------------------]').
rtrim($this->generateOutput('    1 [->--------------------------]')).
rtrim($this->generateOutput('    2 [-->-------------------------]')).
rtrim($this->generateOutput('    3 [--->------------------------]')).
rtrim($this->generateOutput('    3 [============================]')),
stream_get_contents($output->getStream())
);
}

public function testAddingPlaceholderFormatter()
{
ProgressBar::setPlaceholderFormatterDefinition('remaining_steps', function (ProgressBar $bar) {
return $bar->getMaxSteps() - $bar->getProgress();
});
$bar = new ProgressBar($output = $this->getOutputStream(), 3);
$bar->setFormat(' %remaining_steps% [%bar%]');

$bar->start();
$bar->advance();
$bar->finish();

rewind($output->getStream());
$this->assertEquals(
' 3 [>---------------------------]'.
$this->generateOutput(' 2 [=========>------------------]').
$this->generateOutput(' 0 [============================]'),
stream_get_contents($output->getStream())
);
}

public function testMultilineFormat()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 3);
$bar->setFormat("%bar%\nfoobar");

$bar->start();
$bar->advance();
$bar->clear();
$bar->finish();

rewind($output->getStream());
$this->assertEquals(
">---------------------------\nfoobar".
$this->generateOutput("=========>------------------\nfoobar").
"\x0D\x1B[2K\x1B[1A\x1B[2K".
$this->generateOutput("============================\nfoobar"),
stream_get_contents($output->getStream())
);
}

public function testAnsiColorsAndEmojis()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 15);
ProgressBar::setPlaceholderFormatterDefinition('memory', function (ProgressBar $bar) {
static $i = 0;
$mem = 100000 * $i;
$colors = $i++ ? '41;37' : '44;37';

return "\033[".$colors.'m '.Helper::formatMemory($mem)." \033[0m";
});
$bar->setFormat(" \033[44;37m %title:-37s% \033[0m\n %current%/%max% %bar% %percent:3s%%\n 🏁  %remaining:-10s% %memory:37s%");
$bar->setBarCharacter($done = "\033[32m●\033[0m");
$bar->setEmptyBarCharacter($empty = "\033[31m●\033[0m");
$bar->setProgressCharacter($progress = "\033[32m➤ \033[0m");

$bar->setMessage('Starting the demo... fingers crossed', 'title');
$bar->start();
$bar->setMessage('Looks good to me...', 'title');
$bar->advance(4);
$bar->setMessage('Thanks, bye', 'title');
$bar->finish();

rewind($output->getStream());
$this->assertEquals(
" \033[44;37m Starting the demo... fingers crossed  \033[0m\n".
'  0/15 '.$progress.str_repeat($empty, 26)."   0%\n".
" \xf0\x9f\x8f\x81  < 1 sec                        \033[44;37m 0 B \033[0m"
.
$this->generateOutput(
" \033[44;37m Looks good to me...                   \033[0m\n".
'  4/15 '.str_repeat($done, 7).$progress.str_repeat($empty, 19)."  26%\n".
" \xf0\x9f\x8f\x81  < 1 sec                     \033[41;37m 97 KiB \033[0m"
).
$this->generateOutput(
" \033[44;37m Thanks, bye                           \033[0m\n".
' 15/15 '.str_repeat($done, 28)." 100%\n".
" \xf0\x9f\x8f\x81  < 1 sec                    \033[41;37m 195 KiB \033[0m"
),
stream_get_contents($output->getStream())
);
}

public function testSetFormat()
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->setFormat('normal');
$bar->start();
rewind($output->getStream());
$this->assertEquals(
'    0 [>---------------------------]',
stream_get_contents($output->getStream())
);

$bar = new ProgressBar($output = $this->getOutputStream(), 10);
$bar->setFormat('normal');
$bar->start();
rewind($output->getStream());
$this->assertEquals(
'  0/10 [>---------------------------]   0%',
stream_get_contents($output->getStream())
);
}




public function testFormatsWithoutMax($format)
{
$bar = new ProgressBar($output = $this->getOutputStream());
$bar->setFormat($format);
$bar->start();

rewind($output->getStream());
$this->assertNotEmpty(stream_get_contents($output->getStream()));
}






public function provideFormat()
{
return array(
array('normal'),
array('verbose'),
array('very_verbose'),
array('debug'),
);
}

protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL)
{
return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated);
}

protected function generateOutput($expected)
{
$count = substr_count($expected, "\n");

return "\x0D\x1B[2K".($count ? str_repeat("\x1B[1A\x1B[2K", $count) : '').$expected;
}
}
<?php










namespace Symfony\Component\Console\Tests\Output;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Output\OutputInterface;

class NullOutputTest extends TestCase
{
public function testConstructor()
{
$output = new NullOutput();

ob_start();
$output->write('foo');
$buffer = ob_get_clean();

$this->assertSame('', $buffer, '->write() does nothing (at least nothing is printed)');
$this->assertFalse($output->isDecorated(), '->isDecorated() returns false');
}

public function testVerbosity()
{
$output = new NullOutput();
$this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() returns VERBOSITY_QUIET for NullOutput by default');

$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
$this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() always returns VERBOSITY_QUIET for NullOutput');
}

public function testSetFormatter()
{
$output = new NullOutput();
$outputFormatter = new OutputFormatter();
$output->setFormatter($outputFormatter);
$this->assertNotSame($outputFormatter, $output->getFormatter());
}

public function testSetVerbosity()
{
$output = new NullOutput();
$output->setVerbosity(Output::VERBOSITY_NORMAL);
$this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity());
}

public function testSetDecorated()
{
$output = new NullOutput();
$output->setDecorated(true);
$this->assertFalse($output->isDecorated());
}

public function testIsQuiet()
{
$output = new NullOutput();
$this->assertTrue($output->isQuiet());
}

public function testIsVerbose()
{
$output = new NullOutput();
$this->assertFalse($output->isVerbose());
}

public function testIsVeryVerbose()
{
$output = new NullOutput();
$this->assertFalse($output->isVeryVerbose());
}

public function testIsDebug()
{
$output = new NullOutput();
$this->assertFalse($output->isDebug());
}
}
<?php










namespace Symfony\Component\Console\Tests\Output;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\Output;

class ConsoleOutputTest extends TestCase
{
public function testConstructor()
{
$output = new ConsoleOutput(Output::VERBOSITY_QUIET, true);
$this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
$this->assertSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), '__construct() takes a formatter or null as the third argument');
}

public function testSetFormatter()
{
$output = new ConsoleOutput();
$outputFormatter = new OutputFormatter();
$output->setFormatter($outputFormatter);
$this->assertSame($outputFormatter, $output->getFormatter());
}

public function testSetVerbosity()
{
$output = new ConsoleOutput();
$output->setVerbosity(Output::VERBOSITY_VERBOSE);
$this->assertSame(Output::VERBOSITY_VERBOSE, $output->getVerbosity());
}
}
<?php










namespace Symfony\Component\Console\Tests\Output;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Output\StreamOutput;

class StreamOutputTest extends TestCase
{
protected $stream;

protected function setUp()
{
$this->stream = fopen('php://memory', 'a', false);
}

protected function tearDown()
{
$this->stream = null;
}

public function testConstructor()
{
$output = new StreamOutput($this->stream, Output::VERBOSITY_QUIET, true);
$this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
$this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
}





public function testStreamIsRequired()
{
new StreamOutput('foo');
}

public function testGetStream()
{
$output = new StreamOutput($this->stream);
$this->assertEquals($this->stream, $output->getStream(), '->getStream() returns the current stream');
}

public function testDoWrite()
{
$output = new StreamOutput($this->stream);
$output->writeln('foo');
rewind($output->getStream());
$this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream');
}
}
<?php










namespace Symfony\Component\Console\Tests\Output;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class OutputTest extends TestCase
{
public function testConstructor()
{
$output = new TestOutput(Output::VERBOSITY_QUIET, true);
$this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument');
$this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument');
}

public function testSetIsDecorated()
{
$output = new TestOutput();
$output->setDecorated(true);
$this->assertTrue($output->isDecorated(), 'setDecorated() sets the decorated flag');
}

public function testSetGetVerbosity()
{
$output = new TestOutput();
$output->setVerbosity(Output::VERBOSITY_QUIET);
$this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '->setVerbosity() sets the verbosity');

$this->assertTrue($output->isQuiet());
$this->assertFalse($output->isVerbose());
$this->assertFalse($output->isVeryVerbose());
$this->assertFalse($output->isDebug());

$output->setVerbosity(Output::VERBOSITY_NORMAL);
$this->assertFalse($output->isQuiet());
$this->assertFalse($output->isVerbose());
$this->assertFalse($output->isVeryVerbose());
$this->assertFalse($output->isDebug());

$output->setVerbosity(Output::VERBOSITY_VERBOSE);
$this->assertFalse($output->isQuiet());
$this->assertTrue($output->isVerbose());
$this->assertFalse($output->isVeryVerbose());
$this->assertFalse($output->isDebug());

$output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE);
$this->assertFalse($output->isQuiet());
$this->assertTrue($output->isVerbose());
$this->assertTrue($output->isVeryVerbose());
$this->assertFalse($output->isDebug());

$output->setVerbosity(Output::VERBOSITY_DEBUG);
$this->assertFalse($output->isQuiet());
$this->assertTrue($output->isVerbose());
$this->assertTrue($output->isVeryVerbose());
$this->assertTrue($output->isDebug());
}

public function testWriteWithVerbosityQuiet()
{
$output = new TestOutput(Output::VERBOSITY_QUIET);
$output->writeln('foo');
$this->assertEquals('', $output->output, '->writeln() outputs nothing if verbosity is set to VERBOSITY_QUIET');
}

public function testWriteAnArrayOfMessages()
{
$output = new TestOutput();
$output->writeln(array('foo', 'bar'));
$this->assertEquals("foo\nbar\n", $output->output, '->writeln() can take an array of messages to output');
}




public function testWriteRawMessage($message, $type, $expectedOutput)
{
$output = new TestOutput();
$output->writeln($message, $type);
$this->assertEquals($expectedOutput, $output->output);
}

public function provideWriteArguments()
{
return array(
array('<info>foo</info>', Output::OUTPUT_RAW, "<info>foo</info>\n"),
array('<info>foo</info>', Output::OUTPUT_PLAIN, "foo\n"),
);
}

public function testWriteWithDecorationTurnedOff()
{
$output = new TestOutput();
$output->setDecorated(false);
$output->writeln('<info>foo</info>');
$this->assertEquals("foo\n", $output->output, '->writeln() strips decoration tags if decoration is set to false');
}

public function testWriteDecoratedMessage()
{
$fooStyle = new OutputFormatterStyle('yellow', 'red', array('blink'));
$output = new TestOutput();
$output->getFormatter()->setStyle('FOO', $fooStyle);
$output->setDecorated(true);
$output->writeln('<foo>foo</foo>');
$this->assertEquals("\033[33;41;5mfoo\033[39;49;25m\n", $output->output, '->writeln() decorates the output');
}

public function testWriteWithInvalidStyle()
{
$output = new TestOutput();

$output->clear();
$output->write('<bar>foo</bar>');
$this->assertEquals('<bar>foo</bar>', $output->output, '->write() do nothing when a style does not exist');

$output->clear();
$output->writeln('<bar>foo</bar>');
$this->assertEquals("<bar>foo</bar>\n", $output->output, '->writeln() do nothing when a style does not exist');
}




public function testWriteWithVerbosityOption($verbosity, $expected, $msg)
{
$output = new TestOutput();

$output->setVerbosity($verbosity);
$output->clear();
$output->write('1', false);
$output->write('2', false, Output::VERBOSITY_QUIET);
$output->write('3', false, Output::VERBOSITY_NORMAL);
$output->write('4', false, Output::VERBOSITY_VERBOSE);
$output->write('5', false, Output::VERBOSITY_VERY_VERBOSE);
$output->write('6', false, Output::VERBOSITY_DEBUG);
$this->assertEquals($expected, $output->output, $msg);
}

public function verbosityProvider()
{
return array(
array(Output::VERBOSITY_QUIET, '2', '->write() in QUIET mode only outputs when an explicit QUIET verbosity is passed'),
array(Output::VERBOSITY_NORMAL, '123', '->write() in NORMAL mode outputs anything below an explicit VERBOSE verbosity'),
array(Output::VERBOSITY_VERBOSE, '1234', '->write() in VERBOSE mode outputs anything below an explicit VERY_VERBOSE verbosity'),
array(Output::VERBOSITY_VERY_VERBOSE, '12345', '->write() in VERY_VERBOSE mode outputs anything below an explicit DEBUG verbosity'),
array(Output::VERBOSITY_DEBUG, '123456', '->write() in DEBUG mode outputs everything'),
);
}
}

class TestOutput extends Output
{
public $output = '';

public function clear()
{
$this->output = '';
}

protected function doWrite($message, $newline)
{
$this->output .= $message.($newline ? "\n" : '');
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class DescriptorCommand2 extends Command
{
protected function configure()
{
$this
->setName('descriptor:command2')
->setDescription('command 2 description')
->setHelp('command 2 help')
->addUsage('-o|--option_name <argument_name>')
->addUsage('<argument_name>')
->addArgument('argument_name', InputArgument::REQUIRED)
->addOption('option_name', 'o', InputOption::VALUE_NONE)
;
}
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooSubnamespaced1Command extends Command
{
public $input;
public $output;

protected function configure()
{
$this
->setName('foo:bar:baz')
->setDescription('The foo:bar:baz command')
->setAliases(array('foobarbaz'))
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
}
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooSubnamespaced2Command extends Command
{
public $input;
public $output;

protected function configure()
{
$this
->setName('foo:go:bret')
->setDescription('The foo:bar:go command')
->setAliases(array('foobargo'))
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
}
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FoobarCommand extends Command
{
public $input;
public $output;

protected function configure()
{
$this
->setName('foobar:foo')
->setDescription('The foobar:foo command')
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
}
}
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->comment(
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->block(
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
'TEST'
);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
use Symfony\Component\Console\Style\SymfonyStyle;


return function (InputInterface $input, OutputInterface $output) {
$output->setDecorated(true);
$output = new SymfonyStyle($input, $output);
$output->comment(
'Lorem ipsum dolor sit <comment>amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</comment> Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);

$output->writeln('Lorem ipsum dolor sit amet');
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));


 $output->write('Lorem ipsum dolor sit amet');
$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));

$output->write('Lorem ipsum dolor sit amet');
$output->text(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));

$output->newLine();

$output->write('Lorem ipsum dolor sit amet');
$output->comment(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);

$output->title('Title ending with \\');
$output->section('Section ending with \\');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output->setDecorated(true);
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->success(
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
'TEST'
);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->warning('Warning');
$output->caution('Caution');
$output->error('Error');
$output->success('Success');
$output->note('Note');
$output->block('Custom block', 'CUSTOM', 'fg=white;bg=green', 'X ', true);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->title('Title');
$output->warning('Lorem ipsum dolor sit amet');
$output->title('Title');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->block(array('Custom block', 'Second custom block line'), 'CUSTOM', 'fg=white;bg=green', 'X ', true);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->block(
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
'CUSTOM',
'fg=white;bg=green',
'X ',
true
);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);

$output->listing(array(
'Lorem ipsum dolor sit amet',
'consectetur adipiscing elit',
));
$output->success('Lorem ipsum dolor sit amet');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->title('First title');
$output->title('Second title');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->block(
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
null,
null,
'$ ',
true
);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->caution('Lorem ipsum dolor sit amet');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);

$output->write('Lorem ipsum dolor sit amet');
$output->title('First title');

$output->writeln('Lorem ipsum dolor sit amet');
$output->title('Second title');

$output->write('Lorem ipsum dolor sit amet');
$output->write('');
$output->title('Third title');


 $output->write('Lorem ipsum dolor sit amet');
$output->write(array('', '', ''));
$output->title('Fourth title');


 $output->writeln('Lorem ipsum dolor sit amet');
$output->writeln(array('', '')); 
 $output->title('Fifth title');

$output->writeln('Lorem ipsum dolor sit amet');
$output->newLine(2); 
 $output->title('Fifth title');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;
use Symfony\Component\Console\Helper\TableCell;


return function (InputInterface $input, OutputInterface $output) {
$headers = array(
array(new TableCell('Main table title', array('colspan' => 3))),
array('ISBN', 'Title', 'Author'),
);

$rows = array(
array(
'978-0521567817',
'De Monarchia',
new TableCell("Dante Alighieri\nspans multiple rows", array('rowspan' => 2)),
),
array('978-0804169127', 'Divine Comedy'),
);

$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->table($headers, $rows);
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyleWithForcedLineLength($input, $output);
$output->title('Title');
$output->askHidden('Hidden question');
$output->choice('Choice question with default', array('choice1', 'choice2'), 'choice1');
$output->confirm('Confirmation with yes default', true);
$output->text('Duis aute irure dolor in reprehenderit in voluptate velit esse');
};
<?php

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tests\Style\SymfonyStyleWithForcedLineLength;


return function (InputInterface $input, OutputInterface $output) {
$word = 'Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon';
$sfStyle = new SymfonyStyleWithForcedLineLength($input, $output);
$sfStyle->block($word, 'CUSTOM', 'fg=white;bg=blue', ' § ', false);
};
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Foo3Command extends Command
{
protected function configure()
{
$this
->setName('foo3:bar')
->setDescription('The foo3:bar command')
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
try {
try {
throw new \Exception('First exception <p>this is html</p>');
} catch (\Exception $e) {
throw new \Exception('Second exception <comment>comment</comment>', 0, $e);
}
} catch (\Exception $e) {
throw new \Exception('Third exception <fg=blue;bg=red>comment</>', 0, $e);
}
}
}
<?php

use Symfony\Component\Console\Command\Command;

class Foo4Command extends Command
{
protected function configure()
{
$this->setName('foo3:bar:toh');
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Command\Command;

class DescriptorCommand1 extends Command
{
protected function configure()
{
$this
->setName('descriptor:command1')
->setAliases(array('alias1', 'alias2'))
->setDescription('command 1 description')
->setHelp('command 1 help')
;
}
}
<?php


use Symfony\Component\Console\Command\Command;

class Foo6Command extends Command
{
protected function configure()
{
$this->setName('0foo:bar')->setDescription('0foo:bar command');
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Application;

class DescriptorApplication2 extends Application
{
public function __construct()
{
parent::__construct('My Symfony application', 'v1.0');
$this->add(new DescriptorCommand1());
$this->add(new DescriptorCommand2());
}
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooCommand extends Command
{
public $input;
public $output;

protected function configure()
{
$this
->setName('foo:bar')
->setDescription('The foo:bar command')
->setAliases(array('afoobar'))
;
}

protected function interact(InputInterface $input, OutputInterface $output)
{
$output->writeln('interact called');
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;

$output->writeln('called');
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Output\BufferedOutput;






class DummyOutput extends BufferedOutput
{



public function getLogs()
{
$logs = array();
foreach (explode("\n", trim($this->fetch())) as $message) {
preg_match('/^\[(.*)\] (.*)/', $message, $matches);
$logs[] = sprintf('%s %s', $matches[1], $matches[2]);
}

return $logs;
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Application;

class DescriptorApplication1 extends Application
{
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class TestCommand extends Command
{
protected function configure()
{
$this
->setName('namespace:name')
->setAliases(array('name'))
->setDescription('description')
->setHelp('help')
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('execute called');
}

protected function interact(InputInterface $input, OutputInterface $output)
{
$output->writeln('interact called');
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Application;

class DescriptorApplicationMbString extends Application
{
public function __construct()
{
parent::__construct('MbString åpplicätion');

$this->add(new DescriptorCommandMbString());
}
}
<?php

use Symfony\Component\Console\Command\Command;

class BarBucCommand extends Command
{
protected function configure()
{
$this->setName('bar:buc');
}
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Foo1Command extends Command
{
public $input;
public $output;

protected function configure()
{
$this
->setName('foo:bar1')
->setDescription('The foo:bar1 command')
->setAliases(array('afoobar1'))
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
}
}
<?php










namespace Symfony\Component\Console\Tests\Fixtures;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class DescriptorCommandMbString extends Command
{
protected function configure()
{
$this
->setName('descriptor:åèä')
->setDescription('command åèä description')
->setHelp('command åèä help')
->addUsage('-o|--option_name <argument_name>')
->addUsage('<argument_name>')
->addArgument('argument_åèä', InputArgument::REQUIRED)
->addOption('option_åèä', 'o', InputOption::VALUE_NONE)
;
}
}
<?php

use Symfony\Component\Console\Command\Command;

class Foo5Command extends Command
{
public function __construct()
{
}
}
<?php

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Foo2Command extends Command
{
protected function configure()
{
$this
->setName('foo1:bar')
->setDescription('The foo1:bar command')
->setAliases(array('afoobar2'))
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class ArgvInputTest extends TestCase
{
public function testConstructor()
{
$_SERVER['argv'] = array('cli.php', 'foo');
$input = new ArgvInput();
$r = new \ReflectionObject($input);
$p = $r->getProperty('tokens');
$p->setAccessible(true);

$this->assertEquals(array('foo'), $p->getValue($input), '__construct() automatically get its input from the argv server variable');
}

public function testParseArguments()
{
$input = new ArgvInput(array('cli.php', 'foo'));
$input->bind(new InputDefinition(array(new InputArgument('name'))));
$this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');

$input->bind(new InputDefinition(array(new InputArgument('name'))));
$this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() is stateless');
}




public function testParseOptions($input, $options, $expectedOptions, $message)
{
$input = new ArgvInput($input);
$input->bind(new InputDefinition($options));

$this->assertEquals($expectedOptions, $input->getOptions(), $message);
}

public function provideOptions()
{
return array(
array(
array('cli.php', '--foo'),
array(new InputOption('foo')),
array('foo' => true),
'->parse() parses long options without a value',
),
array(
array('cli.php', '--foo=bar'),
array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
array('foo' => 'bar'),
'->parse() parses long options with a required value (with a = separator)',
),
array(
array('cli.php', '--foo', 'bar'),
array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
array('foo' => 'bar'),
'->parse() parses long options with a required value (with a space separator)',
),
array(
array('cli.php', '--foo='),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
array('foo' => null),
'->parse() parses long options with optional value which is empty (with a = separator) as null',
),
array(
array('cli.php', '--foo=', 'bar'),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)),
array('foo' => null),
'->parse() parses long options with optional value which is empty (with a = separator) followed by an argument',
),
array(
array('cli.php', '-f'),
array(new InputOption('foo', 'f')),
array('foo' => true),
'->parse() parses short options without a value',
),
array(
array('cli.php', '-fbar'),
array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
array('foo' => 'bar'),
'->parse() parses short options with a required value (with no separator)',
),
array(
array('cli.php', '-f', 'bar'),
array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)),
array('foo' => 'bar'),
'->parse() parses short options with a required value (with a space separator)',
),
array(
array('cli.php', '-f', ''),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
array('foo' => ''),
'->parse() parses short options with an optional empty value',
),
array(
array('cli.php', '-f', '', 'foo'),
array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
array('foo' => ''),
'->parse() parses short options with an optional empty value followed by an argument',
),
array(
array('cli.php', '-f', '', '-b'),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
array('foo' => '', 'bar' => true),
'->parse() parses short options with an optional empty value followed by an option',
),
array(
array('cli.php', '-f', '-b', 'foo'),
array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')),
array('foo' => null, 'bar' => true),
'->parse() parses short options with an optional value which is not present',
),
array(
array('cli.php', '-fb'),
array(new InputOption('foo', 'f'), new InputOption('bar', 'b')),
array('foo' => true, 'bar' => true),
'->parse() parses short options when they are aggregated as a single one',
),
array(
array('cli.php', '-fb', 'bar'),
array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)),
array('foo' => true, 'bar' => 'bar'),
'->parse() parses short options when they are aggregated as a single one and the last one has a required value',
),
array(
array('cli.php', '-fb', 'bar'),
array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
array('foo' => true, 'bar' => 'bar'),
'->parse() parses short options when they are aggregated as a single one and the last one has an optional value',
),
array(
array('cli.php', '-fbbar'),
array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
array('foo' => true, 'bar' => 'bar'),
'->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator',
),
array(
array('cli.php', '-fbbar'),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)),
array('foo' => 'bbar', 'bar' => null),
'->parse() parses short options when they are aggregated as a single one and one of them takes a value',
),
);
}




public function testInvalidInput($argv, $definition, $expectedExceptionMessage)
{
if (method_exists($this, 'expectException')) {
$this->expectException('RuntimeException');
$this->expectExceptionMessage($expectedExceptionMessage);
} else {
$this->setExpectedException('RuntimeException', $expectedExceptionMessage);
}

$input = new ArgvInput($argv);
$input->bind($definition);
}

public function provideInvalidInput()
{
return array(
array(
array('cli.php', '--foo'),
new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
'The "--foo" option requires a value.',
),
array(
array('cli.php', '-f'),
new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
'The "--foo" option requires a value.',
),
array(
array('cli.php', '-ffoo'),
new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
'The "-o" option does not exist.',
),
array(
array('cli.php', '--foo=bar'),
new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))),
'The "--foo" option does not accept a value.',
),
array(
array('cli.php', 'foo', 'bar'),
new InputDefinition(),
'No arguments expected, got "foo".',
),
array(
array('cli.php', 'foo', 'bar'),
new InputDefinition(array(new InputArgument('number'))),
'Too many arguments, expected arguments "number".',
),
array(
array('cli.php', 'foo', 'bar', 'zzz'),
new InputDefinition(array(new InputArgument('number'), new InputArgument('county'))),
'Too many arguments, expected arguments "number" "county".',
),
array(
array('cli.php', '--foo'),
new InputDefinition(),
'The "--foo" option does not exist.',
),
array(
array('cli.php', '-f'),
new InputDefinition(),
'The "-f" option does not exist.',
),
array(
array('cli.php', '-1'),
new InputDefinition(array(new InputArgument('number'))),
'The "-1" option does not exist.',
),
);
}

public function testParseArrayArgument()
{
$input = new ArgvInput(array('cli.php', 'foo', 'bar', 'baz', 'bat'));
$input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::IS_ARRAY))));

$this->assertEquals(array('name' => array('foo', 'bar', 'baz', 'bat')), $input->getArguments(), '->parse() parses array arguments');
}

public function testParseArrayOption()
{
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));

$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');

$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');

$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');

$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
$input->bind(new InputDefinition(array(
new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
new InputOption('anotherOption', null, InputOption::VALUE_NONE),
)));
$this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
}

public function testParseNegativeNumberAfterDoubleDash()
{
$input = new ArgvInput(array('cli.php', '--', '-1'));
$input->bind(new InputDefinition(array(new InputArgument('number'))));
$this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');

$input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1'));
$input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));
$this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence');
$this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence');
}

public function testParseEmptyStringArgument()
{
$input = new ArgvInput(array('cli.php', '-f', 'bar', ''));
$input->bind(new InputDefinition(array(new InputArgument('empty'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))));

$this->assertEquals(array('empty' => ''), $input->getArguments(), '->parse() parses empty string arguments');
}

public function testGetFirstArgument()
{
$input = new ArgvInput(array('cli.php', '-fbbar'));
$this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null when there is no arguments');

$input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
$this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
}

public function testHasParameterOption()
{
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
$this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input');

$input = new ArgvInput(array('cli.php', '--foo', 'foo'));
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input');

$input = new ArgvInput(array('cli.php', 'foo'));
$this->assertFalse($input->hasParameterOption('--foo'), '->hasParameterOption() returns false if the given short option is not in the raw input');

$input = new ArgvInput(array('cli.php', '--foo=bar'));
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input');
}

public function testToString()
{
$input = new ArgvInput(array('cli.php', '-f', 'foo'));
$this->assertEquals('-f foo', (string) $input);

$input = new ArgvInput(array('cli.php', '-f', '--bar=foo', 'a b c d', "A\nB'C"));
$this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
}




public function testGetParameterOptionEqualSign($argv, $key, $expected)
{
$input = new ArgvInput($argv);
$this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value');
}

public function provideGetParameterOptionValues()
{
return array(
array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'),
array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'),
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'),
);
}

public function testParseSingleDashAsArgument()
{
$input = new ArgvInput(array('cli.php', '-'));
$input->bind(new InputDefinition(array(new InputArgument('file'))));
$this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument');
}

public function testParseOptionWithValueOptionalGivenEmptyAndRequiredArgument()
{
$input = new ArgvInput(array('cli.php', '--foo=', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED))));
$this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments');

$input = new ArgvInput(array('cli.php', '--foo=0', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED))));
$this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments');
}

public function testParseOptionWithValueOptionalGivenEmptyAndOptionalArgument()
{
$input = new ArgvInput(array('cli.php', '--foo=', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL))));
$this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments');

$input = new ArgvInput(array('cli.php', '--foo=0', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL))));
$this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments');
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class InputDefinitionTest extends TestCase
{
protected static $fixtures;

protected $foo;
protected $bar;
protected $foo1;
protected $foo2;

public static function setUpBeforeClass()
{
self::$fixtures = __DIR__.'/../Fixtures/';
}

public function testConstructorArguments()
{
$this->initializeArguments();

$definition = new InputDefinition();
$this->assertEquals(array(), $definition->getArguments(), '__construct() creates a new InputDefinition object');

$definition = new InputDefinition(array($this->foo, $this->bar));
$this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '__construct() takes an array of InputArgument objects as its first argument');
}

public function testConstructorOptions()
{
$this->initializeOptions();

$definition = new InputDefinition();
$this->assertEquals(array(), $definition->getOptions(), '__construct() creates a new InputDefinition object');

$definition = new InputDefinition(array($this->foo, $this->bar));
$this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '__construct() takes an array of InputOption objects as its first argument');
}

public function testSetArguments()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->setArguments(array($this->foo));
$this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->setArguments() sets the array of InputArgument objects');
$definition->setArguments(array($this->bar));

$this->assertEquals(array('bar' => $this->bar), $definition->getArguments(), '->setArguments() clears all InputArgument objects');
}

public function testAddArguments()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArguments(array($this->foo));
$this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArguments() adds an array of InputArgument objects');
$definition->addArguments(array($this->bar));
$this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArguments() does not clear existing InputArgument objects');
}

public function testAddArgument()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArgument($this->foo);
$this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArgument() adds a InputArgument object');
$definition->addArgument($this->bar);
$this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArgument() adds a InputArgument object');
}





public function testArgumentsMustHaveDifferentNames()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArgument($this->foo);
$definition->addArgument($this->foo1);
}





public function testArrayArgumentHasToBeLast()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArgument(new InputArgument('fooarray', InputArgument::IS_ARRAY));
$definition->addArgument(new InputArgument('anotherbar'));
}





public function testRequiredArgumentCannotFollowAnOptionalOne()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArgument($this->foo);
$definition->addArgument($this->foo2);
}

public function testGetArgument()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArguments(array($this->foo));
$this->assertEquals($this->foo, $definition->getArgument('foo'), '->getArgument() returns a InputArgument by its name');
}





public function testGetInvalidArgument()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArguments(array($this->foo));
$definition->getArgument('bar');
}

public function testHasArgument()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArguments(array($this->foo));

$this->assertTrue($definition->hasArgument('foo'), '->hasArgument() returns true if a InputArgument exists for the given name');
$this->assertFalse($definition->hasArgument('bar'), '->hasArgument() returns false if a InputArgument exists for the given name');
}

public function testGetArgumentRequiredCount()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArgument($this->foo2);
$this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
$definition->addArgument($this->foo);
$this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments');
}

public function testGetArgumentCount()
{
$this->initializeArguments();

$definition = new InputDefinition();
$definition->addArgument($this->foo2);
$this->assertEquals(1, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
$definition->addArgument($this->foo);
$this->assertEquals(2, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments');
}

public function testGetArgumentDefaults()
{
$definition = new InputDefinition(array(
new InputArgument('foo1', InputArgument::OPTIONAL),
new InputArgument('foo2', InputArgument::OPTIONAL, '', 'default'),
new InputArgument('foo3', InputArgument::OPTIONAL | InputArgument::IS_ARRAY),

 ));
$this->assertEquals(array('foo1' => null, 'foo2' => 'default', 'foo3' => array()), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');

$definition = new InputDefinition(array(
new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)),
));
$this->assertEquals(array('foo4' => array(1, 2)), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument');
}

public function testSetOptions()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->setOptions() sets the array of InputOption objects');
$definition->setOptions(array($this->bar));
$this->assertEquals(array('bar' => $this->bar), $definition->getOptions(), '->setOptions() clears all InputOption objects');
}





public function testSetOptionsClearsOptions()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$definition->setOptions(array($this->bar));
$definition->getOptionForShortcut('f');
}

public function testAddOptions()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOptions() adds an array of InputOption objects');
$definition->addOptions(array($this->bar));
$this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOptions() does not clear existing InputOption objects');
}

public function testAddOption()
{
$this->initializeOptions();

$definition = new InputDefinition();
$definition->addOption($this->foo);
$this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOption() adds a InputOption object');
$definition->addOption($this->bar);
$this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOption() adds a InputOption object');
}





public function testAddDuplicateOption()
{
$this->initializeOptions();

$definition = new InputDefinition();
$definition->addOption($this->foo);
$definition->addOption($this->foo2);
}





public function testAddDuplicateShortcutOption()
{
$this->initializeOptions();

$definition = new InputDefinition();
$definition->addOption($this->foo);
$definition->addOption($this->foo1);
}

public function testGetOption()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$this->assertEquals($this->foo, $definition->getOption('foo'), '->getOption() returns a InputOption by its name');
}





public function testGetInvalidOption()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$definition->getOption('bar');
}

public function testHasOption()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$this->assertTrue($definition->hasOption('foo'), '->hasOption() returns true if a InputOption exists for the given name');
$this->assertFalse($definition->hasOption('bar'), '->hasOption() returns false if a InputOption exists for the given name');
}

public function testHasShortcut()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$this->assertTrue($definition->hasShortcut('f'), '->hasShortcut() returns true if a InputOption exists for the given shortcut');
$this->assertFalse($definition->hasShortcut('b'), '->hasShortcut() returns false if a InputOption exists for the given shortcut');
}

public function testGetOptionForShortcut()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$this->assertEquals($this->foo, $definition->getOptionForShortcut('f'), '->getOptionForShortcut() returns a InputOption by its shortcut');
}

public function testGetOptionForMultiShortcut()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->multi));
$this->assertEquals($this->multi, $definition->getOptionForShortcut('m'), '->getOptionForShortcut() returns a InputOption by its shortcut');
$this->assertEquals($this->multi, $definition->getOptionForShortcut('mmm'), '->getOptionForShortcut() returns a InputOption by its shortcut');
}





public function testGetOptionForInvalidShortcut()
{
$this->initializeOptions();

$definition = new InputDefinition(array($this->foo));
$definition->getOptionForShortcut('l');
}

public function testGetOptionDefaults()
{
$definition = new InputDefinition(array(
new InputOption('foo1', null, InputOption::VALUE_NONE),
new InputOption('foo2', null, InputOption::VALUE_REQUIRED),
new InputOption('foo3', null, InputOption::VALUE_REQUIRED, '', 'default'),
new InputOption('foo4', null, InputOption::VALUE_OPTIONAL),
new InputOption('foo5', null, InputOption::VALUE_OPTIONAL, '', 'default'),
new InputOption('foo6', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
new InputOption('foo7', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', array(1, 2)),
));
$defaults = array(
'foo1' => false,
'foo2' => null,
'foo3' => 'default',
'foo4' => null,
'foo5' => 'default',
'foo6' => array(),
'foo7' => array(1, 2),
);
$this->assertSame($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options');
}




public function testGetSynopsis(InputDefinition $definition, $expectedSynopsis, $message = null)
{
$this->assertEquals($expectedSynopsis, $definition->getSynopsis(), $message ? '->getSynopsis() '.$message : '');
}

public function getGetSynopsisData()
{
return array(
array(new InputDefinition(array(new InputOption('foo'))), '[--foo]', 'puts optional options in square brackets'),
array(new InputDefinition(array(new InputOption('foo', 'f'))), '[-f|--foo]', 'separates shortcut with a pipe'),
array(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))), '[-f|--foo FOO]', 'uses shortcut as value placeholder'),
array(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))), '[-f|--foo [FOO]]', 'puts optional values in square brackets'),

array(new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED))), '<foo>', 'puts arguments in angle brackets'),
array(new InputDefinition(array(new InputArgument('foo'))), '[<foo>]', 'puts optional arguments in square brackets'),
array(new InputDefinition(array(new InputArgument('foo', InputArgument::IS_ARRAY))), '[<foo>]...', 'uses an ellipsis for array arguments'),
array(new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED | InputArgument::IS_ARRAY))), '<foo> (<foo>)...', 'uses parenthesis and ellipsis for required array arguments'),

array(new InputDefinition(array(new InputOption('foo'), new InputArgument('foo', InputArgument::REQUIRED))), '[--foo] [--] <foo>', 'puts [--] between options and arguments'),
);
}

public function testGetShortSynopsis()
{
$definition = new InputDefinition(array(new InputOption('foo'), new InputOption('bar'), new InputArgument('cat')));
$this->assertEquals('[options] [--] [<cat>]', $definition->getSynopsis(true), '->getSynopsis(true) groups options in [options]');
}




public function testLegacyAsText()
{
$definition = new InputDefinition(array(
new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('http://foo.com/')),
new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
new InputOption('qux', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux option', array('http://foo.com/', 'bar')),
new InputOption('qux2', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux2 option', array('foo' => 'bar')),
));

$this->assertStringEqualsFile(self::$fixtures.'/definition_astext.txt', $definition->asText(), '->asText() returns a textual representation of the InputDefinition');
}




public function testLegacyAsXml()
{
$definition = new InputDefinition(array(
new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'),
new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true),
new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('bar')),
new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'),
new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false),
new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'),
));
$this->assertXmlStringEqualsXmlFile(self::$fixtures.'/definition_asxml.txt', $definition->asXml(), '->asXml() returns an XML representation of the InputDefinition');
}

protected function initializeArguments()
{
$this->foo = new InputArgument('foo');
$this->bar = new InputArgument('bar');
$this->foo1 = new InputArgument('foo');
$this->foo2 = new InputArgument('foo2', InputArgument::REQUIRED);
}

protected function initializeOptions()
{
$this->foo = new InputOption('foo', 'f');
$this->bar = new InputOption('bar', 'b');
$this->foo1 = new InputOption('fooBis', 'f');
$this->foo2 = new InputOption('foo', 'p');
$this->multi = new InputOption('multi', 'm|mm|mmm');
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StringInput;

class StringInputTest extends TestCase
{



public function testTokenize($input, $tokens, $message)
{
$input = new StringInput($input);
$r = new \ReflectionClass('Symfony\Component\Console\Input\ArgvInput');
$p = $r->getProperty('tokens');
$p->setAccessible(true);
$this->assertEquals($tokens, $p->getValue($input), $message);
}

public function testInputOptionWithGivenString()
{
$definition = new InputDefinition(
array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
);


 $input = new StringInput('--foo=bar');
$input->bind($definition);
$this->assertEquals('bar', $input->getOption('foo'));
}




public function testLegacyInputOptionDefinitionInConstructor()
{
$definition = new InputDefinition(
array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
);

$input = new StringInput('--foo=bar', $definition);
$this->assertEquals('bar', $input->getOption('foo'));
}

public function getTokenizeData()
{
return array(
array('', array(), '->tokenize() parses an empty string'),
array('foo', array('foo'), '->tokenize() parses arguments'),
array('  foo  bar  ', array('foo', 'bar'), '->tokenize() ignores whitespaces between arguments'),
array('"quoted"', array('quoted'), '->tokenize() parses quoted arguments'),
array("'quoted'", array('quoted'), '->tokenize() parses quoted arguments'),
array("'a\rb\nc\td'", array("a\rb\nc\td"), '->tokenize() parses whitespace chars in strings'),
array("'a'\r'b'\n'c'\t'd'", array('a', 'b', 'c', 'd'), '->tokenize() parses whitespace chars between args as spaces'),
array('\"quoted\"', array('"quoted"'), '->tokenize() parses escaped-quoted arguments'),
array("\'quoted\'", array('\'quoted\''), '->tokenize() parses escaped-quoted arguments'),
array('-a', array('-a'), '->tokenize() parses short options'),
array('-azc', array('-azc'), '->tokenize() parses aggregated short options'),
array('-awithavalue', array('-awithavalue'), '->tokenize() parses short options with a value'),
array('-a"foo bar"', array('-afoo bar'), '->tokenize() parses short options with a value'),
array('-a"foo bar""foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
array('-a\'foo bar\'', array('-afoo bar'), '->tokenize() parses short options with a value'),
array('-a\'foo bar\'\'foo bar\'', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
array('-a\'foo bar\'"foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'),
array('--long-option', array('--long-option'), '->tokenize() parses long options'),
array('--long-option=foo', array('--long-option=foo'), '->tokenize() parses long options with a value'),
array('--long-option="foo bar"', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
array('--long-option="foo bar""another"', array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
array('--long-option=\'foo bar\'', array('--long-option=foo bar'), '->tokenize() parses long options with a value'),
array("--long-option='foo bar''another'", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
array("--long-option='foo bar'\"another\"", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'),
array('foo -a -ffoo --long bar', array('foo', '-a', '-ffoo', '--long', 'bar'), '->tokenize() parses when several arguments and options'),
);
}

public function testToString()
{
$input = new StringInput('-f foo');
$this->assertEquals('-f foo', (string) $input);

$input = new StringInput('-f --bar=foo "a b c d"');
$this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d'), (string) $input);

$input = new StringInput('-f --bar=foo \'a b c d\' '."'A\nB\\'C'");
$this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input);
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class ArrayInputTest extends TestCase
{
public function testGetFirstArgument()
{
$input = new ArrayInput(array());
$this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null if no argument were passed');
$input = new ArrayInput(array('name' => 'Fabien'));
$this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
$input = new ArrayInput(array('--foo' => 'bar', 'name' => 'Fabien'));
$this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument');
}

public function testHasParameterOption()
{
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
$this->assertFalse($input->hasParameterOption('--bar'), '->hasParameterOption() returns false if an option is not present in the passed parameters');

$input = new ArrayInput(array('--foo'));
$this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters');
}

public function testGetParameterOption()
{
$input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar'));
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');

$input = new ArrayInput(array('Fabien', '--foo' => 'bar'));
$this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name');
}

public function testParseArguments()
{
$input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));

$this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments');
}




public function testParseOptions($input, $options, $expectedOptions, $message)
{
$input = new ArrayInput($input, new InputDefinition($options));

$this->assertEquals($expectedOptions, $input->getOptions(), $message);
}

public function provideOptions()
{
return array(
array(
array('--foo' => 'bar'),
array(new InputOption('foo')),
array('foo' => 'bar'),
'->parse() parses long options',
),
array(
array('--foo' => 'bar'),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
array('foo' => 'bar'),
'->parse() parses long options with a default value',
),
array(
array('--foo' => null),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
array('foo' => 'default'),
'->parse() parses long options with a default value',
),
array(
array('-f' => 'bar'),
array(new InputOption('foo', 'f')),
array('foo' => 'bar'),
'->parse() parses short options',
),
);
}




public function testParseInvalidInput($parameters, $definition, $expectedExceptionMessage)
{
if (method_exists($this, 'expectException')) {
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage($expectedExceptionMessage);
} else {
$this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage);
}

new ArrayInput($parameters, $definition);
}

public function provideInvalidInput()
{
return array(
array(
array('foo' => 'foo'),
new InputDefinition(array(new InputArgument('name'))),
'The "foo" argument does not exist.',
),
array(
array('--foo' => null),
new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))),
'The "--foo" option requires a value.',
),
array(
array('--foo' => 'foo'),
new InputDefinition(),
'The "--foo" option does not exist.',
),
array(
array('-o' => 'foo'),
new InputDefinition(),
'The "-o" option does not exist.',
),
);
}

public function testToString()
{
$input = new ArrayInput(array('-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C"));
$this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input);
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputOption;

class InputOptionTest extends TestCase
{
public function testConstructor()
{
$option = new InputOption('foo');
$this->assertEquals('foo', $option->getName(), '__construct() takes a name as its first argument');
$option = new InputOption('--foo');
$this->assertEquals('foo', $option->getName(), '__construct() removes the leading -- of the option name');
}





public function testArrayModeWithoutValue()
{
new InputOption('foo', 'f', InputOption::VALUE_IS_ARRAY);
}

public function testShortcut()
{
$option = new InputOption('foo', 'f');
$this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument');
$option = new InputOption('foo', '-f|-ff|fff');
$this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
$option = new InputOption('foo', array('f', 'ff', '-fff'));
$this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts');
$option = new InputOption('foo');
$this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default');
}

public function testModes()
{
$option = new InputOption('foo', 'f');
$this->assertFalse($option->acceptValue(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
$this->assertFalse($option->isValueRequired(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');
$this->assertFalse($option->isValueOptional(), '__construct() gives a "InputOption::VALUE_NONE" mode by default');

$option = new InputOption('foo', 'f', null);
$this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
$this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
$this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');

$option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
$this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
$this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode');
$this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode');

$option = new InputOption('foo', 'f', InputOption::VALUE_REQUIRED);
$this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
$this->assertTrue($option->isValueRequired(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');
$this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode');

$option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL);
$this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
$this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
$this->assertTrue($option->isValueOptional(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode');
}




public function testInvalidModes($mode)
{
if (method_exists($this, 'expectException')) {
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage(sprintf('Option mode "%s" is not valid.', $mode));
} else {
$this->setExpectedException('InvalidArgumentException', sprintf('Option mode "%s" is not valid.', $mode));
}

new InputOption('foo', 'f', $mode);
}

public function provideInvalidModes()
{
return array(
array('ANOTHER_ONE'),
array(-1),
);
}




public function testEmptyNameIsInvalid()
{
new InputOption('');
}




public function testDoubleDashNameIsInvalid()
{
new InputOption('--');
}




public function testSingleDashOptionIsInvalid()
{
new InputOption('foo', '-');
}

public function testIsArray()
{
$option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
$this->assertTrue($option->isArray(), '->isArray() returns true if the option can be an array');
$option = new InputOption('foo', null, InputOption::VALUE_NONE);
$this->assertFalse($option->isArray(), '->isArray() returns false if the option can not be an array');
}

public function testGetDescription()
{
$option = new InputOption('foo', 'f', null, 'Some description');
$this->assertEquals('Some description', $option->getDescription(), '->getDescription() returns the description message');
}

public function testGetDefault()
{
$option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL, '', 'default');
$this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');

$option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
$this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value');

$option = new InputOption('foo', null, InputOption::VALUE_REQUIRED);
$this->assertNull($option->getDefault(), '->getDefault() returns null if no default value is configured');

$option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
$this->assertEquals(array(), $option->getDefault(), '->getDefault() returns an empty array if option is an array');

$option = new InputOption('foo', null, InputOption::VALUE_NONE);
$this->assertFalse($option->getDefault(), '->getDefault() returns false if the option does not take a value');
}

public function testSetDefault()
{
$option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default');
$option->setDefault(null);
$this->assertNull($option->getDefault(), '->setDefault() can reset the default value by passing null');
$option->setDefault('another');
$this->assertEquals('another', $option->getDefault(), '->setDefault() changes the default value');

$option = new InputOption('foo', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY);
$option->setDefault(array(1, 2));
$this->assertEquals(array(1, 2), $option->getDefault(), '->setDefault() changes the default value');
}





public function testDefaultValueWithValueNoneMode()
{
$option = new InputOption('foo', 'f', InputOption::VALUE_NONE);
$option->setDefault('default');
}





public function testDefaultValueWithIsArrayMode()
{
$option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY);
$option->setDefault('default');
}

public function testEquals()
{
$option = new InputOption('foo', 'f', null, 'Some description');
$option2 = new InputOption('foo', 'f', null, 'Alternative description');
$this->assertTrue($option->equals($option2));

$option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
$option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description', true);
$this->assertFalse($option->equals($option2));

$option = new InputOption('foo', 'f', null, 'Some description');
$option2 = new InputOption('bar', 'f', null, 'Some description');
$this->assertFalse($option->equals($option2));

$option = new InputOption('foo', 'f', null, 'Some description');
$option2 = new InputOption('foo', '', null, 'Some description');
$this->assertFalse($option->equals($option2));

$option = new InputOption('foo', 'f', null, 'Some description');
$option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description');
$this->assertFalse($option->equals($option2));
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class InputTest extends TestCase
{
public function testConstructor()
{
$input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
$this->assertEquals('foo', $input->getArgument('name'), '->__construct() takes a InputDefinition as an argument');
}

public function testOptions()
{
$input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'))));
$this->assertEquals('foo', $input->getOption('name'), '->getOption() returns the value for the given option');

$input->setOption('name', 'bar');
$this->assertEquals('bar', $input->getOption('name'), '->setOption() sets the value for a given option');
$this->assertEquals(array('name' => 'bar'), $input->getOptions(), '->getOptions() returns all option values');

$input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
$this->assertEquals('default', $input->getOption('bar'), '->getOption() returns the default value for optional options');
$this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getOptions(), '->getOptions() returns all option values, even optional ones');
}





public function testSetInvalidOption()
{
$input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
$input->setOption('foo', 'bar');
}





public function testGetInvalidOption()
{
$input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
$input->getOption('foo');
}

public function testArguments()
{
$input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'))));
$this->assertEquals('foo', $input->getArgument('name'), '->getArgument() returns the value for the given argument');

$input->setArgument('name', 'bar');
$this->assertEquals('bar', $input->getArgument('name'), '->setArgument() sets the value for a given argument');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->getArguments() returns all argument values');

$input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
$this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments');
$this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getArguments(), '->getArguments() returns all argument values, even optional ones');
}





public function testSetInvalidArgument()
{
$input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
$input->setArgument('foo', 'bar');
}





public function testGetInvalidArgument()
{
$input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default'))));
$input->getArgument('foo');
}





public function testValidateWithMissingArguments()
{
$input = new ArrayInput(array());
$input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));
$input->validate();
}





public function testValidateWithMissingRequiredArguments()
{
$input = new ArrayInput(array('bar' => 'baz'));
$input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED), new InputArgument('bar', InputArgument::OPTIONAL))));
$input->validate();
}

public function testValidate()
{
$input = new ArrayInput(array('name' => 'foo'));
$input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED))));

$this->assertNull($input->validate());
}

public function testSetGetInteractive()
{
$input = new ArrayInput(array());
$this->assertTrue($input->isInteractive(), '->isInteractive() returns whether the input should be interactive or not');
$input->setInteractive(false);
$this->assertFalse($input->isInteractive(), '->setInteractive() changes the interactive flag');
}
}
<?php










namespace Symfony\Component\Console\Tests\Input;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputArgument;

class InputArgumentTest extends TestCase
{
public function testConstructor()
{
$argument = new InputArgument('foo');
$this->assertEquals('foo', $argument->getName(), '__construct() takes a name as its first argument');
}

public function testModes()
{
$argument = new InputArgument('foo');
$this->assertFalse($argument->isRequired(), '__construct() gives a "InputArgument::OPTIONAL" mode by default');

$argument = new InputArgument('foo', null);
$this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');

$argument = new InputArgument('foo', InputArgument::OPTIONAL);
$this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode');

$argument = new InputArgument('foo', InputArgument::REQUIRED);
$this->assertTrue($argument->isRequired(), '__construct() can take "InputArgument::REQUIRED" as its mode');
}




public function testInvalidModes($mode)
{
if (method_exists($this, 'expectException')) {
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage(sprintf('Argument mode "%s" is not valid.', $mode));
} else {
$this->setExpectedException('InvalidArgumentException', sprintf('Argument mode "%s" is not valid.', $mode));
}

new InputArgument('foo', $mode);
}

public function provideInvalidModes()
{
return array(
array('ANOTHER_ONE'),
array(-1),
);
}

public function testIsArray()
{
$argument = new InputArgument('foo', InputArgument::IS_ARRAY);
$this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
$argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
$this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array');
$argument = new InputArgument('foo', InputArgument::OPTIONAL);
$this->assertFalse($argument->isArray(), '->isArray() returns false if the argument can not be an array');
}

public function testGetDescription()
{
$argument = new InputArgument('foo', null, 'Some description');
$this->assertEquals('Some description', $argument->getDescription(), '->getDescription() return the message description');
}

public function testGetDefault()
{
$argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
$this->assertEquals('default', $argument->getDefault(), '->getDefault() return the default value');
}

public function testSetDefault()
{
$argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default');
$argument->setDefault(null);
$this->assertNull($argument->getDefault(), '->setDefault() can reset the default value by passing null');
$argument->setDefault('another');
$this->assertEquals('another', $argument->getDefault(), '->setDefault() changes the default value');

$argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY);
$argument->setDefault(array(1, 2));
$this->assertEquals(array(1, 2), $argument->getDefault(), '->setDefault() changes the default value');
}





public function testSetDefaultWithRequiredArgument()
{
$argument = new InputArgument('foo', InputArgument::REQUIRED);
$argument->setDefault('default');
}





public function testSetDefaultWithArrayArgument()
{
$argument = new InputArgument('foo', InputArgument::IS_ARRAY);
$argument->setDefault('default');
}
}
<?php










namespace Symfony\Component\Console\Tests\Command;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Application;

class ListCommandTest extends TestCase
{
public function testExecuteListsCommands()
{
$application = new Application();
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(array('command' => $command->getName()), array('decorated' => false));

$this->assertRegExp('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
}

public function testExecuteListsCommandsWithXmlOption()
{
$application = new Application();
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(array('command' => $command->getName(), '--format' => 'xml'));
$this->assertRegExp('/<command id="list" name="list">/', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
}

public function testExecuteListsCommandsWithRawOption()
{
$application = new Application();
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(array('command' => $command->getName(), '--raw' => true));
$output = <<<'EOF'
help   Displays help for a command
list   Lists commands

EOF;

$this->assertEquals($output, $commandTester->getDisplay(true));
}

public function testExecuteListsCommandsWithNamespaceArgument()
{
require_once realpath(__DIR__.'/../Fixtures/FooCommand.php');
$application = new Application();
$application->add(new \FooCommand());
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(array('command' => $command->getName(), 'namespace' => 'foo', '--raw' => true));
$output = <<<'EOF'
foo:bar   The foo:bar command

EOF;

$this->assertEquals($output, $commandTester->getDisplay(true));
}

public function testExecuteListsCommandsOrder()
{
require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php');
$application = new Application();
$application->add(new \Foo6Command());
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(array('command' => $command->getName()), array('decorated' => false));
$output = <<<'EOF'
Console Tool

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help      Displays help for a command
  list      Lists commands
 0foo
  0foo:bar  0foo:bar command
EOF;

$this->assertEquals($output, trim($commandTester->getDisplay(true)));
}

public function testExecuteListsCommandsOrderRaw()
{
require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php');
$application = new Application();
$application->add(new \Foo6Command());
$commandTester = new CommandTester($command = $application->get('list'));
$commandTester->execute(array('command' => $command->getName(), '--raw' => true));
$output = <<<'EOF'
help       Displays help for a command
list       Lists commands
0foo:bar   0foo:bar command
EOF;

$this->assertEquals($output, trim($commandTester->getDisplay(true)));
}
}
<?php










namespace Symfony\Component\Console\Tests\Command;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Tester\CommandTester;

class CommandTest extends TestCase
{
protected static $fixturesPath;

public static function setUpBeforeClass()
{
self::$fixturesPath = __DIR__.'/../Fixtures/';
require_once self::$fixturesPath.'/TestCommand.php';
}

public function testConstructor()
{
$command = new Command('foo:bar');
$this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument');
}





public function testCommandNameCannotBeEmpty()
{
new Command();
}

public function testSetApplication()
{
$application = new Application();
$command = new \TestCommand();
$command->setApplication($application);
$this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application');
$this->assertEquals($application->getHelperSet(), $command->getHelperSet());
}

public function testSetApplicationNull()
{
$command = new \TestCommand();
$command->setApplication(null);
$this->assertNull($command->getHelperSet());
}

public function testSetGetDefinition()
{
$command = new \TestCommand();
$ret = $command->setDefinition($definition = new InputDefinition());
$this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface');
$this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance');
$command->setDefinition(array(new InputArgument('foo'), new InputOption('bar')));
$this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
$this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
$command->setDefinition(new InputDefinition());
}

public function testAddArgument()
{
$command = new \TestCommand();
$ret = $command->addArgument('foo');
$this->assertEquals($command, $ret, '->addArgument() implements a fluent interface');
$this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command');
}

public function testAddOption()
{
$command = new \TestCommand();
$ret = $command->addOption('foo');
$this->assertEquals($command, $ret, '->addOption() implements a fluent interface');
$this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command');
}

public function testGetNamespaceGetNameSetName()
{
$command = new \TestCommand();
$this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name');
$command->setName('foo');
$this->assertEquals('foo', $command->getName(), '->setName() sets the command name');

$ret = $command->setName('foobar:bar');
$this->assertEquals($command, $ret, '->setName() implements a fluent interface');
$this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name');
}




public function testInvalidCommandNames($name)
{
if (method_exists($this, 'expectException')) {
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage(sprintf('Command name "%s" is invalid.', $name));
} else {
$this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));
}

$command = new \TestCommand();
$command->setName($name);
}

public function provideInvalidCommandNames()
{
return array(
array(''),
array('foo:'),
);
}

public function testGetSetDescription()
{
$command = new \TestCommand();
$this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description');
$ret = $command->setDescription('description1');
$this->assertEquals($command, $ret, '->setDescription() implements a fluent interface');
$this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description');
}

public function testGetSetHelp()
{
$command = new \TestCommand();
$this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help');
$ret = $command->setHelp('help1');
$this->assertEquals($command, $ret, '->setHelp() implements a fluent interface');
$this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help');
$command->setHelp('');
$this->assertEquals('', $command->getHelp(), '->getHelp() does not fall back to the description');
}

public function testGetProcessedHelp()
{
$command = new \TestCommand();
$command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
$this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly');
$this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%');

$command = new \TestCommand();
$command->setHelp('');
$this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description');
}

public function testGetSetAliases()
{
$command = new \TestCommand();
$this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases');
$ret = $command->setAliases(array('name1'));
$this->assertEquals($command, $ret, '->setAliases() implements a fluent interface');
$this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
}

public function testSetAliasesNull()
{
$command = new \TestCommand();
$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException');
$command->setAliases(null);
}

public function testGetSynopsis()
{
$command = new \TestCommand();
$command->addOption('foo');
$command->addArgument('bar');
$this->assertEquals('namespace:name [--foo] [--] [<bar>]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
}

public function testAddGetUsages()
{
$command = new \TestCommand();
$command->addUsage('foo1');
$command->addUsage('foo2');
$this->assertContains('namespace:name foo1', $command->getUsages());
$this->assertContains('namespace:name foo2', $command->getUsages());
}

public function testGetHelper()
{
$application = new Application();
$command = new \TestCommand();
$command->setApplication($application);
$formatterHelper = new FormatterHelper();
$this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
}





public function testGetHelperWithoutHelperSet()
{
$command = new \TestCommand();
$command->getHelper('formatter');
}

public function testMergeApplicationDefinition()
{
$application1 = new Application();
$application1->getDefinition()->addArguments(array(new InputArgument('foo')));
$application1->getDefinition()->addOptions(array(new InputOption('bar')));
$command = new \TestCommand();
$command->setApplication($application1);
$command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo'))));

$r = new \ReflectionObject($command);
$m = $r->getMethod('mergeApplicationDefinition');
$m->setAccessible(true);
$m->invoke($command);
$this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
$this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
$this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options');
$this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options');

$m->invoke($command);
$this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options');
}

public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
{
$application1 = new Application();
$application1->getDefinition()->addArguments(array(new InputArgument('foo')));
$application1->getDefinition()->addOptions(array(new InputOption('bar')));
$command = new \TestCommand();
$command->setApplication($application1);
$command->setDefinition($definition = new InputDefinition(array()));

$r = new \ReflectionObject($command);
$m = $r->getMethod('mergeApplicationDefinition');
$m->setAccessible(true);
$m->invoke($command, false);
$this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the command options');
$this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments');

$m->invoke($command, true);
$this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments');

$m->invoke($command);
$this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments');
}

public function testRunInteractive()
{
$tester = new CommandTester(new \TestCommand());

$tester->execute(array(), array('interactive' => true));

$this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive');
}

public function testRunNonInteractive()
{
$tester = new CommandTester(new \TestCommand());

$tester->execute(array(), array('interactive' => false));

$this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive');
}





public function testExecuteMethodNeedsToBeOverridden()
{
$command = new Command('foo');
$command->run(new StringInput(''), new NullOutput());
}





public function testRunWithInvalidOption()
{
$command = new \TestCommand();
$tester = new CommandTester($command);
$tester->execute(array('--bar' => true));
}

public function testRunReturnsIntegerExitCode()
{
$command = new \TestCommand();
$exitCode = $command->run(new StringInput(''), new NullOutput());
$this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');

$command = $this->getMockBuilder('TestCommand')->setMethods(array('execute'))->getMock();
$command->expects($this->once())
->method('execute')
->will($this->returnValue('2.3'));
$exitCode = $command->run(new StringInput(''), new NullOutput());
$this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
}

public function testRunWithApplication()
{
$command = new \TestCommand();
$command->setApplication(new Application());
$exitCode = $command->run(new StringInput(''), new NullOutput());

$this->assertSame(0, $exitCode, '->run() returns an integer exit code');
}

public function testRunReturnsAlwaysInteger()
{
$command = new \TestCommand();

$this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
}

public function testRunWithProcessTitle()
{
$command = new \TestCommand();
$command->setApplication(new Application());
$command->setProcessTitle('foo');
$this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
if (function_exists('cli_set_process_title')) {
if (null === @cli_get_process_title() && 'Darwin' === PHP_OS) {
$this->markTestSkipped('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.');
}
$this->assertEquals('foo', cli_get_process_title());
}
}

public function testSetCode()
{
$command = new \TestCommand();
$ret = $command->setCode(function (InputInterface $input, OutputInterface $output) {
$output->writeln('from the code...');
});
$this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
$tester = new CommandTester($command);
$tester->execute(array());
$this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
}

public function getSetCodeBindToClosureTests()
{
return array(
array(true, 'not bound to the command'),
array(false, 'bound to the command'),
);
}





public function testSetCodeBindToClosure($previouslyBound, $expected)
{
$code = createClosure();
if ($previouslyBound) {
$code = $code->bindTo($this);
}

$command = new \TestCommand();
$command->setCode($code);
$tester = new CommandTester($command);
$tester->execute(array());
$this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay());
}

public function testSetCodeWithStaticClosure()
{
$command = new \TestCommand();
$command->setCode(self::createClosure());
$tester = new CommandTester($command);
$tester->execute(array());

if (PHP_VERSION_ID < 70000) {

 $this->assertEquals('interact called'.PHP_EOL.'not bound'.PHP_EOL, $tester->getDisplay());
} else {

 $this->assertEquals('interact called'.PHP_EOL.'bound'.PHP_EOL, $tester->getDisplay());
}
}

private static function createClosure()
{
return function (InputInterface $input, OutputInterface $output) {
$output->writeln(isset($this) ? 'bound' : 'not bound');
};
}

public function testSetCodeWithNonClosureCallable()
{
$command = new \TestCommand();
$ret = $command->setCode(array($this, 'callableMethodCommand'));
$this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
$tester = new CommandTester($command);
$tester->execute(array());
$this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
}





public function testSetCodeWithNonCallable()
{
$command = new \TestCommand();
$command->setCode(array($this, 'nonExistentMethod'));
}

public function callableMethodCommand(InputInterface $input, OutputInterface $output)
{
$output->writeln('from the code...');
}




public function testLegacyAsText()
{
$command = new \TestCommand();
$command->setApplication(new Application());
$tester = new CommandTester($command);
$tester->execute(array('command' => $command->getName()));
$this->assertStringEqualsFile(self::$fixturesPath.'/command_astext.txt', $command->asText(), '->asText() returns a text representation of the command');
}




public function testLegacyAsXml()
{
$command = new \TestCommand();
$command->setApplication(new Application());
$tester = new CommandTester($command);
$tester->execute(array('command' => $command->getName()));
$this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/command_asxml.txt', $command->asXml(), '->asXml() returns an XML representation of the command');
}
}



function createClosure()
{
return function (InputInterface $input, OutputInterface $output) {
$output->writeln($this instanceof Command ? 'bound to the command' : 'not bound to the command');
};
}
<?php










namespace Symfony\Component\Console\Tests\Command;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
use Symfony\Component\Console\Application;

class HelpCommandTest extends TestCase
{
public function testExecuteForCommandAlias()
{
$command = new HelpCommand();
$command->setApplication(new Application());
$commandTester = new CommandTester($command);
$commandTester->execute(array('command_name' => 'li'), array('decorated' => false));
$this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
$this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
$this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
}

public function testExecuteForCommand()
{
$command = new HelpCommand();
$commandTester = new CommandTester($command);
$command->setCommand(new ListCommand());
$commandTester->execute(array(), array('decorated' => false));
$this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
}

public function testExecuteForCommandWithXmlOption()
{
$command = new HelpCommand();
$commandTester = new CommandTester($command);
$command->setCommand(new ListCommand());
$commandTester->execute(array('--format' => 'xml'));
$this->assertContains('<command', $commandTester->getDisplay(), '->execute() returns an XML help text if --xml is passed');
}

public function testExecuteForApplicationCommand()
{
$application = new Application();
$commandTester = new CommandTester($application->get('help'));
$commandTester->execute(array('command_name' => 'list'));
$this->assertContains('list [options] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
}

public function testExecuteForApplicationCommandWithXmlOption()
{
$application = new Application();
$commandTester = new CommandTester($application->get('help'));
$commandTester->execute(array('command_name' => 'list', '--format' => 'xml'));
$this->assertContains('list [--xml] [--raw] [--format FORMAT] [--] [&lt;namespace&gt;]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
$this->assertContains('<command', $commandTester->getDisplay(), '->execute() returns an XML help text if --format=xml is passed');
}
}
<?php










namespace Symfony\Component\Console\Input;







interface InputAwareInterface
{





public function setInput(InputInterface $input);
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;













class InputDefinition
{
private $arguments;
private $requiredCount;
private $hasAnArrayArgument = false;
private $hasOptional;
private $options;
private $shortcuts;






public function __construct(array $definition = array())
{
$this->setDefinition($definition);
}






public function setDefinition(array $definition)
{
$arguments = array();
$options = array();
foreach ($definition as $item) {
if ($item instanceof InputOption) {
$options[] = $item;
} else {
$arguments[] = $item;
}
}

$this->setArguments($arguments);
$this->setOptions($options);
}






public function setArguments($arguments = array())
{
$this->arguments = array();
$this->requiredCount = 0;
$this->hasOptional = false;
$this->hasAnArrayArgument = false;
$this->addArguments($arguments);
}






public function addArguments($arguments = array())
{
if (null !== $arguments) {
foreach ($arguments as $argument) {
$this->addArgument($argument);
}
}
}








public function addArgument(InputArgument $argument)
{
if (isset($this->arguments[$argument->getName()])) {
throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
}

if ($this->hasAnArrayArgument) {
throw new LogicException('Cannot add an argument after an array argument.');
}

if ($argument->isRequired() && $this->hasOptional) {
throw new LogicException('Cannot add a required argument after an optional one.');
}

if ($argument->isArray()) {
$this->hasAnArrayArgument = true;
}

if ($argument->isRequired()) {
++$this->requiredCount;
} else {
$this->hasOptional = true;
}

$this->arguments[$argument->getName()] = $argument;
}










public function getArgument($name)
{
if (!$this->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}

$arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;

return $arguments[$name];
}








public function hasArgument($name)
{
$arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;

return isset($arguments[$name]);
}






public function getArguments()
{
return $this->arguments;
}






public function getArgumentCount()
{
return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
}






public function getArgumentRequiredCount()
{
return $this->requiredCount;
}






public function getArgumentDefaults()
{
$values = array();
foreach ($this->arguments as $argument) {
$values[$argument->getName()] = $argument->getDefault();
}

return $values;
}






public function setOptions($options = array())
{
$this->options = array();
$this->shortcuts = array();
$this->addOptions($options);
}






public function addOptions($options = array())
{
foreach ($options as $option) {
$this->addOption($option);
}
}








public function addOption(InputOption $option)
{
if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
}

if ($option->getShortcut()) {
foreach (explode('|', $option->getShortcut()) as $shortcut) {
if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
}
}
}

$this->options[$option->getName()] = $option;
if ($option->getShortcut()) {
foreach (explode('|', $option->getShortcut()) as $shortcut) {
$this->shortcuts[$shortcut] = $option->getName();
}
}
}










public function getOption($name)
{
if (!$this->hasOption($name)) {
throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
}

return $this->options[$name];
}











public function hasOption($name)
{
return isset($this->options[$name]);
}






public function getOptions()
{
return $this->options;
}








public function hasShortcut($name)
{
return isset($this->shortcuts[$name]);
}








public function getOptionForShortcut($shortcut)
{
return $this->getOption($this->shortcutToName($shortcut));
}






public function getOptionDefaults()
{
$values = array();
foreach ($this->options as $option) {
$values[$option->getName()] = $option->getDefault();
}

return $values;
}










private function shortcutToName($shortcut)
{
if (!isset($this->shortcuts[$shortcut])) {
throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
}

return $this->shortcuts[$shortcut];
}








public function getSynopsis($short = false)
{
$elements = array();

if ($short && $this->getOptions()) {
$elements[] = '[options]';
} elseif (!$short) {
foreach ($this->getOptions() as $option) {
$value = '';
if ($option->acceptValue()) {
$value = sprintf(
' %s%s%s',
$option->isValueOptional() ? '[' : '',
strtoupper($option->getName()),
$option->isValueOptional() ? ']' : ''
);
}

$shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
$elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
}
}

if (count($elements) && $this->getArguments()) {
$elements[] = '[--]';
}

foreach ($this->getArguments() as $argument) {
$element = '<'.$argument->getName().'>';
if (!$argument->isRequired()) {
$element = '['.$element.']';
} elseif ($argument->isArray()) {
$element = $element.' ('.$element.')';
}

if ($argument->isArray()) {
$element .= '...';
}

$elements[] = $element;
}

return implode(' ', $elements);
}








public function asText()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);

$descriptor = new TextDescriptor();
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
$descriptor->describe($output, $this, array('raw_output' => true));

return $output->fetch();
}










public function asXml($asDom = false)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);

$descriptor = new XmlDescriptor();

if ($asDom) {
return $descriptor->getInputDefinitionDocument($this);
}

$output = new BufferedOutput();
$descriptor->describe($output, $this);

return $output->fetch();
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;












abstract class Input implements InputInterface
{



protected $definition;
protected $options = array();
protected $arguments = array();
protected $interactive = true;






public function __construct(InputDefinition $definition = null)
{
if (null === $definition) {
$this->definition = new InputDefinition();
} else {
$this->bind($definition);
$this->validate();
}
}




public function bind(InputDefinition $definition)
{
$this->arguments = array();
$this->options = array();
$this->definition = $definition;

$this->parse();
}




abstract protected function parse();




public function validate()
{
$definition = $this->definition;
$givenArguments = $this->arguments;

$missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {
return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
});

if (count($missingArguments) > 0) {
throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
}
}




public function isInteractive()
{
return $this->interactive;
}




public function setInteractive($interactive)
{
$this->interactive = (bool) $interactive;
}




public function getArguments()
{
return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
}




public function getArgument($name)
{
if (!$this->definition->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}

return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
}




public function setArgument($name, $value)
{
if (!$this->definition->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}

$this->arguments[$name] = $value;
}




public function hasArgument($name)
{
return $this->definition->hasArgument($name);
}




public function getOptions()
{
return array_merge($this->definition->getOptionDefaults(), $this->options);
}




public function getOption($name)
{
if (!$this->definition->hasOption($name)) {
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}

return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
}




public function setOption($name, $value)
{
if (!$this->definition->hasOption($name)) {
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
}

$this->options[$name] = $value;
}




public function hasOption($name)
{
return $this->definition->hasOption($name);
}








public function escapeToken($token)
{
return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;






class InputArgument
{
const REQUIRED = 1;
const OPTIONAL = 2;
const IS_ARRAY = 4;

private $name;
private $mode;
private $default;
private $description;











public function __construct($name, $mode = null, $description = '', $default = null)
{
if (null === $mode) {
$mode = self::OPTIONAL;
} elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
}

$this->name = $name;
$this->mode = $mode;
$this->description = $description;

$this->setDefault($default);
}






public function getName()
{
return $this->name;
}






public function isRequired()
{
return self::REQUIRED === (self::REQUIRED & $this->mode);
}






public function isArray()
{
return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
}








public function setDefault($default = null)
{
if (self::REQUIRED === $this->mode && null !== $default) {
throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
}

if ($this->isArray()) {
if (null === $default) {
$default = array();
} elseif (!is_array($default)) {
throw new LogicException('A default value for an array argument must be an array.');
}
}

$this->default = $default;
}






public function getDefault()
{
return $this->default;
}






public function getDescription()
{
return $this->description;
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\InvalidOptionException;










class ArrayInput extends Input
{
private $parameters;







public function __construct(array $parameters, InputDefinition $definition = null)
{
$this->parameters = $parameters;

parent::__construct($definition);
}




public function getFirstArgument()
{
foreach ($this->parameters as $key => $value) {
if ($key && '-' === $key[0]) {
continue;
}

return $value;
}
}




public function hasParameterOption($values)
{
$values = (array) $values;

foreach ($this->parameters as $k => $v) {
if (!is_int($k)) {
$v = $k;
}

if (in_array($v, $values)) {
return true;
}
}

return false;
}




public function getParameterOption($values, $default = false)
{
$values = (array) $values;

foreach ($this->parameters as $k => $v) {
if (is_int($k)) {
if (in_array($v, $values)) {
return true;
}
} elseif (in_array($k, $values)) {
return $v;
}
}

return $default;
}






public function __toString()
{
$params = array();
foreach ($this->parameters as $param => $val) {
if ($param && '-' === $param[0]) {
$params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
} else {
$params[] = $this->escapeToken($val);
}
}

return implode(' ', $params);
}




protected function parse()
{
foreach ($this->parameters as $key => $value) {
if (0 === strpos($key, '--')) {
$this->addLongOption(substr($key, 2), $value);
} elseif ('-' === $key[0]) {
$this->addShortOption(substr($key, 1), $value);
} else {
$this->addArgument($key, $value);
}
}
}









private function addShortOption($shortcut, $value)
{
if (!$this->definition->hasShortcut($shortcut)) {
throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
}

$this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
}










private function addLongOption($name, $value)
{
if (!$this->definition->hasOption($name)) {
throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name));
}

$option = $this->definition->getOption($name);

if (null === $value) {
if ($option->isValueRequired()) {
throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
}

$value = $option->isValueOptional() ? $option->getDefault() : true;
}

$this->options[$name] = $value;
}









private function addArgument($name, $value)
{
if (!$this->definition->hasArgument($name)) {
throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
}

$this->arguments[$name] = $value;
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;










class StringInput extends ArgvInput
{
const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';









public function __construct($input, InputDefinition $definition = null)
{
if ($definition) {
@trigger_error('The $definition argument of the '.__METHOD__.' method is deprecated and will be removed in 3.0. Set this parameter with the bind() method instead.', E_USER_DEPRECATED);
}

parent::__construct(array(), null);

$this->setTokens($this->tokenize($input));

if (null !== $definition) {
$this->bind($definition);
}
}










private function tokenize($input)
{
$tokens = array();
$length = strlen($input);
$cursor = 0;
while ($cursor < $length) {
if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
} elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
$tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
} elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
$tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
} elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
$tokens[] = stripcslashes($match[1]);
} else {

 throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
}

$cursor += strlen($match[0]);
}

return $tokens;
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;






class InputOption
{
const VALUE_NONE = 1;
const VALUE_REQUIRED = 2;
const VALUE_OPTIONAL = 4;
const VALUE_IS_ARRAY = 8;

private $name;
private $shortcut;
private $mode;
private $default;
private $description;












public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
{
if (0 === strpos($name, '--')) {
$name = substr($name, 2);
}

if (empty($name)) {
throw new InvalidArgumentException('An option name cannot be empty.');
}

if (empty($shortcut)) {
$shortcut = null;
}

if (null !== $shortcut) {
if (is_array($shortcut)) {
$shortcut = implode('|', $shortcut);
}
$shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
$shortcuts = array_filter($shortcuts);
$shortcut = implode('|', $shortcuts);

if (empty($shortcut)) {
throw new InvalidArgumentException('An option shortcut cannot be empty.');
}
}

if (null === $mode) {
$mode = self::VALUE_NONE;
} elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
}

$this->name = $name;
$this->shortcut = $shortcut;
$this->mode = $mode;
$this->description = $description;

if ($this->isArray() && !$this->acceptValue()) {
throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
}

$this->setDefault($default);
}






public function getShortcut()
{
return $this->shortcut;
}






public function getName()
{
return $this->name;
}






public function acceptValue()
{
return $this->isValueRequired() || $this->isValueOptional();
}






public function isValueRequired()
{
return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
}






public function isValueOptional()
{
return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
}






public function isArray()
{
return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
}








public function setDefault($default = null)
{
if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
}

if ($this->isArray()) {
if (null === $default) {
$default = array();
} elseif (!is_array($default)) {
throw new LogicException('A default value for an array option must be an array.');
}
}

$this->default = $this->acceptValue() ? $default : false;
}






public function getDefault()
{
return $this->default;
}






public function getDescription()
{
return $this->description;
}








public function equals(InputOption $option)
{
return $option->getName() === $this->getName()
&& $option->getShortcut() === $this->getShortcut()
&& $option->getDefault() === $this->getDefault()
&& $option->isArray() === $this->isArray()
&& $option->isValueRequired() === $this->isValueRequired()
&& $option->isValueOptional() === $this->isValueOptional()
;
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\RuntimeException;


























class ArgvInput extends Input
{
private $tokens;
private $parsed;







public function __construct(array $argv = null, InputDefinition $definition = null)
{
if (null === $argv) {
$argv = $_SERVER['argv'];
}


 array_shift($argv);

$this->tokens = $argv;

parent::__construct($definition);
}

protected function setTokens(array $tokens)
{
$this->tokens = $tokens;
}




protected function parse()
{
$parseOptions = true;
$this->parsed = $this->tokens;
while (null !== $token = array_shift($this->parsed)) {
if ($parseOptions && '' == $token) {
$this->parseArgument($token);
} elseif ($parseOptions && '--' == $token) {
$parseOptions = false;
} elseif ($parseOptions && 0 === strpos($token, '--')) {
$this->parseLongOption($token);
} elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
$this->parseShortOption($token);
} else {
$this->parseArgument($token);
}
}
}






private function parseShortOption($token)
{
$name = substr($token, 1);

if (strlen($name) > 1) {
if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {

 $this->addShortOption($name[0], substr($name, 1));
} else {
$this->parseShortOptionSet($name);
}
} else {
$this->addShortOption($name, null);
}
}








private function parseShortOptionSet($name)
{
$len = strlen($name);
for ($i = 0; $i < $len; ++$i) {
if (!$this->definition->hasShortcut($name[$i])) {
throw new RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
}

$option = $this->definition->getOptionForShortcut($name[$i]);
if ($option->acceptValue()) {
$this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));

break;
} else {
$this->addLongOption($option->getName(), null);
}
}
}






private function parseLongOption($token)
{
$name = substr($token, 2);

if (false !== $pos = strpos($name, '=')) {
if (0 === strlen($value = substr($name, $pos + 1))) {
array_unshift($this->parsed, null);
}
$this->addLongOption(substr($name, 0, $pos), $value);
} else {
$this->addLongOption($name, null);
}
}








private function parseArgument($token)
{
$c = count($this->arguments);


 if ($this->definition->hasArgument($c)) {
$arg = $this->definition->getArgument($c);
$this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;


 } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
$arg = $this->definition->getArgument($c - 1);
$this->arguments[$arg->getName()][] = $token;


 } else {
$all = $this->definition->getArguments();
if (count($all)) {
throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))));
}

throw new RuntimeException(sprintf('No arguments expected, got "%s".', $token));
}
}









private function addShortOption($shortcut, $value)
{
if (!$this->definition->hasShortcut($shortcut)) {
throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
}

$this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
}









private function addLongOption($name, $value)
{
if (!$this->definition->hasOption($name)) {
throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
}

$option = $this->definition->getOption($name);


 if (!isset($value[0])) {
$value = null;
}

if (null !== $value && !$option->acceptValue()) {
throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
}

if (null === $value && $option->acceptValue() && count($this->parsed)) {

 
 $next = array_shift($this->parsed);
if (isset($next[0]) && '-' !== $next[0]) {
$value = $next;
} elseif (empty($next)) {
$value = null;
} else {
array_unshift($this->parsed, $next);
}
}

if (null === $value) {
if ($option->isValueRequired()) {
throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
}

if (!$option->isArray()) {
$value = $option->isValueOptional() ? $option->getDefault() : true;
}
}

if ($option->isArray()) {
$this->options[$name][] = $value;
} else {
$this->options[$name] = $value;
}
}




public function getFirstArgument()
{
foreach ($this->tokens as $token) {
if ($token && '-' === $token[0]) {
continue;
}

return $token;
}
}




public function hasParameterOption($values)
{
$values = (array) $values;

foreach ($this->tokens as $token) {
foreach ($values as $value) {
if ($token === $value || 0 === strpos($token, $value.'=')) {
return true;
}
}
}

return false;
}




public function getParameterOption($values, $default = false)
{
$values = (array) $values;
$tokens = $this->tokens;

while (0 < count($tokens)) {
$token = array_shift($tokens);

foreach ($values as $value) {
if ($token === $value || 0 === strpos($token, $value.'=')) {
if (false !== $pos = strpos($token, '=')) {
return substr($token, $pos + 1);
}

return array_shift($tokens);
}
}
}

return $default;
}






public function __toString()
{
$self = $this;
$tokens = array_map(function ($token) use ($self) {
if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
return $match[1].$self->escapeToken($match[2]);
}

if ($token && $token[0] !== '-') {
return $self->escapeToken($token);
}

return $token;
}, $this->tokens);

return implode(' ', $tokens);
}
}
<?php










namespace Symfony\Component\Console\Input;

use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;






interface InputInterface
{





public function getFirstArgument();











public function hasParameterOption($values);












public function getParameterOption($values, $default = false);






public function bind(InputDefinition $definition);






public function validate();






public function getArguments();










public function getArgument($name);









public function setArgument($name, $value);








public function hasArgument($name);






public function getOptions();










public function getOption($name);









public function setOption($name, $value);








public function hasOption($name);






public function isInteractive();






public function setInteractive($interactive);
}
<?php










namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputDefinition;






class ListCommand extends Command
{



protected function configure()
{
$this
->setName('list')
->setDefinition($this->createDefinition())
->setDescription('Lists commands')
->setHelp(<<<'EOF'
The <info>%command.name%</info> command lists all commands:

  <info>php %command.full_name%</info>

You can also display the commands for a specific namespace:

  <info>php %command.full_name% test</info>

You can also output the information in other formats by using the <comment>--format</comment> option:

  <info>php %command.full_name% --format=xml</info>

It's also possible to get raw list of commands (useful for embedding command runner):

  <info>php %command.full_name% --raw</info>
EOF
)
;
}




public function getNativeDefinition()
{
return $this->createDefinition();
}




protected function execute(InputInterface $input, OutputInterface $output)
{
if ($input->getOption('xml')) {
@trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED);

$input->setOption('format', 'xml');
}

$helper = new DescriptorHelper();
$helper->describe($output, $this->getApplication(), array(
'format' => $input->getOption('format'),
'raw_text' => $input->getOption('raw'),
'namespace' => $input->getArgument('namespace'),
));
}




private function createDefinition()
{
return new InputDefinition(array(
new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
));
}
}
<?php










namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Helper\DescriptorHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;






class HelpCommand extends Command
{
private $command;




protected function configure()
{
$this->ignoreValidationErrors();

$this
->setName('help')
->setDefinition(array(
new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
))
->setDescription('Displays help for a command')
->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays help for a given command:

  <info>php %command.full_name% list</info>

You can also output the help in other formats by using the <comment>--format</comment> option:

  <info>php %command.full_name% --format=xml list</info>

To display the list of available commands, please use the <info>list</info> command.
EOF
)
;
}






public function setCommand(Command $command)
{
$this->command = $command;
}




protected function execute(InputInterface $input, OutputInterface $output)
{
if (null === $this->command) {
$this->command = $this->getApplication()->find($input->getArgument('command_name'));
}

if ($input->getOption('xml')) {
@trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED);

$input->setOption('format', 'xml');
}

$helper = new DescriptorHelper();
$helper->describe($output, $this->command, array(
'format' => $input->getOption('format'),
'raw_text' => $input->getOption('raw'),
));

$this->command = null;
}
}
<?php










namespace Symfony\Component\Console\Command;

use Symfony\Component\Console\Descriptor\TextDescriptor;
use Symfony\Component\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\LogicException;






class Command
{
private $application;
private $name;
private $processTitle;
private $aliases = array();
private $definition;
private $help;
private $description;
private $ignoreValidationErrors = false;
private $applicationDefinitionMerged = false;
private $applicationDefinitionMergedWithArgs = false;
private $inputBound = false;
private $code;
private $synopsis = array();
private $usages = array();
private $helperSet;








public function __construct($name = null)
{
$this->definition = new InputDefinition();

if (null !== $name) {
$this->setName($name);
}

$this->configure();

if (!$this->name) {
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
}
}






public function ignoreValidationErrors()
{
$this->ignoreValidationErrors = true;
}






public function setApplication(Application $application = null)
{
$this->application = $application;
if ($application) {
$this->setHelperSet($application->getHelperSet());
} else {
$this->helperSet = null;
}
}






public function setHelperSet(HelperSet $helperSet)
{
$this->helperSet = $helperSet;
}






public function getHelperSet()
{
return $this->helperSet;
}






public function getApplication()
{
return $this->application;
}









public function isEnabled()
{
return true;
}




protected function configure()
{
}


















protected function execute(InputInterface $input, OutputInterface $output)
{
throw new LogicException('You must override the execute() method in the concrete command class.');
}











protected function interact(InputInterface $input, OutputInterface $output)
{
}










protected function initialize(InputInterface $input, OutputInterface $output)
{
}
















public function run(InputInterface $input, OutputInterface $output)
{

 $this->getSynopsis(true);
$this->getSynopsis(false);


 $this->mergeApplicationDefinition();


 if (!$this->inputBound) {
try {
$input->bind($this->definition);
} catch (ExceptionInterface $e) {
if (!$this->ignoreValidationErrors) {
throw $e;
}
}
}

$this->initialize($input, $output);

if (null !== $this->processTitle) {
if (function_exists('cli_set_process_title')) {
if (false === @cli_set_process_title($this->processTitle)) {
if ('Darwin' === PHP_OS) {
$output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
} else {
$error = error_get_last();
trigger_error($error['message'], E_USER_WARNING);
}
}
} elseif (function_exists('setproctitle')) {
setproctitle($this->processTitle);
} elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
$output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
}
}

if ($input->isInteractive()) {
$this->interact($input, $output);
}


 
 
 if ($input->hasArgument('command') && null === $input->getArgument('command')) {
$input->setArgument('command', $this->getName());
}

$input->validate();

if ($this->code) {
$statusCode = call_user_func($this->code, $input, $output);
} else {
$statusCode = $this->execute($input, $output);
}

return is_numeric($statusCode) ? (int) $statusCode : 0;
}















public function setCode($code)
{
if (!is_callable($code)) {
throw new InvalidArgumentException('Invalid callable provided to Command::setCode.');
}

if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
$r = new \ReflectionFunction($code);
if (null === $r->getClosureThis()) {
if (PHP_VERSION_ID < 70000) {

 
 
 
 $code = @\Closure::bind($code, $this);
} else {
$code = \Closure::bind($code, $this);
}
}
}

$this->code = $code;

return $this;
}








public function mergeApplicationDefinition($mergeArgs = true)
{
if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
return;
}

$this->definition->addOptions($this->application->getDefinition()->getOptions());

if ($mergeArgs) {
$currentArguments = $this->definition->getArguments();
$this->definition->setArguments($this->application->getDefinition()->getArguments());
$this->definition->addArguments($currentArguments);
}

$this->applicationDefinitionMerged = true;
if ($mergeArgs) {
$this->applicationDefinitionMergedWithArgs = true;
}
}








public function setDefinition($definition)
{
if ($definition instanceof InputDefinition) {
$this->definition = $definition;
} else {
$this->definition->setDefinition($definition);
}

$this->applicationDefinitionMerged = false;

return $this;
}






public function getDefinition()
{
return $this->definition;
}











public function getNativeDefinition()
{
return $this->getDefinition();
}











public function addArgument($name, $mode = null, $description = '', $default = null)
{
$this->definition->addArgument(new InputArgument($name, $mode, $description, $default));

return $this;
}












public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
{
$this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));

return $this;
}















public function setName($name)
{
$this->validateName($name);

$this->name = $name;

return $this;
}













public function setProcessTitle($title)
{
$this->processTitle = $title;

return $this;
}






public function getName()
{
return $this->name;
}








public function setDescription($description)
{
$this->description = $description;

return $this;
}






public function getDescription()
{
return $this->description;
}








public function setHelp($help)
{
$this->help = $help;

return $this;
}






public function getHelp()
{
return $this->help;
}







public function getProcessedHelp()
{
$name = $this->name;

$placeholders = array(
'%command.name%',
'%command.full_name%',
);
$replacements = array(
$name,
$_SERVER['PHP_SELF'].' '.$name,
);

return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
}










public function setAliases($aliases)
{
if (!is_array($aliases) && !$aliases instanceof \Traversable) {
throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
}

foreach ($aliases as $alias) {
$this->validateName($alias);
}

$this->aliases = $aliases;

return $this;
}






public function getAliases()
{
return $this->aliases;
}








public function getSynopsis($short = false)
{
$key = $short ? 'short' : 'long';

if (!isset($this->synopsis[$key])) {
$this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
}

return $this->synopsis[$key];
}








public function addUsage($usage)
{
if (0 !== strpos($usage, $this->name)) {
$usage = sprintf('%s %s', $this->name, $usage);
}

$this->usages[] = $usage;

return $this;
}






public function getUsages()
{
return $this->usages;
}











public function getHelper($name)
{
if (null === $this->helperSet) {
throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
}

return $this->helperSet->get($name);
}








public function asText()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);

$descriptor = new TextDescriptor();
$output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
$descriptor->describe($output, $this, array('raw_output' => true));

return $output->fetch();
}










public function asXml($asDom = false)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);

$descriptor = new XmlDescriptor();

if ($asDom) {
return $descriptor->getCommandDocument($this);
}

$output = new BufferedOutput();
$descriptor->describe($output, $this);

return $output->fetch();
}




public function setInputBound($inputBound)
{
$this->inputBound = $inputBound;
}










private function validateName($name)
{
if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
}
}
}
<?php










namespace Symfony\Component\Console\Exception;




class LogicException extends \LogicException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Console\Exception;






class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Console\Exception;






interface ExceptionInterface
{
}
<?php










namespace Symfony\Component\Console\Exception;






class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
{
private $alternatives;







public function __construct($message, array $alternatives = array(), $code = 0, \Exception $previous = null)
{
parent::__construct($message, $code, $previous);

$this->alternatives = $alternatives;
}




public function getAlternatives()
{
return $this->alternatives;
}
}
<?php










namespace Symfony\Component\Console\Exception;




class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Console\Exception;




class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php











namespace Humbug\SelfUpdate;

class VersionParser
{




private $versions;




private $modifier = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?';




public function __construct(array $versions = array())
{
$this->versions = $versions;
}







public function getMostRecentStable()
{
return $this->selectRecentStable();
}







public function getMostRecentUnStable()
{
return $this->selectRecentUnstable();
}







public function getMostRecentAll()
{
return $this->selectRecentAll();
}







public function isStable($version)
{
return $this->stable($version);
}








public function isPreRelease($version)
{
return !$this->stable($version) && !$this->development($version);
}








public function isUnstable($version)
{
return !$this->stable($version);
}







public function isDevelopment($version)
{
return $this->development($version);
}

private function selectRecentStable()
{
$candidates = array();
foreach ($this->versions as $version) {
if (!$this->stable($version)) {
continue;
}
$candidates[] = $version;
}
if (empty($candidates)) {
return false;
}
return $this->findMostRecent($candidates);
}

private function selectRecentUnstable()
{
$candidates = array();
foreach ($this->versions as $version) {
if ($this->stable($version) || $this->development($version)) {
continue;
}
$candidates[] = $version;
}
if (empty($candidates)) {
return false;
}
return $this->findMostRecent($candidates);
}

private function selectRecentAll()
{
$candidates = array();
foreach ($this->versions as $version) {
if ($this->development($version)) {
continue;
}
$candidates[] = $version;
}
if (empty($candidates)) {
return false;
}
return $this->findMostRecent($candidates);
}

private function findMostRecent(array $candidates)
{
$candidate = null;
$tracker = null;
foreach ($candidates as $version) {
if (version_compare($candidate, $version, '<')) {
$candidate = $version;
}
}
return $candidate;
}

private function stable($version)
{
$version = preg_replace('{#.+$}i', '', $version);
if ($this->development($version)) {
return false;
}
preg_match('{'.$this->modifier.'$}i', strtolower($version), $match);
if (!empty($match[3])) {
return false;
}
if (!empty($match[1])) {
if ('beta' === $match[1] || 'b' === $match[1]
|| 'alpha' === $match[1] || 'a' === $match[1]
|| 'rc' === $match[1]) {
return false;
}
}
return true;
}

private function development($version)
{
if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
return true;
}
if (1 == preg_match("/-\d+-[a-z0-9]{8,}$/", $version)) {
return true;
}
return false;
}
}
<?php











namespace Humbug\SelfUpdate;

use Humbug\SelfUpdate\Exception\RuntimeException;
use Humbug\SelfUpdate\Exception\InvalidArgumentException;
use Humbug\SelfUpdate\Exception\FilesystemException;
use Humbug\SelfUpdate\Exception\HttpRequestException;
use Humbug\SelfUpdate\Exception\NoSignatureException;
use Humbug\SelfUpdate\Strategy\StrategyInterface;
use Humbug\SelfUpdate\Strategy\ShaStrategy;
use Humbug\SelfUpdate\Strategy\GithubStrategy;

class Updater
{

const STRATEGY_SHA1 = 'sha1';

const STRATEGY_GITHUB = 'github';




protected $strategy;




protected $localPharFile;




protected $localPharFileBasename;




protected $localPubKeyFile;




protected $hasPubKey;




protected $tempDirectory;




protected $newVersion;




protected $oldVersion;




protected $backupExtension = '-old.phar';




protected $backupPath;




protected $restorePath;




protected $newVersionAvailable;








public function __construct($localPharFile = null, $hasPubKey = true, $strategy = self::STRATEGY_SHA1)
{
ini_set('phar.require_hash', 1);
$this->setLocalPharFile($localPharFile);
if (!is_bool($hasPubKey)) {
throw new InvalidArgumentException(
'Constructor parameter $hasPubKey must be boolean or null.'
);
} else {
$this->hasPubKey = $hasPubKey;
}
if ($this->hasPubKey) {
$this->setLocalPubKeyFile();
}
$this->setTempDirectory();
$this->setStrategy($strategy);
}






public function hasUpdate()
{
$this->newVersionAvailable = $this->newVersionAvailable();
return $this->newVersionAvailable;
}






public function update()
{
if ($this->newVersionAvailable === false
|| (!is_bool($this->newVersionAvailable) && !$this->hasUpdate())) {
return false;
}
$this->backupPhar();
$this->downloadPhar();
$this->replacePhar();
return true;
}






public function rollback()
{
if (!$this->restorePhar()) {
return false;
}
return true;
}




public function setStrategy($strategy)
{
switch ($strategy) {
case self::STRATEGY_GITHUB:
$this->strategy = new GithubStrategy;
break;

default:
$this->strategy = new ShaStrategy;
break;
}
}

public function setStrategyObject(StrategyInterface $strategy)
{
$this->strategy = $strategy;
}

public function getStrategy()
{
return $this->strategy;
}






public function setBackupExtension($extension)
{
$this->backupExtension = $extension;
}






public function getBackupExtension()
{
return $this->backupExtension;
}

public function getLocalPharFile()
{
return $this->localPharFile;
}

public function getLocalPharFileBasename()
{
return $this->localPharFileBasename;
}

public function getLocalPubKeyFile()
{
return $this->localPubKeyFile;
}

public function getTempDirectory()
{
return $this->tempDirectory;
}

public function getTempPharFile()
{
return $this->getTempDirectory()
. '/'
. sprintf('%s.phar.temp', $this->getLocalPharFileBasename());
}

public function getNewVersion()
{
return $this->newVersion;
}

public function getOldVersion()
{
return $this->oldVersion;
}






public function setBackupPath($filePath)
{
$path = realpath(dirname($filePath));
if (!is_dir($path)) {
throw new FilesystemException(sprintf(
'The backup directory does not exist: %s.', $path
));
}
if (!is_writable($path)) {
throw new FilesystemException(sprintf(
'The backup directory is not writeable: %s.', $path
));
}
$this->backupPath = $filePath;
}






public function getBackupPath()
{
return $this->backupPath;
}






public function setRestorePath($filePath)
{
$path = realpath(dirname($filePath));
if (!file_exists($path)) {
throw new FilesystemException(sprintf(
'The restore phar does not exist: %s.', $path
));
}
if (!is_readable($path)) {
throw new FilesystemException(sprintf(
'The restore file is not readable: %s.', $path
));
}
$this->restorePath = $filePath;
}






public function getRestorePath()
{
return $this->restorePath;
}

public function throwRuntimeException($errno, $errstr)
{
throw new RuntimeException($errstr);
}

public function throwHttpRequestException($errno, $errstr)
{
throw new HttpRequestException($errstr);
}

protected function hasPubKey()
{
return $this->hasPubKey;
}

protected function newVersionAvailable()
{
$this->newVersion = $this->strategy->getCurrentRemoteVersion($this);
$this->oldVersion = $this->strategy->getCurrentLocalVersion($this);

if (!empty($this->newVersion) && ($this->newVersion !== $this->oldVersion)) {
return true;
}
return false;
}

protected function backupPhar()
{
$result = copy($this->getLocalPharFile(), $this->getBackupPharFile());
if ($result === false) {
$this->cleanupAfterError();
throw new FilesystemException(sprintf(
'Unable to backup %s to %s.',
$this->getLocalPharFile(),
$this->getBackupPharFile()
));
}
}

protected function downloadPhar()
{
$this->strategy->download($this);

if (!file_exists($this->getTempPharFile())) {
throw new FilesystemException(
'Creation of download file failed.'
);
}

if ($this->getStrategy() instanceof ShaStrategy) {
$tmpVersion = sha1_file($this->getTempPharFile());
if ($tmpVersion !== $this->getNewVersion()) {
$this->cleanupAfterError();
throw new HttpRequestException(sprintf(
'Download file appears to be corrupted or outdated. The file '
. 'received does not have the expected SHA-1 hash: %s.',
$this->getNewVersion()
));
}
}

try {
$this->validatePhar($this->getTempPharFile());
} catch (\Exception $e) {
restore_error_handler();
$this->cleanupAfterError();
throw $e;
}
}

protected function replacePhar()
{
rename($this->getTempPharFile(), $this->getLocalPharFile());
}

protected function restorePhar()
{
$backup = $this->getRestorePharFile();
if (!file_exists($backup)) {
throw new RuntimeException(sprintf(
'The backup file does not exist: %s.', $backup
));
}
$this->validatePhar($backup);
return rename($backup, $this->getLocalPharFile());
}

protected function getBackupPharFile()
{
if (null !== $this->getBackupPath()) {
return $this->getBackupPath();
}
return $this->getTempDirectory()
. '/'
. sprintf('%s%s', $this->getLocalPharFileBasename(), $this->getBackupExtension());
}

protected function getRestorePharFile()
{
if (null !== $this->getRestorePath()) {
return $this->getRestorePath();
}
return $this->getTempDirectory()
. '/'
. sprintf('%s%s', $this->getLocalPharFileBasename(), $this->getBackupExtension()
);
}

protected function getTempPubKeyFile()
{
return $this->getTempDirectory()
. '/'
. sprintf('%s.phar.temp.pubkey', $this->getLocalPharFileBasename());
}

protected function setLocalPharFile($localPharFile)
{
if (!is_null($localPharFile)) {
$localPharFile = realpath($localPharFile);
} else {
$localPharFile = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
}
if (!file_exists($localPharFile)) {
throw new RuntimeException(sprintf(
'The set phar file does not exist: %s.', $localPharFile
));
}
if (!is_writable($localPharFile)) {
throw new FilesystemException(sprintf(
'The current phar file is not writeable and cannot be replaced: %s.',
$localPharFile
));
}
$this->localPharFile = $localPharFile;
$this->localPharFileBasename = basename($localPharFile, '.phar');
}

protected function setLocalPubKeyFile()
{
$localPubKeyFile = $this->getLocalPharFile() . '.pubkey';
if (!file_exists($localPubKeyFile)) {
throw new RuntimeException(sprintf(
'The phar pubkey file does not exist: %s.', $localPubKeyFile
));
}
$this->localPubKeyFile = $localPubKeyFile;
}

protected function setTempDirectory()
{
$tempDirectory = dirname($this->getLocalPharFile());
if (!is_writable($tempDirectory)) {
throw new FilesystemException(sprintf(
'The directory is not writeable: %s.', $tempDirectory
));
}
$this->tempDirectory = $tempDirectory;
}

protected function validatePhar($phar)
{
$phar = realpath($phar);
if ($this->hasPubKey()) {
copy($this->getLocalPubKeyFile(), $phar . '.pubkey');
}
chmod($phar, fileperms($this->getLocalPharFile()));

set_error_handler(array($this, 'throwRuntimeException'));
$phar = new \Phar($phar);
$signature = $phar->getSignature();
if ($this->hasPubKey() && strtolower($signature['hash_type']) !== 'openssl') {
throw new NoSignatureException(
'The downloaded phar file has no OpenSSL signature.'
);
}
restore_error_handler();
if ($this->hasPubKey()) {
@unlink($phar . '.pubkey');
}
unset($phar);
}

protected function cleanupAfterError()
{

 @unlink($this->getTempPharFile());
@unlink($this->getTempPubKeyFile());
}
}
<?php









namespace Humbug\SelfUpdate\Exception;

class NoSignatureException extends RuntimeException
{
}
<?php









namespace Humbug\SelfUpdate\Exception;

interface ExceptionInterface
{
}
<?php









namespace Humbug\SelfUpdate\Exception;

class HttpRequestException extends RuntimeException
{
}
<?php









namespace Humbug\SelfUpdate\Exception;

class JsonParsingException extends RuntimeException
{
}
<?php









namespace Humbug\SelfUpdate\Exception;

class InvalidArgumentException extends \RuntimeException implements ExceptionInterface
{
}
<?php









namespace Humbug\SelfUpdate\Exception;

class FilesystemException extends RuntimeException
{
}
<?php









namespace Humbug\SelfUpdate\Exception;

class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php











namespace Humbug\SelfUpdate\Strategy;

use Humbug\SelfUpdate\Updater;

interface StrategyInterface
{







public function download(Updater $updater);







public function getCurrentRemoteVersion(Updater $updater);







public function getCurrentLocalVersion(Updater $updater);
}
<?php











namespace Humbug\SelfUpdate\Strategy;

use Humbug\SelfUpdate\Updater;
use Humbug\SelfUpdate\VersionParser;
use Humbug\SelfUpdate\Exception\HttpRequestException;
use Humbug\SelfUpdate\Exception\InvalidArgumentException;
use Humbug\SelfUpdate\Exception\JsonParsingException;

class GithubStrategy implements StrategyInterface
{

const API_URL = 'https://packagist.org/packages/%s.json';

const STABLE = 'stable';

const UNSTABLE = 'unstable';

const ANY = 'any';




private $localVersion;




private $remoteVersion;




private $remoteUrl;




private $pharName;




private $packageName;




private $stability = self::STABLE;







public function download(Updater $updater)
{

set_error_handler(array($updater, 'throwHttpRequestException'));
$result = humbug_get_contents($this->remoteUrl);
restore_error_handler();
if (false === $result) {
throw new HttpRequestException(sprintf(
'Request to URL failed: %s', $this->remoteUrl
));
}

file_put_contents($updater->getTempPharFile(), $result);
}







public function getCurrentRemoteVersion(Updater $updater)
{

set_error_handler(array($updater, 'throwHttpRequestException'));
$packageUrl = $this->getApiUrl();
$package = json_decode(humbug_get_contents($packageUrl), true);
restore_error_handler();

if (null === $package || json_last_error() !== JSON_ERROR_NONE) {
throw new JsonParsingException(
'Error parsing JSON package data'
. (function_exists('json_last_error_msg') ? ': ' . json_last_error_msg() : '')
);
}

$versions = array_keys($package['package']['versions']);
$versionParser = new VersionParser($versions);
if ($this->getStability() === self::STABLE) {
$this->remoteVersion = $versionParser->getMostRecentStable();
} elseif ($this->getStability() === self::UNSTABLE) {
$this->remoteVersion = $versionParser->getMostRecentUnstable();
} else {
$this->remoteVersion = $versionParser->getMostRecentAll();
}




if (!empty($this->remoteVersion)) {
$this->remoteUrl = $this->getDownloadUrl($package);
}

return $this->remoteVersion;
}







public function getCurrentLocalVersion(Updater $updater)
{
return $this->localVersion;
}






public function setCurrentLocalVersion($version)
{
$this->localVersion = $version;
}






public function setPackageName($name)
{
$this->packageName = $name;
}






public function getPackageName()
{
return $this->packageName;
}






public function setPharName($name)
{
$this->pharName = $name;
}






public function getPharName()
{
return $this->pharName;
}






public function setStability($stability)
{
if ($stability !== self::STABLE && $stability !== self::UNSTABLE && $stability !== self::ANY) {
throw new InvalidArgumentException(
'Invalid stability value. Must be one of "stable", "unstable" or "any".'
);
}
$this->stability = $stability;
}






public function getStability()
{
return $this->stability;
}

protected function getApiUrl()
{
return sprintf(self::API_URL, $this->getPackageName());
}

protected function getDownloadUrl(array $package)
{
$baseUrl = preg_replace(
'{\.git$}',
'',
$package['package']['versions'][$this->remoteVersion]['source']['url']
);
$downloadUrl = sprintf(
'%s/releases/download/%s/%s',
$baseUrl,
$this->remoteVersion,
$this->getPharName()
);
return $downloadUrl;
}
}
<?php











namespace Humbug\SelfUpdate\Strategy;

use Humbug\SelfUpdate\Updater;
use Humbug\SelfUpdate\Exception\HttpRequestException;
use Humbug\SelfUpdate\Exception\InvalidArgumentException;

class ShaStrategy implements StrategyInterface
{




protected $versionUrl;




protected $pharUrl;







public function download(Updater $updater)
{

set_error_handler(array($updater, 'throwHttpRequestException'));
$result = humbug_get_contents($this->getPharUrl());
restore_error_handler();
if (false === $result) {
throw new HttpRequestException(sprintf(
'Request to URL failed: %s', $this->getPharUrl()
));
}

file_put_contents($updater->getTempPharFile(), $result);
}







public function getCurrentRemoteVersion(Updater $updater)
{

set_error_handler(array($updater, 'throwHttpRequestException'));
$version = humbug_get_contents($this->getVersionUrl());
restore_error_handler();
if (false === $version) {
throw new HttpRequestException(sprintf(
'Request to URL failed: %s', $this->getVersionUrl()
));
}
if (empty($version)) {
throw new HttpRequestException(
'Version request returned empty response.'
);
}
if (!preg_match('%^[a-z0-9]{40}%', $version, $matches)) {
throw new HttpRequestException(
'Version request returned incorrectly formatted response.'
);
}

return $matches[0];
}







public function getCurrentLocalVersion(Updater $updater)
{
return sha1_file($updater->getLocalPharFile());
}






public function setPharUrl($url)
{
if (!$this->validateAllowedUrl($url)) {
throw new InvalidArgumentException(
sprintf('Invalid url passed as argument: %s.', $url)
);
}
$this->pharUrl = $url;
}






public function getPharUrl()
{
return $this->pharUrl;
}






public function setVersionUrl($url)
{
if (!$this->validateAllowedUrl($url)) {
throw new InvalidArgumentException(
sprintf('Invalid url passed as argument: %s.', $url)
);
}
$this->versionUrl = $url;
}






public function getVersionUrl()
{
return $this->versionUrl;
}

protected function validateAllowedUrl($url)
{
if (filter_var($url, FILTER_VALIDATE_URL)
&& in_array(parse_url($url, PHP_URL_SCHEME), array('http', 'https', 'file'))) {
return true;
}
return false;
}
}
<?php









namespace Humbug;




class FileGetContents
{

protected $options = array('http' => array());

protected static $lastResponseHeaders;

protected static $nextRequestHeaders;

public function __construct()
{
$this->checkConfig();
$options = $this->getTlsStreamContextDefaults(null);
$this->options = array_replace_recursive($this->options, $options);
}

public function get($filename, $context = null)
{
$context = $this->getStreamContext($filename);
self::setHttpHeaders($context);
$result = file_get_contents($filename, null, $context);
self::setLastResponseHeaders($http_response_header);
return $result;
}

public static function setLastResponseHeaders($headers)
{
self::$lastResponseHeaders = $headers;
}

public static function getLastResponseHeaders()
{
return self::$lastResponseHeaders;
}

public static function setNextRequestHeaders(array $headers)
{
self::$nextRequestHeaders = $headers;
}

public static function hasNextRequestHeaders()
{
return !empty(self::$nextRequestHeaders);
}

public static function getNextRequestHeaders()
{
$return = self::$nextRequestHeaders;
self::$nextRequestHeaders = null;
return $return;
}

public static function setHttpHeaders($context)
{
$headers = self::getNextRequestHeaders();
if (!empty($headers)) {
$options = stream_context_get_options($context);
if (!isset($options['http'])) {
$options['http'] = array('header'=>array());
} elseif (!isset($options['http']['header'])) {
$options['http']['header'] = array();
} elseif (is_string($options['http']['header'])) {
$options['http']['header'] = explode("\r\n", $options['http']['header']);
}
$headers = empty($options['http']['headers']) ? $headers : array_merge($options['http']['headers'], $headers);
stream_context_set_option(
$context,
'http',
'header',
$headers
);
}
return $context;
}

protected function checkConfig()
{ 
if (!extension_loaded('openssl')) {
throw new \RuntimeException(
'The openssl extension is not loaded but is required for secure HTTPS connections'
);
}
}

protected function getStreamContext($url)
{
$host = parse_url($url, PHP_URL_HOST);
if (PHP_VERSION_ID < 50600) {
$this->options['ssl']['CN_match'] = $host;
$this->options['ssl']['SNI_server_name'] = $host;
}
return $this->getMergedStreamContext($url);
}

protected function getTlsStreamContextDefaults($cafile)
{
$ciphers = implode(':', array(
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-ECDSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES256-GCM-SHA384',
'ECDHE-ECDSA-AES256-GCM-SHA384',
'DHE-RSA-AES128-GCM-SHA256',
'DHE-DSS-AES128-GCM-SHA256',
'kEDH+AESGCM',
'ECDHE-RSA-AES128-SHA256',
'ECDHE-ECDSA-AES128-SHA256',
'ECDHE-RSA-AES128-SHA',
'ECDHE-ECDSA-AES128-SHA',
'ECDHE-RSA-AES256-SHA384',
'ECDHE-ECDSA-AES256-SHA384',
'ECDHE-RSA-AES256-SHA',
'ECDHE-ECDSA-AES256-SHA',
'DHE-RSA-AES128-SHA256',
'DHE-RSA-AES128-SHA',
'DHE-DSS-AES128-SHA256',
'DHE-RSA-AES256-SHA256',
'DHE-DSS-AES256-SHA',
'DHE-RSA-AES256-SHA',
'AES128-GCM-SHA256',
'AES256-GCM-SHA384',
'AES128-SHA256',
'AES256-SHA256',
'AES128-SHA',
'AES256-SHA',
'AES',
'CAMELLIA',
'DES-CBC3-SHA',
'!aNULL',
'!eNULL',
'!EXPORT',
'!DES',
'!RC4',
'!MD5',
'!PSK',
'!aECDH',
'!EDH-DSS-DES-CBC3-SHA',
'!EDH-RSA-DES-CBC3-SHA',
'!KRB5-DES-CBC3-SHA',
'!ADH'
));

$options = array(
'ssl' => array(
'ciphers' => $ciphers,
'verify_peer' => true,
'verify_depth' => 7,
'SNI_enabled' => true,
)
);

if (!$cafile) {
$cafile = self::getSystemCaRootBundlePath();
}
if (is_dir($cafile)) {
$options['ssl']['capath'] = $cafile;
} elseif ($cafile) {
$options['ssl']['cafile'] = $cafile;
} else {
throw new \RuntimeException('A valid cafile could not be located locally.');
}

if (version_compare(PHP_VERSION, '5.4.13') >= 0) {
$options['ssl']['disable_compression'] = true;
}

return $options;
}













protected function getMergedStreamContext($url)
{
$options = $this->options;


 if (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy'])) {

 $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
}

if (!empty($proxy)) {
$proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
$proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';

if (isset($proxy['port'])) {
$proxyURL .= ":" . $proxy['port'];
} elseif ('http://' == substr($proxyURL, 0, 7)) {
$proxyURL .= ":80";
} elseif ('https://' == substr($proxyURL, 0, 8)) {
$proxyURL .= ":443";
}


 $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);

if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
}

$options['http'] = array(
'proxy' => $proxyURL,
);


 switch (parse_url($url, PHP_URL_SCHEME)) {
case 'http': 
 $reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) {
$options['http']['request_fulluri'] = true;
}
break;
case 'https': 
 $reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI');
if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) {
$options['http']['request_fulluri'] = true;
}
break;
}


if (isset($proxy['user'])) {
$auth = urldecode($proxy['user']);
if (isset($proxy['pass'])) {
$auth .= ':' . urldecode($proxy['pass']);
}
$auth = base64_encode($auth);

$options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n";
}
}

return stream_context_create($options);
}

































public static function getSystemCaRootBundlePath()
{
static $found = null;
if ($found !== null) {
return $found;
}


 
 $envCertFile = getenv('SSL_CERT_FILE');
if ($envCertFile && is_readable($envCertFile) && self::validateCaFile(file_get_contents($envCertFile))) {

 return $envCertFile;
}

$caBundlePaths = array(
'/etc/pki/tls/certs/ca-bundle.crt', 
 '/etc/ssl/certs/ca-certificates.crt', 
 '/etc/ssl/ca-bundle.pem', 
 '/usr/local/share/certs/ca-root-nss.crt', 
 '/usr/ssl/certs/ca-bundle.crt', 
 '/opt/local/share/curl/curl-ca-bundle.crt', 
 '/usr/local/share/curl/curl-ca-bundle.crt', 
 '/usr/share/ssl/certs/ca-bundle.crt', 
 '/etc/ssl/cert.pem', 
 );

$found = null;
$configured = ini_get('openssl.cafile');
if ($configured && strlen($configured) > 0 && is_readable($caBundle) && self::validateCaFile(file_get_contents($caBundle))) {
$found = true;
$caBundle = $configured;
} else {
foreach ($caBundlePaths as $caBundle) {
if (@is_readable($caBundle) && self::validateCaFile(file_get_contents($caBundle))) {
$found = true;
break;
}
}
if (!$found) {
foreach ($caBundlePaths as $caBundle) {
$caBundle = dirname($caBundle);
if (is_dir($caBundle) && glob($caBundle.'/*')) {
$found = true;
break;
}
}
}
}
if ($found) {
$found = $caBundle;
}
return $found;
}

protected static function validateCaFile($contents) {

 
 if (
PHP_VERSION_ID <= 50327
|| (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50422)
|| (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50506)
) {
return !empty($contents);
}

return (bool) openssl_x509_parse($contents);
}
}
<?php









use Humbug\FileGetContents;

if (!function_exists('humbug_get_contents')) {

function humbug_get_contents($filename, $use_include_path = false, $context = null) {
static $fileGetContents = null;

if ('https' == parse_url($filename, PHP_URL_SCHEME) && PHP_VERSION_ID < 50600) {
if (!isset($fileGetContents)) {
$fileGetContents = new FileGetContents;
}
return $fileGetContents->get($filename, $context);
} elseif (FileGetContents::hasNextRequestHeaders()) {
if ($context === null) {
$context = stream_context_create();
}
$context = FileGetContents::setHttpHeaders($context);
}
$return = file_get_contents($filename, $use_include_path, $context);
if (isset($http_response_header)) {
FileGetContents::setLastResponseHeaders($http_response_header);
}
return $return;
}

}

if (!function_exists('humbug_get_headers')) {

function humbug_get_headers() {
return FileGetContents::getLastResponseHeaders();
}

}

if (!function_exists('humbug_set_headers')) {

function humbug_set_headers(array $headers) {
return FileGetContents::setNextRequestHeaders($headers);
}

}<?php

namespace spec\Http\Promise;

use Http\Promise\Promise;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class FulfilledPromiseSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('result');
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Promise\FulfilledPromise');
}

function it_is_a_promise()
{
$this->shouldImplement('Http\Promise\Promise');
}

function it_returns_a_fulfilled_promise()
{
$promise = $this->then(function ($result) {
return $result;
});

$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Promise\FulfilledPromise');
$promise->getState()->shouldReturn(Promise::FULFILLED);
$promise->wait()->shouldReturn('result');
}

function it_returns_a_rejected_promise()
{
$exception = new \Exception();

$promise = $this->then(function () use ($exception) {
throw $exception;
});

$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Promise\RejectedPromise');
$promise->getState()->shouldReturn(Promise::REJECTED);
$promise->shouldThrow($exception)->duringWait();
}

function it_returns_itself_when_no_on_fulfilled_callback_is_passed()
{
$this->then()->shouldReturn($this);
}

function it_is_in_fulfilled_state()
{
$this->getState()->shouldReturn(Promise::FULFILLED);
}

function it_has_a_result()
{
$this->wait()->shouldReturn('result');
}

function it_does_not_unwrap_a_value()
{
$this->wait(false)->shouldNotReturn('result');
}
}
<?php

namespace spec\Http\Promise;

use Http\Promise\Promise;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class RejectedPromiseSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith(new \Exception());
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Promise\RejectedPromise');
}

function it_is_a_promise()
{
$this->shouldImplement('Http\Promise\Promise');
}

function it_returns_a_fulfilled_promise()
{
$exception = new \Exception();
$this->beConstructedWith($exception);

$promise = $this->then(null, function (\Exception $exceptionReceived) use($exception) {
return 'result';
});

$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Promise\FulfilledPromise');
$promise->getState()->shouldReturn(Promise::FULFILLED);
$promise->wait()->shouldReturn('result');
}

function it_returns_a_rejected_promise()
{
$exception = new \Exception();
$this->beConstructedWith($exception);

$promise = $this->then(null, function (\Exception $exceptionReceived) use($exception) {
if (Argument::is($exceptionReceived)->scoreArgument($exception)) {
throw $exception;
}
});

$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Promise\RejectedPromise');
$promise->getState()->shouldReturn(Promise::REJECTED);
$promise->shouldThrow($exception)->duringWait();
}

function it_returns_itself_when_no_on_rejected_callback_is_passed()
{
$this->then()->shouldReturn($this);
}

function it_is_in_rejected_state()
{
$this->getState()->shouldReturn(Promise::REJECTED);
}

function it_returns_an_exception()
{
$exception = new \Exception();

$this->beConstructedWith($exception);
$this->shouldThrow($exception)->duringWait();
}

function it_does_not_unwrap_a_value()
{
$this->shouldNotThrow('Exception')->duringWait(false);
}
}
<?php

namespace Http\Promise;






final class RejectedPromise implements Promise
{



private $exception;




public function __construct(\Exception $exception)
{
$this->exception = $exception;
}




public function then(callable $onFulfilled = null, callable $onRejected = null)
{
if (null === $onRejected) {
return $this;
}

try {
return new FulfilledPromise($onRejected($this->exception));
} catch (\Exception $e) {
return new self($e);
}
}




public function getState()
{
return Promise::REJECTED;
}




public function wait($unwrap = true)
{
if ($unwrap) {
throw $this->exception;
}
}
}
<?php

namespace Http\Promise;












interface Promise
{



const PENDING = 'pending';




const FULFILLED = 'fulfilled';




const REJECTED = 'rejected';












public function then(callable $onFulfilled = null, callable $onRejected = null);






public function getState();
















public function wait($unwrap = true);
}
<?php

namespace Http\Promise;






final class FulfilledPromise implements Promise
{



private $result;




public function __construct($result)
{
$this->result = $result;
}




public function then(callable $onFulfilled = null, callable $onRejected = null)
{
if (null === $onFulfilled) {
return $this;
}

try {
return new self($onFulfilled($this->result));
} catch (\Exception $e) {
return new RejectedPromise($e);
}
}




public function getState()
{
return Promise::FULFILLED;
}




public function wait($unwrap = true)
{
if ($unwrap) {
return $this->result;
}
}
}
<?php

namespace Http\Adapter\Guzzle6;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Psr\Http\Message\RequestInterface;






class Client implements HttpClient, HttpAsyncClient
{



private $client;




public function __construct(ClientInterface $client = null)
{
if (!$client) {
$client = static::buildClient();
}

$this->client = $client;
}








public static function createWithConfig(array $config)
{
return new self(static::buildClient($config));
}




public function sendRequest(RequestInterface $request)
{
$promise = $this->sendAsyncRequest($request);

return $promise->wait();
}




public function sendAsyncRequest(RequestInterface $request)
{
$promise = $this->client->sendAsync($request);

return new Promise($promise, $request);
}








private static function buildClient(array $config = [])
{
$handlerStack = new HandlerStack(\GuzzleHttp\choose_handler());
$handlerStack->push(Middleware::prepareBody(), 'prepare_body');
$config = array_merge(['handler' => $handlerStack], $config);

return new GuzzleClient($config);
}
}
<?php

namespace Http\Adapter\Guzzle6;

use GuzzleHttp\Exception as GuzzleExceptions;
use GuzzleHttp\Promise\PromiseInterface;
use Http\Client\Exception as HttplugException;
use Http\Promise\Promise as HttpPromise;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;






class Promise implements HttpPromise
{



private $promise;




private $state;




private $response;




private $exception;




private $request;





public function __construct(PromiseInterface $promise, RequestInterface $request)
{
$this->request = $request;
$this->state = self::PENDING;
$this->promise = $promise->then(function ($response) {
$this->response = $response;
$this->state = self::FULFILLED;

return $response;
}, function ($reason) use ($request) {
$this->state = self::REJECTED;

if ($reason instanceof HttplugException) {
$this->exception = $reason;
} elseif ($reason instanceof GuzzleExceptions\GuzzleException) {
$this->exception = $this->handleException($reason, $request);
} elseif ($reason instanceof \Exception) {
$this->exception = new \RuntimeException('Invalid exception returned from Guzzle6', 0, $reason);
} else {
$this->exception = new \UnexpectedValueException('Reason returned from Guzzle6 must be an Exception', 0, $reason);
}

throw $this->exception;
});
}




public function then(callable $onFulfilled = null, callable $onRejected = null)
{
return new static($this->promise->then($onFulfilled, $onRejected), $this->request);
}




public function getState()
{
return $this->state;
}




public function wait($unwrap = true)
{
$this->promise->wait(false);

if ($unwrap) {
if ($this->getState() == self::REJECTED) {
throw $this->exception;
}

return $this->response;
}
}









private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request)
{
if ($exception instanceof GuzzleExceptions\SeekException) {
return new HttplugException\RequestException($exception->getMessage(), $request, $exception);
}

if ($exception instanceof GuzzleExceptions\ConnectException) {
return new HttplugException\NetworkException($exception->getMessage(), $exception->getRequest(), $exception);
}

if ($exception instanceof GuzzleExceptions\RequestException) {

 if ($exception->hasResponse()) {
return new HttplugException\HttpException(
$exception->getMessage(),
$exception->getRequest(),
$exception->getResponse(),
$exception
);
}

return new HttplugException\RequestException($exception->getMessage(), $exception->getRequest(), $exception);
}

return new HttplugException\TransferException($exception->getMessage(), 0, $exception);
}
}
<?php

namespace spec\Http\Client\Promise;

use Http\Client\Exception\TransferException;
use Http\Promise\Promise;
use PhpSpec\ObjectBehavior;
use Psr\Http\Message\ResponseInterface;

class HttpFulfilledPromiseSpec extends ObjectBehavior
{
function let(ResponseInterface $response)
{
$this->beConstructedWith($response);
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Client\Promise\HttpFulfilledPromise');
}

function it_is_a_promise()
{
$this->shouldImplement('Http\Promise\Promise');
}

function it_returns_a_http_fulfilled_promise()
{
$promise = $this->then(function ($result) {
return $result;
});
$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Client\Promise\HttpFulfilledPromise');
$promise->getState()->shouldReturn(Promise::FULFILLED);
$promise->wait()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface');
}

function it_returns_a_http_rejected_promise()
{
$exception = new TransferException();
$promise = $this->then(function () use ($exception) {
throw $exception;
});
$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Client\Promise\HttpRejectedPromise');
$promise->getState()->shouldReturn(Promise::REJECTED);
$promise->shouldThrow($exception)->duringWait();
}

function it_returns_itself_when_no_on_fulfilled_callback_is_passed()
{
$this->then()->shouldReturn($this);
}

function it_is_in_fulfilled_state()
{
$this->getState()->shouldReturn(Promise::FULFILLED);
}

function it_has_a_response()
{
$this->wait()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface');
}

function it_does_not_unwrap_a_response()
{
$this->wait(false)->shouldNotReturnAnInstanceOf('Psr\Http\Message\ResponseInterface');
}

function it_throws_not_http_exception()
{
$this->shouldThrow('Exception')->duringThen(function () {
throw new \Exception();
}, null);
}
}
<?php

namespace spec\Http\Client\Promise;

use Http\Client\Exception;
use Http\Client\Exception\TransferException;
use Http\Promise\Promise;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Psr\Http\Message\ResponseInterface;

class HttpRejectedPromiseSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith(new TransferException());
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Client\Promise\HttpRejectedPromise');
}

function it_is_a_promise()
{
$this->shouldImplement('Http\Promise\Promise');
}

function it_returns_a_fulfilled_promise(ResponseInterface $response)
{
$exception = new TransferException();
$this->beConstructedWith($exception);

$promise = $this->then(null, function (Exception $exceptionReceived) use($exception, $response) {
return $response->getWrappedObject();
});

$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Client\Promise\HttpFulfilledPromise');
$promise->getState()->shouldReturn(Promise::FULFILLED);
$promise->wait()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface');
}

function it_returns_a_rejected_promise()
{
$exception = new TransferException();
$this->beConstructedWith($exception);

$promise = $this->then(null, function (Exception $exceptionReceived) use($exception) {
if (Argument::is($exceptionReceived)->scoreArgument($exception)) {
throw $exception;
}
});

$promise->shouldHaveType('Http\Promise\Promise');
$promise->shouldHaveType('Http\Client\Promise\HttpRejectedPromise');
$promise->getState()->shouldReturn(Promise::REJECTED);
$promise->shouldThrow($exception)->duringWait();
}

function it_returns_itself_when_no_on_rejected_callback_is_passed()
{
$this->then()->shouldReturn($this);
}

function it_is_in_rejected_state()
{
$this->getState()->shouldReturn(Promise::REJECTED);
}

function it_returns_an_exception()
{
$exception = new TransferException();

$this->beConstructedWith($exception);
$this->shouldThrow($exception)->duringWait();
}

function it_does_not_unwrap_a_value()
{
$this->shouldNotThrow('Http\Client\Exception')->duringWait(false);
}

function it_throws_not_http_exception()
{
$this->shouldThrow('Exception')->duringThen(null, function () {
throw new \Exception();
});
}
}
<?php

namespace spec\Http\Client\Exception;

use PhpSpec\ObjectBehavior;

class TransferExceptionSpec extends ObjectBehavior
{
function it_is_a_runtime_exception()
{
$this->shouldHaveType('RuntimeException');
}

function it_is_an_exception()
{
$this->shouldImplement('Http\Client\Exception');
}
}
<?php

namespace spec\Http\Client\Exception;

use Http\Client\Exception\RequestException;
use Psr\Http\Message\RequestInterface;
use PhpSpec\ObjectBehavior;

class RequestExceptionSpec extends ObjectBehavior
{
function let(RequestInterface $request)
{
$this->beConstructedWith('message', $request);
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Client\Exception\RequestException');
}

function it_is_a_transfer_exception()
{
$this->shouldHaveType('Http\Client\Exception\TransferException');
}

function it_has_a_request(RequestInterface $request)
{
$this->getRequest()->shouldReturn($request);
}
}
<?php

namespace spec\Http\Client\Exception;

use Psr\Http\Message\RequestInterface;
use PhpSpec\ObjectBehavior;

class NetworkExceptionSpec extends ObjectBehavior
{
function let(RequestInterface $request)
{
$this->beConstructedWith('message', $request);
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Client\Exception\NetworkException');
}

function it_is_a_request_exception()
{
$this->shouldHaveType('Http\Client\Exception\RequestException');
}
}
<?php

namespace spec\Http\Client\Exception;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use PhpSpec\ObjectBehavior;

class HttpExceptionSpec extends ObjectBehavior
{
function let(RequestInterface $request, ResponseInterface $response)
{
$this->beConstructedWith('message', $request, $response);
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Client\Exception\HttpException');
}

function it_is_a_request_exception()
{
$this->shouldHaveType('Http\Client\Exception\RequestException');
}

function it_has_a_response(ResponseInterface $response)
{
$this->getResponse()->shouldReturn($response);
}

function it_creates_an_http_exception(RequestInterface $request, ResponseInterface $response)
{
$request->getRequestTarget()->willReturn('/uri');
$request->getMethod()->willReturn('GET');
$response->getStatusCode()->willReturn(100);
$response->getReasonPhrase()->willReturn('Continue');

$e = $this->create($request, $response);

$e->shouldHaveType('Http\Client\Exception\HttpException');
$e->getMessage()->shouldReturn('[url] /uri [http method] GET [status code] 100 [reason phrase] Continue');
}
}
<?php

namespace Http\Client;

use Http\Promise\Promise;
use Psr\Http\Message\RequestInterface;






interface HttpAsyncClient
{











public function sendAsyncRequest(RequestInterface $request);
}
<?php

namespace Http\Client\Promise;

use Http\Client\Exception;
use Http\Promise\Promise;
use Psr\Http\Message\ResponseInterface;

final class HttpFulfilledPromise implements Promise
{



private $response;




public function __construct(ResponseInterface $response)
{
$this->response = $response;
}




public function then(callable $onFulfilled = null, callable $onRejected = null)
{
if (null === $onFulfilled) {
return $this;
}

try {
return new self($onFulfilled($this->response));
} catch (Exception $e) {
return new HttpRejectedPromise($e);
}
}




public function getState()
{
return Promise::FULFILLED;
}




public function wait($unwrap = true)
{
if ($unwrap) {
return $this->response;
}
}
}
<?php

namespace Http\Client\Promise;

use Http\Client\Exception;
use Http\Promise\Promise;

final class HttpRejectedPromise implements Promise
{



private $exception;




public function __construct(Exception $exception)
{
$this->exception = $exception;
}




public function then(callable $onFulfilled = null, callable $onRejected = null)
{
if (null === $onRejected) {
return $this;
}

try {
return new HttpFulfilledPromise($onRejected($this->exception));
} catch (Exception $e) {
return new self($e);
}
}




public function getState()
{
return Promise::REJECTED;
}




public function wait($unwrap = true)
{
if ($unwrap) {
throw $this->exception;
}
}
}
<?php

namespace Http\Client;






interface Exception
{
}
<?php

namespace Http\Client;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;








interface HttpClient
{










public function sendRequest(RequestInterface $request);
}
<?php

namespace Http\Client\Exception;

use Psr\Http\Message\RequestInterface;









class RequestException extends TransferException
{



private $request;






public function __construct($message, RequestInterface $request, \Exception $previous = null)
{
$this->request = $request;

parent::__construct($message, 0, $previous);
}






public function getRequest()
{
return $this->request;
}
}
<?php

namespace Http\Client\Exception;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;








class HttpException extends RequestException
{



protected $response;







public function __construct(
$message,
RequestInterface $request,
ResponseInterface $response,
\Exception $previous = null
) {
parent::__construct($message, $request, $previous);

$this->response = $response;
$this->code = $response->getStatusCode();
}






public function getResponse()
{
return $this->response;
}










public static function create(
RequestInterface $request,
ResponseInterface $response,
\Exception $previous = null
) {
$message = sprintf(
'[url] %s [http method] %s [status code] %s [reason phrase] %s',
$request->getRequestTarget(),
$request->getMethod(),
$response->getStatusCode(),
$response->getReasonPhrase()
);

return new self($message, $request, $response, $previous);
}
}
<?php

namespace Http\Client\Exception;

use Http\Client\Exception;






class TransferException extends \RuntimeException implements Exception
{
}
<?php

namespace Http\Client\Exception;








class NetworkException extends RequestException
{
}
<?php



require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit154b92334fcc3e94229a830a701cb9c1::getLoader();
<?php

namespace XdgBaseDir;









class Xdg
{
const S_IFDIR = 040000; 
 const S_IRWXO = 00007; 
 const S_IRWXG = 00056; 
 const RUNTIME_DIR_FALLBACK = 'php-xdg-runtime-dir-fallback-';




public function getHomeDir()
{
return getenv('HOME') ?: (getenv('HOMEDRIVE') . DIRECTORY_SEPARATOR . getenv('HOMEPATH'));
}




public function getHomeConfigDir()
{
$path = getenv('XDG_CONFIG_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.config';

return $path;
}




public function getHomeDataDir()
{
$path = getenv('XDG_DATA_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.local' . DIRECTORY_SEPARATOR . 'share';

return $path;
}




public function getConfigDirs()
{
$configDirs = getenv('XDG_CONFIG_DIRS') ? explode(':', getenv('XDG_CONFIG_DIRS')) : array('/etc/xdg');

$paths = array_merge(array($this->getHomeConfigDir()), $configDirs);

return $paths;
}




public function getDataDirs()
{
$dataDirs = getenv('XDG_DATA_DIRS') ? explode(':', getenv('XDG_DATA_DIRS')) : array('/usr/local/share', '/usr/share');

$paths = array_merge(array($this->getHomeDataDir()), $dataDirs);

return $paths;
}




public function getHomeCacheDir()
{
$path = getenv('XDG_CACHE_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.cache';

return $path;

}

public function getRuntimeDir($strict=true)
{
if ($runtimeDir = getenv('XDG_RUNTIME_DIR')) {
return $runtimeDir;
}

if ($strict) {
throw new \RuntimeException('XDG_RUNTIME_DIR was not set');
}

$fallback = sys_get_temp_dir() . DIRECTORY_SEPARATOR . self::RUNTIME_DIR_FALLBACK . getenv('USER');

$create = false;

if (!is_dir($fallback)) {
mkdir($fallback, 0700, true);
}

$st = lstat($fallback);


 if (!$st['mode'] & self::S_IFDIR) {
rmdir($fallback);
$create = true;
} elseif ($st['uid'] != getmyuid() ||
$st['mode'] & (self::S_IRWXG | self::S_IRWXO)
) {
rmdir($fallback);
$create = true;
}

if ($create) {
mkdir($fallback, 0700, true);
}

return $fallback;
}

}
<?php










if (!function_exists('array_column')) {

















function array_column($input = null, $columnKey = null, $indexKey = null)
{

 
 
 $argc = func_num_args();
$params = func_get_args();

if ($argc < 2) {
trigger_error("array_column() expects at least 2 parameters, {$argc} given", E_USER_WARNING);
return null;
}

if (!is_array($params[0])) {
trigger_error(
'array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given',
E_USER_WARNING
);
return null;
}

if (!is_int($params[1])
&& !is_float($params[1])
&& !is_string($params[1])
&& $params[1] !== null
&& !(is_object($params[1]) && method_exists($params[1], '__toString'))
) {
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
return false;
}

if (isset($params[2])
&& !is_int($params[2])
&& !is_float($params[2])
&& !is_string($params[2])
&& !(is_object($params[2]) && method_exists($params[2], '__toString'))
) {
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
return false;
}

$paramsInput = $params[0];
$paramsColumnKey = ($params[1] !== null) ? (string) $params[1] : null;

$paramsIndexKey = null;
if (isset($params[2])) {
if (is_float($params[2]) || is_int($params[2])) {
$paramsIndexKey = (int) $params[2];
} else {
$paramsIndexKey = (string) $params[2];
}
}

$resultArray = array();

foreach ($paramsInput as $row) {
$key = $value = null;
$keySet = $valueSet = false;

if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
$keySet = true;
$key = (string) $row[$paramsIndexKey];
}

if ($paramsColumnKey === null) {
$valueSet = true;
$value = $row;
} elseif (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
$valueSet = true;
$value = $row[$paramsColumnKey];
}

if ($valueSet) {
if ($keySet) {
$resultArray[$key] = $value;
} else {
$resultArray[] = $value;
}
}

}

return $resultArray;
}

}
<?php








namespace JsonSchema\Uri\Retrievers;






interface UriRetrieverInterface
{






public function retrieve($uri);





public function getContentType();
}<?php








namespace JsonSchema\Uri\Retrievers;

use JsonSchema\Exception\ResourceNotFoundException;
use JsonSchema\Validator;






class FileGetContents extends AbstractRetriever
{
protected $messageBody;





public function retrieve($uri)
{
$context = stream_context_create(array(
'http' => array(
'method' => 'GET',
'header' => "Accept: " . Validator::SCHEMA_MEDIA_TYPE
)));

set_error_handler(function() use ($uri) {
throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
});
$response = file_get_contents($uri);
restore_error_handler();

if (false === $response) {
throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
}
if ($response == ''
&& substr($uri, 0, 7) == 'file://' && substr($uri, -1) == '/'
) {
throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
}

$this->messageBody = $response;
if (! empty($http_response_header)) {
$this->fetchContentType($http_response_header);
} else {

 $this->contentType = null;
}

return $this->messageBody;
}





private function fetchContentType(array $headers)
{
foreach ($headers as $header) {
if ($this->contentType = self::getContentTypeMatchInHeader($header)) {
return true;
}
}

return false;
}





protected static function getContentTypeMatchInHeader($header)
{
if (0 < preg_match("/Content-Type:(\V*)/ims", $header, $match)) {
return trim($match[1]);
}
}
}
<?php




namespace JsonSchema\Uri\Retrievers;






abstract class AbstractRetriever implements UriRetrieverInterface
{




protected $contentType;





public function getContentType()
{
return $this->contentType;
}
}
<?php

namespace JsonSchema\Uri\Retrievers;

use JsonSchema\Validator;













class PredefinedArray extends AbstractRetriever
{




private $schemas;







public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE)
{
$this->schemas = $schemas;
$this->contentType = $contentType;
}





public function retrieve($uri)
{
if (!array_key_exists($uri, $this->schemas)) {
throw new \JsonSchema\Exception\ResourceNotFoundException(sprintf(
'The JSON schema "%s" was not found.',
$uri
));
}

return $this->schemas[$uri];
}
}
<?php








namespace JsonSchema\Uri\Retrievers;

use JsonSchema\Validator;






class Curl extends AbstractRetriever
{
protected $messageBody;

public function __construct()
{
if (!function_exists('curl_init')) {
throw new \RuntimeException("cURL not installed");
}
}





public function retrieve($uri)
{
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: ' . Validator::SCHEMA_MEDIA_TYPE));

$response = curl_exec($ch);
if (false === $response) {
throw new \JsonSchema\Exception\ResourceNotFoundException('JSON schema not found');
}

$this->fetchMessageBody($response);
$this->fetchContentType($response);

curl_close($ch);

return $this->messageBody;
}




private function fetchMessageBody($response)
{
preg_match("/(?:\r\n){2}(.*)$/ms", $response, $match);
$this->messageBody = $match[1];
}





protected function fetchContentType($response)
{
if (0 < preg_match("/Content-Type:(\V*)/ims", $response, $match)) {
$this->contentType = trim($match[1]);

return true;
}

return false;
}
}<?php








namespace JsonSchema\Uri;

use JsonSchema\Uri\Retrievers\FileGetContents;
use JsonSchema\Uri\Retrievers\UriRetrieverInterface;
use JsonSchema\Validator;
use JsonSchema\Exception\InvalidSchemaMediaTypeException;
use JsonSchema\Exception\JsonDecodingException;
use JsonSchema\Exception\ResourceNotFoundException;






class UriRetriever
{



protected $uriRetriever = null;





private $schemaCache = array();








public function confirmMediaType($uriRetriever, $uri)
{
$contentType = $uriRetriever->getContentType();

if (is_null($contentType)) {

 return;
}

if (Validator::SCHEMA_MEDIA_TYPE === $contentType) {
return;
}

if (substr($uri, 0, 23) == 'http://json-schema.org/') {

 return true;
}

throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE));
}









public function getUriRetriever()
{
if (is_null($this->uriRetriever)) {
$this->setUriRetriever(new FileGetContents);
}

return $this->uriRetriever;
}














public function resolvePointer($jsonSchema, $uri)
{
$resolver = new UriResolver();
$parsed = $resolver->parse($uri);
if (empty($parsed['fragment'])) {
return $jsonSchema;
}

$path = explode('/', $parsed['fragment']);
while ($path) {
$pathElement = array_shift($path);
if (! empty($pathElement)) {
$pathElement = str_replace('~1', '/', $pathElement);
$pathElement = str_replace('~0', '~', $pathElement);
if (! empty($jsonSchema->$pathElement)) {
$jsonSchema = $jsonSchema->$pathElement;
} else {
throw new ResourceNotFoundException(
'Fragment "' . $parsed['fragment'] . '" not found'
. ' in ' . $uri
);
}

if (! is_object($jsonSchema)) {
throw new ResourceNotFoundException(
'Fragment part "' . $pathElement . '" is no object '
. ' in ' . $uri
);
}
}
}

return $jsonSchema;
}








public function retrieve($uri, $baseUri = null)
{
$resolver = new UriResolver();
$resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri);


 $arParts = $resolver->parse($resolvedUri);
if (isset($arParts['fragment'])) {
unset($arParts['fragment']);
$fetchUri = $resolver->generate($arParts);
}

$jsonSchema = $this->loadSchema($fetchUri);


 $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri);

if ($jsonSchema instanceof \stdClass) {
$jsonSchema->id = $resolvedUri;
}

return $jsonSchema;
}









protected function loadSchema($fetchUri)
{
if (isset($this->schemaCache[$fetchUri])) {
return $this->schemaCache[$fetchUri];
}

$uriRetriever = $this->getUriRetriever();
$contents = $this->uriRetriever->retrieve($fetchUri);
$this->confirmMediaType($uriRetriever, $fetchUri);
$jsonSchema = json_decode($contents);

if (JSON_ERROR_NONE < $error = json_last_error()) {
throw new JsonDecodingException($error);
}

$this->schemaCache[$fetchUri] = $jsonSchema;

return $jsonSchema;
}







public function setUriRetriever(UriRetrieverInterface $uriRetriever)
{
$this->uriRetriever = $uriRetriever;

return $this;
}







public function parse($uri)
{
preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);

$components = array();
if (5 < count($match)) {
$components = array(
'scheme' => $match[2],
'authority' => $match[4],
'path' => $match[5]
);
}

if (7 < count($match)) {
$components['query'] = $match[7];
}

if (9 < count($match)) {
$components['fragment'] = $match[9];
}

return $components;
}







public function generate(array $components)
{
$uri = $components['scheme'] . '://'
. $components['authority']
. $components['path'];

if (array_key_exists('query', $components)) {
$uri .= $components['query'];
}

if (array_key_exists('fragment', $components)) {
$uri .= $components['fragment'];
}

return $uri;
}








public function resolve($uri, $baseUri = null)
{
$components = $this->parse($uri);
$path = $components['path'];

if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) {
return $uri;
}

$baseComponents = $this->parse($baseUri);
$basePath = $baseComponents['path'];

$baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath);

return $this->generate($baseComponents);
}





public function isValid($uri)
{
$components = $this->parse($uri);

return !empty($components);
}
}
<?php








namespace JsonSchema\Uri;

use JsonSchema\Exception\UriResolverException;






class UriResolver
{






public function parse($uri)
{
preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);

$components = array();
if (5 < count($match)) {
$components = array(
'scheme' => $match[2],
'authority' => $match[4],
'path' => $match[5]
);
} 
if (7 < count($match)) {
$components['query'] = $match[7];
}
if (9 < count($match)) {
$components['fragment'] = $match[9];
}

return $components;
}







public function generate(array $components)
{
$uri = $components['scheme'] . '://' 
. $components['authority']
. $components['path'];

if (array_key_exists('query', $components)) {
$uri .= $components['query'];
}
if (array_key_exists('fragment', $components)) {
$uri .= '#' . $components['fragment'];
}

return $uri;
}








public function resolve($uri, $baseUri = null)
{
if ($uri == '') {
return $baseUri;
}

$components = $this->parse($uri);
$path = $components['path'];

if (! empty($components['scheme'])) {
return $uri;
}
$baseComponents = $this->parse($baseUri);
$basePath = $baseComponents['path'];

$baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath);
if (isset($components['fragment'])) {
$baseComponents['fragment'] = $components['fragment'];
}

return $this->generate($baseComponents);
}









public static function combineRelativePathWithBasePath($relativePath, $basePath)
{
$relativePath = self::normalizePath($relativePath);
if ($relativePath == '') {
return $basePath;
}
if ($relativePath{0} == '/') {
return $relativePath;
}

$basePathSegments = explode('/', $basePath);

preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match);
$numLevelUp = strlen($match[0]) /3 + 1;
if ($numLevelUp >= count($basePathSegments)) {
throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath));
}

$basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp);
$path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath);

return implode('/', $basePathSegments) . '/' . $path;
}







private static function normalizePath($path)
{
$path = preg_replace('|((?<!\.)\./)*|', '', $path);
$path = preg_replace('|//|', '/', $path);

return $path;
}





public function isValid($uri)
{
$components = $this->parse($uri);

return !empty($components);
}
}
<?php








namespace JsonSchema;

use JsonSchema\Exception\JsonDecodingException;
use JsonSchema\Uri\Retrievers\UriRetrieverInterface;
use JsonSchema\Uri\UriRetriever;







class RefResolver
{







protected static $depth = 0;





public static $maxDepth = 7;




protected $uriRetriever = null;




protected $rootSchema = null;




public function __construct($retriever = null)
{
$this->uriRetriever = $retriever;
}








public function fetchRef($ref, $sourceUri)
{
$retriever = $this->getUriRetriever();
$jsonSchema = $retriever->retrieve($ref, $sourceUri);
$this->resolve($jsonSchema);

return $jsonSchema;
}







public function getUriRetriever()
{
if (is_null($this->uriRetriever)) {
$this->setUriRetriever(new UriRetriever);
}

return $this->uriRetriever;
}















public function resolve($schema, $sourceUri = null)
{
if (self::$depth > self::$maxDepth) {
self::$depth = 0;
throw new JsonDecodingException(JSON_ERROR_DEPTH);
}
++self::$depth;

if (! is_object($schema)) {
--self::$depth;
return;
}

if (null === $sourceUri && ! empty($schema->id)) {
$sourceUri = $schema->id;
}

if (null === $this->rootSchema) {
$this->rootSchema = $schema;
}


 $this->resolveRef($schema, $sourceUri);


 
 foreach (array('additionalItems', 'additionalProperties', 'extends', 'items') as $propertyName) {
$this->resolveProperty($schema, $propertyName, $sourceUri);
}


 
 
 foreach (array('disallow', 'extends', 'items', 'type', 'allOf', 'anyOf', 'oneOf') as $propertyName) {
$this->resolveArrayOfSchemas($schema, $propertyName, $sourceUri);
}


 foreach (array('dependencies', 'patternProperties', 'properties') as $propertyName) {
$this->resolveObjectOfSchemas($schema, $propertyName, $sourceUri);
}

--self::$depth;
}









public function resolveArrayOfSchemas($schema, $propertyName, $sourceUri)
{
if (! isset($schema->$propertyName) || ! is_array($schema->$propertyName)) {
return;
}

foreach ($schema->$propertyName as $possiblySchema) {
$this->resolve($possiblySchema, $sourceUri);
}
}









public function resolveObjectOfSchemas($schema, $propertyName, $sourceUri)
{
if (! isset($schema->$propertyName) || ! is_object($schema->$propertyName)) {
return;
}

foreach (get_object_vars($schema->$propertyName) as $possiblySchema) {
$this->resolve($possiblySchema, $sourceUri);
}
}









public function resolveProperty($schema, $propertyName, $sourceUri)
{
if (! isset($schema->$propertyName)) {
return;
}

$this->resolve($schema->$propertyName, $sourceUri);
}









public function resolveRef($schema, $sourceUri)
{
$ref = '$ref';

if (empty($schema->$ref)) {
return;
}

$splitRef = explode('#', $schema->$ref, 2);

$refDoc = $splitRef[0];
$refPath = null;
if (count($splitRef) === 2) {
$refPath = explode('/', $splitRef[1]);
array_shift($refPath);
}

if (empty($refDoc) && empty($refPath)) {

 return;
}

if (!empty($refDoc)) {
$refSchema = $this->fetchRef($refDoc, $sourceUri);
} else {
$refSchema = $this->rootSchema;
}

if (null !== $refPath) {
$refSchema = $this->resolveRefSegment($refSchema, $refPath);
}

unset($schema->$ref);


 foreach (get_object_vars($refSchema) as $prop => $value) {
$schema->$prop = $value;
}
}







public function setUriRetriever(UriRetriever $retriever)
{
$this->uriRetriever = $retriever;

return $this;
}

protected function resolveRefSegment($data, $pathParts)
{
foreach ($pathParts as $path) {
$path = strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%'));

if (is_array($data)) {
$data = $data[$path];
} else {
$data = $data->{$path};
}
}

return $data;
}
}
<?php








namespace JsonSchema\Constraints;

use JsonSchema\Exception\InvalidArgumentException;







class SchemaConstraint extends Constraint
{



public function check($element, $schema = null, $path = null, $i = null)
{
if ($schema !== null) {

 $this->checkUndefined($element, $schema, '', '');
} elseif (property_exists($element, $this->inlineSchemaProperty)) {

 $this->checkUndefined($element, $element->{$this->inlineSchemaProperty}, '', '');
} else {
throw new InvalidArgumentException('no schema found to verify against');
}
}
}<?php








namespace JsonSchema\Constraints;







class StringConstraint extends Constraint
{



public function check($element, $schema = null, $path = null, $i = null)
{

 if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) {
$this->addError($path, "Must be at most " . $schema->maxLength . " characters long", 'maxLength', array(
'maxLength' => $schema->maxLength,
));
}


 if (isset($schema->minLength) && $this->strlen($element) < $schema->minLength) {
$this->addError($path, "Must be at least " . $schema->minLength . " characters long", 'minLength', array(
'minLength' => $schema->minLength,
));
}


 if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#', $element)) {
$this->addError($path, "Does not match the regex pattern " . $schema->pattern, 'pattern', array(
'pattern' => $schema->pattern,
));
}

$this->checkFormat($element, $schema, $path, $i);
}

private function strlen($string)
{
if (extension_loaded('mbstring')) {
return mb_strlen($string, mb_detect_encoding($string));
} else {
return strlen($string);
}
}
}
<?php








namespace JsonSchema\Constraints;







class FormatConstraint extends Constraint
{



public function check($element, $schema = null, $path = null, $i = null)
{
if (!isset($schema->format)) {
return;
}

switch ($schema->format) {
case 'date':
if (!$date = $this->validateDateTime($element, 'Y-m-d')) {
$this->addError($path, sprintf('Invalid date %s, expected format YYYY-MM-DD', json_encode($element)), 'format', array('format' => $schema->format,));
}
break;

case 'time':
if (!$this->validateDateTime($element, 'H:i:s')) {
$this->addError($path, sprintf('Invalid time %s, expected format hh:mm:ss', json_encode($element)), 'format', array('format' => $schema->format,));
}
break;

case 'date-time':
if (!$this->validateDateTime($element, 'Y-m-d\TH:i:s\Z') &&
!$this->validateDateTime($element, 'Y-m-d\TH:i:s.u\Z') &&
!$this->validateDateTime($element, 'Y-m-d\TH:i:sP') &&
!$this->validateDateTime($element, 'Y-m-d\TH:i:sO')
) {
$this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format,));
}
break;

case 'utc-millisec':
if (!$this->validateDateTime($element, 'U')) {
$this->addError($path, sprintf('Invalid time %s, expected integer of milliseconds since Epoch', json_encode($element)), 'format', array('format' => $schema->format,));
}
break;

case 'regex':
if (!$this->validateRegex($element)) {
$this->addError($path, 'Invalid regex format ' . $element, 'format', array('format' => $schema->format,));
}
break;

case 'color':
if (!$this->validateColor($element)) {
$this->addError($path, "Invalid color", 'format', array('format' => $schema->format,));
}
break;

case 'style':
if (!$this->validateStyle($element)) {
$this->addError($path, "Invalid style", 'format', array('format' => $schema->format,));
}
break;

case 'phone':
if (!$this->validatePhone($element)) {
$this->addError($path, "Invalid phone number", 'format', array('format' => $schema->format,));
}
break;

case 'uri':
if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
$this->addError($path, "Invalid URL format", 'format', array('format' => $schema->format,));
}
break;

case 'email':
if (null === filter_var($element, FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE)) {
$this->addError($path, "Invalid email", 'format', array('format' => $schema->format,));
}
break;

case 'ip-address':
case 'ipv4':
if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV4)) {
$this->addError($path, "Invalid IP address", 'format', array('format' => $schema->format,));
}
break;

case 'ipv6':
if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV6)) {
$this->addError($path, "Invalid IP address", 'format', array('format' => $schema->format,));
}
break;

case 'host-name':
case 'hostname':
if (!$this->validateHostname($element)) {
$this->addError($path, "Invalid hostname", 'format', array('format' => $schema->format,));
}
break;

default:

 
 
 
 
 
 break;
}
}

protected function validateDateTime($datetime, $format)
{
$dt = \DateTime::createFromFormat($format, $datetime);

if (!$dt) {
return false;
}

if ($datetime === $dt->format($format)) {
return true;
}


 
 
 
 if ((strpos('u', $format) !== -1) && (intval($dt->format('u')) > 0)) {
return true;
}

return false;
}

protected function validateRegex($regex)
{
return false !== @preg_match('/' . $regex . '/', '');
}

protected function validateColor($color)
{
if (in_array(strtolower($color), array('aqua', 'black', 'blue', 'fuchsia',
'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple',
'red', 'silver', 'teal', 'white', 'yellow'))) {
return true;
}

return preg_match('/^#([a-f0-9]{3}|[a-f0-9]{6})$/i', $color);
}

protected function validateStyle($style)
{
$properties = explode(';', rtrim($style, ';'));
$invalidEntries = preg_grep('/^\s*[-a-z]+\s*:\s*.+$/i', $properties, PREG_GREP_INVERT);

return empty($invalidEntries);
}

protected function validatePhone($phone)
{
return preg_match('/^\+?(\(\d{3}\)|\d{3}) \d{3} \d{4}$/', $phone);
}

protected function validateHostname($host)
{
return preg_match('/^[_a-z]+\.([_a-z]+\.?)+$/i', $host);
}
}
<?php








namespace JsonSchema\Constraints;

use JsonSchema\Exception\InvalidArgumentException;
use JsonSchema\Uri\UriResolver;







class UndefinedConstraint extends Constraint
{



public function check($value, $schema = null, $path = null, $i = null)
{
if (is_null($schema)) {
return;
}

if (!is_object($schema)) {
throw new InvalidArgumentException(
'Given schema must be an object in ' . $path
. ' but is a ' . gettype($schema)
);
}

$i = is_null($i) ? "" : $i;
$path = $this->incrementPath($path, $i);


 $this->validateCommonProperties($value, $schema, $path);


 $this->validateOfProperties($value, $schema, $path);


 $this->validateTypes($value, $schema, $path, $i);
}









public function validateTypes($value, $schema = null, $path = null, $i = null)
{

 if (is_array($value)) {
$this->checkArray($value, $schema, $path, $i);
}


 if (is_object($value) && (isset($schema->properties) || isset($schema->patternProperties) || isset($schema->additionalProperties))) {
$this->checkObject(
$value,
isset($schema->properties) ? $schema->properties : null,
$path,
isset($schema->additionalProperties) ? $schema->additionalProperties : null,
isset($schema->patternProperties) ? $schema->patternProperties : null
);
}


 if (is_string($value)) {
$this->checkString($value, $schema, $path, $i);
}


 if (is_numeric($value)) {
$this->checkNumber($value, $schema, $path, $i);
}


 if (isset($schema->enum)) {
$this->checkEnum($value, $schema, $path, $i);
}
}









protected function validateCommonProperties($value, $schema = null, $path = null, $i = "")
{

 if (isset($schema->extends)) {
if (is_string($schema->extends)) {
$schema->extends = $this->validateUri($schema, $schema->extends);
}
if (is_array($schema->extends)) {
foreach ($schema->extends as $extends) {
$this->checkUndefined($value, $extends, $path, $i);
}
} else {
$this->checkUndefined($value, $schema->extends, $path, $i);
}
}


 if (is_object($value)) {
if (!($value instanceof UndefinedConstraint) && isset($schema->required) && is_array($schema->required) ) {

 foreach ($schema->required as $required) {
if (!property_exists($value, $required)) {
$this->addError((!$path) ? $required : "$path.$required", "The property " . $required . " is required", 'required');
}
}
} else if (isset($schema->required) && !is_array($schema->required)) {

 if ( $schema->required && $value instanceof UndefinedConstraint) {
$this->addError($path, "Is missing and it is required", 'required');
}
}
}


 if (!($value instanceof UndefinedConstraint)) {
$this->checkType($value, $schema, $path);
}


 if (isset($schema->disallow)) {
$initErrors = $this->getErrors();

$typeSchema = new \stdClass();
$typeSchema->type = $schema->disallow;
$this->checkType($value, $typeSchema, $path);


 if (count($this->getErrors()) == count($initErrors)) {
$this->addError($path, "Disallowed value was matched", 'disallow');
} else {
$this->errors = $initErrors;
}
}

if (isset($schema->not)) {
$initErrors = $this->getErrors();
$this->checkUndefined($value, $schema->not, $path, $i);


 if (count($this->getErrors()) == count($initErrors)) {
$this->addError($path, "Matched a schema which it should not", 'not');
} else {
$this->errors = $initErrors;
}
}


 if (is_object($value)) {
if (isset($schema->minProperties)) {
if (count(get_object_vars($value)) < $schema->minProperties) {
$this->addError($path, "Must contain a minimum of " . $schema->minProperties . " properties", 'minProperties', array('minProperties' => $schema->minProperties,));
}
}
if (isset($schema->maxProperties)) {
if (count(get_object_vars($value)) > $schema->maxProperties) {
$this->addError($path, "Must contain no more than " . $schema->maxProperties . " properties", 'maxProperties', array('maxProperties' => $schema->maxProperties,));
}
}
}


 if (is_object($value) && isset($schema->dependencies)) {
$this->validateDependencies($value, $schema->dependencies, $path);
}
}









protected function validateOfProperties($value, $schema, $path, $i = "")
{

 if ($value instanceof UndefinedConstraint) {
return;
}

if (isset($schema->allOf)) {
$isValid = true;
foreach ($schema->allOf as $allOf) {
$initErrors = $this->getErrors();
$this->checkUndefined($value, $allOf, $path, $i);
$isValid = $isValid && (count($this->getErrors()) == count($initErrors));
}
if (!$isValid) {
$this->addError($path, "Failed to match all schemas", 'allOf');
}
}

if (isset($schema->anyOf)) {
$isValid = false;
$startErrors = $this->getErrors();
foreach ($schema->anyOf as $anyOf) {
$initErrors = $this->getErrors();
$this->checkUndefined($value, $anyOf, $path, $i);
if ($isValid = (count($this->getErrors()) == count($initErrors))) {
break;
}
}
if (!$isValid) {
$this->addError($path, "Failed to match at least one schema", 'anyOf');
} else {
$this->errors = $startErrors;
}
}

if (isset($schema->oneOf)) {
$allErrors = array();
$matchedSchemas = 0;
$startErrors = $this->getErrors();
foreach ($schema->oneOf as $oneOf) {
$this->errors = array();
$this->checkUndefined($value, $oneOf, $path, $i);
if (count($this->getErrors()) == 0) {
$matchedSchemas++;
}
$allErrors = array_merge($allErrors, array_values($this->getErrors()));
}
if ($matchedSchemas !== 1) {
$this->addErrors(
array_merge(
$allErrors,
array(array(
'property' => $path,
'message' => "Failed to match exactly one schema",
'constraint' => 'oneOf',
),),
$startErrors
)
);
} else {
$this->errors = $startErrors;
}
}
}









protected function validateDependencies($value, $dependencies, $path, $i = "")
{
foreach ($dependencies as $key => $dependency) {
if (property_exists($value, $key)) {
if (is_string($dependency)) {

 if (!property_exists($value, $dependency)) {
$this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies');
}
} else if (is_array($dependency)) {

 foreach ($dependency as $d) {
if (!property_exists($value, $d)) {
$this->addError($path, "$key depends on $d and $d is missing", 'dependencies');
}
}
} else if (is_object($dependency)) {

 $this->checkUndefined($value, $dependency, $path, $i);
}
}
}
}

protected function validateUri($schema, $schemaUri = null)
{
$resolver = new UriResolver();
$retriever = $this->getUriRetriever();

$jsonSchema = null;
if ($resolver->isValid($schemaUri)) {
$schemaId = property_exists($schema, 'id') ? $schema->id : null;
$jsonSchema = $retriever->retrieve($schemaId, $schemaUri);
}

return $jsonSchema;
}
}
<?php








namespace JsonSchema\Constraints;

use JsonSchema\Uri\UriRetriever;







abstract class Constraint implements ConstraintInterface
{
protected $checkMode = self::CHECK_MODE_NORMAL;
protected $uriRetriever;
protected $errors = array();
protected $inlineSchemaProperty = '$schema';

const CHECK_MODE_NORMAL = 1;
const CHECK_MODE_TYPE_CAST = 2;




private $factory;






public function __construct($checkMode = self::CHECK_MODE_NORMAL, UriRetriever $uriRetriever = null, Factory $factory = null)
{
$this->checkMode = $checkMode;
$this->uriRetriever = $uriRetriever;
$this->factory = $factory;
}




public function getUriRetriever()
{
if (is_null($this->uriRetriever))
{
$this->setUriRetriever(new UriRetriever);
}

return $this->uriRetriever;
}




public function getFactory()
{
if (!$this->factory) {
$this->factory = new Factory($this->getUriRetriever());
}

return $this->factory;
}




public function setUriRetriever(UriRetriever $uriRetriever)
{
$this->uriRetriever = $uriRetriever;
}




public function addError($path, $message, $constraint='', array $more=null)
{
$error = array(
'property' => $path,
'message' => $message,
'constraint' => $constraint,
);

if (is_array($more) && count($more) > 0)
{
$error += $more;
}

$this->errors[] = $error;
}




public function addErrors(array $errors)
{
$this->errors = array_merge($this->errors, $errors);
}




public function getErrors()
{
return $this->errors;
}




public function isValid()
{
return !$this->getErrors();
}





public function reset()
{
$this->errors = array();
}









protected function incrementPath($path, $i)
{
if ($path !== '') {
if (is_int($i)) {
$path .= '[' . $i . ']';
} elseif ($i == '') {
$path .= '';
} else {
$path .= '.' . $i;
}
} else {
$path = $i;
}

return $path;
}









protected function checkArray($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('collection');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}










protected function checkObject($value, $schema = null, $path = null, $i = null, $patternProperties = null)
{
$validator = $this->getFactory()->createInstanceFor('object');
$validator->check($value, $schema, $path, $i, $patternProperties);

$this->addErrors($validator->getErrors());
}









protected function checkType($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('type');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}









protected function checkUndefined($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('undefined');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}









protected function checkString($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('string');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}









protected function checkNumber($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('number');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}









protected function checkEnum($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('enum');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}

protected function checkFormat($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('format');
$validator->check($value, $schema, $path, $i);

$this->addErrors($validator->getErrors());
}





protected function retrieveUri($uri)
{
if (null === $this->uriRetriever) {
$this->setUriRetriever(new UriRetriever);
}
$jsonSchema = $this->uriRetriever->retrieve($uri);

 return $jsonSchema;
}
}
<?php








namespace JsonSchema\Constraints;







class EnumConstraint extends Constraint
{



public function check($element, $schema = null, $path = null, $i = null)
{

 if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) {
return;
}

foreach ($schema->enum as $enum) {
$type = gettype($element);
if ($type === gettype($enum)) {
if ($type == "object") {
if ($element == $enum)
return;
} else {
if ($element === $enum)
return;

}
}
}

$this->addError($path, "Does not have a value in the enumeration " . print_r($schema->enum, true), 'enum', array('enum' => $schema->enum,));
}
}
<?php








namespace JsonSchema\Constraints;






interface ConstraintInterface
{





public function getErrors();






public function addErrors(array $errors);









public function addError($path, $message, $constraint='', array $more=null);






public function isValid();










public function check($value, $schema = null, $path = null, $i = null);
}<?php








namespace JsonSchema\Constraints;







class CollectionConstraint extends Constraint
{



public function check($value, $schema = null, $path = null, $i = null)
{

 if (isset($schema->minItems) && count($value) < $schema->minItems) {
$this->addError($path, "There must be a minimum of " . $schema->minItems . " items in the array", 'minItems', array('minItems' => $schema->minItems,));
}


 if (isset($schema->maxItems) && count($value) > $schema->maxItems) {
$this->addError($path, "There must be a maximum of " . $schema->maxItems . " items in the array", 'maxItems', array('maxItems' => $schema->maxItems,));
}


 if (isset($schema->uniqueItems) && $schema->uniqueItems) {
$unique = $value;
if (is_array($value) && count($value)) {
$unique = array_map(function($e) { return var_export($e, true); }, $value);
}
if (count(array_unique($unique)) != count($value)) {
$this->addError($path, "There are no duplicates allowed in the array", 'uniqueItems');
}
}


 if (isset($schema->items)) {
$this->validateItems($value, $schema, $path, $i);
}
}









protected function validateItems($value, $schema = null, $path = null, $i = null)
{
if (is_object($schema->items)) {

 foreach ($value as $k => $v) {
$initErrors = $this->getErrors();


 $this->checkUndefined($v, $schema->items, $path, $k);


 if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) {
$secondErrors = $this->getErrors();
$this->checkUndefined($v, $schema->additionalItems, $path, $k);
}


 if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) {
$this->errors = $secondErrors;
} else if (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) {
$this->errors = $initErrors;
}
}
} else {

 foreach ($value as $k => $v) {
if (array_key_exists($k, $schema->items)) {
$this->checkUndefined($v, $schema->items[$k], $path, $k);
} else {

 if (property_exists($schema, 'additionalItems')) {
if ($schema->additionalItems !== false) {
$this->checkUndefined($v, $schema->additionalItems, $path, $k);
} else {
$this->addError(
$path, 'The item ' . $i . '[' . $k . '] is not defined and the definition does not allow additional items', 'additionalItems', array('additionalItems' => $schema->additionalItems,));
}
} else {

 $this->checkUndefined($v, new \stdClass(), $path, $k);
}
}
}


 if(count($value) > 0) {
for ($k = count($value); $k < count($schema->items); $k++) {
$this->checkUndefined(new UndefinedConstraint(), $schema->items[$k], $path, $k);
}
}
}
}
}
<?php








namespace JsonSchema\Constraints;

use JsonSchema\Exception\InvalidArgumentException;
use UnexpectedValueException as StandardUnexpectedValueException;







class TypeConstraint extends Constraint
{



static $wording = array(
'integer' => 'an integer',
'number' => 'a number',
'boolean' => 'a boolean',
'object' => 'an object',
'array' => 'an array',
'string' => 'a string',
'null' => 'a null',
'any' => NULL, 
 0 => NULL, 
 );




public function check($value = null, $schema = null, $path = null, $i = null)
{
$type = isset($schema->type) ? $schema->type : null;
$isValid = true;

if (is_array($type)) {

 $validatedOneType = false;
$errors = array();
foreach ($type as $tp) {
$validator = new TypeConstraint($this->checkMode);
$subSchema = new \stdClass();
$subSchema->type = $tp;
$validator->check($value, $subSchema, $path, null);
$error = $validator->getErrors();

if (!count($error)) {
$validatedOneType = true;
break;
}

$errors = $error;
}

if (!$validatedOneType) {
$this->addErrors($errors);

return;
}
} elseif (is_object($type)) {
$this->checkUndefined($value, $type, $path);
} else {
$isValid = $this->validateType($value, $type);
}

if ($isValid === false) {
if (!isset(self::$wording[$type])) {
throw new StandardUnexpectedValueException(
sprintf(
"No wording for %s available, expected wordings are: [%s]",
var_export($type, true),
implode(', ', array_filter(self::$wording)))
);
}
$this->addError($path, ucwords(gettype($value)) . " value found, but " . self::$wording[$type] . " is required", 'type');
}
}











protected function validateType($value, $type)
{

 if (!$type) {
return true;
}

if ('integer' === $type) {
return is_int($value);
}

if ('number' === $type) {
return is_numeric($value) && !is_string($value);
}

if ('boolean' === $type) {
return is_bool($value);
}

if ('object' === $type) {
return is_object($value);

 }

if ('array' === $type) {
return is_array($value);
}

if ('string' === $type) {
return is_string($value);
}

if ('email' === $type) {
return is_string($value);
}

if ('null' === $type) {
return is_null($value);
}

if ('any' === $type) {
return true;
}

throw new InvalidArgumentException((is_object($value) ? 'object' : $value) . ' is an invalid type for ' . $type);
}
}
<?php








namespace JsonSchema\Constraints;







class ObjectConstraint extends Constraint
{



function check($element, $definition = null, $path = null, $additionalProp = null, $patternProperties = null)
{
if ($element instanceof UndefinedConstraint) {
return;
}

$matches = array();
if ($patternProperties) {
$matches = $this->validatePatternProperties($element, $path, $patternProperties);
}

if ($definition) {

 $this->validateDefinition($element, $definition, $path);
}


 $this->validateElement($element, $matches, $definition, $path, $additionalProp);
}

public function validatePatternProperties($element, $path, $patternProperties)
{
$try = array('/','#','+','~','%');
$matches = array();
foreach ($patternProperties as $pregex => $schema) {
$delimiter = '/';

 foreach ($try as $delimiter) {
if (strpos($pregex, $delimiter) === false) { 
 break;
}
}


 if (@preg_match($delimiter. $pregex . $delimiter, '') === false) {
$this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array('pregex' => $pregex,));
continue;
}
foreach ($element as $i => $value) {
if (preg_match($delimiter . $pregex . $delimiter, $i)) {
$matches[] = $i;
$this->checkUndefined($value, $schema ? : new \stdClass(), $path, $i);
}
}
}
return $matches;
}










public function validateElement($element, $matches, $objectDefinition = null, $path = null, $additionalProp = null)
{
foreach ($element as $i => $value) {

$property = $this->getProperty($element, $i, new UndefinedConstraint());
$definition = $this->getProperty($objectDefinition, $i);


 if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) {
$this->addError($path, "The property " . $i . " is not defined and the definition does not allow additional properties", 'additionalProp');
}


 if (!in_array($i, $matches) && $additionalProp && !$definition) {
if ($additionalProp === true) {
$this->checkUndefined($value, null, $path, $i);
} else {
$this->checkUndefined($value, $additionalProp, $path, $i);
}
}


 $require = $this->getProperty($definition, 'requires');
if ($require && !$this->getProperty($element, $require)) {
$this->addError($path, "The presence of the property " . $i . " requires that " . $require . " also be present", 'requires');
}

if (!$definition) {

 $this->checkUndefined($value, new \stdClass(), $path, $i);
}
}
}








public function validateDefinition($element, $objectDefinition = null, $path = null)
{
foreach ($objectDefinition as $i => $value) {
$property = $this->getProperty($element, $i, new UndefinedConstraint());
$definition = $this->getProperty($objectDefinition, $i);
$this->checkUndefined($property, $definition, $path, $i);
}
}










protected function getProperty($element, $property, $fallback = null)
{
if (is_array($element) ) {
return array_key_exists($property, $element) ? $element[$property] : $fallback;
} elseif (is_object($element)) {
return property_exists($element, $property) ? $element->$property : $fallback;
}

return $fallback;
}
}
<?php








namespace JsonSchema\Constraints;







class NumberConstraint extends Constraint
{



public function check($element, $schema = null, $path = null, $i = null)
{

 if (isset($schema->exclusiveMinimum)) {
if (isset($schema->minimum)) {
if ($schema->exclusiveMinimum && $element <= $schema->minimum) {
$this->addError($path, "Must have a minimum value of " . $schema->minimum, 'exclusiveMinimum', array('minimum' => $schema->minimum,));
} else if ($element < $schema->minimum) {
$this->addError($path, "Must have a minimum value of " . $schema->minimum, 'minimum', array('minimum' => $schema->minimum,));
}
} else {
$this->addError($path, "Use of exclusiveMinimum requires presence of minimum", 'missingMinimum');
}
} else if (isset($schema->minimum) && $element < $schema->minimum) {
$this->addError($path, "Must have a minimum value of " . $schema->minimum, 'minimum', array('minimum' => $schema->minimum,));
}


 if (isset($schema->exclusiveMaximum)) {
if (isset($schema->maximum)) {
if ($schema->exclusiveMaximum && $element >= $schema->maximum) {
$this->addError($path, "Must have a maximum value of " . $schema->maximum, 'exclusiveMaximum', array('maximum' => $schema->maximum,));
} else if ($element > $schema->maximum) {
$this->addError($path, "Must have a maximum value of " . $schema->maximum, 'maximum', array('maximum' => $schema->maximum,));
}
} else {
$this->addError($path, "Use of exclusiveMaximum requires presence of maximum", 'missingMinimum');
}
} else if (isset($schema->maximum) && $element > $schema->maximum) {
$this->addError($path, "Must have a maximum value of " . $schema->maximum, 'maximum', array('maximum' => $schema->maximum,));
}


 if (isset($schema->divisibleBy) && $this->fmod($element, $schema->divisibleBy) != 0) {
$this->addError($path, "Is not divisible by " . $schema->divisibleBy, 'divisibleBy', array('divisibleBy' => $schema->divisibleBy,));
}


 if (isset($schema->multipleOf) && $this->fmod($element, $schema->multipleOf) != 0) {
$this->addError($path, "Must be a multiple of " . $schema->multipleOf, 'multipleOf', array('multipleOf' => $schema->multipleOf,));
}

$this->checkFormat($element, $schema, $path, $i);
}

private function fmod($number1, $number2)
{
$modulus = fmod($number1, $number2);
$precision = abs(0.0000000001);
$diff = (float)($modulus - $number2);

if (-$precision < $diff && $diff < $precision) {
return 0.0;
}

$decimals1 = mb_strpos($number1, ".") ? mb_strlen($number1) - mb_strpos($number1, ".") - 1 : 0;
$decimals2 = mb_strpos($number2, ".") ? mb_strlen($number2) - mb_strpos($number2, ".") - 1 : 0;

return (float)round($modulus, max($decimals1, $decimals2));
}
}
<?php








namespace JsonSchema\Constraints;

use JsonSchema\Exception\InvalidArgumentException;
use JsonSchema\Uri\UriRetriever;
use JsonSchema\Validator;




class Factory
{



protected $uriRetriever;




protected $constraintMap = array(
'array' => 'JsonSchema\Constraints\CollectionConstraint',
'collection' => 'JsonSchema\Constraints\CollectionConstraint',
'object' => 'JsonSchema\Constraints\ObjectConstraint',
'type' => 'JsonSchema\Constraints\TypeConstraint',
'undefined' => 'JsonSchema\Constraints\UndefinedConstraint',
'string' => 'JsonSchema\Constraints\StringConstraint',
'number' => 'JsonSchema\Constraints\NumberConstraint',
'enum' => 'JsonSchema\Constraints\EnumConstraint',
'format' => 'JsonSchema\Constraints\FormatConstraint',
'schema' => 'JsonSchema\Constraints\SchemaConstraint',
'validator' => 'JsonSchema\Validator',
);




public function __construct(UriRetriever $uriRetriever = null)
{
if (!$uriRetriever) {
$uriRetriever = new UriRetriever();
}

$this->uriRetriever = $uriRetriever;
}




public function getUriRetriever()
{
return $this->uriRetriever;
}






public function setConstraintClass($name, $class)
{

 if (!class_exists($class)) {
throw new InvalidArgumentException('Unknown constraint ' . $name);
}

 if (!in_array('JsonSchema\Constraints\ConstraintInterface', class_implements($class))) {
throw new InvalidArgumentException('Invalid class ' . $name);
}
$this->constraintMap[$name] = $class;
return $this;
}








public function createInstanceFor($constraintName)
{
if (array_key_exists($constraintName, $this->constraintMap)) {
return new $this->constraintMap[$constraintName](Constraint::CHECK_MODE_NORMAL, $this->uriRetriever, $this);
}
throw new InvalidArgumentException('Unknown constraint ' . $constraintName);
}
}
<?php








namespace JsonSchema;

use JsonSchema\Constraints\SchemaConstraint;
use JsonSchema\Constraints\Constraint;








class Validator extends Constraint
{
const SCHEMA_MEDIA_TYPE = 'application/schema+json';








public function check($value, $schema = null, $path = null, $i = null)
{
$validator = $this->getFactory()->createInstanceFor('schema');
$validator->check($value, $schema);

$this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR));
}
}
<?php








namespace JsonSchema\Exception;




class ResourceNotFoundException extends \RuntimeException
{
}<?php








namespace JsonSchema\Exception;




class UriResolverException extends \RuntimeException
{
}<?php








namespace JsonSchema\Exception;




class InvalidSourceUriException extends InvalidArgumentException
{
}
<?php








namespace JsonSchema\Exception;




class InvalidArgumentException extends \InvalidArgumentException
{
}<?php








namespace JsonSchema\Exception;




class InvalidSchemaMediaTypeException extends \RuntimeException
{ 
}<?php








namespace JsonSchema\Exception;




class JsonDecodingException extends \RuntimeException
{
public function __construct($code = JSON_ERROR_NONE, \Exception $previous = null)
{
switch ($code) {
case JSON_ERROR_DEPTH:
$message = 'The maximum stack depth has been exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$message = 'Invalid or malformed JSON';
break;
case JSON_ERROR_CTRL_CHAR:
$message = 'Control character error, possibly incorrectly encoded';
break;
case JSON_ERROR_UTF8:
$message = 'Malformed UTF-8 characters, possibly incorrectly encoded';
break;
case JSON_ERROR_SYNTAX:
$message = 'JSON syntax is malformed';
break;
default:
$message = 'Syntax error';
}
parent::__construct($message, $code, $previous);
}
}<?php

namespace Shopware\PluginInfo;

use Shopware\PluginInfo\Backend\AutoDetect;
use Shopware\PluginInfo\Backend\BackendInterface;

use JsonSchema;
use Shopware\PluginInfo\Exceptions\ConstraintException;
use Shopware\PluginInfo\Exceptions\ValidatorException;

class PluginInfo
{



private $backend;




private $hydrator;




public function __construct(BackendInterface $backend = null)
{
if (!$backend) {
$backend = new AutoDetect();
}

$this->backend = $backend;
$this->hydrator = new PluginInfoHydrator();
}







public function get($plugin)
{
$pluginJson = $this->backend->getPluginInfo($plugin);

$this->validate($pluginJson);

$pluginStruct = $this->hydrator->get($pluginJson);

return new InfoDecorator($pluginStruct);
}







private function validate($json)
{
$retriever = new JsonSchema\Uri\UriRetriever();


 $prefix = strpos(__DIR__, 'phar://') === 0 ? '' : 'file://';

$schema = $retriever->retrieve(
$prefix . __DIR__ . '/../res/plugin-info-schema.json'
);


$validator = new JsonSchema\Validator();
$validator->check(json_decode(json_encode($json)), $schema);

if (!$validator->isValid()) {
$errors = array_map(function($error) {
return $error['property'] . ': ' . $error['message'];
}, $validator->getErrors());
throw new ValidatorException("Json not valid: " . implode(', ', $errors));
}
}
}
<?php

namespace Shopware\PluginInfo;

use Shopware\PluginInfo\Backend\BackendInterface;
use Shopware\PluginInfo\Exceptions\ConstraintException;
use Shopware\PluginInfo\Struct\Info;

class PluginInfoHydrator
{





public function get($pluginData)
{
$struct = new Info();

$struct->label = $this->prepareLabel($pluginData);
$struct->currentVersion= $this->prepareCurrentVersion($pluginData);
$struct->copyright = isset($pluginData['copyright']) ? $pluginData['copyright'] : null;
$struct->link = isset($pluginData['link']) ? $pluginData['link'] : null;
$struct->license = isset($pluginData['license']) ? $pluginData['license'] : null;
$struct->author = isset($pluginData['author']) ? $pluginData['author'] : null;
$struct->changelog = isset($pluginData['changelog']) ? $pluginData['changelog'] : array();
$struct->compatibility = $this->prepareCompatibility($pluginData);

$struct->description = isset($pluginData['description']) ? $pluginData['description'] : array();
$struct->info = isset($pluginData['info']) ? $pluginData['info'] : array();

return $struct;
}

private function prepareCurrentVersion($json)
{
if (!isset($json['currentVersion'])) {
throw new ConstraintException('currentVersion is a required field');
}

return $json['currentVersion'];
}

private function prepareCompatibility($json)
{
$compatibility = isset($json['compatibility']) ? $json['compatibility'] : array();

if (!isset($compatibility['minimumVersion'])) {
$compatibility['minimumVersion'] = '0.0.0';
}

if (!isset($compatibility['maximumVersion'])) {
$compatibility['maximumVersion'] = '99.99.99';
}

if (!isset($compatibility['blacklist'])) {
$compatibility['blacklist'] = array();
}

return $compatibility;
}

private function prepareLabel($json)
{
if (!isset($json['label'])) {
throw new ConstraintException("Field 'label' is required");
}

return $json['label'];
}
}
<?php

namespace Shopware\PluginInfo\Exceptions;







class ValidatorException extends \Exception {};<?php

namespace Shopware\PluginInfo\Exceptions;







class ConstraintException extends \Exception {};<?php

namespace Shopware\PluginInfo\Struct;

class Info
{



public $label;




public $copyright;
public $license;
public $link;
public $author;
public $changelog;
public $compatibility;
public $currentVersion;

public $description;
public $info;
}
<?php

namespace Shopware\PluginInfo;

use Shopware\PluginInfo\Struct\Info;





class InfoDecorator
{



private $info;

public function __construct(Info $info)
{
$this->info = $info;
}





public function getLabel($language = 'en')
{
$label = $this->info->label;

if ($language === null) {
return $label;
}

if (!isset($label[$language])) {
throw new \OutOfRangeException("Label for $language not available");
}

return $label[$language];
}




public function getCopyright()
{
return $this->info->copyright;
}




public function getCompatibility()
{
return $this->info->compatibility;
}





public function getChangelogs($language = null)
{
$changeLogs = $this->info->changelog;

if ($language === null) {
return $changeLogs;
}

if (!isset($changeLogs[$language])) {
throw new \OutOfRangeException("Changelog for $language not available");
}

return $changeLogs[$language];
}






public function getChangelog($version, $language)
{
$changeLogs = $this->getChangelogs($language);

if (!isset($changeLogs[$version])) {
throw new \OutOfRangeException("Changelog for $language and version $version not available");
}

return $changeLogs[$version];
}




public function getCompatibilities()
{
return $this->info->compatibility;
}





public function isCompatibleWith($version)
{
if ($this->getChangelogs() === null) {
return true;
}

$minimum = $this->info->compatibility['minimumVersion'] ? : '0.0.0';
$maximum = $this->info->compatibility['maximumVersion'] ? : '99.99.99';
$blacklist = $this->info->compatibility['blacklist'] ? : array();








return version_compare($version, $minimum, '>=') && version_compare($version, $maximum, '<=') && !in_array(
$version,
$blacklist
);
}




public function getLicense()
{
return $this->info->license;
}

public function getLink()
{
return $this->info->link;
}

public function getAuthor()
{
return $this->info->author;
}

public function getCurrentVersion()
{
return $this->info->currentVersion;
}

public function getInfo($language = null)
{
if ($language == null) {
return $this->info->info;
}

if (!isset($this->info->info[$language])) {
throw new \OutOfRangeException("info for $language not available");
}

return $this->info->info[$language];
}

public function getStoreDescription($language = null)
{
if ($language == null) {
return $this->info->description;
}

if (!isset($this->info->description[$language])) {
throw new \OutOfRangeException("store description for $language not available");
}

return $this->info->description[$language];
}
}
<?php

namespace Shopware\PluginInfo\Backend;







class AutoDetect implements BackendInterface
{





public function getPluginInfo($plugin)
{
switch (true) {
case is_array($plugin);
$backend = new ArrayTestCase();
break;
case is_dir($plugin):
$backend = new Directory();
break;
case is_file($plugin):
$backend = new Zip();
break;
default:
throw new \RuntimeException("Could not automatically detect type of given plugin");
}

return $backend->getPluginInfo($plugin);
}
}<?php

namespace Shopware\PluginInfo\Backend;







class ArrayTestCase implements BackendInterface
{



public function getPluginInfo($plugin)
{
return $plugin['json'];
}
}
<?php

namespace Shopware\PluginInfo\Backend;

interface BackendInterface
{




public function getPluginInfo($plugin);
}
<?php

namespace Shopware\PluginInfo\Backend;








class Zip implements BackendInterface
{




public function getPluginInfo($plugin)
{
$zipArchive = $this->openZipArchive($plugin);

if ($path = $this->searchForPluginJson($zipArchive)) {
$jsonString = $this->getFileFromZip($path, $zipArchive);
return json_decode($jsonString, true);
} elseif ($path = $this->searchForPluginXml($zipArchive)) {
$xmlString = $this->getFileFromZip($path, $zipArchive);
return $this->readXml($xmlString);
} else {
throw new \RuntimeException('Plugin info file not found in zip (plugin.json or plugin.xml)');
}
}





private function openZipArchive($path)
{
$zip = new \ZipArchive();
if ($zip->open($path) !== true) {
throw new \RuntimeException("Could not open zip archive {$path}");
}

return $zip;
}






private function getFileFromZip($filePath, \ZipArchive $zip)
{
return $zip->getFromName($filePath);
}





private function searchForPluginJson(\ZipArchive $zip)
{
$filePath = preg_quote('plugin.json');

$pattern = "#(?P<namespace>Backend|Core|Frontend)/(?P<name>.*)/(?P<file>{$filePath})#i";

for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
if (preg_match($pattern, $filename)) {
return $filename;
}
}

return false;
}





private function searchForPluginXml(\ZipArchive $zip)
{
$filePath = preg_quote('plugin.xml');

$pattern = "#(?P<name>.*)/(?P<file>{$filePath})#i";

for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
if (preg_match($pattern, $filename)) {
return $filename;
}
}

return false;
}





private function readXml($data)
{
$dom = new \DOMDocument();
$dom->loadXML($data);

return $this->parseInfo($dom);
}





private function parseInfo(\DOMDocument $xml)
{
$xpath = new \DOMXPath($xml);

if (false === $entries = $xpath->query('//plugin')) {
return;
}

$entry = $entries[0];
$info = [];

foreach ($this->getChildren($entry, 'label') as $label) {
$lang = ($label->getAttribute('lang')) ? $label->getAttribute('lang') : 'en';
$info['label'][$lang] = $label->nodeValue;
}

foreach ($this->getChildren($entry, 'description') as $description) {
$lang = ($description->getAttribute('lang')) ? $description->getAttribute('lang') : 'en';
$info['description'][$lang] = trim($description->nodeValue);
}

$simpleKeys = ['version', 'license', 'author', 'copyright', 'link'];
foreach ($simpleKeys as $simpleKey) {
if ($names = $this->getChildren($entry, $simpleKey)) {
if ($simpleKey === 'version') {
$info['currentVersion'] = $names[0]->nodeValue;
} else {
$info[$simpleKey] = $names[0]->nodeValue;
}
}
}

foreach ($this->getChildren($entry, 'changelog') as $changelog) {
$version = $changelog->getAttribute('version');

foreach ($this->getChildren($changelog, 'changes') as $changes) {
$lang = ($changes->getAttribute('lang')) ? $changes->getAttribute('lang') : 'en';
$info['changelog'][$lang][$version] = $changes->nodeValue;
}
}

$compatibility = $this->getFirstChild($entry, 'compatibility');
if ($compatibility) {
$info['compatibility'] = [
'minimumVersion' => $compatibility->getAttribute('minVersion'),
'maximumVersion' => $compatibility->getAttribute('maxVersion'),
'blacklist' => $this->getChildrenValues($compatibility, 'blacklist')
];
}

return $info;
}









private function getChildren(\DOMNode $node, $name)
{
$children = array();
foreach ($node->childNodes as $child) {
if ($child instanceof \DOMElement && $child->localName === $name) {
$children[] = $child;
}
}

return $children;
}






private function getFirstChild(\DOMNode $node, $name)
{
if ($children = $this->getChildren($node, $name)) {
return $children[0];
}

return null;
}









private function getChildrenValues(\DOMNode $node, $name)
{
$children = array();
foreach ($node->childNodes as $child) {
if ($child instanceof \DOMElement && $child->localName === $name) {
$children[] = $child->nodeValue;
}
}

return $children;
}
}
<?php

namespace Shopware\PluginInfo\Backend;







class Directory implements BackendInterface
{



public function getPluginInfo($plugin)
{
$path = rtrim($plugin, '/') . '/';

$jsonPath = $path . DIRECTORY_SEPARATOR . 'plugin.json';
if (!file_exists($jsonPath)) {
throw new \RuntimeException("Cannot find $jsonPath");
}

return json_decode(file_get_contents($jsonPath), true);
}
}
<?php
namespace ShopwareCli;

class DirectoryFilterIterator extends \FilterIterator
{



public function accept()
{
return $this->isValidDir($this->current());
}






private function isValidDir(\DirectoryIterator $fileInfo)
{
return
$fileInfo->isDir() &&
!$fileInfo->isDot() &&

 stripos($fileInfo->getBasename(), '.') !== 0;
}
}
<?php

namespace ShopwareCli\Application;

use Symfony\Component\Console\Command\Command;

interface ConsoleAwareExtension
{





public function getConsoleCommands();
}
<?php

namespace ShopwareCli\Application;

use Symfony\Component\DependencyInjection\ContainerBuilder;

interface ContainerAwareExtension
{



public function setContainer(ContainerBuilder $container);
}
<?php

namespace ShopwareCli\Application;

use Composer\Autoload\ClassLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;


















class ExtensionManager
{



protected $extensions;




private $autoLoader;




public function __construct(ClassLoader $autoLoader)
{
$this->autoLoader = $autoLoader;
}







public function discoverExtensions($extensionDirs)
{

 foreach ($extensionDirs as $extensionDir) {

foreach (new \DirectoryIterator($extensionDir) as $vendorPath) {
if (!$this->isValidExtensionDir($vendorPath)) {
continue;
}

$vendorName = $vendorPath->getBasename();
$this->registerExtensionNamespace($vendorPath->getPathname(), "{$vendorName}\\");
$this->discoverVendorFolder($vendorPath->getPathname(), $vendorName);
}
}
}







private function discoverVendorFolder($vendorPath, $vendorName)
{

foreach (new \DirectoryIterator($vendorPath) as $extensionPath) {
if (!$this->isValidExtensionDir($extensionPath) || $extensionPath->getBasename() === 'vendor') {
continue;
}

if (!file_exists($extensionPath->getPathname() . '/Bootstrap.php')) {
throw new \RuntimeException(sprintf('Could not find Bootstrap.php in %s', $extensionPath->getPathname()));
}

$extensionName = $extensionPath->getBasename();
$className = "{$vendorName}\\{$extensionName}\\Bootstrap";
$extensionInstance = $this->bootstrapExtension($className);
$this->setExtension("{$vendorName}\\{$extensionName}", $extensionInstance);
}
}






private function isValidExtensionDir(\DirectoryIterator $vendorPath)
{
return $vendorPath->isDir()
&& !$vendorPath->isDot()
&& stripos($vendorPath->getBasename(), '.') !== 0; 
 }







private function registerExtensionNamespace($path, $namespace)
{
$namespace = rtrim($namespace, '\\') . '\\';
$this->autoLoader->addPsr4($namespace, $path);
}







public function bootstrapExtension($className)
{
$extension = new $className();

return $extension;
}






public function injectContainer(ContainerBuilder $container)
{
foreach ($this->extensions as $extension) {
if ($extension instanceof ContainerAwareExtension) {
$extension->setContainer($container);
}
}
}






public function getExtensions()
{
return $this->extensions;
}







public function getExtension($name)
{
return $this->extensions[$name];
}







public function setExtension($name, $class)
{
$this->extensions[$name] = $class;
}
}
<?php

namespace ShopwareCli\Application;

use ShopwareCli\Command;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class CommandManager
{



private $container;



private $extensionManager;

public function __construct(ExtensionManager $extensionManager, ContainerBuilder $container)
{
$this->extensionManager = $extensionManager;
$this->container = $container;
}






public function getCommands()
{
$commands = array_merge(
$this->getDefaultCommands(),
$this->collectPluginCommands()
);

foreach ($commands as $command) {
if ($command instanceof ContainerAwareInterface) {
$command->setContainer($this->container);
}
}

return $commands;
}






public function collectPluginCommands()
{
$commands = [];

foreach ($this->extensionManager->getExtensions() as $plugin) {
if ($plugin instanceof ConsoleAwareExtension) {
foreach ($plugin->getConsoleCommands() as $command) {
$commands[] = $command;
}
}
}

return $commands;
}




private function getDefaultCommands()
{
return [
new Command\CacheCommand(),
new Command\CacheGetCommand()
];
}
}
<?php

namespace ShopwareCli\Application;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;

class DependencyInjection
{
const DEFAULT_PROCESS_TIMEOUT = 180;




public static function createContainer($rootDir)
{
$container = new ContainerBuilder(
new ParameterBag(['kernel.root_dir' => $rootDir])
);


 $container->setDefinition('autoloader', new Definition('Composer\Autoload\ClassLoader'))->setSynthetic(true);
$container->setDefinition('input_interface', new Definition('Symfony\Component\Console\Input\InputInterface'))->setSynthetic(true);
$container->setDefinition('output_interface', new Definition('Symfony\Component\Console\Input\InputInterface'))->setSynthetic(true);
$container->setDefinition('question_helper', new Definition('Symfony\Component\Console\Helper\QuestionHelper'))->setSynthetic(true);

$container->register('io_service', 'ShopwareCli\Services\IoService')
->addArgument(new Reference('input_interface'))
->addArgument(new Reference('output_interface'))
->addArgument(new Reference('question_helper'));

$container->register('process_executor', 'ShopwareCli\Services\ProcessExecutor')
->addArgument(new Reference('output_interface'))
->addArgument(getenv('SW_TIMEOUT') ?: self::DEFAULT_PROCESS_TIMEOUT);

$container->register('git_identity_environment', 'ShopwareCli\Services\GitIdentityEnvironment')
->addArgument(new Reference('path_provider'))
->addArgument(new Reference('config'));

$container->register('git_util', 'ShopwareCli\Services\GitUtil')
->addArgument(new Reference('output_interface'))
->addArgument(new Reference('git_identity_environment'))
->addArgument(getenv('SW_TIMEOUT') ?: self::DEFAULT_PROCESS_TIMEOUT);

$container->register('utilities', 'ShopwareCli\Utilities')
->addArgument(new Reference('io_service'));

$container->register('xdg', '\XdgBaseDir\Xdg');

$container->register('plugin_info', '\Shopware\PluginInfo\PluginInfo');

$container->register('directory_gateway', 'ShopwareCli\Services\PathProvider\DirectoryGateway\XdgGateway')
->addArgument(new Reference('xdg'));

$container->register('file_downloader', 'ShopwareCli\Services\StreamFileDownloader')
->addArgument(new Reference('io_service'));

$container->register('path_provider', 'ShopwareCli\Services\PathProvider\PathProvider')
->addArgument(new Reference('directory_gateway'));

$container->register('cache', 'ShopwareCli\Cache\File')
->addArgument($container->get('path_provider'));

$container->register('rest_service_factory', 'ShopwareCli\Services\Rest\RestServiceFactory')
->addArgument(new Reference('service_container'));

$container->register('config_file_collector', 'ShopwareCli\ConfigFileCollector')
->addArgument(new Reference('path_provider'));

$container->register('config', 'ShopwareCli\Config')
->addArgument(new Reference('config_file_collector'));

$container->register('extension_manager', 'ShopwareCli\Application\ExtensionManager')
->addArgument(new Reference('autoloader'));

$container->register('command_manager', 'ShopwareCli\Application\CommandManager')
->addArgument(new Reference('extension_manager'))
->addArgument(new Reference('service_container'));

$container->register('openssl_verifier', 'ShopwareCli\Services\OpenSSLVerifier')
->addArgument('%kernel.root_dir%/Resources/public.key');

$container->register('shopware_info', 'ShopwareCli\Services\ShopwareInfo');

return $container;
}
}
<?php

namespace Shopware\AutoUpdate;

use Humbug\SelfUpdate\Updater;
use Shopware\AutoUpdate\Command\RollbackCommand;
use Shopware\AutoUpdate\Command\SelfUpdateCommand;
use ShopwareCli\Application\ConsoleAwareExtension;
use ShopwareCli\Application\ContainerAwareExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;







class Bootstrap implements ConsoleAwareExtension, ContainerAwareExtension
{

protected $container;




public function setContainer(ContainerBuilder $container)
{
$this->container = $container;

if (!$this->isPharFile()) {
return;
}

$this->populateContainer($container);
}





public function getConsoleCommands()
{
if (!$this->isPharFile()) {
return [];
}

if ($this->checkUpdateOnRun()) {
$this->runUpdate();
}

return [
new SelfUpdateCommand($this->container->get('updater')),
new RollbackCommand($this->container->get('updater')),
];
}




private function populateContainer($container)
{
$container->set('updater', $this->createUpdater());
}




private function createUpdater()
{
$config = $this->container->get('config');
$pharUrl = $config['update']['pharUrl'];
$versionUrl = $config['update']['vesionUrl'];
$verifyKey = (bool)$config['update']['verifyPublicKey'];

$updater = new Updater(null, $verifyKey);
$updater->getStrategy()->setPharUrl($pharUrl);
$updater->getStrategy()->setVersionUrl($versionUrl);

return $updater;
}







public function isPharFile()
{
$toolPath = $this->container->get('path_provider')->getCliToolPath();

return strpos($toolPath, 'phar:') !== false ;
}




private function runUpdate()
{
$updater = $this->container->get('updater');

try {
$result = $updater->update();
if (!$result) {
return;
}

$new = $updater->getNewVersion();
$old = $updater->getOldVersion();

exit(sprintf(
"Updated from SHA-1 %s to SHA-1 %s. Please run again\n", $old, $new
));
} catch (\Exception $e) {
echo "\nCheck your connection\n";
exit(1);
}
}




private function checkUpdateOnRun()
{
$config = $this->container->get('config');
if (!isset($config['update']['checkOnStartup'])) {
return false;
}

return $config['update']['checkOnStartup'];
}
}
<?php
namespace Shopware\AutoUpdate\Command;

use Humbug\SelfUpdate\Updater;
use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Services\ShopwareInfo;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class RollbackCommand extends BaseCommand
{



private $updater;

public function __construct(Updater $updater)
{
$this->updater = $updater;
parent::__construct();
}




protected function configure()
{
$this->setName('rollback');
}




protected function execute(InputInterface $input, OutputInterface $output)
{
try {
$result = $this->updater->rollback();
if (!$result) {
$output->writeln('Rollback failed!');
return 1;
}
} catch (\Exception $e) {
$output->writeln($e->getMessage());
$output->writeln('Unable to rollback');
return 1;
}

$output->writeln('Rollback successful');
return 0;
}
}
<?php
namespace Shopware\AutoUpdate\Command;

use Humbug\SelfUpdate\Updater;
use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Services\ShopwareInfo;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class SelfUpdateCommand extends BaseCommand
{



private $updater;

public function __construct(Updater $updater)
{
$this->updater = $updater;
parent::__construct();
}




protected function configure()
{
$this->setName('self-update');
}




protected function execute(InputInterface $input, OutputInterface $output)
{
try {
$result = $this->updater->update();
if (!$result) {
$output->writeln('No update needed.');
return 0;
}

$new = $this->updater->getNewVersion();
$old = $this->updater->getOldVersion();

$output->writeln(sprintf(
'Updated from SHA-1 %s to SHA-1 %s. Please run again', $old, $new
));

return 0;
} catch (\Exception $e) {
$output->writeln('Unable to update. Please check your connection');
$this->printException($output, $e);

return 1;
}
}





protected function printException(OutputInterface $output, \Exception $exception)
{
do {
$output->writeln(sprintf('(%d) %s in %s:%d:', $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
$trace = $exception->getTraceAsString();
$trace = preg_replace('/^/m', '    ', $trace);
$trace = preg_replace("/(\r?\n)/s", PHP_EOL, $trace);
$output->writeln($trace);
} while ($exception = $exception->getPrevious());
}
}
<?php

namespace Shopware\RunCli;

use Shopware\RunCli\Command\RunCliCommand;
use ShopwareCli\Application\ConsoleAwareExtension;

class Bootstrap implements ConsoleAwareExtension
{



public function getConsoleCommands()
{
return [
new RunCliCommand()
];
}
}
<?php
namespace Shopware\RunCli\Command;

use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Services\IoService;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class RunCliCommand extends BaseCommand
{



protected function configure()
{
$this
->setName('run')
->setDescription('Run shopware console commands from shopware subdirectories.')
->addOption(
'shopwarePath',
null,
InputOption::VALUE_OPTIONAL,
'Your shopware path.',
''
)
->addArgument(
'sw-command',
InputArgument::IS_ARRAY,
'arguments for your shopare command'
)
->setHelp(
<<<EOF
The <info>%command.name%</info> command allows you to trigger shopware cli commands from any subdirectory.
EOF
);
;
}




public function execute(InputInterface $input, OutputInterface $output)
{
$shopwarePath = $input->getOption('shopwarePath');
$arguments = implode(' ', $input->getArgument('sw-command'));


$ioService = $this->container->get('io_service');
$shopwarePath = $this->getValidShopwarePath($shopwarePath, $ioService);

system("{$shopwarePath}/bin/console {$arguments}");
}






public function getValidShopwarePath($shopwarePath, IoService $ioService)
{
if (!$shopwarePath) {
$shopwarePath = realpath(getcwd());
}

do {
if ($this->container->get('utilities')->isShopwareInstallation($shopwarePath)) {
return $shopwarePath;
}
} while (($shopwarePath = dirname($shopwarePath)) && $shopwarePath != '/');

return $ioService->askAndValidate(
'Path to your Shopware installation: ',
[$this->container->get('utilities'), 'validateShopwarePath']
);
}
}
<?php

namespace Shopware\DataGenerator\Writer;

use PDO;




class DatabaseWriter implements WriterInterface
{



private $config;




private $data = [];

public function __construct($config, $resourceName)
{
$this->config = $config;
$this->resourceName = $resourceName;
}




public function write($content)
{
if (!is_array($content)) {
$this->data[] = $content;
} else {
$this->data = array_merge($this->data, $content);
}
}




public function flush()
{

$connection = $this->connectToDatabase($this->config);

$connection->beginTransaction();

foreach ($this->data as $query) {
if (!$connection->query($query)) {
$info = implode(',', $connection->errorInfo());
throw new \Exception("Failed to execute $query\n\nCode: $info");
}
}
$this->data = [];

$connection->commit();
}






private function connectToDatabase($config)
{
$connection = new PDO(
'mysql:host='.$config['host'].';dbname='.$config['dbname'], $config['username'], $config['password'],
[
PDO::MYSQL_ATTR_LOCAL_INFILE => true, 
 PDO::ERRMODE_EXCEPTION => 1,
]
);

return $connection;
}




public function getPriority()
{
return -10;
}
}
<?php

namespace Shopware\DataGenerator\Writer;







class BufferedFileWriter implements WriterInterface
{



protected $fileHandle;




protected $buffer = [];




protected $bufferCounter = 0;




protected $fileName;




private $maxBufferSize;





public function __construct($file, $maxBufferSize = 50)
{
$this->fileName = $file;
$this->fileHandle = fopen($file, 'w');
$this->maxBufferSize = $maxBufferSize;
}

public function setWriteBuffer($writeBuffer)
{
$this->maxBufferSize = $writeBuffer;
}

public function getFileName()
{
return $this->fileName;
}




public function write($content)
{
if (!is_array($content)) {
$this->buffer[] = $content;
$this->bufferCounter += 1;
} else {
$this->buffer = array_merge($this->buffer, $content);
$this->bufferCounter += count($content);
}
if ($this->bufferCounter >= $this->maxBufferSize) {
$this->flush();
}
}




public function flush()
{
if (!$this->buffer) {
return;
}

fputs($this->fileHandle, implode("\n", $this->buffer) . "\n");
$this->buffer = [];
$this->bufferCounter = 0;
}




public function getPriority()
{
return 10;
}
}
<?php

namespace Shopware\DataGenerator\Writer;







interface WriterInterface
{



public function flush();







public function write($content);






public function getPriority();
}
<?php

namespace Shopware\DataGenerator\Writer;

use Shopware\DataGenerator\Struct\Config;
use ShopwareCli\Services\IoService;





class WriterManager
{



private $writers = [];




private $defaultWriterType;




private $writerConfig = [];




private $config;




private $displayImportMessage = false;




private $ioService;





public function __construct(
Config $config,
IoService $ioService
) {
$this->config = $config;
$this->ioService = $ioService;
}







public function createWriter($resourceKey, $type = null, $writerType = null)
{
$writerType = $writerType ?: $this->defaultWriterType;

switch ($writerType) {
case 'database':
if ($type == 'sql') {
$writer = new DatabaseWriter($this->writerConfig[$writerType], $resourceKey);
break;
}

default:
$resourcePath = getcwd().'/output/'.$this->config->getOutputName().$resourceKey;
if ($type) {
$resourcePath .= '.'.$type;
}
if ($type == 'sql') {
$this->displayImportMessage = true;
}
$writer = new BufferedFileWriter($resourcePath);
}

$this->writers[] = $writer;

return $writer;
}




public function flushAll()
{
$this->ioService->writeln('Flushing data...');

$compare = function ($a, $b) {
if ($a->getPriority() == $b->getPriority()) {
return 0;
}

return ($a->getPriority() > $b->getPriority()) ? -1 : 1;
};

$writers = $this->writers;
usort($writers, $compare);

foreach ($writers as $writer) {
$writer->flush();
}

if ($this->displayImportMessage == true) {
$this->ioService->writeln('Done. Please import SQLs using something like this:');
$this->ioService->writeln('mysql --local-infile -uroot -proot DATABASE < FILE.sql');
}
}




public function clear()
{
$this->writers = [];
}




public function setDefaultWriterType($defaultWriterType)
{
$this->defaultWriterType = $defaultWriterType;
}





public function setConfig($writerType, $value)
{
$this->writerConfig[$writerType] = $value;
}
}
<?php

namespace Shopware\DataGenerator;

use Faker\Factory;
use Faker\Generator;

class RandomDataProvider
{





protected $faker;

public function __construct()
{
$this->faker = Factory::create();
}




public function setProviderLocale($locale)
{
if ($locale === null) {
$this->faker = Factory::create();
} else {
$this->faker = Factory::create($locale);
}
}




public function getRandomCity()
{
return $this->faker->city;
}




public function getRandomFirstName()
{
return $this->faker->firstName;
}




public function getRandomLastName()
{
return $this->faker->lastName;
}




public function getRandomWord()
{
return $this->faker->word;
}





public function getSentence($wordCount)
{
return $this->faker->sentence(max($wordCount, 1));
}




public function getRandomIpv4()
{
return $this->faker->ipv4;
}
}
<?php

namespace Shopware\DataGenerator\Struct;

class Config
{





protected $numberArticles = 0;

protected $numberCategories = 0;

protected $numberCustomers = 0;

protected $numberOrders = 0;

protected $numberNewsletter = 0;

protected $numberVouchers = 0;

protected $categoriesPerArticle = 0;

protected $articleFilterGroups = 0;

protected $articleFilterOptions = 0;

protected $articleFilterValues = 0;

protected $generatorLocale;






protected $imageDir;




protected $createImages;




protected $thumbnailSizes;






protected $minVariants;






protected $maxVariants;






protected $outputName;







protected $seed;






protected $chunkSize;




public function setNumberArticles($numberArticles)
{
$this->numberArticles = $numberArticles;
}




public function getNumberArticles()
{
return $this->numberArticles;
}




public function setNumberCategories($numberCategories)
{
$this->numberCategories = $numberCategories;
}




public function setNumberCategoriesPerArticle($categoriesPerArticle)
{
$this->categoriesPerArticle = max(1, $categoriesPerArticle);
}




public function getCategoriesPerArticle()
{
return $this->categoriesPerArticle;
}




public function getNumberCategories()
{
return $this->numberCategories;
}




public function setNumberCustomers($numberCustomers)
{
$this->numberCustomers = $numberCustomers;
}




public function getNumberCustomers()
{
return $this->numberCustomers;
}




public function setNumberOrders($numberOrders)
{
$this->numberOrders = $numberOrders;
}




public function getNumberOrders()
{
return $this->numberOrders;
}




public function setNumberNewsletter($numberNewsletter)
{
$this->numberNewsletter = $numberNewsletter;
}




public function getNumberNewsletter()
{
return $this->numberNewsletter;
}




public function setOutputName($outputName)
{
$this->outputName = $outputName;
}




public function setMaxVariants($maxVariants)
{
$this->maxVariants = $maxVariants;
}




public function setMinVariants($minVariants)
{
$this->minVariants = $minVariants;
}




public function getMaxVariants()
{
return $this->maxVariants;
}




public function getMinVariants()
{
return $this->minVariants;
}




public function setThumbnailSizes($thumbnailSizes)
{
if (empty($thumbnailSizes)) {
$this->thumbnailSizes = null;

return;
}
if (is_string($thumbnailSizes)) {
$thumbnailSizes = explode(',', $thumbnailSizes);
}
$this->thumbnailSizes = $thumbnailSizes;
}

public function getThumbnailSizes()
{
return $this->thumbnailSizes;
}




public function getNumberVouchers()
{
return $this->numberVouchers;
}




public function setNumberVouchers($numberVouchers)
{
$this->numberVouchers = $numberVouchers;
}




public function getArticleFilterGroups()
{
return $this->articleFilterGroups;
}




public function setArticleFilterGroups($articleFilterGroups)
{
$this->articleFilterGroups = $articleFilterGroups;
}




public function getArticleFilterOptions()
{
return $this->articleFilterOptions;
}




public function setArticleFilterOptions($articleFilterOptions)
{
$this->articleFilterOptions = $articleFilterOptions;
}




public function getArticleFilterValues()
{
return $this->articleFilterValues;
}




public function setArticleFilterValues($articleFilterValues)
{
$this->articleFilterValues = $articleFilterValues;
}




public function setImageDir($imageDir)
{
$dir = $imageDir . '/' . 'thumbnail';
if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
}
$this->imageDir = $imageDir;
}




public function getImageDir()
{
return $this->imageDir;
}




public function setCreateImages($createImages)
{
$this->createImages = (bool) $createImages;
}




public function getCreateImages()
{
return $this->createImages;
}

public function createOutputDir()
{
$outputDir = getcwd() . '/output';
if (!is_dir($outputDir) && !mkdir($outputDir) && !is_dir($outputDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', 'output'));
}
}




public function setChunkSize($chunkSize)
{
$this->chunkSize = $chunkSize;
}




public function getChunkSize()
{
return $this->chunkSize;
}




public function setSeed($seed)
{
$this->seed = $seed;
}




public function getOutputName()
{
return $this->outputName;
}




public function getSeed()
{
return $this->seed;
}




public function setGeneratorLocale($generatorLocale)
{
$this->generatorLocale = $generatorLocale;
}




public function getGeneratorLocale()
{
return $this->generatorLocale;
}
}
<?php

namespace Shopware\DataGenerator;

use Shopware\DataGenerator\Struct\Config;




class DataGenerator
{





protected $type;





public $generator;




private $resourceLoader;




private $config;






public function __construct(
RandomDataProvider $generator,
ResourceLoader $resourceLoader,
Config $config
) {
$this->generator = $generator;
$this->resourceLoader = $resourceLoader;
$this->config = $config;
}





protected function initSeed($seed)
{
if (!empty($seed)) {
mt_srand($this->config->getSeed());
}
}







public function run()
{
$locale = $this->config->getGeneratorLocale();
if (!empty($locale)) {
$this->generator->setProviderLocale($locale);
}

$this->initSeed($this->config->getSeed());
$this->config->createOutputDir();

$resource = $this->resourceLoader->getResource($this->type);

$resource->generateData();
}




public function setType($type)
{
$this->type = $type;
}
}
<?php

namespace Shopware\DataGenerator;

use ShopwareCli\Application\ConsoleAwareExtension;
use ShopwareCli\Application\ContainerAwareExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class Bootstrap implements ContainerAwareExtension, ConsoleAwareExtension
{
protected $container;

public function setContainer(ContainerBuilder $container)
{
$this->container = $container;

$this->container->register('random_data_provider', '\Shopware\DataGenerator\RandomDataProvider');

$this->container->register('generator_config', '\Shopware\DataGenerator\Struct\Config');

$this->container->register('resource_loader', '\Shopware\DataGenerator\ResourceLoader')
->addArgument(new Reference('service_container'));

$this->container->register('data_generator', '\Shopware\DataGenerator\DataGenerator')
->addArgument(new Reference('random_data_provider'))
->addArgument(new Reference('resource_loader'))
->addArgument(new Reference('generator_config'));

$this->container->register('writer_manager', '\Shopware\DataGenerator\Writer\WriterManager')
->addArgument(new Reference('generator_config'))
->addArgument(new Reference('io_service'));
}






public function getConsoleCommands()
{
return [
new Command\CreateDataCommand(),
];
}
}
<?php

namespace Shopware\DataGenerator;

use Plugin\ShopwarePluginCreator\Generator;
use Shopware\DataGenerator\Resources\BaseResource;
use Symfony\Component\DependencyInjection\Container;

class ResourceLoader
{



private $resources;



private $container;

public function __construct(Container $container)
{
$this->container = $container;
}





public function getResource($type)
{
if (!isset($this->resources[$type])) {
$className = 'Shopware\DataGenerator\Resources\\' . ucfirst($type);
$this->resources[$type] = new $className(
$this->container->get('generator_config'),
$this->container->get('random_data_provider'),
$this->container->get('io_service'),
$this->container->get('writer_manager')
);

if (strtolower($type) == 'orders') {
$this->resources[$type]->setArticleResource($this->getResource('articles'));
}
if (strtolower($type) == 'articles') {
$this->resources[$type]->setCategoryResource($this->getResource('categories'));
}
}

return $this->resources[$type];
}
}
<?php

namespace Shopware\DataGenerator\Services;







class LoadDataInfile
{
protected $mappings = [
's_articles' => [
'id',
'supplierID',
'name',
'description',
'description_long',
'shippingtime',
'datum',
'active',
'taxID',
'pseudosales',
'topseller',
'keywords',
'changetime',
'pricegroupID',
'pricegroupActive',
'filtergroupID',
'laststock',
'crossbundlelook',
'notification',
'template',
'mode',
'main_detail_id',
'available_from',
'available_to',
'configurator_set_id'
],
's_articles_details' => [
'id',
'articleID',
'ordernumber',
'suppliernumber',
'kind',
'additionaltext',
'sales',
'active',
'instock',
'stockmin',
'weight',
'position',
'width',
'height',
'length',
'ean',
'unitID',
'purchasesteps',
'maxpurchase',
'minpurchase',
'purchaseunit',
'referenceunit',
'packunit',
'releasedate',
'shippingfree',
'shippingtime'
],
's_articles_prices' => [
'pricegroup',
'from',
'to',
'articleID',
'articledetailsID',
'price',
'pseudoprice',
'baseprice',
'percent'
],
's_articles_categories' => ['articleID', 'categoryID'],
's_media' => ['id', 'albumID', 'name', 'path', 'type', 'extension', 'created'],
's_articles_img' => ['articleID', 'img', 'main', 'extension', 'media_id'],
's_articles_attributes' => ['articleID', 'articledetailsID'],
's_article_configurator_sets' => ['id', 'name'],
's_article_configurator_option_relations' => ['article_id', 'option_id'],
's_article_configurator_groups' => ['id', 'name', 'description', 'position'],
's_article_configurator_options' => ['id', 'group_id', 'name', 'position'],
's_article_configurator_set_group_relations' => ['set_id', 'group_id'],
's_article_configurator_set_option_relations' => ['set_id', 'option_id'],
's_filter_articles' => ['articleID', 'valueID'],
's_filter' => ['id', 'name', 'position', 'comparable', 'sortmode'],
's_filter_options' => ['id', 'name', 'filterable'],
's_filter_values' => ['id', 'optionID', 'value', 'position'],
's_filter_relations' => ['groupID', 'optionID', 'position'],
's_articles_categories_ro' => ['articleID', 'categoryID', 'parentCategoryID'],
's_user' => [
'id',
'customernumber',
'password',
'email',
'active',
'accountmode',
'confirmationkey',
'paymentID',
'firstlogin',
'lastlogin',
'sessionID',
'newsletter',
'validation',
'affiliate',
'customergroup',
'paymentpreset',
'language',
'subshopID',
'referer',
'pricegroupID',
'internalcomment',
'failedlogins',
'lockeduntil',
'default_billing_address_id',
'default_shipping_address_id',
'salutation',
'firstname',
'lastname',
'birthday'
],
's_user_addresses' => [
'id',
'user_id',
'company',
'department',
'salutation',
'firstname',
'lastname',
'street',
'zipcode',
'city',
'country_id',
'state_id',
'ustid',
'phone',
'additional_address_line1',
'additional_address_line2',
'title',
],
's_user_attributes' => ['userID'],
's_user_billingaddress' => [
'id',
'userID',
'company',
'department',
'salutation',
'firstname',
'lastname',
'street',
'zipcode',
'city',
'phone',
'countryID',
'stateID',
'ustid'
],
's_user_billingaddress_attributes' => ['billingID'],
's_user_shippingaddress' => [
'id',
'userID',
'company',
'department',
'salutation',
'firstname',
'lastname',
'street',
'zipcode',
'city',
'countryID',
'stateID'
],
's_user_shippingaddress_attributes' => ['shippingID'],
's_emarketing_vouchers' => [
'id',
'description',
'vouchercode',
'value',
'minimumcharge',
'valid_from',
'valid_to',
'ordercode',
'modus',
'percental',
'numorder',
'customergroup',
'taxconfig'
],
's_emarketing_vouchers_attributes' => ['voucherID'],
's_emarketing_voucher_codes' => ['voucherID', 'userID', 'code', 'cashed']
];









public function get($tableName, $file)
{
if (!$columns = $this->mappings[$tableName]) {
throw new \RuntimeException("No definition for $tableName");
}

$columns = implode(
', ',
array_map(
function ($column) {
return "`$column`";
},
$columns
)
);

return <<<EOD
LOAD DATA LOCAL INFILE '{$file}' IGNORE INTO TABLE {$tableName}
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\n'
({$columns});
EOD;
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Shopware\DataGenerator\RandomDataProvider;
use Shopware\DataGenerator\Struct\Config;
use Shopware\DataGenerator\Writer\WriterInterface;
use Shopware\DataGenerator\Writer\WriterManager;
use ShopwareCli\Services\IoService;
use Symfony\Component\Console\Helper\ProgressBar;

abstract class BaseResource
{





protected $ids = [];




protected $tables = [];




protected $config;




protected $generator;




protected $ioService;




protected $writerManager;




protected $progressBar;







public function __construct(
Config $config,
RandomDataProvider $generator,
IoService $ioService,
WriterManager $writerManager
) {
$this->config = $config;
$this->generator = $generator;
$this->ioService = $ioService;
$this->writerManager = $writerManager;
}








protected function getUniqueId($type)
{
if (empty($this->ids[$type])) {
$this->ids[$type] = 1;

return 1;
}

$this->ids[$type] += 1;

return $this->ids[$type];
}






public function getIds($field = null)
{
if ($field) {
return $this->ids[$field];
}

return $this->ids;
}




protected function prepareTables()
{
$sql = [
'SET autocommit = 0;',
'SET foreign_key_checks=0;',
'SET unique_checks=0;',
'SET @@session.sql_mode = "";',
];

foreach ($this->tables as $table) {
$sql[] = "TRUNCATE `{$table}`;";
$sql[] = "ALTER TABLE `{$table}` DISABLE KEYS;";
}
$sql[] = 'COMMIT;';

return $sql;
}






protected function enableKeys()
{
$sql = [];

foreach ($this->tables as $table) {
$sql[] = "ALTER TABLE `{$table}` ENABLE KEYS;";
$sql[] = 'SET unique_checks=1;';
}
$sql[] = 'COMMIT;';

return $sql;
}




protected function createProgressBar($number)
{
$this->progressBar = $this->ioService->createProgressBar($number);
$this->progressBar->start();
$this->progressBar->setRedrawFrequency(1000);
}




protected function advanceProgressBar($step = 1)
{
if (!$this->progressBar) {
return;
}

$this->progressBar->advance($step);
}

protected function finishProgressBar()
{
if (!$this->progressBar) {
return;
}

$this->progressBar->finish();
}











abstract public function create(WriterInterface $writer);







final public function generateData()
{
$path = explode('\\', get_class($this));
$writer = $this->writerManager->createWriter(strtolower(array_pop($path)), 'sql');
$writer->write($this->prepareTables());

$this->create($writer);
$this->ioService->writeln('');

$this->writerManager->flushAll();
$writer->write($this->enableKeys());
$this->writerManager->clear();
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Faker\Factory;
use Shopware\DataGenerator\Writer\WriterInterface;

class Orders extends BaseResource
{
private static $devices = [
'desktop',
'mobile',
'tablet'
];




protected $tables = [
's_order',
's_order_details',
's_order_billingaddress',
's_order_billingaddress_attributes',
's_order_shippingaddress',
's_order_shippingaddress_attributes'
];




protected $numberDetails;




private $articleResource;




public function setArticleResource(Articles $articleResource)
{
$this->articleResource = $articleResource;
}




public function create(WriterInterface $writer)
{
$orderCSVWriter = $this->writerManager->createWriter('order', 'csv');

$number = $this->config->getNumberOrders();
$this->createProgressBar($number);

if (!$this->articleResource) {
throw new \RuntimeException('Article resource not available');
}


 $this->ids['ordernumber'] = 1000;


$valueData = [
'orderValues' => [],
'orderDetailValues' => [],
'customerBillingValues' => [],
'customerShippingValues' => [],
'customerBillingAttributeValues' => [],
];

$articleDetails = $this->articleResource->getArticleDetailsFlat();

$totalNumberCustomers = $this->config->getNumberCustomers();
$orderNumbers = [];
$orderDates = [];

for ($orderCounter = 0; $orderCounter < $number; $orderCounter++) {
$faker = Factory::create();

$id = $this->getUniqueId('order');
$orderNumber = $this->getUniqueId('ordernumber');

$orderNumbers[] = $orderNumber;

$currentCustomer = mt_rand(1, $totalNumberCustomers);
$currentCustomerNumber = 20002 + $currentCustomer;

 $numArticles = $id === 1 ? 100 : mt_rand(1, 4);
$totalPrice = $numArticles * 47.90;
$totalPricePreTax = $totalPrice / 1.19;


 $valueData['customerBillingValues'][] = "( {$currentCustomer}, {$id}, '', '', 'mr', $currentCustomerNumber, '{$this->quote($faker->firstName)}', '{$this->quote($faker->lastName)}', '{$this->quote($faker->streetAddress)}', '{$this->quote($faker->postcode)}', '{$this->quote($faker->city)}', '', 2, 0 )";
$valueData['customerShippingValues'][] = "( {$currentCustomer}, {$id}, '', '', 'mr', '{$this->quote($faker->firstName)}', '{$this->quote($faker->lastName)}', '{$this->quote($faker->streetAddress)}', '{$this->quote($faker->postcode)}', '{$this->quote($faker->city)}', 2, 0)";
$valueData['customerBillingAttributeValues'][] = "({$id}, {$id})";

$cleared = mt_rand(9, 21);
$state = mt_rand(0, 8);
$payment = mt_rand(2, 6);
$device = self::$devices[mt_rand(0, count(self::$devices) - 1)];
$date = $faker->dateTimeBetween('-2years', 'now');

$dateFormatted = $date->format('Y-m-d');

if (isset($orderDates[$dateFormatted])) {
$orderDates[$dateFormatted]++;
} else {
$orderDates[$dateFormatted] = 0;
}


$valueData['orderValues'][] = "({$id}, $orderNumber, {$currentCustomer}, {$totalPrice}, {$totalPricePreTax}, 0, 0, '{$date->format('Y-m-d H:i:s')}', {$state}, {$cleared}, {$payment}, '', '', '', '', 1, 0, '', '', '', NULL, '', '1', 9, 'EUR', 1, 1, '217.86.205.141', '{$device}')";

for ($detailCounter = 1; $detailCounter <= $numArticles; $detailCounter++) {
$detailId = $this->getUniqueId('orderDetail');

$articleId = $articleDetails[mt_rand(1, $this->articleResource->getIds('article'))];
$valueData['orderDetailValues'][] = "({$detailId}, {$id}, '{$orderNumber}', '{$articleId}', 'sw-not-real', 47.90, 1, '{$this->generator->getSentence(3)}', 1, 0, 0)";
}
}

$begin = new \DateTime(min(array_keys($orderDates)));
$end = new \DateTime(max(array_keys($orderDates)));

$interval = \DateInterval::createFromDateString('1 day');

foreach (new \DatePeriod($begin, $interval, $end) as $dt) {

$date = $dt->format('Y-m-d');

$ordersOnDate = isset($orderDates[$date]) ? $orderDates[$date] : 10;
$pageImpressions = $ordersOnDate * mt_rand(200, 1500);
$uniqueVisits = $ordersOnDate * mt_rand(1, 50);

$valueData['visitors'][] = "(1, \"{$date}\", {$pageImpressions}, {$uniqueVisits}, \"desktop\")";
}

$writer->write($this->createSQL($valueData));
$orderCSVWriter->write($orderNumbers);

$this->finishProgressBar();
}






private function createSQL($valueData)
{
$sql = [];

$sql[] = '
            INSERT INTO `s_order` (`id`,`ordernumber`, `userID`, `invoice_amount`, `invoice_amount_net`, `invoice_shipping`, `invoice_shipping_net`, `ordertime`, `status`, `cleared`, `paymentID`, `transactionID`, `comment`,  `customercomment`, `internalcomment`, `net`, `taxfree`, `partnerID`, `temporaryID`, `referer`, `cleareddate`, `trackingcode`, `language`, `dispatchID`, `currency`, `currencyFactor`, `subshopID`, `remote_addr`, `deviceType`) VALUES '.implode(
",\n            ",
$valueData['orderValues']
).';';

$sql[] = '
            INSERT INTO `s_order_details` (`id`, `orderID`, `ordernumber`, `articleID`, `articleordernumber`, `price`, `quantity`, `name`, `status`, `shipped`, `shippedgroup`) VALUES
            '.implode(',', $valueData['orderDetailValues']).';';

$sql[] = '
            INSERT INTO `s_order_billingaddress` (`userID`, `orderID`, `company`, `department`, `salutation`, `customernumber`, `firstname`, `lastname`, `street`, `zipcode`, `city`, `phone`, `countryID`, `stateID`) VALUES '.implode(
' , ',
$valueData['customerBillingValues']
).';';
$sql[] = '
            INSERT INTO `s_order_shippingaddress` (`userID`, `orderID`, `company`, `department`, `salutation`, `firstname`, `lastname`, `street`, `zipcode`, `city`, `countryID`, `stateID`) VALUES '.implode(
' , ',
$valueData['customerShippingValues']
).';';

$sql[] = '
            INSERT INTO `s_order_shippingaddress_attributes` (`id`, `shippingID`) VALUES '.implode(
', ',
$valueData['customerBillingAttributeValues']
).';';
$sql[] = '
            INSERT INTO `s_order_billingaddress_attributes` (`id`, `billingID`) VALUES '.implode(
', ',
$valueData['customerBillingAttributeValues']
).';';

$sql[] = '
            INSERT INTO `s_statistics_visitors` (`shopID`, `datum`, `pageimpressions`, `uniquevisits`, `deviceType`) VALUES '.implode(
', ',
$valueData['visitors']
).';';


return $sql;
}





private function quote($string)
{
return str_replace('\'', "\'", $string);
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Shopware\DataGenerator\Writer\WriterInterface;

class Categories extends BaseResource
{



protected $tables = ['s_categories'];






public $categoriesFlat = [];







protected $categoriesSum;




protected $total;









private function buildNestedTree($number, $parentCategory = null, $depth = 0, $leftNeighbour = null)
{
$categoriesOnThisLevel = ($depth === 0) ? 6 : rand(2, 10);
$categoriesPerChild = round($number / $categoriesOnThisLevel);


 
 
 if ($this->categoriesSum > $this->total) {
$categoriesPerChild = 0;
$categoriesOnThisLevel = 1;
}

if ($leftNeighbour) {
$left = $leftNeighbour['right'] + 1;
} elseif ($parentCategory) {
$left = $parentCategory['left'] + 1;
}


 if (!$parentCategory) {
$id = 3;
$thisCategory = [
'id' => 3,
'parent' => 1,
'path' => '',
'name' => 'Deutsch',
'level' => 1,
'position' => 0,
'left' => 2,
'right' => 887,
'children' => [],
];
} else {
if ($categoriesPerChild < 1) {
$id = $this->getUniqueId('finalCats');
} else {
$id = $this->getUniqueId('category');
}
$this->categoriesFlat[$id] = null;

$path = $this->buildPath($parentCategory['id']);
$path = '|' . implode('|', $path) . '|';

$this->categoriesFlat[$id] = [
'id' => $id,
'parent' => $parentCategory['id'],
'path' => $path,
'level' => ($depth + 1),
'left' => $left,
'right' => ($left + 1),
'position' => 0,
'children' => [],
];
$thisCategory = $this->categoriesFlat[$id];
}

if ($categoriesPerChild < 1) {
$this->categoriesFlat[$id] = $thisCategory;

return $thisCategory;
}

$lastChild = null;
for ($c = 0; $c < $categoriesOnThisLevel; ++$c) {
$lastChild = $this->buildNestedTree($categoriesPerChild, $thisCategory, ($depth + 1), $lastChild);
$lastChild['position'] = $c;

 
 }

$thisCategory['right'] = $lastChild['right'] + 1;

$this->categoriesFlat[$id] = $thisCategory;

return $thisCategory;
}








private function buildPath($id)
{
if (!$id) {
return [];
}
$path = [$id];

if (!isset($this->categoriesFlat[$id])) {
return $path;
}

$parent = $this->categoriesFlat[$id];
if (isset($parent['parent'])) {
$path = array_merge($path, $this->buildPath($parent['parent']));
}

return $path;
}






public function getUniqueId($type)
{
++$this->categoriesSum;
if (empty($this->ids[$type])) {
$this->ids[$type] = 1;

return 1;
}

$this->ids[$type] += 1;

return $this->ids[$type];
}




public function create(WriterInterface $writer)
{

 $this->ids['category'] = 3;
$this->ids['finalCats'] = 1000000;

$this->total = $this->config->getNumberCategories();

$this->createProgressBar($this->total);

$this->categoriesFlat[1] = null;
$this->categoriesFlat[3] = null;
$germanCategory = $this->buildNestedTree($this->config->getNumberCategories());

$thisCategory = [
'id' => 1,
'parent' => 'NULL',
'path' => '',
'name' => 'Root',
'level' => 0,
'position' => 0,
'left' => 1,
'right' => $germanCategory['right'] + 1,
'children' => [$germanCategory],
];
$this->categoriesFlat[1] = $thisCategory;

$categoryUrls = $this->writerManager->createWriter('categories', 'csv');

$categoryURLs = [];
$values = [];
foreach ($this->categoriesFlat as $id => $category) {
$this->advanceProgressBar();
$categoryURLs[] = "/cat/index/sCategory/{$category['id']}";

$name = isset($category['name']) ? $category['name'] : $this->generator->getRandomWord();
$values[] = "({$category['id']}, {$category['parent']}, '{$category['path']}', '{$name}', {$id}, 1)";
}

$categoryValues = sprintf(
'INSERT INTO `s_categories` (`id`, `parent`, `path`, `description`, `position`, `active`) VALUES %s ;',
implode(",\n             ", $values)
);

$this->finishProgressBar();

$writer->write($categoryValues);
$categoryUrls->write($categoryURLs);
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Shopware\DataGenerator\Services\LoadDataInfile;
use Shopware\DataGenerator\Writer\WriterInterface;

class Articles extends BaseResource
{
const GROUPS = 500;
const OPTIONS = 10;




protected $tables = [
's_media',
's_articles',
's_articles_img',
's_articles_prices',
's_articles_details',
's_articles_attributes',
's_articles_categories',
's_articles_categories_ro',
's_article_configurator_sets',
's_article_configurator_options',
's_article_configurator_groups',
's_article_configurator_option_relations',
's_article_configurator_set_group_relations',
's_article_configurator_set_option_relations',
's_filter',
's_filter_articles',
's_filter_attributes',
's_filter_options',
's_filter_values',
's_filter_relations',
];




protected $loadDataInfile;




protected $categoryResource;




protected $articleDetailsFlat;

protected $configuratorsGroups = [];




public function getArticleDetailsFlat()
{
return $this->articleDetailsFlat;
}

public function createConfiguratorOptions()
{
for ($group = 0; $group <= self::GROUPS; ++$group) {
$currentGroup = ['id' => $this->getUniqueId(
'conf_group'
), 'name' => 'Configurator Group '.$group, 'position' => $group, $options = []];
for ($option = 0; $option <= self::OPTIONS; ++$option) {
$currentGroup['options'][] = ['id' => $this->getUniqueId(
'conf_option'
), 'name' => 'Option'.$option, 'position' => $option];
}
$this->configuratorsGroups[] = $currentGroup;
}
}






protected function createFilterGroupSQL(WriterInterface $importWriter)
{
$filterGroupValues = [];
$filterOptionValues = [];
$filterValueValues = [];
$filterOptionGroupRelationValues = [];

$filterGroups = $this->config->getArticleFilterGroups();
$filterOptions = $this->config->getArticleFilterOptions();
$filterValues = $this->config->getArticleFilterValues();

for ($groupId = 1; $groupId <= $filterGroups; ++$groupId) {
$filterGroupValues[] = "$groupId, Filtergroup #{$groupId}, {$groupId}, ".rand(0, 1).', '.rand(0, 1);

for ($o = 1; $o <= $filterOptions; ++$o) {
$optionId = $o + ($groupId - 1) * $filterOptions;
$filterOptionValues[] = "$optionId, Option #{$o},  ".rand(0, 1);
$filterOptionGroupRelationValues[] = "$groupId, $optionId, $o";

for ($v = 1; $v <= $filterValues; ++$v) {
$valueId = $v + ($optionId - 1) * $filterValues;
$filterValueValues[] = "$valueId, $optionId, Value #{$valueId}, $valueId";
}
}
}

$filter = $this->writerManager->createWriter('filter', 'csv');
$filterOptions = $this->writerManager->createWriter('filter_options', 'csv');
$filterValues = $this->writerManager->createWriter('filter_values', 'csv');
$filterRelations = $this->writerManager->createWriter('filter_relations', 'csv');

$filter->write($filterGroupValues);
$filterOptions->write($filterOptionValues);
$filterValues->write($filterValueValues);
$filterRelations->write($filterOptionGroupRelationValues);

$importWriter->write($this->loadDataInfile->get('s_filter', $filter->getFileName()));
$importWriter->write($this->loadDataInfile->get('s_filter_options', $filterOptions->getFileName()));
$importWriter->write($this->loadDataInfile->get('s_filter_values', $filterValues->getFileName()));
$importWriter->write($this->loadDataInfile->get('s_filter_relations', $filterRelations->getFileName()));
}








private function createCartesianProduct($arrays)
{
$cartesian = [];
$dims = array_reverse($arrays);

foreach ($dims as $dimName => $dim) {
$buf = [];

foreach ($dim as $val) {
$buf[] = [$dimName => $val];
}

if (!count($cartesian)) {
$cartesian = $buf;
} else {
$tmp = [];
foreach ($buf as $elBuf) {
foreach ($cartesian as $elAp) {
$tmp[] = array_merge($elBuf, $elAp);
}
}
$cartesian = $tmp;
}
}

return $cartesian;
}




public function create(WriterInterface $writer)
{
$this->createConfiguratorOptions();

$number = $this->config->getNumberArticles();
$this->loadDataInfile = new LoadDataInfile();

$urls = $this->writerManager->createWriter('article_urls', 'csv');

$articles = $this->writerManager->createWriter('articles', 'csv');
$details = $this->writerManager->createWriter('articles_details', 'csv');
$prices = $this->writerManager->createWriter('articles_price', 'csv');
$attributes = $this->writerManager->createWriter('articles_attributes', 'csv');
$configuratorSets = $this->writerManager->createWriter('articles_configurator_set', 'csv');
$configuratorGroups = $this->writerManager->createWriter('articles_configurator_group_values', 'csv');
$configuratorOptions = $this->writerManager->createWriter('articles_configurator_option_values', 'csv');
$configuratorSetOptionRelations = $this->writerManager->createWriter(
'articles_configurator_set_option_relation',
'csv'
);
$configuratorSetGroupRelations = $this->writerManager->createWriter(
'articles_configurator_set_group_relation',
'csv'
);
$articleCategories = $this->writerManager->createWriter('articles_categories', 'csv');
$articlesCategoriesRO = $this->writerManager->createWriter('s_articles_categories_ro', 'csv');
$filterArticles = $this->writerManager->createWriter('filter_articles', 'csv');
$articleConfiguratorRelations = $this->writerManager->createWriter(
'article_configurator_option_relations',
'csv'
);

if ($this->config->getNumberOrders() > 0) {
$maxDetails = $this->config->getNumberArticles() * $this->config->getMaxVariants();
$this->articleDetailsFlat = new \SplFixedArray($maxDetails);
}

if (!$this->categoryResource->categoriesFlat) {
throw new \RuntimeException('Category resource not found');
}

$categoriesFlat = $this->categoryResource->categoriesFlat;
$validCategoryIds = array_filter(
array_keys($categoriesFlat),
function ($item) {
return $item >= 1000000;
}
);
$categoriesPerArticle = min(count($validCategoryIds), $this->config->getCategoriesPerArticle());
if (count($validCategoryIds) < $this->config->getCategoriesPerArticle()) {
$this->ioService->writeln(
'<comment>Number of categories per article will be lower than specified</comment>'
);
}

$this->createProgressBar($number);

$images = [];

$priceVariations = $this->generatePriceVariations($number);



foreach ($this->configuratorsGroups as $currentGroup) {
$configuratorGroups->write(
"{$currentGroup['id']}, {$currentGroup['name']},NULL, {$currentGroup['position']}"
);

foreach ($currentGroup['options'] as $currentOption) {
$configuratorOptions->write(
"{$currentOption['id']}, {$currentGroup['id']}, {$currentOption['name']}, {$currentOption['position']}"
);
}
}

for ($articleCounter = 0; $articleCounter < $number; ++$articleCounter) {
$this->advanceProgressBar();
$id = $this->getUniqueId('article');
$createConfigurator = $id === 1 ? 1 : rand(0, 1); 
 
 $numberOfVariants = $createConfigurator === 1 ? rand(
$this->config->getMinVariants(),
$this->config->getMaxVariants()
) : 1;

if ($numberOfVariants == 1) {
$createConfigurator = 0;
}

$createFilter = rand(0, 3);

$urls->write("/detail/index/sArticle/{$id}");


 $articleDetailId = $this->getUniqueId('articleDetail');
$detailIDs = [$articleDetailId];

$configuratorSetId = $createConfigurator === 1 ? $id : 'NULL';


 $numberOfGroups = max(1, $numberOfVariants / self::OPTIONS);


 if ($createConfigurator === 1) {
$numberOfVariants = self::OPTIONS * $numberOfGroups;
}


 
 
 if ($createConfigurator) {
$groups = [];
$options = [];
$configuratorSets->write("{$id}, Test-Configurator-Set Article {$id}");
$randomGroups = array_rand($this->configuratorsGroups, $numberOfGroups);

 if (!is_array($randomGroups)) {
$randomGroups = [$randomGroups];
}


 foreach ($randomGroups as $g) {
$currentGroup = $this->configuratorsGroups[$g];

 $curOptions = array_column($this->configuratorsGroups[$g]['options'], 'id');
$options = array_merge($curOptions, $options);
$groups[$currentGroup['id']] = $curOptions;
}




$allOptions = $this->createCartesianProduct($groups);


 
 foreach (array_keys($groups) as $groupId) {
$configuratorSetGroupRelations->write("{$id}, {$groupId}");
}


 foreach ($options as $optionId) {
$configuratorSetOptionRelations->write("{$id}, {$optionId}");
}
}

shuffle($validCategoryIds);
for ($i = 0; $i < $categoriesPerArticle; ++$i) {
$articleCategories->write("{$id}, {$validCategoryIds[$i]}");

$categoryIds = $this->getCategoryPath($validCategoryIds[$i], $categoriesFlat);
if (empty($categoryIds)) {
continue;
}

$last = $categoryIds[0];
foreach ($categoryIds as $categoryId) {
$articlesCategoriesRO->write("{$id}, {$categoryId}, {$last}");
}
}

if ($this->config->getCreateImages()) {
throw new \Exception('Not implemented, yet');

 for ($i = 1; $i <= $numImagesPerArticle; ++$i) {
$mediaId = $this->getUniqueId('media');
$name = $physicallyCreateEachImage ? $baseName.$id : $baseName;
$images[] = $name;
$mediaValues[] = "({$mediaId}, -1, {$name}, media/image/{$name}.jpg, IMAGE, jpg, 2012-08-15 )";
$main = ($i === 1) ? 1 : 2;
$articlesImgValues[] = "({$id},{$name}, {$main}, jpg, {$mediaId} )";
}
}

$filterOptions = $this->config->getArticleFilterOptions();
$filterValues = $this->config->getArticleFilterValues();


 $filterGroupId = 1;
if ($createFilter === 0) {
$filterGroupId = rand(1, $filterOptions);
for ($option = 1; $option <= $filterOptions; ++$option) {
$optionId = $option * $filterGroupId;
$valueId = rand(1, $filterValues) * $optionId;
$filterArticles->write("{$id}, {$valueId}");
}
}


 
 
 $name = rtrim($this->generator->getSentence(3), '.');
$articles->write(
"{$id}, 2, {$name}, SHORT DESCRIPTION, LONG DESCRIPTION, NULL, 2012-08-15, 1, 1, 20, 0, , 2012-08-30 16:57:00, 1, 0, {$filterGroupId}, 0, 0, 0, , 0, {$articleDetailId}, NULL, NULL, {$configuratorSetId}"
);


 for ($i = 1; $i <= $numberOfVariants; ++$i) {
if ($this->config->getNumberOrders() > 0) {
$this->articleDetailsFlat[$articleDetailId] = "{$id}|sw-{$id}-{$i}|{$articleDetailId}";
}
$kind = $i === 1 ? 1 : 2;

$purchaseUnit = rand(0, 5);
$referenceUnit = rand($purchaseUnit, $purchaseUnit * 4);

$details->write(
"{$articleDetailId}, {$id},sw-{$id}-{$i}, , {$kind}, , 0, 1, 25, 0, 0.000, 0, NULL, NULL, NULL, NULL, 1, NULL, NULL, 1, {$purchaseUnit}, {$referenceUnit}, Flasche(n), 2012-06-13, 0, "
);

$index = rand(0, count($priceVariations) - 1);
$variantPrices = $priceVariations[$index];

foreach ($variantPrices as $price) {
$prices->write(
"EK,{$price['from']},{$price['to']},{$id},{$articleDetailId},{$price['price']}, 0, 0, 0 "
);
$attributes->write("{$id}, {$articleDetailId}");
}


 if ($i < $numberOfVariants) {
$articleDetailId = $this->getUniqueId('articleDetail');
$detailIDs[] = $articleDetailId;
}
}


 if ($createConfigurator) {
foreach ($detailIDs as $detailID) {
$options = array_pop($allOptions);
if (empty($options)) {
continue;
}
foreach ($options as $option) {
$articleConfiguratorRelations->write("{$detailID}, ".$option);
}
}
}
}

if ($this->config->getCreateImages()) {
$this->copyImages(
$this->config->getImageDir(),
$images,
$thumbs = $this->config->getThumbnailSizes(),
$useSmallImage = 1
);
}

$writer->write($this->loadDataInfile->get('s_articles', $articles->getFileName()));
$writer->write($this->loadDataInfile->get('s_articles_details', $details->getFileName()));
$writer->write($this->loadDataInfile->get('s_articles_prices', $prices->getFileName()));

$writer->write($this->loadDataInfile->get('s_articles_categories', $articleCategories->getFileName()));
$writer->write(
$this->loadDataInfile->get('s_articles_categories_ro', $articlesCategoriesRO->getFileName())
);
$writer->write($this->loadDataInfile->get('s_articles_attributes', $attributes->getFileName()));
$writer->write(
$this->loadDataInfile->get('s_article_configurator_sets', $configuratorSets->getFileName())
);
$writer->write(
$this->loadDataInfile->get(
's_article_configurator_option_relations',
$articleConfiguratorRelations->getFileName()
)
);
$writer->write(
$this->loadDataInfile->get('s_article_configurator_groups', $configuratorGroups->getFileName())
);
$writer->write(
$this->loadDataInfile->get('s_article_configurator_options', $configuratorOptions->getFileName())
);
$writer->write(
$this->loadDataInfile->get(
's_article_configurator_set_option_relations',
$configuratorSetOptionRelations->getFileName()
)
);
$writer->write(
$this->loadDataInfile->get(
's_article_configurator_set_group_relations',
$configuratorSetGroupRelations->getFileName()
)
);

$writer->write($this->loadDataInfile->get('s_filter_articles', $filterArticles->getFileName()));

$this->createFilterGroupSQL($writer);

$this->finishProgressBar();
}







private function getCategoryPath($id, $categories)
{
if (!$id) {
return [];
}
if (!isset($categories[$id])) {
return [];
}
if ($id == 1) {
return [];
}

$category = $categories[$id];
$result[] = $id;
if ($category['parent']) {
$parent = $this->getCategoryPath($category['parent'], $categories);
$result = array_merge($result, $parent);
}

return $result;
}









private function copyImages($imageDir, $images, $thumbs, $useSmallImage)
{
$assetsDir = ''; 
 
 $destination = $assetsDir.($useSmallImage ? '/images/beach_small.jpg' : '/images/beach.jpg');
foreach ($images as $imageName) {
$target = $imageDir.'/'.$imageName.'.jpg';
copy($destination, $target);

foreach ($thumbs as $size) {
$target = $imageDir.'/thumbnail/'.$imageName.'_'.$size.'.jpg';
copy($destination, $target);
}
}
}




public function getCategoryResource()
{
return $this->categoryResource;
}




public function setCategoryResource(Categories $categoryResource)
{
$this->categoryResource = $categoryResource;
}




private function generatePriceVariations($number)
{
$count = $number / 5;

$variations = [];

for ($v = 0; $v <= $count; ++$v) {

 $priceCount = rand(1, 5);
$to = 0;


 $price = rand(3, 2000);
for ($i = 1; $i <= $priceCount; ++$i) {
$from = $to + 1;
$to = $from + rand(2, 4);
if ($i == $priceCount) {
$to = 'beliebig';
}
$price = $price * ((100 - rand(10, 40))) / 100;

$variations[$v][] = [
'from' => $from,
'to' => $to,
'price' => $price,
];
}
}

return $variations;
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Shopware\DataGenerator\Services\LoadDataInfile;
use Shopware\DataGenerator\Writer\WriterInterface;

class Vouchers extends BaseResource
{



protected $numberOfIndividualVoucherCodes = 1000;




protected $tables = [
's_emarketing_vouchers',
's_emarketing_vouchers_attributes',
's_emarketing_vouchers_cashed',
's_emarketing_voucher_codes',
];




private $loadDataInfile;




public function create(WriterInterface $writer)
{
$number = $this->config->getNumberVouchers();
$this->loadDataInfile = new LoadDataInfile();

$voucherCsv = $this->writerManager->createWriter('vouchers', 'csv');
$voucherCodeCsv = $this->writerManager->createWriter('voucher_code', 'csv');
$voucherAttributeCsv = $this->writerManager->createWriter('voucher_code', 'csv');

$this->createProgressBar($number);

for ($voucherCounter = 0; $voucherCounter < $number; $voucherCounter++) {
$this->advanceProgressBar();

$id = $this->getUniqueId('voucher');

$isIndividual = $voucherCounter % 2 === 1;
$isPercental = !$voucherCounter % 3;
$numOrder = !$isIndividual; 

$code = 'code'.$id;
if ($isIndividual) {
$code = '';
}
$value = mt_rand(5, 100);

$voucherCsv->write(
"{$id},Voucher #{$id},{$code},{$value},101,\N,\N,VOUCHER{$id},{$isIndividual},{$isPercental},{$numOrder},\N,auto"
);
$voucherAttributeCsv->write("{$id}");

if ($isIndividual) {
for ($i = 0; $i < $this->numberOfIndividualVoucherCodes; $i++) {
$code = "code-{$id}-{$i}";
$voucherCodeCsv->write("{$id},\N,{$code},0");
}
}
}

$writer->write($this->loadDataInfile->get('s_emarketing_vouchers', $voucherCsv->getFileName()));
$writer->write(
$this->loadDataInfile->get('s_emarketing_vouchers_attributes', $voucherAttributeCsv->getFileName())
);
$writer->write($this->loadDataInfile->get('s_emarketing_voucher_codes', $voucherCodeCsv->getFileName()));
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Shopware\DataGenerator\Writer\WriterInterface;

class Newsletter extends BaseResource
{
protected $tables = [
's_campaigns_articles',
's_campaigns_banner',
's_campaigns_containers',
's_campaigns_groups',
's_campaigns_html',
's_campaigns_links',
's_campaigns_logs',
's_campaigns_mailaddresses',
's_campaigns_maildata',
's_campaigns_mailings',
's_campaigns_positions',
's_campaigns_sender',
's_campaigns_templates'
];




public function create(WriterInterface $writer)
{
$number = $this->config->getNumberNewsletter();
$this->createProgressBar($number);

$addressValues = [];
for ($i = 0; $i < $number; $i++) {
$this->advanceProgressBar();
$addressId = $this->getUniqueId('addressId');

$addressValues[] = "({$addressId}, 0, 1, 'newsletter_test_{$addressId}@shopware.de', 0, 0)";
}


 $writer->write(
sprintf(
'INSERT IGNORE INTO `s_campaigns_mailaddresses` (`id`, `customer`, `groupID`, `email`, `lastmailing`, `lastread`) VALUES %s;',
implode(",\n ", $addressValues)
)
);


 $writer->write(
"INSERT IGNORE INTO `s_campaigns_groups` (`id`, `name`) VALUES (1, 'Newsletter-Empfänger');"
);


 $groups = [
['EK' => 0, 'H' => 0],
[1 => 0]
];
$groups = serialize($groups);


 $writer->write(
"INSERT IGNORE INTO `s_campaigns_mailings` (`id`, `datum`, `groups`, `subject`, `sendermail`, `sendername`, `plaintext`,
                `templateID`, `languageID`, `status`, `locked`, `recipients`, `read`, `clicked`, `customergroup`, `publish`)
            VALUES (1, '2013-04-25', '{$groups}', 'Newsletter-Test', 'info@example.com',
                'Newsletter Absender', 0, 1, 1, 0, '2013-04-25 17:45:12', {$this->config->getNumberNewsletter()}, 0, 0, 'EK', 1
            );"
);


 $writer->write(
"INSERT IGNORE INTO `s_campaigns_containers` (`id`, `promotionID`, `type`, `description`, `position`)
            VALUES (1, 1, 'ctText', 'Newsletter-Test', 1);"
);


 $writer->write(
"INSERT IGNORE INTO `s_campaigns_html` (`id`, `parentID`, `headline`, `html`, `image`, `link`, `alignment`)
            VALUES (1, '1', 'Newsletter-Test', '<p>Hallo <strong>Welt</strong></p>', '', '', 'left');"
);


 $writer->write(
"INSERT IGNORE INTO `s_campaigns_sender` (`email`, `name`) VALUES ('info@example.com', 'Newsletter Absender');"
);


 $writer->write(
"INSERT INTO `s_campaigns_templates` (`id`, `path`, `description`) VALUES
            (1, 'index.tpl', 'Standardtemplate'),
            (2, 'indexh.tpl', 'Händler');"
);

$this->finishProgressBar();
}
}
<?php

namespace Shopware\DataGenerator\Resources;

use Faker\Factory;
use Shopware\DataGenerator\Services\LoadDataInfile;
use Shopware\DataGenerator\Writer\WriterInterface;

class Customers extends BaseResource
{



protected $tables = [
's_user',
's_user_attributes',
's_user_addresses',
's_user_billingaddress',
's_user_billingaddress_attributes',
's_user_shippingaddress',
's_user_shippingaddress_attributes'
];





protected $ids = [];




private $loadDataInfile;




public function create(WriterInterface $writer)
{
$this->ids['customerNumber'] = 20002;
$number = $this->config->getNumberCustomers();
$this->loadDataInfile = new LoadDataInfile();

$importCustomers = $this->writerManager->createWriter('customers', 'csv');
$importCustomersAttributes = $this->writerManager->createWriter('customers_attributes', 'csv');
$importCustomersAddresses = $this->writerManager->createWriter('customers_addresses', 'csv');
$importCustomersBilling = $this->writerManager->createWriter('customers_billing', 'csv');
$importCustomersBillingAttributes = $this->writerManager->createWriter('customers_billing_attributes', 'csv');
$importCustomersShipping = $this->writerManager->createWriter('customers_shipping', 'csv');
$importCustomersShippingAttributes = $this->writerManager->createWriter('customers_shipping_attributes', 'csv');


$this->createProgressBar($number);

for ($customerCounter = 0; $customerCounter < $number; $customerCounter++) {
$faker = Factory::create();

$this->advanceProgressBar();

$id = $this->getUniqueId('customer');
$customerNumber = $this->getUniqueId('customerNumber');

$group = $customerCounter % 2 === 1 ? 'EK' : 'H';

$sex = $customerCounter % 2 === 1 ? 'mr' : 'ms';

$birthday = '';

if (rand(1, 4) !== 4) {
$birthday = $faker->dateTimeThisCentury->format('Y-m-d');
}

$importCustomers->write(
"{$id},{$customerNumber},a256a310bc1e5db755fd392c524028a8,{$faker->email},1,0,,5,2013-01-11,2015-01-01 00:00:00,,0,,0,{$group},0,1,1,,\N,,0,\N,{$id},{$id},{$sex},{$faker->firstName},{$faker->lastName}, {$birthday}"
);
$importCustomersAttributes->write("{$id}");
$importCustomersBillingAttributes->write("{$id}");
$importCustomersBillingAttributes->write("{$id}");

$customerAttributeValues[] = "{$id}";
$importCustomersBilling->write(
"{$id}, {$id}, , , {$sex}, {$this->generator->getRandomFirstName()}, {$this->generator->getRandomLastName()}, {$this->generator->getRandomWord()} " . rand(
1,
500
) . "' , " . rand(42000, 50000) . ", {$this->generator->getRandomCity()}, " . rand(
9999,
99999
) . ', 2, 0, '
);
$importCustomersShipping->write(
"{$id}, {$id}, , , {$sex}, {$this->generator->getRandomFirstName()}, {$this->generator->getRandomLastName()}, {$this->generator->getRandomWord()} " . rand(
1,
500
) . "' , " . rand(42000, 50000) . ", {$this->generator->getRandomCity()}, 2, 0"
);

$zip = rand(42000, 50000);
$importCustomersAddresses->write(
"{$id}, {$id}, company, department, mr, {$this->generator->getRandomFirstName()}, {$this->generator->getRandomLastName()}, {$this->generator->getRandomWord()}, {$zip}, {$this->generator->getRandomCity()}, 2, 0, ustid, phone,,,"
);
}

$writer->write($this->loadDataInfile->get('s_user', $importCustomers->getFileName()));
$writer->write(
$this->loadDataInfile->get('s_user_attributes', $importCustomersAttributes->getFileName())
);
$writer->write(
$this->loadDataInfile->get('s_user_addresses', $importCustomersAddresses->getFileName())
);
$writer->write(
$this->loadDataInfile->get('s_user_billingaddress', $importCustomersBilling->getFileName())
);
$writer->write(
$this->loadDataInfile->get('s_user_shippingaddress', $importCustomersShipping->getFileName())
);
$writer->write(
$this->loadDataInfile->get(
's_user_billingaddress_attributes',
$importCustomersBillingAttributes->getFileName()
)
);
$writer->write(
$this->loadDataInfile->get(
's_user_shippingaddress_attributes',
$importCustomersShippingAttributes->getFileName()
)
);

$writer->write('UPDATE s_user SET birthday = NULL WHERE birthday = "0000-00-00 00:00"');
}
}
<?php

namespace Shopware\DataGenerator\Command;

use Shopware\DataGenerator\DataGenerator;
use Shopware\DataGenerator\Struct\Config;
use ShopwareCli\Command\BaseCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class CreateDataCommand extends BaseCommand
{
protected $utilities;
protected $zipDir;

protected function configure()
{
$this
->setName('generate')
->addOption(
'articles',
'a',
InputOption::VALUE_OPTIONAL,
'Number of articles to create',
0
)
->addOption(
'articleFilterGroups',
null,
InputOption::VALUE_OPTIONAL,
'Number article filter option groups to create',
0
)
->addOption(
'articleFilterOptions',
null,
InputOption::VALUE_OPTIONAL,
'Number article filter options to create',
0
)
->addOption(
'articleFilterValues',
null,
InputOption::VALUE_OPTIONAL,
'Number article filter values to create per each filter option',
0
)
->addOption(
'articleMinVariants',
null,
InputOption::VALUE_OPTIONAL,
'minimum number of variants',
0
)
->addOption(
'articleMaxVariants',
null,
InputOption::VALUE_OPTIONAL,
'max number of variants',
0
)
->addOption(
'orders',
'o',
InputOption::VALUE_OPTIONAL,
'Number of orders to create',
0
)
->addOption(
'categories',
'c',
InputOption::VALUE_OPTIONAL,
'Number of categories to create',
0
)
->addOption(
'categoriesPerArticle',
null,
InputOption::VALUE_OPTIONAL,
'Number of categories to assign to each article',
0
)
->addOption(
'newsletter',
'e',
InputOption::VALUE_OPTIONAL,
'Number of newsletter to create',
0
)
->addOption(
'customers',
'u',
InputOption::VALUE_OPTIONAL,
'Number of customers to create',
0
)
->addOption(
'vouchers',
null,
InputOption::VALUE_OPTIONAL,
'Number of vouchers to create',
0
)
->addOption(
'chunk-size',
null,
InputOption::VALUE_OPTIONAL,
'Chunk size',
1000
)
->addOption(
'seed',
's',
InputOption::VALUE_OPTIONAL,
'Random seed',
0
)
->addOption(
'installDir',
null,
InputOption::VALUE_OPTIONAL,
'Your Shopware installation path. If provided, data will be automatically injected into the configured database.',
''
)
->setDescription('Creates fake data for your Shopware installation.

If executed from a Shopware installation, or if \'installDir\' is provided, the data will be automatically written into your Shopware database
Otherwise, data will be exported to individual files in the \'<current dir>\\output\' folder
You need to import wht .sql files in the order in which they are generated (see the command output)

See the command options to know which data types can be generated
Requires \'local-infile=1\' in your MySQL installation.

<comment>WARNING:</comment>
<comment>This command is DESTRUCTIVE, and will replace existing data in your Shopware database. Do not run in production environments</comment>
            ');
}





public function interact(InputInterface $input, OutputInterface $output)
{
$articles = $input->getOption('articles');
$orders = $input->getOption('orders');
$customers = $input->getOption('customers');
$newsletter = $input->getOption('newsletter');
$categories = $input->getOption('categories');
$vouchers = $input->getOption('vouchers');

if ($articles || $orders || $customers || $newsletter || $categories || $vouchers) {
return;
}

$ioService = $this->container->get('io_service');
$ioService->writeln('<info>Please provide the desired number of…</info>');

$this->askConfigOptions($input, 'articles', 'Articles', 10000);
$this->askConfigOptions($input, 'categories', 'Categories', 500);
$this->askConfigOptions($input, 'categoriesPerArticle', 'Categories per article', 3);
$this->askConfigOptions($input, 'articleMinVariants', 'Minimum variants per article', 1);
$this->askConfigOptions($input, 'articleMaxVariants', 'Maximum variants per article', 20);
$this->askConfigOptions($input, 'articleFilterGroups', 'Filter groups', 0);
$this->askConfigOptions($input, 'articleFilterOptions', 'Filter Options', 0);
$this->askConfigOptions($input, 'articleFilterValues', 'Filter Values', 0);
$this->askConfigOptions($input, 'orders', 'Orders', 0);
$this->askConfigOptions($input, 'newsletter', 'Newsletters', 0);
$this->askConfigOptions($input, 'customers', 'Customers', 1000);
$this->askConfigOptions($input, 'vouchers', 'Vouchers', 0);
}







private function askConfigOptions(InputInterface $input, $optionName, $optionHumanName = null, $default = 0)
{
$ioService = $this->container->get('io_service');

$optionHumanName = $optionHumanName ?: $optionName;
$optionValue = (int) $input->getOption($optionName);
if ($optionValue !== 0) {
return;
}

$optionValue = $ioService->askAndValidate(
"<question>{$optionHumanName}</question> [{$default}]: ",
[$this, 'validateInt']
);
$input->setOption($optionName, trim($optionValue) ? $optionValue : $default);
}








public function validateInt($input)
{
if (empty($input)) {
return 0;
}
if (!is_numeric($input)) {
throw new \RuntimeException('Field has to be numeric');
}

return (int) $input;
}

protected function execute(InputInterface $input, OutputInterface $output)
{

$generator = $this->container->get('data_generator');

$articles = $input->getOption('articles');
$orders = $input->getOption('orders');
$customers = $input->getOption('customers');
$newsletter = $input->getOption('newsletter');
$categories = $input->getOption('categories');
$categoriesPerArticle = $input->getOption('categoriesPerArticle');
$vouchers = $input->getOption('vouchers');
$articleFilterGroups = $input->getOption('articleFilterGroups');
$articleFilterOptions = $input->getOption('articleFilterOptions');
$articleFilterValues = $input->getOption('articleFilterValues');
$articleMinVariants = max($input->getOption('articleMinVariants'), 1);
$articleMaxVariants = max($input->getOption('articleMaxVariants'), $articleMinVariants);

$seed = $input->getOption('seed');
$chunkSize = $input->getOption('chunk-size');

if (!($articles || $orders || $customers || $newsletter || $categories || $vouchers)) {
$output->writeln(
'<error>At least one of the optional arguments should be provided. Use the --help option for more info.</error>'
);

return;
}

$shopwarePath = $input->getOption('installDir');
if (!$shopwarePath) {
$shopwarePath = realpath(getcwd());
}
$writerManager = $this->container->get('writer_manager');
if (is_readable($shopwarePath.'/config.php')) {
$shopwareConfig = require $shopwarePath.'/config.php';
if (!array_key_exists('db', $shopwareConfig)) {
$output->writeln('<error>Invalid Shopware configuration file.</error>');

return;
}
$writerManager->setConfig('database', $shopwareConfig['db']);
$writerManager->setDefaultWriterType('database');
} else {
$writerManager->setDefaultWriterType('file');
}

$config = $this->container->get('config');
$generatorLocale = empty($config['DataGenerator']['locale']) ? null : $config['DataGenerator']['locale'];

$this->configureGenerator(
$seed,
$articles,
$orders,
$categories,
$categoriesPerArticle,
$customers,
$newsletter,
$vouchers,
$articleFilterGroups,
$articleFilterOptions,
$articleFilterValues,
$chunkSize,
$articleMinVariants,
$articleMaxVariants,
$generatorLocale
);

foreach (['categories', 'articles', 'customers', 'orders', 'newsletter', 'vouchers'] as $type) {
if ($$type > 0) {
$output->writeln("Creating {$type}");
$generator->setType($type);
$generator->run();
}
}
}


















protected function configureGenerator(
$seed,
$articles,
$orders,
$categories,
$categoriesPerArticle,
$customers,
$newsletter,
$vouchers,
$articleFilterGroups,
$articleFilterOptions,
$articleFilterValues,
$chunkSize,
$minVariants,
$maxVariants,
$generatorLocale
) {

 if ($articles > 0 && !$categories) {
throw new \UnexpectedValueException('Articles require categories');
}
if ($orders > 0 && !$articles) {
throw new \UnexpectedValueException('Orders require articles');
}


$config = $this->container->get('generator_config');
$config->setChunkSize($chunkSize);
$config->setNumberArticles($articles);
$config->setNumberCategories($categories);
$config->setNumberCategoriesPerArticle($categoriesPerArticle);
$config->setNumberOrders($orders);
$config->setNumberCustomers($customers);
$config->setNumberNewsletter($newsletter);
$config->setNumberVouchers($vouchers);
$config->setArticleFilterGroups($articleFilterGroups);
$config->setArticleFilterOptions($articleFilterOptions);
$config->setArticleFilterValues($articleFilterValues);
$config->setSeed($seed);
$config->setGeneratorLocale($generatorLocale);

$config->setOutputName('');


 
 $config->setCreateImages(false);
$config->setThumbnailSizes('105x105,140x140,285x255,30x30,57x57,720x600');

$config->setMinVariants($minVariants);
$config->setMaxVariants($maxVariants);
}
}
<?php

namespace Shopware\Plugin;

interface RepositoryAwareExtension
{
public function getRepositories();
}
<?php

namespace Shopware\Plugin\Struct;

use ShopwareCli\Struct;







class PluginBootstrap extends Struct
{
public $name;
public $module;
}
<?php

namespace Shopware\Plugin\Struct;

use ShopwareCli\Struct;







class Plugin extends Struct
{
public $name;

public $cloneUrlHttp;

public $cloneUrlSsh;

public $module;

public $repository;

public $repoType;
}
<?php

namespace Shopware\Plugin\Struct;

use ShopwareCli\Struct;







class DisplayPlugin extends Struct
{
public $index;
public $repoType;
public $name;
public $module;
public $repository;






public static function createFromPluginAndIndex(Plugin $plugin, $index)
{
return new static([
'index' => $index,
'name' => $plugin->name,
'module' => $plugin->module,
'repoType' => $plugin->repoType,
'repository' => $plugin->repository,
]);
}
}
<?php

namespace Shopware\Plugin;

use Shopware\Plugin\Command\InstallCommand;
use Shopware\Plugin\Command\ZipCommand;
use Shopware\Plugin\Command\ZipLocalCommand;
use ShopwareCli\Application\ConsoleAwareExtension;
use ShopwareCli\Application\ContainerAwareExtension;
use ShopwareCli\Services\ProcessExecutor;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;







class Bootstrap implements ContainerAwareExtension, ConsoleAwareExtension
{



public function setContainer(ContainerBuilder $container)
{
$this->populateContainer($container);
}




public function getConsoleCommands()
{
return [
new InstallCommand(),
new ZipCommand(),
new ZipLocalCommand()
];
}




private function populateContainer($container)
{
$container->register('plugin_column_renderer', 'Shopware\Plugin\Services\ConsoleInteraction\PluginColumnRenderer')
->addArgument(new Reference('io_service'))
->addArgument(new Reference('config'));

$container->register('plugin_selector', 'Shopware\Plugin\Services\ConsoleInteraction\PluginInputVerificator')
->addArgument(new Reference('io_service'))
->addArgument(new Reference('plugin_column_renderer'));

$container->register('plugin_operation_manager', 'Shopware\Plugin\Services\ConsoleInteraction\PluginOperationManager')
->addArgument(new Reference('plugin_provider'))
->addArgument(new Reference('plugin_selector'))
->addArgument(new Reference('io_service'));

$container->register('bootstrap_info', 'Shopware\Plugin\Services\BootstrapInfo');

$container->register('install_service', 'Shopware\Plugin\Services\Install')
->addArgument(new Reference('checkout_service'))
->addArgument(new Reference('io_service'))
->addArgument(new Reference('process_executor'));

$container->register('zip_service', 'Shopware\Plugin\Services\Zip')
->addArgument(new Reference('checkout_service'))
->addArgument(new Reference('utilities'))
->addArgument(new Reference('process_executor'));

$container->register('checkout_service', 'Shopware\Plugin\Services\Checkout')
->addArgument(new Reference('utilities'))
->addArgument(new Reference('git_util'))
->addArgument(new Reference('io_service'));

$container->register('default_repository_factory', 'Shopware\Plugin\Services\Repositories\DefaultRepositoryFactory')
->addArgument(new Reference('service_container'));

$container->register('repository_manager', 'Shopware\Plugin\Services\RepositoryManager')
->addArgument(new Reference('extension_manager'))
->addArgument(new Reference('default_repository_factory'));

$container->register('plugin_provider', 'Shopware\Plugin\Services\PluginProvider')
->addArgument(new Reference('config'));
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Services\GitUtil;
use ShopwareCli\Services\IoService;
use ShopwareCli\Utilities;







class Checkout
{



protected $utilities;




private $ioService;




private $gitUtil;






public function __construct(Utilities $utilities, GitUtil $gitUtil, IoService $ioService)
{
$this->utilities = $utilities;
$this->ioService = $ioService;
$this->gitUtil = $gitUtil;
}







public function checkout(Plugin $plugin, $path, $branch = null, $useHttp = false)
{
if ($useHttp) {
$cloneUrl = $plugin->cloneUrlHttp;
} else {
$cloneUrl = $plugin->cloneUrlSsh;
}
$pluginName = $plugin->name;

if ($plugin->module) {
$destPath = $plugin->module . '/' . $pluginName;
} else {
$destPath = $pluginName;
}

$absPath = $path . '/' . $destPath;

if (is_dir($absPath)) {
$this->updatePlugin($branch, $absPath, $pluginName);

return;
}

$this->installPlugin($branch, $cloneUrl, $absPath, $pluginName);
}






private function updatePlugin($branch, $absPath, $pluginName)
{
$this->ioService->writeln('Plugin is already installed');
$this->utilities->changeDir($absPath);

$this->gitUtil->run('fetch --progress origin');

$output = $this->gitUtil->run('log HEAD..origin/master --oneline');
if (trim($output) === '') {
$this->ioService->writeln("Plugin '$pluginName' is up to date");
if ($branch) {
$this->gitUtil->run("checkout {$branch}");
}

return;
}

$this->ioService->writeln('Incoming changes:');
$this->ioService->writeln($output);

$this->gitUtil->run('reset --hard HEAD');
$this->gitUtil->run('pull');
if ($branch) {

 $cwd = getcwd();
$this->utilities->changeDir($absPath);
$this->gitUtil->run("checkout {$branch}");
$this->utilities->changeDir($cwd);
}
$this->ioService->writeln("Plugin '$pluginName' successfully updated.\n");
}







private function installPlugin($branch, $cloneUrl, $absPath, $pluginName)
{
$this->gitUtil->run("clone  --progress $cloneUrl $absPath");
if ($branch) {

 $cwd = getcwd();
$this->utilities->changeDir($absPath);
$this->gitUtil->run("checkout {$branch}");
$this->utilities->changeDir($cwd);
}
$branch = $branch ?: 'master';
$this->ioService->writeln("Successfully checked out '$branch' for '$pluginName'\n");
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\Struct\Plugin;







class PluginFactory
{










public static function getPlugin($name, $sshUrl, $httpUrl, $repoName, $repoType = null)
{
$plugin = new Plugin();

self::setPluginModuleFromName($name, $plugin);

$plugin->cloneUrlSsh = $sshUrl;
$plugin->cloneUrlHttp = $httpUrl;
$plugin->repository = $repoName;
$plugin->repoType = $repoType;

return $plugin;
}





private static function setPluginModuleFromName($name, Plugin $plugin)
{
if (stripos($name, 'frontend') === 0) {
$plugin->module = 'Frontend';
$plugin->name = substr($name, 9);
} elseif (stripos($name, 'backend') === 0) {
$plugin->module = 'Backend';
$plugin->name = substr($name, 8);
} elseif (stripos($name, 'core') === 0) {
$plugin->module = 'Core';
$plugin->name = substr($name, 5);
}


 if (empty($plugin->module)) {
$plugin->module = null;
$plugin->name = $name;
}
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\Services\Repositories\BaseRepository;
use Shopware\Plugin\Services\Repositories\RepositoryInterface;
use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Config;





class PluginProvider
{



protected $repositories = [];




protected $sortBy;




private $config;




public function __construct(Config $config)
{
$this->config = $config;
$this->sortBy = $config['general']['sortBy'];
}




public function setRepositories($repositories)
{
$this->repositories = $repositories;
}







protected function sortPlugins($plugins)
{
switch ($this->sortBy) {
case 'repository':
usort($plugins, function ($a, $b) {
return $a->repository . $a->name > $b->repository . $b->name;
});
break;
case 'module':
usort($plugins, function ($a, $b) {
return $a->module . $a->name > $b->module . $b->name;
});
break;
default:
usort($plugins, function ($a, $b) {
return $a->name > $b->name;
});
break;
}

return $plugins;
}








public function getPluginByName($name, $exact = false)
{
$result = [];
foreach ($this->repositories as $repo) {
$result = array_merge($result, $repo->getPluginByName($name, $exact));
}

return $this->sortPlugins($result);
}







public function getPluginsByRepositoryName($name)
{
$result = [];
foreach ($this->repositories as $repo) {
if ($repo instanceof BaseRepository && stripos($repo->getName(), $name) !== false) {
$result = array_merge($result, $repo->getPlugins());
}
}

return $this->sortPlugins($result);
}






public function getPlugins()
{
$result = [];
foreach ($this->repositories as $repo) {
$result = array_merge($result, $repo->getPlugins());
}

return $this->sortPlugins($result);
}
}
<?php

namespace Shopware\Plugin\Services\Repositories\Standard;

use Shopware\Plugin\Services\Repositories\BaseRepository;





class Stash extends BaseRepository
{



public function getPluginByName($name, $exact = false)
{
$plugins = $this->getPlugins();
foreach ($plugins as $key => $plugin) {
if (!$this->doesMatch($plugin->name, $name, $exact)) {
unset($plugins[$key]);
}
}

return $plugins;
}




public function getPlugins()
{
echo "Reading Stash repo {$this->name}\n";

$content = $this->restService->get($this->repository)->getResult();

if (isset($content['errors'])) {
throw new \RuntimeException(
sprintf("Stash Repo communication error: '%s'", $content['errors'][0]['message'])
);
}

$plugins = [];
foreach ($content['values'] as $repo) {
$urls = [];
foreach ($repo['links']['clone'] as $clone) {
$clone['href'] = str_replace('stashadmin@', '', $clone['href']);
$urls[$clone['name']] = $clone['href'];
}

$plugins[] = $this->createPlugin($urls['ssh'], $urls['http'], $repo['name']);
}

return $plugins;
}
}
<?php

namespace Shopware\Plugin\Services\Repositories\Standard;

use Shopware\Plugin\Services\Repositories\BaseRepository;






class GitHub extends BaseRepository
{



public function getPluginByName($name, $exact = false)
{
$plugins = $this->getPlugins();
foreach ($plugins as $key => $plugin) {
if (!$this->doesMatch($plugin->name, $name, $exact)) {
unset($plugins[$key]);
}
}

return $plugins;
}




public function getPlugins()
{
echo "Reading Shopware repo {$this->name}\n";
$content = $this->restService->get($this->repository)->getResult();

$plugins = [];
foreach ($content as $repo) {
$plugins[] = $this->createPlugin($repo['ssh_url'], $repo['clone_url'], $repo['name']);
}

return $plugins;
}
}
<?php

namespace Shopware\Plugin\Services\Repositories\Standard;

use Shopware\Plugin\Services\Repositories\BaseRepository;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;








class SimpleList extends BaseRepository implements ContainerAwareInterface
{

protected $container;

public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}




public function getPluginByName($name, $exact = false)
{
$plugins = $this->getPlugins();
foreach ($plugins as $key => $plugin) {
if (!$this->doesMatch($plugin->name, $name, $exact)) {
unset($plugins[$key]);
}
}

return $plugins;
}




public function getPlugins()
{
$config = $this->container->get('config');
if (!isset($config['repositories']['SimpleList'])) {
return [];
}

$plugins = [];
foreach ($config['repositories']['SimpleList']['repositories'] as $repositoryName => $repository) {
foreach ($repository['plugins'] as $name => $cloneUrls) {
$plugins[] = $this->createPlugin($cloneUrls['ssh'], $cloneUrls['http'], $name);
}
}

return $plugins;
}
}
<?php

namespace Shopware\Plugin\Services\Repositories\Standard;

use Shopware\Plugin\Services\Repositories\BaseRepository;

class BitBucket extends BaseRepository
{



public function getPluginByName($name, $exact = false)
{
$plugins = $this->getPlugins();
foreach ($plugins as $key => $plugin) {
if (!$this->doesMatch($plugin->name, $name, $exact)) {
unset($plugins[$key]);
}
}

return $plugins;
}




public function getPlugins()
{
echo "Reading BitBucket repo {$this->name}\n";
$content = $this->restService->get($this->repository)->getResult();

$plugins = [];
foreach ($content['values'] as $repo) {
$cloneUrls = [];

foreach ($repo['links']['clone'] as $cloneUrl) {
$cloneUrls[$cloneUrl['name']] = $cloneUrl['href'];
}

$cloneUrls['https'] = str_replace('shopwareAG@', '', $cloneUrls['https']);

$plugins[] = $this->createPlugin($cloneUrls['ssh'], $cloneUrls['https'], $repo['name']);
}

return $plugins;
}
}
<?php

namespace Shopware\Plugin\Services\Repositories;

use Shopware\Plugin\Services\PluginFactory;
use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Services\Rest\RestInterface;







abstract class BaseRepository implements RepositoryInterface
{



protected $name;




protected $repository;




protected $useHttp
;



protected $restService;




protected $color;







public function __construct($repository, $name, RestInterface $restService = null, $color = null)
{
$this->repository = $repository;
$this->name = $name;
$this->restService = $restService;
$this->color = $color;
}







public function createPlugin($sshUrl, $httpUrl, $name)
{
$type = array_slice(explode('\\', get_class($this)), -1);
$type = $type[0];

return PluginFactory::getPlugin($name, $sshUrl, $httpUrl, $this->name, $type);
}









protected function doesMatch($actual, $searched, $exact = false)
{
return (
!$exact && stripos($actual, $searched) !== false
|| $exact && $searched == $actual
);
}




public function getName()
{
return $this->name;
}
}
<?php

namespace Shopware\Plugin\Services\Repositories;

use Shopware\Plugin\Struct\Plugin;







interface RepositoryInterface
{









public function getPluginByName($name, $exact = false);






public function getPlugins();
}
<?php

namespace Shopware\Plugin\Services\Repositories;

use ShopwareCli\Config;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;







class DefaultRepositoryFactory
{




private $supportedRepositories = ['GitHub', 'Stash', 'BitBucket', 'SimpleList'];

private $defaultRepositories = [];




private $container;




public function __construct(Container $container)
{
$this->container = $container;
}




public function getDefaultRepositories()
{
if (!$this->defaultRepositories) {
$this->setupRepositories();
}

return $this->defaultRepositories;
}




private function setupRepositories()
{

$config = $this->container->get('config');

foreach ($config->getRepositories() as $type => $data) {
if (!in_array($type, $this->supportedRepositories)) {
continue;
}

$this->createSubRepositories($type, $data);
}
}







private function createSubRepositories($type, $data)
{
$baseUrl = isset($data['config']['endpoint']) ? $data['config']['endpoint'] : null;
$username = isset($data['config']['username']) ? $data['config']['username'] : null;
$password = isset($data['config']['password']) ? $data['config']['password'] : null;

foreach ($data['repositories'] as $name => $repoConfig) {
$cacheTime = isset($repoConfig['cache']) ? $repoConfig['cache'] : 3600;

$restClient = $baseUrl ? $this->container->get('rest_service_factory')->factory($baseUrl, $username, $password, $cacheTime) : null;

$this->defaultRepositories[] = $this->createRepository($name, $type, $repoConfig, $restClient);
}
}








private function createRepository($name, $type, $repoConfig, $restClient)
{
$className = 'Shopware\\Plugin\\Services\\Repositories\\Standard\\' . $type;
$repo = new $className(
isset($repoConfig['url']) ? $repoConfig['url'] : '',
$name,
$restClient
);

if ($repo instanceof ContainerAwareInterface) {
$repo->setContainer($this->container);
}

return $repo;
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\Struct\PluginBootstrap;







class BootstrapInfo
{






public function analyze($bootstrapFile)
{
$content = file_get_contents($bootstrapFile);

list($namespace, $name) = $this->analyzeClass($content);

$info = new PluginBootstrap();
$info->module = $namespace;
$info->name = $name;

return $info;
}








private function analyzeClass($content)
{
$pattern = '#.*Shopware_Plugins_(?P<namespace>[a-zA-Z0-9]+)_(?P<name>[a-zA-Z0-9]+)_Bootstrap.*#';
$matches = [];
preg_match($pattern, $content, $matches);
if (empty($matches)) {
throw new \RuntimeException('Could not analyze bootstrap');
}

return [$matches['namespace'], $matches['name']];
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Utilities;






class Zip
{



protected $checkout;




protected $utilities;




private $processExecutor;






public function __construct(Checkout $checkout, Utilities $utilities, ProcessExecutor $processExecutor)
{
$this->checkout = $checkout;
$this->utilities = $utilities;
$this->processExecutor = $processExecutor;
}










public function zip(Plugin $plugin, $path, $zipTo, $branch, $useHttp = false)
{
$this->checkout->checkout($plugin, $path, $branch, $useHttp);

if ($plugin->module) {
$pluginPath = $path . '/' . $plugin->module . '/' . $plugin->name;
} else {
$pluginPath = $path . '/' . $plugin->name;
}

$blackListPath = $pluginPath . '/.sw-zip-blacklist';

if (file_exists($blackListPath)) {
$blackList = file_get_contents($blackListPath);
$blackList = array_filter(explode("\n", $blackList));

foreach ($blackList as $item) {
$this->processExecutor->execute('rm -rf ' . $pluginPath . '/' . $item);
}
$this->processExecutor->execute('rm -rf ' . $blackListPath);
}

if (file_exists($pluginPath . '/composer.json')) {
$this->processExecutor->execute('composer install --no-dev', $pluginPath);
}

$outputFile = "{$zipTo}/{$plugin->name}.zip";

if ($plugin->module) {
$this->zipDir($plugin->module, $outputFile);
} else {
$this->zipDir($plugin->name, $outputFile);
}

return $outputFile;
}





public function zipDir($directory, $outputFile)
{
$this->processExecutor->execute("zip -r $outputFile $directory -x *.git*");
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Services\IoService;
use ShopwareCli\Services\ProcessExecutor;




class Install
{



protected $checkout;




private $ioService;




private $processExecutor;






public function __construct(Checkout $checkout, IoService $ioService, ProcessExecutor $processExecutor)
{
$this->checkout = $checkout;
$this->ioService = $ioService;
$this->processExecutor = $processExecutor;
}








public function install(Plugin $plugin, $shopwarePath, $inputActivate = false, $branch = 'master', $useHttp = false)
{
$installationPath = $shopwarePath . '/engine/Shopware/Plugins/Local/';
$pluginPath = $installationPath . '/' . $plugin->module . '/' . $plugin->name;

if (!$plugin->module) {
$installationPath = $shopwarePath . '/custom/plugins/';
$pluginPath = $installationPath . '/' . $plugin->name;
}

$this->checkout->checkout(
$plugin,
$installationPath,
$branch,
$useHttp
);

if ($inputActivate) {
$this->ioService->writeln(exec($shopwarePath . '/bin/console sw:plugin:refresh'));
$this->ioService->writeln(exec($shopwarePath . '/bin/console sw:plugin:install --activate ' . $plugin->name));
}

$this->addPluginVcsMapping($plugin, $shopwarePath);
$this->installGitHook($pluginPath);
}





private function addPluginVcsMapping(Plugin $plugin, $shopwarePath)
{
$vcsMappingFile = $shopwarePath . '/.idea/vcs.xml';
$pluginDestPath = $plugin->module . '/' . $plugin->name;

if (!file_exists($vcsMappingFile)) {
return;
}

$mapping = file_get_contents($vcsMappingFile);
$xml = new \SimpleXMLElement($mapping);
foreach ($xml->component->mapping as $mapping) {

 if (strpos($this->normalize($mapping['directory']), $this->normalize($pluginDestPath)) !== false) {
return;
}
}

$mappingDirectory = '$PROJECT_DIR$/engine/Shopware/Plugins/Local/' . $pluginDestPath;

if (!$plugin->module) {
$mappingDirectory = '$PROJECT_DIR$/custom/plugins/' . $plugin->name;
}


 $newMapping = $xml->component->addChild('mapping');
$newMapping->addAttribute('vcs', 'Git');
$newMapping->addAttribute('directory', $mappingDirectory);

$xml->asXML($vcsMappingFile);
}







private function normalize($string)
{
return strtolower(str_replace(['/', '\\'], '-', $string));
}




private function installGitHook($pluginPath)
{
$installShFile = $pluginPath . '/.githooks/install_hooks.sh';

if (!file_exists($installShFile)) {
return;
}

$this->processExecutor->execute($installShFile);
}
}
<?php

namespace Shopware\Plugin\Services;

use Shopware\Plugin\RepositoryAwareExtension;
use Shopware\Plugin\Services\Repositories\DefaultRepositoryFactory;
use ShopwareCli\Application\ExtensionManager;







class RepositoryManager
{



private $defaultRepositoryFactory;



private $extensionManager;

public function __construct(ExtensionManager $extensionManager, DefaultRepositoryFactory $defaultRepositoryFactory)
{
$this->defaultRepositoryFactory = $defaultRepositoryFactory;
$this->extensionManager = $extensionManager;
}






public function getRepositories()
{
$defaultRepositories = $this->defaultRepositoryFactory->getDefaultRepositories();
$pluginRepositories = $this->collectPluginRepositories();

return array_merge($defaultRepositories, $pluginRepositories);
}






private function collectPluginRepositories()
{
$repositories = [];

foreach ($this->extensionManager->getExtensions() as $plugin) {
if ($plugin instanceof RepositoryAwareExtension) {
foreach ($plugin->getRepositories() as $repository) {
$repositories[] = $repository;
}
}
}

return $repositories;
}
}
<?php

namespace Shopware\Plugin\Services\ConsoleInteraction;

use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Services\IoService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;







class PluginInputVerificator
{



protected $inputInterface;




protected $outputInterface;




protected $outputRenderer;




private $ioService;





public function __construct(IoService $ioService, PluginColumnRenderer $outputRenderer)
{
$this->outputRenderer = $outputRenderer;
$this->ioService = $ioService;
}









public function selectPlugin($plugins, array $allowedAnswers = ['all'])
{
while (true) {
system('clear');
$this->outputRenderer->show($plugins);

$question = new Question(
$this->formatQuestion(count($plugins), $allowedAnswers)
);

$response = $this->ioService->ask($question);

if (in_array($response, $allowedAnswers, true)) {
return $response;
}

if ($range = $this->getPluginRange($response)) {
return array_filter(
array_map(
function ($number) use ($plugins) {
return isset($plugins[$number - 1]) ? $plugins[$number - 1] : null;
},
$range
),
function ($plugin) {
return $plugin;
}
);
}

if (isset($plugins[$response - 1])) {
return $plugins[$response - 1];
}

$question = new Question('<error>Invalid answer, hit enter to continue</error>');
$this->ioService->ask($question);
}
}








private function formatQuestion($count, $allowedAnswers)
{
$template = "\n<question>Which plugin(s) do you want to install?</question> Type <comment>1-{$count}</comment> %s ";

if (empty($allowedAnswers)) {
return sprintf($template, '');
}

if (count($allowedAnswers) === 1) {
return sprintf($template, sprintf('or "%s"', $allowedAnswers[0]));
}

$allowedAnswers = array_map(
function ($option) {
return sprintf('"<comment>%s</comment>"', $option);
},
$allowedAnswers
);

return sprintf($template, sprintf('or one of these: %s', implode(', ', $allowedAnswers)));
}









private function getPluginRange($userInput)
{
$pattern = '#(?P<from>[0-9]+)-(?P<to>[0-9]+)#';
$matches = [];

preg_match($pattern, $userInput, $matches);

if (empty($matches) || !isset($matches['from']) || !isset($matches['to'])) {
return false;
}

return range($matches['from'], $matches['to']);
}
}
<?php

namespace Shopware\Plugin\Services\ConsoleInteraction;

use Shopware\Plugin\Services\PluginProvider;
use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Services\IoService;
use ShopwareCli\Utilities;
use Symfony\Component\Console\Output\OutputInterface;












class PluginOperationManager
{



protected $pluginProvider;




protected $output;




protected $pluginSelector;




private $ioService;






public function __construct(
PluginProvider $pluginProvider,
PluginInputVerificator $pluginSelector,
IoService $ioService
) {
$this->pluginProvider = $pluginProvider;
$this->pluginSelector = $pluginSelector;
$this->ioService = $ioService;
}









public function searchAndOperate($names, $callback, $params)
{
foreach ($names as $name) {
$plugins = $this->pluginProvider->getPluginByName($name);
$count = count($plugins);

if ($count === 0) {
$plugins = $this->pluginProvider->getPluginsByRepositoryName($name);
$count = count($plugins);
}
if ($count === 0) {
$this->ioService->writeln("\n<error>Could not find a plugin named '{$name}'</error>");

return;
}

$this->ioService->writeln("\nWill now process '<comment>{$name}</comment>'");

if ($count === 1) {
$this->executeMethodCallback($plugins[0], $callback, $params);

return;
}

$response = $this->pluginSelector->selectPlugin($plugins, ['all']);
$plugins = $this->getPluginsFromResponse($response, $plugins);

foreach ($plugins as $plugin) {
$this->executeMethodCallback($plugin, $callback, $params);
}
}
}






private function executeMethodCallback($subject, $callback, $params)
{
call_user_func_array($callback, [$subject, &$params]);
}








private function getPluginsFromResponse($response, $plugins)
{
if ($response instanceof Plugin) {
return [$response];
}

if (is_array($response)) {
return $response;
}

if ($response === 'all') {
return $plugins;
}
}







public function operationLoop($callback, $params)
{
$plugins = $this->pluginProvider->getPlugins();
while (true) {
$response = $this->pluginSelector->selectPlugin($plugins, ['all', 'exit']);

if ($response === 'exit') {
return;
}

$this->ioService->cls();

$responsePlugins = $this->getPluginsFromResponse($response, $plugins);
foreach ($responsePlugins as $plugin) {
$this->executeMethodCallback($plugin, $callback, $params);
}
$this->ioService->ask("\n<error>Done, hit enter to continue.</error>");
$this->ioService->cls();
}
}
}
<?php

namespace Shopware\Plugin\Services\ConsoleInteraction;

use Shopware\Plugin\Struct\DisplayPlugin;
use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Config;
use ShopwareCli\Services\IoService;







class PluginColumnRenderer
{



protected $config;




protected $small = false;




private $ioService;





public function __construct(IoService $ioService, Config $config)
{
$this->config = $config;
$this->ioService = $ioService;
}




public function setSmall($isSmall)
{
$this->small = $isSmall;
}






public function show($allPlugins)
{

 if ($this->small) {
$columns = 3;
} else {
$columns = 2;
}

$displayPlugins = $this->createDisplayPlugins($allPlugins);
$pluginColumns = $this->createPluginColumns($displayPlugins, $columns);

$this->printLegend($displayPlugins);
$this->printColumns($pluginColumns);
}





private function createDisplayPlugins($plugins)
{
$displayPlugins = [];
foreach ($plugins as $key => $plugin) {
$displayPlugins[] = DisplayPlugin::createFromPluginAndIndex($plugin, $key + 1);
}

return $displayPlugins;
}






private function createPluginColumns($plugins, $columns)
{
$length = count($plugins);
$pluginColumns = [];

$pluginsPerColumn = ceil($length / $columns);

 for ($i = 0; $i < $columns; $i++) {
$sliceOffset = $pluginsPerColumn * $i;
$sliceLength = $pluginsPerColumn * ($i + 1);

$pluginColumns[$i] = array_slice($plugins, $sliceOffset, $sliceLength);
}

return $pluginColumns;
}




private function printColumns($pluginColumns)
{
$columnCount = count($pluginColumns);
$rowCount = count($pluginColumns[0]) -1;

foreach (range(0, $rowCount) as $row) {
$currentRow = [];
foreach (range(0, $columnCount -1) as $column) {
if (isset($pluginColumns[$column][$row])) {
$currentRow[] = $pluginColumns[$column][$row];
}
}

$this->printRow($currentRow);
}
}




private function printRow($row)
{
if ($this->small) {
$baseMask = '%4.4s #COL_START#%-25.25s#COL_END#';
$spacer = ' ';
} else {
$baseMask = '%4.4s #COL_START#%-30.30s#COL_END#';
$spacer = '                   ';
}

$columns = [];

foreach ($row as $plugin) {
$mask = $this->getMaskForPlugin($plugin, $baseMask);

$columns[] = sprintf($mask, $plugin->index, $this->formatPlugin($plugin));
}

$this->ioService->write(implode($columns, $spacer));
$this->ioService->writeln('');
}






private function printLegend($plugins)
{
if (!$this->config['general']['enableRepositoryColors']) {
return;
}

$repos = [];
foreach ($plugins as $plugin) {
$repos[$plugin->repoType . '(' . $plugin->repository . ')'] = $this->getColorForPlugin($plugin);
}

$output = [];
foreach ($repos as $name => $color) {
$color = $color ?: 'white';

$output[] = "<fg={$color}>{$name}</fg={$color}>";
}

$this->ioService->writeln('Legend:');
$this->ioService->writeln(implode(', ', $output) . "\n");
}








private function getMaskForPlugin(DisplayPlugin $plugin, $baseMask)
{
$color = $this->getColorForPlugin($plugin);

if (!$this->config['general']['enableRepositoryColors'] || !$plugin || !$color) {
$baseMask = str_replace('#COL_START#', '', $baseMask);
$baseMask = str_replace('#COL_END#', '', $baseMask);
} else {
$baseMask = str_replace('#COL_START#', "<fg={$color}>", $baseMask);
$baseMask = str_replace('#COL_END#', "</fg={$color}>", $baseMask);
}

return $baseMask;
}





private function formatPlugin(DisplayPlugin $plugin)
{
return $this->formatModuleName($plugin) . '/' . $plugin->name;
}







private function formatModuleName(DisplayPlugin $plugin)
{
if ($this->small) {
return $plugin->module[0];
} else {
return $plugin->module;
}
}







private function getColorForPlugin(DisplayPlugin $plugin)
{
$repos = $this->config->getRepositories();
$hasColorConfig = $plugin ? isset($repos[$plugin->repoType]['repositories'][$plugin->repository]['color']) : false;

if (!$hasColorConfig) {
return false;
}

$color = $repos[$plugin->repoType]['repositories'][$plugin->repository]['color'];

return $color;
}
}
<?php

namespace Shopware\Plugin\Command;

use ShopwareCli\Command\BaseCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;







class ZipCommand extends BaseCommand
{
protected $utilities;
protected $zipDir;

protected function configure()
{
$this
->setName('plugin:zip:vcs')
->setDescription('Creates a installable plugin zip in the current directory from VCS')
->addArgument(
'names',
InputArgument::IS_ARRAY,
'Name of the plugin to install'
)
->addOption(
'small',
null,
InputOption::VALUE_NONE,
'If set, the task will yell in uppercase letters'
)
->addOption(
'useHttp',
null,
InputOption::VALUE_NONE,
'Checkout the repo via HTTP'
)
->addOption(
'branch',
'-b',
InputOption::VALUE_OPTIONAL,
'Checkout the given branch'
);
}

protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->zipDir = getcwd();
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$names = $input->getArgument('names');
$small = $input->getOption('small');
$useHttp = $input->getOption('useHttp');
$branch = $input->getOption('branch');

$this->container->get('io_service')->cls();

$this->container->get('plugin_column_renderer')->setSmall($small);
$interactionManager = $this->container->get('plugin_operation_manager');

$params = ['output' => $output, 'branch' => $branch, 'useHttp' => $useHttp];

if (!empty($names)) {
$interactionManager->searchAndOperate($names, [$this, 'doZip'], $params);

return;
}

$interactionManager->operationLoop([$this, 'doZip'], $params);
}

public function doZip($plugin, $params)
{
$this->container->get('zip_service')->zip($plugin, $this->getTempDir(), $this->getZipDir(), $params['branch'], $params['useHttp']);
}

protected function getTempDir()
{
$tempDirectory = sys_get_temp_dir();
$tempDirectory .= '/plugin-inst-' . uniqid('', true);
if (!is_dir($tempDirectory) && !mkdir($tempDirectory, 0777, true) && !is_dir($tempDirectory)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $tempDirectory));
}

$this->container->get('utilities')->changeDir($tempDirectory);

return $tempDirectory;
}

protected function getZipDir()
{
return $this->zipDir;
}
}
<?php

namespace Shopware\Plugin\Command;

use Shopware\Plugin\Struct\PluginBootstrap;
use ShopwareCli\Command\BaseCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;







class ZipLocalCommand extends BaseCommand
{
protected $utilities;
protected $zipDir;

protected function configure()
{
$this
->setName('plugin:zip:dir')
->setDescription('Creates a installable plugin zip from a given plugin directory')
->addArgument(
'dir',
InputArgument::REQUIRED,
'Name of the plugin to install'
);
}

protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->zipDir = getcwd();
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$directory = $input->getArgument('dir');
$directory = rtrim($directory, '/');
$this->validatePluginDir($directory);

$this->doZip($directory);
}




public function validatePluginDir($dir)
{
$fileName = basename($dir);

if (!file_exists($dir . '/Bootstrap.php') && !file_exists($dir . '/' . $fileName . '.php')) {
throw new \RuntimeException("Could not find Bootstrap.php or $fileName.php in $dir");
}
}




public function doZip($pluginDirectory)
{
if (file_exists($pluginDirectory . '/Bootstrap.php')) {

$info = $this->container->get('bootstrap_info')->analyze($pluginDirectory . '/Bootstrap.php');

$outputFile = $this->getZipDir() . '/' . $info->name . '.zip';
$tempDir = $this->getTempDir();
$sourceDir = $tempDir . '/' . $info->module . '/' . $info->name;
if (!is_dir($sourceDir) && !mkdir($sourceDir, 0777, true) && !is_dir($sourceDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $sourceDir));
}

$this->container->get('process_executor')->execute("cp -r {$pluginDirectory}/* $sourceDir");
$this->container->get('utilities')->changeDir($tempDir);

$this->container->get('zip_service')->zipDir($info->module . '/' . $info->name, $outputFile);
} else {
$pluginName = basename($pluginDirectory);
$outputFile = $this->getZipDir() . '/' . $pluginName . '.zip';

$tempDir = $this->getTempDir();
$sourceDir = $tempDir . '/' . $pluginName;
if (!is_dir($sourceDir) && !mkdir($sourceDir, 0777, true) && !is_dir($sourceDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $sourceDir));
}

$this->container->get('process_executor')->execute("cp -r {$pluginDirectory}/* $sourceDir");
$this->container->get('utilities')->changeDir($tempDir);

$this->container->get('zip_service')->zipDir($pluginName, $outputFile);
}

$this->container->get('io_service')->writeln("<info>Created file $outputFile</info>");
}

protected function getTempDir()
{
$tempDirectory = sys_get_temp_dir();
$tempDirectory .= '/plugin-inst-' . uniqid('', true);
if (!is_dir($tempDirectory) && !mkdir($tempDirectory, 0777, true) && !is_dir($tempDirectory)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $tempDirectory));
}

return $tempDirectory;
}

protected function getZipDir()
{
return $this->zipDir;
}
}
<?php

namespace Shopware\Plugin\Command;

use Shopware\Plugin\Services\ConsoleInteraction\PluginOperationManager;
use Shopware\Plugin\Services\Install;
use Shopware\Plugin\Struct\Plugin;
use ShopwareCli\Command\BaseCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;







class InstallCommand extends BaseCommand
{



protected $shopwarePath;




public function getInstallService()
{
return $this->container->get('install_service');
}




protected function configure()
{
$this
->setName('plugin:install')
->setDescription('Install a plugin in the current or a given shopware installation')
->addArgument(
'names',
InputArgument::IS_ARRAY,
'Name of the plugin to install, or the repository to filter by'
)
->addOption(
'shopware-root',
'r',
InputOption::VALUE_OPTIONAL,
'Root of your shopware installation'
)
->addOption(
'small',
null,
InputOption::VALUE_NONE,
'If set, the task will yell in uppercase letters'
)
->addOption(
'useHttp',
null,
InputOption::VALUE_NONE,
'Checkout the repo via HTTP'
)
->addOption(
'checkout',
'c',
InputOption::VALUE_NONE,
'Checkout into current directory. No shopware checks, no subdirectory creation'
)
->addOption(
'branch',
'-b',
InputOption::VALUE_OPTIONAL,
'Checkout the given branch'
);
}




protected function execute(InputInterface $input, OutputInterface $output)
{
$names = $input->getArgument('names');
$small = $input->getOption('small');
$useHttp = $input->getOption('useHttp');
$branch = $input->getOption('branch');
$shopwarePath = $input->getOption('shopware-root');
$checkout = $input->getOption('checkout');

if (!$shopwarePath) {
$shopwarePath = null;
}
$this->container->get('io_service')->cls();

if (!$checkout) {
$shopwarePath = $this->container->get('utilities')->getValidShopwarePath($shopwarePath);
$this->shopwarePath = $shopwarePath;
}


$interactionManager = $this->container->get('plugin_operation_manager');

$this->container->get('plugin_column_renderer')->setSmall($small);

$params = ['checkout' => $checkout, 'branch' => $branch, 'useHttp' => $useHttp];

if (!empty($names)) {
if (!$checkout) {
$params['activate'] = $this->askActivatePluginQuestion();
}
$interactionManager->searchAndOperate($names, [$this, 'doInstall'], $params);

return;
}

$interactionManager->operationLoop([$this, 'doInstall'], $params);
}





public function doInstall($plugin, &$params)
{
if ($params['checkout']) {
$this->checkout($plugin, $params);
} else {
$this->install($plugin, $params);
}
}




protected function getShopwarePath()
{
$this->container->get('utilities')->changeDir($this->shopwarePath);

return $this->shopwarePath;
}




protected function askActivatePluginQuestion()
{
$question = new ConfirmationQuestion('<question>Activate plugins after checkout?</question> <comment>[Y/n]</comment> ', true);
$activate = $this->container->get('io_service')->ask($question);

return $activate;
}





private function install($plugin, &$params)
{
if (!isset($params['activate'])) {
$params['activate'] = $this->askActivatePluginQuestion();
}

$this->container->get('utilities')->changeDir($this->getShopwarePath() . '/engine/Shopware/Plugins/Local/');

$this->getInstallService()->install(
$plugin,
$this->getShopwarePath(),
$params['activate'],
$params['branch'],
$params['useHttp']
);
}





private function checkout($plugin, &$params)
{
$url = $params['useHttp'] ? $plugin->cloneUrlHttp : $plugin->cloneUrlSsh;

$destination = strtolower($plugin->module . '_' . $plugin->name);
$path = realpath('.') . '/' . $destination;
$this->container->get('io_service')->writeln("<info>Checking out $plugin->name to $path</info>");

$repo = escapeshellarg($url);
$branch = $params['branch'] ? escapeshellarg($params['branch']) : null;
$destination = escapeshellarg('./' . $destination);

$branchArg = $branch ? "-b {$branch}" : '';

$this->container->get('git_util')->run(
"clone --progress {$branchArg} {$repo} {$destination}"
);
}
}
<?php

namespace Shopware\Install\Struct;

use ShopwareCli\Struct;

class InstallationRequest extends Struct
{

private $release;


private $installDir;


private $onlyUnpack;


private $skipDownload;


private $dbHost;


private $dbPort;


private $dbSocket;


private $dbUser;


private $dbPassword;


private $dbName;


private $shopLocale;


private $shopHost;


private $shopPath;


private $shopName;


private $shopEmail;


private $shopCurrency;


private $adminUsername;


private $adminPassword;


private $adminEmail;


private $adminLocale;


private $adminName;


private $noSkipImport;


private $skipAdminCreation;




public function __construct(array $values = [])
{
foreach ($values as $name => $value) {
$this->$name = $value;
}
}

public function all()
{
return get_object_vars($this);
}




public function getRelease()
{
return $this->release;
}




public function getInstallDir()
{
return $this->installDir;
}




public function getOnlyUnpack()
{
return $this->onlyUnpack;
}




public function getSkipDownload()
{
return $this->skipDownload;
}




public function getAbsoluteInstallDir()
{
return realpath($this->installDir);
}




public function getDbHost()
{
return $this->dbHost;
}




public function getDbPort()
{
return $this->dbPort;
}




public function getDbSocket()
{
return $this->dbSocket;
}




public function getDbUser()
{
return $this->dbUser;
}




public function getDbPassword()
{
return $this->dbPassword;
}




public function getDbName()
{
return $this->dbName;
}




public function getShopLocale()
{
return $this->shopLocale;
}




public function getShopHost()
{
return $this->shopHost;
}




public function getShopPath()
{
return $this->shopPath;
}




public function getShopName()
{
return $this->shopName;
}




public function getShopEmail()
{
return $this->shopEmail;
}




public function getShopCurrency()
{
return $this->shopCurrency;
}




public function getAdminUsername()
{
return $this->adminUsername;
}




public function getAdminPassword()
{
return $this->adminPassword;
}




public function getAdminEmail()
{
return $this->adminEmail;
}




public function getAdminLocale()
{
return $this->adminLocale;
}




public function getAdminName()
{
return $this->adminName;
}




public function getNoSkipImport()
{
return $this->noSkipImport;
}




public function getSkipAdminCreation()
{
return $this->skipAdminCreation;
}
}
<?php

namespace Shopware\Install;

use Shopware\Install\Command\ShopwareClearCacheCommand;
use Shopware\Install\Command\ShopwareInstallReleaseCommand;
use Shopware\Install\Command\ShopwareInstallVcsCommand;
use ShopwareCli\Application\ConsoleAwareExtension;
use ShopwareCli\Application\ContainerAwareExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;







class Bootstrap implements ContainerAwareExtension, ConsoleAwareExtension
{



public function setContainer(ContainerBuilder $container)
{
$this->populateContainer($container);
}




public function getConsoleCommands()
{
return [
new ShopwareInstallVcsCommand(),
new ShopwareInstallReleaseCommand(),
new ShopwareClearCacheCommand()
];
}




private function populateContainer(ContainerBuilder $container)
{
$container->register('shopware_checkout_service', 'Shopware\Install\Services\Checkout')
->addArgument(new Reference('git_util'))
->addArgument(new Reference('io_service'));

$container->register('post_install', 'Shopware\Install\Services\PostInstall')
->addArgument(new Reference('process_executor'))
->addArgument(new Reference('shopware-install.owner'))
->addArgument(new Reference('config'))
->addArgument(new Reference('shopware_info'));

$container->register('shopware_release_download_service', 'Shopware\Install\Services\ReleaseDownloader')
->addArgument(new Reference('process_executor'))
->addArgument(new Reference('io_service'))
->addArgument(new Reference('file_downloader'))
->addArgument(new Reference('openssl_verifier'))
->addArgument($container->get('path_provider')->getCachePath());

$container->register('shopware-install.vcs_generator', 'Shopware\Install\Services\VcsGenerator')
->addArgument(new Reference('io_service'));

$container->register('shopware-install.config_writer', 'Shopware\Install\Services\ConfigWriter')
->addArgument(new Reference('io_service'));

$container->register('shopware-install.owner', 'Shopware\Install\Services\Owner');

$container->register('shopware-install.database', 'Shopware\Install\Services\Database')
->addArgument(new Reference('utilities'))
->addArgument(new Reference('io_service'))
->addArgument(new Reference('process_executor'));

$container->register('shopware-install.demodata', 'Shopware\Install\Services\Demodata')
->addArgument(new Reference('path_provider'))
->addArgument(new Reference('io_service'))
->addArgument(new Reference('shopware_info'))
->addArgument(new Reference('process_executor'));

$container->register('shopware_vcs_install_service', 'Shopware\Install\Services\Install\Vcs')
->addArgument(new Reference('shopware_checkout_service'))
->addArgument(new Reference('config'))
->addArgument(new Reference('shopware-install.vcs_generator'))
->addArgument(new Reference('shopware-install.config_writer'))
->addArgument(new Reference('shopware-install.database'))
->addArgument(new Reference('shopware-install.demodata'))
->addArgument(new Reference('io_service'))
->addArgument(new Reference('post_install'));

$container->register('shopware_release_install_service', 'Shopware\Install\Services\Install\Release')
->addArgument(new Reference('shopware_release_download_service'))
->addArgument(new Reference('config'))
->addArgument(new Reference('shopware-install.vcs_generator'))
->addArgument(new Reference('shopware-install.config_writer'))
->addArgument(new Reference('shopware-install.database'))
->addArgument(new Reference('shopware-install.demodata'))
->addArgument(new Reference('io_service'))
->addArgument(new Reference('post_install'))
->addArgument(new Reference('process_executor'));
}
}
<?php

namespace Shopware\Install\Services;

use ShopwareCli\Services\GitUtil;
use ShopwareCli\Services\IoService;







class Checkout
{



private $ioService;




private $gitUtil;





public function __construct(GitUtil $gitUtil, IoService $ioService)
{
$this->ioService = $ioService;
$this->gitUtil = $gitUtil;
}






public function checkout($repo, $branch, $destination)
{
$this->ioService->writeln("<info>Checkout out $repo to $destination</info>");

$repo = escapeshellarg($repo);
$branch = escapeshellarg($branch);
$destination = escapeshellarg($destination);

$this->gitUtil->run(
"clone --progress -b {$branch} {$repo} {$destination}"
);
}
}
<?php

namespace Shopware\Install\Services;

use ShopwareCli\Services\IoService;
use ShopwareCli\Services\PathProvider\PathProvider;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Services\ShopwareInfo;







class Demodata
{



private $pathProvider;




private $demoUrl = 'http://releases.s3.shopware.com/test_images_since_5.1.zip';




private $ioService;



private $shopwareInfo;




private $processExecutor;







public function __construct(PathProvider $pathProvider, IoService $ioService, ShopwareInfo $shopwareInfo, ProcessExecutor $processExecutor)
{
$this->pathProvider = $pathProvider;
$this->ioService = $ioService;
$this->shopwareInfo = $shopwareInfo;
$this->processExecutor = $processExecutor;
}




public function setup($installDir)
{
$assetDir = $this->pathProvider->getAssetsPath();
if (!is_dir($assetDir) && !mkdir($assetDir) && !is_dir($assetDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $assetDir));
}

$targetFile = md5($this->demoUrl) . '_demo.zip';

if (!file_exists($assetDir . '/' . $targetFile)) {
$this->ioService->writeln('<info>Downloading demodata from shopware.de</info>');
$this->processExecutor->execute("wget {$this->demoUrl} -O {$assetDir}/{$targetFile}");
$this->ioService->writeln('<info>Unzipping demo data</info>');
$this->processExecutor->execute("unzip -q {$assetDir}/{$targetFile} -d {$assetDir}");
}


 $this->ioService->writeln('<info>Copying demo data to shop</info>');
$this->processExecutor->execute("cp -rf {$assetDir}/files {$installDir}");
$this->processExecutor->execute("cp -rf {$assetDir}/media {$installDir}");
$this->processExecutor->execute('find ' .$this->shopwareInfo->getCacheDir($installDir) ." -type d -exec chmod 777 {} \;", true);
$this->processExecutor->execute('find ' .$this->shopwareInfo->getMediaDir($installDir) ." -type d -exec chmod 777 {} \;", true);
$this->processExecutor->execute('find ' .$this->shopwareInfo->getFilesDir($installDir) ." -type d -exec chmod 777 {} \;", true);
$this->processExecutor->execute('find ' .$this->shopwareInfo->getCacheDir($installDir) ."  -type d -exec chmod 777 {} \;", true);
}




public function runLicenseImport($installDir)
{
if (file_exists("{$installDir}/bin/console")) {
try {
$this->runCliCommands($installDir);
} catch (\RuntimeException $e) {
$this->ioService->writeln("<comment>Skipping license import: {$e->getMessage()}</comment>");
}
}

$this->ioService->writeln('<info>Clearing the cache</info>');

$this->processExecutor->execute($this->shopwareInfo->getCacheDir($installDir) . '/clear_cache.sh');
}




private function runCliCommands($installDir)
{
$this->ioService->writeln('<info>Running license import</info>');

$this->processExecutor->execute("{$installDir}/bin/console sw:generate:attributes");
$this->processExecutor->execute("{$installDir}/bin/console sw:plugin:refresh");
$this->processExecutor->execute("{$installDir}/bin/console sw:plugin:install SwagLicense --activate");

$licenseFile = @getenv('HOME').'/licenses.txt';
if (file_exists($licenseFile)) {
$this->processExecutor->execute("{$installDir}/bin/console swaglicense:import {$licenseFile}");
}
}
}
<?php

namespace Shopware\Install\Services;

use ShopwareCli\Config;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Services\ShopwareInfo;

class PostInstall
{



private $processExecutor;



private $owner;



private $config;



private $shopwareInfo;

public function __construct(ProcessExecutor $processExecutor, Owner $owner, Config $config, ShopwareInfo $shopwareInfo)
{
$this->processExecutor = $processExecutor;
$this->owner = $owner;
$this->config = $config;
$this->shopwareInfo = $shopwareInfo;
}

public function fixShopHost($database)
{
$connection = $this->getConnection();
$connection->query("USE `{$database}`");

$connection->exec('UPDATE s_core_shops SET host = NULL WHERE host = ""');
}






public function fixPermissions($directory)
{
$command = sprintf('chmod 0777 -R "%s"', $this->shopwareInfo->getLogDir($directory));
$this->processExecutor->execute($command, null, true);

$command = sprintf('chmod 0777 -R "%s"', $this->shopwareInfo->getCacheDir($directory));
$this->processExecutor->execute($command, null, true);

if (file_exists($directory . '/web')) {
$command = sprintf('chmod 0777 -R "%s"', $directory.'/web');
$this->processExecutor->execute($command, null, true);
}

$command = sprintf('chmod +x  "%s"', $directory . '/bin/console');
$this->processExecutor->execute($command, null, true);

$command = sprintf('chmod +x  "%s"', $this->shopwareInfo->getCacheDir($directory) . '/clear_cache.sh');
$this->processExecutor->execute($command, null, true);

$this->setUser($directory);
$this->setGroup($directory);
}






public function setupTheme($directory)
{
if (!file_exists($directory . '/themes')) {
return;
}

$command = sprintf('php bin/console sw:generate:attributes');
$this->processExecutor->execute($command, $directory, true);

$command = sprintf('php bin/console sw:theme:initialize');
$this->processExecutor->execute($command, $directory, true);
}







public function importCustomDeltas($database)
{
if (!isset($this->config['CustomDeltas'])) {
return;
}

$connection = $this->getConnection();
$connection->query("USE `{$database}`");

foreach ($this->config['CustomDeltas'] as $file) {
if (!file_exists($file)) {
throw new \RuntimeException("File '{$file}' not found");
}
$connection->exec(file_get_contents($file));
}
}






public function runCustomScripts($path)
{
if (!isset($this->config['CustomScripts'])) {
return;
}

foreach ($this->config['CustomScripts'] as $script) {
$this->processExecutor->execute($script, $path, true);
}
}






private function setUser($directory)
{
if (isset($this->config['ChangeOwner'], $this->config['ChangeOwner']['user'])) {
$this->owner->setUser($directory, $this->config['ChangeOwner']['user'], true);
}
}






private function setGroup($directory)
{
if (isset($this->config['ChangeOwner'], $this->config['ChangeOwner']['group'])) {
$this->owner->setGroup($directory, $this->config['ChangeOwner']['group'], true);
}
}






private function getConnection()
{
$username = $this->config['DatabaseConfig']['user'];
$password = $this->config['DatabaseConfig']['pass'];
$host = $this->config['DatabaseConfig']['host'];
$port = isset($this->config['DatabaseConfig']['port']) ? $this->config['DatabaseConfig']['port'] : 3306;

$connection = new \PDO("mysql:host={$host};charset=utf8;port={$port}", $username, $password);
$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

return $connection;
}
}
<?php

namespace Shopware\Install\Services;

use GuzzleHttp\Client;
use ShopwareCli\Services\FileDownloader;
use ShopwareCli\Services\IoService;
use ShopwareCli\Services\OpenSSLVerifier;
use ShopwareCli\Services\ProcessExecutor;

class ReleaseDownloader
{
const DOWNLOAD_URL_LATEST = 'http://install.s3.shopware.com/';
const DOWNLOAD_UPDATE_API = 'http://update-api.shopware.com/v1/releases/install';




private $cachePath;



private $ioService;




private $processExecutor;




private $downloader;



private $openSSLVerifier;








public function __construct(
ProcessExecutor $processExecutor,
IoService $ioService,
FileDownloader $downloader,
OpenSSLVerifier $openSSLVerifier,
$cachePath
) {
$this->cachePath = $cachePath;
$this->ioService = $ioService;
$this->processExecutor = $processExecutor;
$this->downloader = $downloader;
$this->openSSLVerifier = $openSSLVerifier;
}







public function downloadRelease($release, $installDir)
{
$this->ioService->writeln('<info>Downloading release</info>');
$zipLocation = $this->downloadFromUpdateApi($release);

if (!is_dir($installDir) && !mkdir($installDir) && !is_dir($installDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $installDir));
}

$this->ioService->writeln('<info>Unzipping archive</info>');
$this->processExecutor->execute("unzip -qq {$zipLocation} -d {$installDir}");
}







private function downloadFromUpdateApi($release)
{
$indexedReleases = $this->getIndexedReleasesList();

if (array_key_exists($release, $indexedReleases)) {
$content = $indexedReleases[$release];
} else {
if ($release == 'latest') {
$content = array_shift($indexedReleases);
} else {
throw new \RuntimeException(sprintf('Could not find release %s', $release));
}
}

$version = $content['version'];
$url = $content['uri'];
$sha1 = $content['sha1'];

$target = $this->getTempFile();
$cacheFilePath = $this->getCacheFilePath($version);

if (file_exists($cacheFilePath)) {
return $cacheFilePath;
}

$this->downloader->download($url, $target);
$sha1Actual = sha1_file($target);
if ($sha1 != $sha1Actual) {
throw new \RuntimeException('Hash mismatch');
}
copy($target, $cacheFilePath);

return $cacheFilePath;
}







private function getIndexedReleasesList()
{
$client = new Client();

$response = $client->get(self::DOWNLOAD_UPDATE_API);
$signature = $response->getHeader('X-Shopware-Signature');

if ($this->openSSLVerifier->isSystemSupported()) {
if (!$this->openSSLVerifier->isValid($response->getBody(), $signature[0])) {
throw new \RuntimeException('API signature verification failed');
}
}

$releases = json_decode($response->getBody(), true);
if (empty($releases)) {
throw new \RuntimeException('Could not get releases list package');
}

$indexedReleases = [];
foreach ($releases as $release) {
$indexedReleases[$release['version']] = $release;
}

return $indexedReleases;
}







private function getCacheFilePath($release)
{
return $this->cachePath."/{$release}.zip";
}






private function getTempFile()
{
return sys_get_temp_dir().'/'.uniqid('release_download', true);
}
}
<?php

namespace Shopware\Install\Services;







class Owner
{







public function setUser($path, $user, $recursive)
{
chown($path, $user);

if (!$recursive || !is_dir($path)) {
return;
}

foreach ($this->getIterator($path) as $file) {
chown($file, $user);
}
}








public function setGroup($path, $group, $recursive)
{
chgrp($path, $group);

if (!$recursive || !is_dir($path)) {
return;
}

foreach ($this->getIterator($path) as $file) {
chgrp($file, $group);
}
}







private function getIterator($path)
{
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);

return $iterator;
}
}
<?php

namespace Shopware\Install\Services;

use ShopwareCli\Services\IoService;







class VcsGenerator
{
protected $templateVcsMapping = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
    <component name="VcsDirectoryMappings">
        %s
    </component>
</project>
EOF;

protected $templateVcsMappingDirectory = '<mapping directory="$PROJECT_DIR$%s" vcs="Git" />';



private $ioService;

public function __construct(IoService $ioService)
{
$this->ioService = $ioService;
}

public function createVcsMapping($installDir, $paths)
{
$this->ioService->writeln('<info>Generating VCS mapping</info>');

$dir = $installDir.'/.idea';
if (!is_dir($dir) && !mkdir($dir) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
}

$mappings = [];
foreach ($paths as $path) {
if ($path == '/') {
$path = '';
}
$mappings[] = sprintf($this->templateVcsMappingDirectory, $path);
}

$mappings = implode("\n", $mappings);

file_put_contents($dir . '/vcs.xml', sprintf($this->templateVcsMapping, $mappings));
}
}
<?php

namespace Shopware\Install\Services;

use ShopwareCli\Services\IoService;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Utilities;







class Database
{



private $utilities;




private $connection;




private $ioService;




private $processExecutor;






public function __construct(Utilities $utilities, IoService $ioService, ProcessExecutor $processExecutor)
{
$this->utilities = $utilities;
$this->ioService = $ioService;
$this->processExecutor = $processExecutor;
}

private function createConnection($host, $username, $password, $port = 3306)
{
$this->connection = new \PDO("mysql:host={$host};charset=utf8;port={$port}", $username, $password);
$this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

return $this->connection;
}

private function getConnection()
{
if (!$this->connection) {
throw new \RuntimeException('Connection was not created');
}

return $this->connection;
}

public function setup($user, $password, $name, $host, $port = 3306)
{
$this->ioService->writeln("<info>Creating database $name</info>");

$this->createConnection($host, $user, $password, $port)->query("CREATE DATABASE IF NOT EXISTS `{$name}`;");
$this->getConnection()->query("use `{$name}`;");
}









public function importReleaseInstallDeltas($installDir)
{
$this->getConnection()->exec(
<<<'EOF'
            SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
            SET time_zone = "+00:00";
            SET FOREIGN_KEY_CHECKS = 0;
            /*!40101 SET @saved_cs_client     = @@character_set_client */;
            /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
            /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
            /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
            /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
            /*!40103 SET TIME_ZONE='+00:00' */;
            /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
            /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
            /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
            /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
EOF
);

$this->importBaseDelta($installDir);

$this->getConnection()->exec(
<<<'EOF'
           SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
           SET time_zone = "+00:00";
           SET @locale_de_DE = (SELECT id FROM s_core_locales WHERE locale = "de_DE");
           SET @locale_en_GB = (SELECT id FROM s_core_locales WHERE locale = "en_GB");
EOF
);

$this->importSnippetDeltas($installDir);
}




public function runBuildScripts($installDir)
{
$buildXml = $installDir . '/build/build.xml';
if (!file_exists($buildXml)) {
$this->ioService->writeln("<error>Could not find {$buildXml}</error>");
$this->ioService->writeln(
"<error>If you checked out an SW version < 4.1.0, you can just import {$installDir}/_sql/demo/VERSION.sql</error>"
);

return;
}

$this->ioService->writeln('<info>Running build-unit</info>');
$command = sprintf('ant -f %s build-unit', $buildXml);
$this->processExecutor->execute($command);
}







private function saltPassword($password)
{
return md5('A9ASD:_AD!_=%a8nx0asssblPlasS$' . md5($password));
}












public function createAdmin($user, $name, $mail, $language, $password)
{
$this->ioService->writeln("<info>Creating admin user $user</info>");

$fetchLanguageId = $this->getConnection()->prepare('SELECT id FROM s_core_locales WHERE locale = ?');
$fetchLanguageId->execute([$language]);
$fetchLanguageId = $fetchLanguageId->fetchColumn();

$authTableVersion = $this->getConnection()->prepare('SELECT COUNT(*) as count FROM s_schema_version WHERE version = 411');
$authTableVersion->execute();
$authTableVersion = $authTableVersion->fetchColumn();

if (!$fetchLanguageId) {
throw new \RuntimeException('Could not resolve language '.$language);
}


 $this->getConnection()->query('DELETE FROM s_core_auth');


 if ($authTableVersion) {
$query = <<<'EOF'
INSERT INTO s_core_auth (roleID,username,password,localeID,`name`,email,active,lockeduntil)
VALUES (
    1,?,?,?,?,?,1,'0000-00-00 00:00:00'
)
EOF;
} else {
$query = <<<'EOF'
INSERT INTO s_core_auth (roleID,username,password,localeID,`name`,email,active,admin,salted,lockeduntil)
VALUES (
    1,?,?,?,?,?,1,1,1,'0000-00-00 00:00:00'
)
EOF;
}

$prepareStatement = $this->getConnection()->prepare($query);
$prepareStatement->execute([
$user,
$this->saltPassword($password),
$fetchLanguageId,
$name,
$mail
]);

return true;
}





private function importBaseDelta($installDir)
{
$this->ioService->writeln('<info>Importing main delta</info>');

$installDataDir = $this->getInstallDataFolder($installDir);

$path42 = "{$installDataDir}/sw4_clean.sql";
$pathLatest = "{$installDataDir}/install.sql";

if (!$installDataDir || (!file_exists($path42) && !file_exists($pathLatest))) {
throw new \RuntimeException('Could not find setup delta');
}

$path = file_exists($path42) ? $path42 : $pathLatest;

$deltas = explode(";\n", file_get_contents($path));
foreach ($deltas as $delta) {
$this->getConnection()->exec($delta);
}
}





private function importSnippetDeltas($installDir)
{
$this->ioService->writeln('<info>Importing snippet delta</info>');

$installDataDir = $this->getInstallDataFolder($installDir);
$snippetsFilePath = "{$installDataDir}/snippets.sql";

if (!file_exists($installDataDir) || !file_exists($snippetsFilePath)) {
$this->ioService->writeln('<error>Could not import snippet deltas. This is only ok for shopware versions < 4.2</error>');

return;
}

$deltas = explode(";\n", file_get_contents($snippetsFilePath));
foreach ($deltas as $delta) {
$this->getConnection()->exec($delta);
}
}

private function getInstallDataFolder($installDir)
{
$path42 = "{$installDir}/install/assets/sql";
$pathLatest = "{$installDir}/recovery/install/data/sql";

if (!file_exists($path42) && !file_exists($pathLatest)) {
return;
}

return file_exists($path42) ? $path42 : $pathLatest;
}
}
<?php

namespace Shopware\Install\Services\Install;

use Shopware\Install\Services\Checkout;
use Shopware\Install\Services\ConfigWriter;
use Shopware\Install\Services\Database;
use Shopware\Install\Services\Demodata;
use Shopware\Install\Services\PostInstall;
use Shopware\Install\Services\VcsGenerator;
use ShopwareCli\Config;
use ShopwareCli\Services\IoService;







class Vcs
{

protected $checkout;


protected $config;


protected $vcsGenerator;


protected $configWriter;


protected $database;


protected $demoData;



private $ioService;



private $postInstall;

public function __construct(
Checkout $checkout,
Config $config,
VcsGenerator $vcsGenerator,
ConfigWriter $configWriter,
Database $database,
Demodata $demodata,
IoService $ioService,
PostInstall $postInstall
) {
$this->checkout = $checkout;
$this->config = $config;
$this->vcsGenerator = $vcsGenerator;
$this->configWriter = $configWriter;
$this->database = $database;
$this->demoData = $demodata;
$this->ioService = $ioService;
$this->postInstall = $postInstall;
}











public function installShopware($branch, $installDir, $basePath, $database, $httpUser = null, $noDemoData = false)
{
$this->checkoutRepos($branch, $installDir, $httpUser);


 $installDir = realpath($installDir);

$this->generateVcsMapping($installDir);
$this->writeBuildProperties($installDir, $basePath, $database);
$this->setupDatabase($installDir, $database);
$this->demoData->runLicenseImport($installDir);

if (!$noDemoData) {
$this->demoData->setup($installDir);
}

$this->ioService->writeln('<info>Running post release scripts</info>');
$this->postInstall->fixPermissions($installDir);
$this->postInstall->importCustomDeltas($database);
$this->postInstall->runCustomScripts($installDir);
$this->postInstall->fixShopHost($database);

$this->ioService->writeln('<info>Install completed</info>');
}

private function getDestinationPath($installDir, $destination)
{
return $installDir . $destination;
}







private function checkCoreConfig()
{
$core = $this->config['ShopwareInstallRepos']['core'];
if (!$core['destination'] || !$core['ssh'] || !$core['http']) {
throw new \RuntimeException('You need to have a repo "core" defined in the config.yaml of this plugin');
}

return $core;
}









private function checkoutRepo($branch, $installDir, $httpUser, $repo)
{
$type = $httpUser ? 'http' : 'ssh';

$this->checkout->checkout($repo[$type], $branch, $this->getDestinationPath($installDir, $repo['destination']));
}








private function checkoutRepos($branch, $installDir, $httpUser)
{
$core = $this->checkCoreConfig();

$this->checkoutRepo($branch, $installDir, $httpUser, $core);

foreach ($this->config['ShopwareInstallRepos'] as $name => $repo) {
if ($name == 'core') {
continue;
}
$this->checkoutRepo('master', $installDir, $httpUser, $repo);
}
}






private function generateVcsMapping($installDir)
{
$this->vcsGenerator->createVcsMapping($installDir, array_map(function ($repo) {
return $repo['destination'];
}, $this->config['ShopwareInstallRepos']));
}








private function writeBuildProperties($installDir, $basePath, $database)
{
$this->configWriter->writeBuildProperties(
$installDir,
$this->config['ShopConfig']['host'],
$basePath,
$this->config['DatabaseConfig']['user'],
$this->config['DatabaseConfig']['pass'],
$database,
$this->config['DatabaseConfig']['host'],
isset($this->config['DatabaseConfig']['port']) ? $this->config['DatabaseConfig']['port'] : 3306
);
}







private function setupDatabase($installDir, $database)
{
$this->database->setup(
$this->config['DatabaseConfig']['user'],
$this->config['DatabaseConfig']['pass'],
$database,
$this->config['DatabaseConfig']['host'],
isset($this->config['DatabaseConfig']['port']) ? $this->config['DatabaseConfig']['port'] : 3306
);

$this->database->runBuildScripts($installDir);
}
}
<?php

namespace Shopware\Install\Services\Install;

use Shopware\Install\Services\ConfigWriter;
use Shopware\Install\Services\Database;
use Shopware\Install\Services\Demodata;
use Shopware\Install\Services\PostInstall;
use Shopware\Install\Services\ReleaseDownloader;
use Shopware\Install\Services\VcsGenerator;
use Shopware\Install\Struct\InstallationRequest;
use ShopwareCli\Config;
use ShopwareCli\Services\IoService;
use ShopwareCli\Services\ProcessExecutor;







class Release
{



protected $config;




protected $vcsGenerator;




protected $configWriter;




protected $database;




protected $demoData;




private $releaseDownloader;




private $demodata;




private $ioService;



private $postInstall;




private $processExecutor;












public function __construct(
ReleaseDownloader $releaseDownloader,
Config $config,
VcsGenerator $vcsGenerator,
ConfigWriter $configWriter,
Database $database,
Demodata $demodata,
IoService $ioService,
PostInstall $postInstall,
ProcessExecutor $processExecutor
) {
$this->releaseDownloader = $releaseDownloader;
$this->config = $config;
$this->vcsGenerator = $vcsGenerator;
$this->configWriter = $configWriter;
$this->database = $database;
$this->demodata = $demodata;
$this->ioService = $ioService;
$this->postInstall = $postInstall;
$this->processExecutor = $processExecutor;
}




public function installShopware(InstallationRequest $request)
{
if (!$request->getSkipDownload()) {
$this->releaseDownloader->downloadRelease($request->getRelease(), $request->getInstallDir());
}

if ($request->getOnlyUnpack()) {
return;
}

if ($request->getRelease() === 'latest' || version_compare($request->getRelease(), '5.1.2', '>=')) {
$this->createDatabase($request);
$this->createShopwareConfig($request);
$this->runInstaller($request);
} else {
$this->generateVcsMapping($request->getAbsoluteInstallDir());
$this->createShopwareConfig($request);
$this->setupDatabase($request);
$this->lockInstaller($request->getAbsoluteInstallDir());
}

$this->ioService->writeln('<info>Running post release scripts</info>');
$this->postInstall->fixPermissions($request->getAbsoluteInstallDir());
$this->postInstall->setupTheme($request->getAbsoluteInstallDir());
$this->postInstall->importCustomDeltas($request->getDbName());
$this->postInstall->runCustomScripts($request->getAbsoluteInstallDir());

$this->demodata->runLicenseImport($request->getAbsoluteInstallDir());

$this->ioService->writeln('<info>Install completed</info>');
}

private function createDatabase(InstallationRequest $request)
{
$this->database->setup(
$request->getDbUser() ?: $this->config['DatabaseConfig']['user'],
$request->getDbPassword() ?: $this->config['DatabaseConfig']['pass'],
$request->getDbName(),
$request->getDbHost() ?: $this->config['DatabaseConfig']['host'],
$request->getDbPort() ?: $this->config['DatabaseConfig']['port'] ?: 3306
);
}

private function generateVcsMapping($installDir)
{
$this->vcsGenerator->createVcsMapping($installDir, array_map(function ($repo) {
return $repo['destination'];
}, $this->config['ShopwareInstallRepos']));
}

private function runInstaller(InstallationRequest $request)
{
$delegateOptions = [
'dbHost', 'dbPort', 'dbSocket', 'dbUser', 'dbPassword', 'dbName',
'shopLocale', 'shopHost', 'shopPath', 'shopName', 'shopEmail', 'shopCurrency',
'adminUsername', 'adminPassword', 'adminEmail', 'adminLocale', 'adminName'
];

$arguments = [];
foreach ($request->all() as $key => $value) {
if (!in_array($key, $delegateOptions) || strlen($value) === 0) {
continue;
}

$key = strtolower(preg_replace('/[A-Z]/', '-$0', $key));
$arguments[] = sprintf('--%s="%s"', $key, $value);
}

if ($request->getNoSkipImport()) {
$arguments[] = '--no-skip-import';
}

if ($request->getSkipAdminCreation()) {
$arguments[] = '--skip-admin-creation';
}

$arguments = join(' ', $arguments);

$this->processExecutor->execute("php {$request->getAbsoluteInstallDir()}/recovery/install/index.php {$arguments}");
}






private function createShopwareConfig(InstallationRequest $request)
{
$this->configWriter->writeConfigPhp(
$request->getAbsoluteInstallDir(),
$request->getDbUser() ?: $this->config['DatabaseConfig']['user'],
$request->getDbPassword() ?: $this->config['DatabaseConfig']['pass'],
$request->getDbName(),
$request->getDbHost() ?: $this->config['DatabaseConfig']['host'],
$request->getDbPort() ?: $this->config['DatabaseConfig']['port'] ?: 3306
);
}

private function setupDatabase(InstallationRequest $request)
{
$this->database->setup(
$request->getDbUser() ?: $this->config['DatabaseConfig']['user'],
$request->getDbPassword() ?: $this->config['DatabaseConfig']['pass'],
$request->getDbName(),
$request->getDbHost() ?: $this->config['DatabaseConfig']['host'],
$request->getDbPort() ?: $this->config['DatabaseConfig']['port'] ?: 3306
);
$this->database->importReleaseInstallDeltas($request->getAbsoluteInstallDir());

if ($request->getSkipAdminCreation() !== true) {
$this->database->createAdmin(
$request->getAdminUsername(),
$request->getAdminName(),
$request->getAdminEmail(),
$request->getAdminLocale(),
$request->getAdminPassword()
);
}
}






private function lockInstaller($installDir)
{
if (file_exists($installDir . '/recovery/install/data')) {
touch($installDir . '/recovery/install/data/install.lock');
}
}
}
<?php

namespace Shopware\Install\Services;

use ShopwareCli\Services\IoService;







class ConfigWriter
{
protected $configTemplate = <<<EOF
<?php
return array(
    'db' => array(
        'username' => '%s',
        'password' => '%s',
        'dbname' => '%s',
        'host' => '%s',
        'port' => '%s'
    )
);
EOF;

protected $buildPropertiesTemplate = <<<EOF
app.host = %s
app.path = %s

db.name = %s
db.host = %s
db.user = %s
db.password = %s
db.port = %s

EOF;



private $ioService;

public function __construct(IoService $ioService)
{
$this->ioService = $ioService;
}

public function writeConfigPhp($installDir, $user, $password, $name, $host, $port = 3306)
{
$this->ioService->writeln('<info>Writing config.php</info>');

$config = sprintf($this->configTemplate, $user, $password, $name, $host, $port);

file_put_contents($installDir . '/config.php', $config);
}

public function writeBuildProperties($installDir, $shopHost, $shopPath, $dbUser, $dbPassword, $dbName, $dbHost, $port = 3306)
{
$this->ioService->writeln('<info>Writing build.properties</info>');

$shopPath = '/' . ltrim($shopPath, '/');

$config = sprintf($this->buildPropertiesTemplate, $shopHost, $shopPath, $dbName, $dbHost, $dbUser, $dbPassword, $port);

file_put_contents($installDir . '/build/build.properties', $config);
}
}
<?php
namespace Shopware\Install\Command;

use Shopware\Install\Struct\InstallationRequest;
use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Config;
use ShopwareCli\Services\IoService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ShopwareInstallReleaseCommand extends BaseCommand
{



protected function getConfig()
{
return $this->container->get('config');
}




protected function configure()
{
$this->setName('install:release')
->setDescription('Allows setting up shopware from release package.')
->setHelp(
<<<EOF
                            The <info>%command.name%</info> sets up shopware
EOF
);

$this->addInstallerOptions();
$this->addDbOptions();
$this->addShopOptions();
$this->addAdminOptions();
}

private function addInstallerOptions()
{
$this
->addOption('release', 'r', InputOption::VALUE_REQUIRED, 'Release version. Default: Latest')
->addOption('install-dir', 'i', InputOption::VALUE_REQUIRED, 'Install directory')
->addOption('unpack-only', null, InputOption::VALUE_NONE, 'Only unpack the downloaded release')
->addOption('skip-download', null, InputOption::VALUE_NONE, 'Skip release downloading');
}

private function addDbOptions()
{
$this
->addOption('db-host', null, InputOption::VALUE_REQUIRED, 'Database host', 'localhost')
->addOption('db-port', null, InputOption::VALUE_REQUIRED, 'Database port', '3306')
->addOption('db-socket', null, InputOption::VALUE_REQUIRED, 'Database socket')
->addOption('db-user', null, InputOption::VALUE_REQUIRED, 'Database user')
->addOption('db-password', null, InputOption::VALUE_REQUIRED, 'Database password')
->addOption('db-name', null, InputOption::VALUE_REQUIRED, 'Database name')
->addOption('no-skip-import', null, InputOption::VALUE_NONE, 'Import database data even if a valid schema already exists')
;
}

private function addShopOptions()
{
$this
->addOption('shop-locale', null, InputOption::VALUE_REQUIRED, 'Shop locale', 'de_DE')
->addOption('shop-host', null, InputOption::VALUE_REQUIRED, 'Shop host', 'localhost')
->addOption('shop-path', 'p', InputOption::VALUE_REQUIRED, 'Shop path', '')
->addOption('shop-name', null, InputOption::VALUE_REQUIRED, 'Shop name', 'Demo shop')
->addOption('shop-email', null, InputOption::VALUE_REQUIRED, 'Shop email address', 'your.email@shop.com')
->addOption('shop-currency', null, InputOption::VALUE_REQUIRED, 'Shop currency', 'EUR')
;
}

private function addAdminOptions()
{
$this
->addOption('skip-admin-creation', null, InputOption::VALUE_NONE, 'If provided, no admin user will be created.')
->addOption('admin-username', null, InputOption::VALUE_REQUIRED, 'Administrator username', 'demo')
->addOption('admin-password', null, InputOption::VALUE_REQUIRED, 'Administrator password', 'demo')
->addOption('admin-email', null, InputOption::VALUE_REQUIRED, 'Administrator email address', 'demo@demo.demo')
->addOption('admin-locale', null, InputOption::VALUE_REQUIRED, 'Administrator locale', 'de_DE')
->addOption('admin-name', null, InputOption::VALUE_REQUIRED, 'Administrator name', 'Demo user')
;
}




protected function execute(InputInterface $input, OutputInterface $output)
{
$request = new InstallationRequest([
'release' => $input->getOption('release'),
'installDir' => $input->getOption('install-dir'),
'onlyUnpack' => $input->getOption('unpack-only'),
'skipDownload' => $input->getOption('skip-download'),
'dbHost' => $input->getOption('db-host'),
'dbPort' => $input->getOption('db-port'),
'dbSocket' => $input->getOption('db-socket'),
'dbUser' => $input->getOption('db-user'),
'dbPassword' => $input->getOption('db-password'),
'dbName' => $input->getOption('db-name'),
'shopLocale' => $input->getOption('shop-locale'),
'shopHost' => $input->getOption('shop-host'),
'shopPath' => $input->getOption('shop-path'),
'shopName' => $input->getOption('shop-name'),
'shopEmail' => $input->getOption('shop-email'),
'shopCurrency' => $input->getOption('shop-currency'),
'adminUsername' => $input->getOption('admin-username'),
'adminPassword' => $input->getOption('admin-password'),
'adminEmail' => $input->getOption('admin-email'),
'adminLocale' => $input->getOption('admin-locale'),
'adminName' => $input->getOption('admin-name'),
'noSkipImport' => $input->getOption('no-skip-import'),
'skipAdminCreation' => $input->getOption('skip-admin-creation')
]);


$installService = $this->container->get('shopware_release_install_service');
$installService->installShopware($request);
}





public function interact(InputInterface $input, OutputInterface $output)
{
$this->validateInput($input);


$ioService = $this->container->get('io_service');

$this->askGenericOptions($input, $ioService);

$suggestion = '';
if (!$input->getOption('skip-download')) {
$release = $this->askRelease($input, $ioService);
$suggestion = $release ?: 'latest';

$installDir = $this->askInstallationDirectory($input, $ioService, $suggestion);
$suggestion = $installDir ?: $suggestion;
}

if (!$input->getOption('unpack-only')) {
$this->askBasePath($input, $ioService, $suggestion);

$this->askDatabaseUser($input, $ioService);
$this->askDatabasePassword($input, $ioService);
$this->askDatabaseName($input, $ioService, $suggestion);
}
}






public function genericValidator($input)
{
if (empty($input)) {
throw new \RuntimeException('Field may not be empty');
}

return $input;
}






public function validateInstallDir($path)
{
if (is_dir($path)) {
throw new \RuntimeException("Path '{$path}'' is not empty");
}

return $path;
}





protected function validateInput(InputInterface $input)
{
$language = $input->getOption('shop-locale');
if (!in_array($language, ['en_GB', 'de_DE'])) {
throw new \RuntimeException("Invalid locale: '$language'");
}
}







private function askGenericOptions(InputInterface $input, IoService $ioService)
{
$required = [
'admin-username' => 'backend user name',
'admin-password' => 'backend user password',
'admin-name' => 'your full name',
'admin-email' => 'your email'
];

$config = $this->getConfig();

foreach ($required as $field => $description) {

 if ($input->getOption($field)) {
continue;
}


 if (isset($config['ShopConfig']) && isset($config['ShopConfig'][$field])) {
$input->setOption($field, $config['ShopConfig'][$field]);
continue;
}

$hidden = false;

if ($field === 'admin-password') {
$hidden = true;
}

$fieldData = $ioService->askAndValidate(
"Please enter $description: ",
[$this, 'genericValidator'],
false,
null,
$hidden
);
$input->setOption($field, $fieldData);
}
}







private function askRelease(InputInterface $input, IoService $ioService)
{
$release = $input->getOption('release');
if (!$release) {
$release = $ioService->ask('Please provide the release you want to install [latest]: ');
$release = trim($release) ? $release : 'latest';
$input->setOption('release', $release);

return $release;
}

return $release;
}








private function askInstallationDirectory(InputInterface $input, IoService $ioService, $suggestion)
{
$installDir = $input->getOption('install-dir');
if (!$installDir) {
$installDir = $ioService->askAndValidate(
"Please provide the install directory [{$suggestion}]: ",
[$this, 'validateInstallDir']
);
$input->setOption('install-dir', trim($installDir) ? $installDir : $suggestion);

return $installDir;
}

return $installDir;
}






private function askDatabaseName(InputInterface $input, IoService $ioService, $suggestion)
{
$databaseName = $input->getOption('db-name');
if (!$databaseName) {
$databaseName = $ioService->ask("Please provide the database name you want to use [{$suggestion}]: ");
$input->setOption('db-name', trim($databaseName) ? $databaseName : $suggestion);
}
}






private function askBasePath(InputInterface $input, IoService $ioService, $suggestion)
{
$basePath = $input->getOption('shop-path');
if (!$basePath) {
$suggestion = '/' . ltrim($suggestion, '/');
$basePath = $ioService->ask("Please provide the shop base path you want to use [{$suggestion}]: ");
$input->setOption('shop-path', trim($basePath) ? $basePath : $suggestion);
}
}





private function askDatabaseUser(InputInterface $input, IoService $ioService)
{
$databaseUser = $input->getOption('db-user');
if (!$databaseUser) {
$databaseUser = $ioService->ask('Please provide the database user: ');
$input->setOption('db-user', trim($databaseUser));
}
}





private function askDatabasePassword(InputInterface $input, IoService $ioService)
{
$databasePassword = $input->getOption('db-password');
if (!$databasePassword) {
$databasePassword = $ioService->ask('Please provide the database password: ', null, true);
$input->setOption('db-password', trim($databasePassword));
}
}
}
<?php
namespace Shopware\Install\Command;

use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Services\ProcessExecutor;
use ShopwareCli\Services\ShopwareInfo;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ShopwareClearCacheCommand extends BaseCommand
{



protected function configure()
{
$this
->setName('cache:clear')
->setDescription('Clear the shopware cache.')
->addOption(
'installDir',
'i',
InputOption::VALUE_OPTIONAL,
'Install directory'
)
->setHelp('The <info>%command.name%</info> clears the shopware cache');
}




protected function execute(InputInterface $input, OutputInterface $output)
{
$path = $this->checkPath($input);

if (strpos($path, '/') !== 0) {
$path = './'.$path;
}


$shopwareInfo = $this->container->get('shopware_info');


$processExecutor = $this->container->get('process_executor');
$processExecutor->execute($shopwareInfo->getCacheDir($path).'/clear_cache.sh');
}






public function validateShopwareDirectory($path)
{
if (!$this->container->get('utilities')->isShopwareInstallation($path)) {
throw new \RuntimeException("'$path' is not a valid shopware path");
}

return rtrim($path, '/');
}





private function checkPath(InputInterface $input)
{
$shopwarePath = $input->getOption('installDir');

$shopwarePath = $this->container->get('utilities')->getValidShopwarePath($shopwarePath);

$input->setOption('installDir', $shopwarePath);

return $shopwarePath;
}
}
<?php
namespace Shopware\Install\Command;

use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Services\IoService;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ShopwareInstallVcsCommand extends BaseCommand
{
const MAIN_BRANCH = '5.5';




protected function configure()
{
$this
->setName('install:vcs')
->setDescription('Allows setting up shopware from VCS.')
->addOption(
'branch',
'-b',
InputOption::VALUE_OPTIONAL,
'Branch to checkout'
)
->addOption(
'databaseName',
'-d',
InputOption::VALUE_OPTIONAL,
'Name of database'
)
->addOption(
'installDir',
'i',
InputOption::VALUE_OPTIONAL,
'Install directory'
)
->addOption(
'basePath',
'p',
InputOption::VALUE_OPTIONAL,
'base path of the shop'
)
->addOption(
'user',
'u',
InputOption::VALUE_OPTIONAL,
'GIT repos username. If given, checkout will be done using HTTP'
)
->addOption(
'noDemoData',
null,
InputOption::VALUE_NONE,
'If set, the demo data will not be installed'
)
->setHelp(
<<<EOF
The <info>%command.name%</info> sets up shopware
EOF
);
;
}




protected function execute(InputInterface $input, OutputInterface $output)
{

$installService = $this->container->get('shopware_vcs_install_service');

$installService->installShopware(
$input->getOption('branch'),
trim($input->getOption('installDir'), '/'),
$input->getOption('basePath'),
$input->getOption('databaseName'),
$input->getOption('user'),
$input->getOption('noDemoData')
);
}





public function interact(InputInterface $input, OutputInterface $output)
{

$ioService = $this->container->get('io_service');

$branch = $this->askBranch($input, $ioService);

$suggestion = $this->suggestNameFromBranch($branch) ?: self::MAIN_BRANCH;

$installDir = $this->askInstallationDir($input, $ioService, $suggestion);

$suggestion = $installDir ?: $suggestion;

$this->askDatabaseName($input, $ioService, $suggestion);
$this->askBasePath($input, $ioService, $suggestion);
}







private function suggestNameFromBranch($branch)
{
$result = [];
$pattern = '#sw-(?P<number>.+?)/(?P<target>.+?)/.*#i';
preg_match($pattern, $branch, $result);

if (isset($result['number'])) {
return 'sw' . $result['number'];
}

return str_replace('.', '', $branch);
}






public function validateInstallDir($path)
{
if (is_dir($path)) {
throw new \RuntimeException("Path '{$path}'' is not empty");
}

return $path;
}








private function askInstallationDir(InputInterface $input, IoService $ioService, $suggestion)
{
$installDir = $input->getOption('installDir');
if (!$installDir) {
$installDir = $ioService->askAndValidate(
"Please provide the install directory <{$suggestion}>: ",
[$this, 'validateInstallDir']
);
$input->setOption('installDir', trim($installDir) ? $installDir : $suggestion);

return $installDir;
}

return $installDir;
}






private function askDatabaseName(InputInterface $input, IoService $ioService, $suggestion)
{
$databaseName = $input->getOption('databaseName');
if (!$databaseName) {
$databaseName = $ioService->ask("Please provide the database name you want to use <{$suggestion}>: ");
$input->setOption('databaseName', trim($databaseName) ? $databaseName : $suggestion);
}
}






private function askBasePath(InputInterface $input, IoService $ioService, $suggestion)
{
$basePath = $input->getOption('basePath');
if (!$basePath) {
$basePath = $ioService->ask("Please provide the basepath you want to use <{$suggestion}>: ");
$input->setOption('basePath', trim($basePath) ? $basePath : $suggestion);
}
}







private function askBranch(InputInterface $input, IoService $ioService)
{
$branch = $input->getOption('branch');
if (!$branch) {
$branchSuggestion = self::MAIN_BRANCH;
$branch = $ioService->ask("Please provide the branch you want to install <{$branchSuggestion}>: ");
$branch = trim($branch) ? $branch : self::MAIN_BRANCH;
$input->setOption('branch', $branch);

return $branch;
}

return $branch;
}
}
<?php

namespace Shopware\PluginCreator\Struct;

use ShopwareCli\Struct;







class Configuration extends Struct
{
public $phpFileHeader = "<?php\n";


 public $pluginConfig;


 public $name;

 public $namespace;


 public $hasFrontend;

 public $hasBackend;

 public $hasWidget;

 public $hasApi;

 public $hasModels;

 public $hasCommands;

 public $hasFilter;


 public $backendModel;

 public $licenseHeader;
public $licenseHeaderPlain;


 public $isLegacyPlugin = false;


 public $hasElasticSearch = false;
}
<?php

namespace Shopware\PluginCreator;

use Shopware\PluginCreator\Command\CreatePluginCommand;
use ShopwareCli\Application\ConsoleAwareExtension;
use ShopwareCli\Application\ContainerAwareExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class Bootstrap implements ContainerAwareExtension, ConsoleAwareExtension
{
protected $container;

public function setContainer(ContainerBuilder $container)
{
$this->container = $container;
}






public function getConsoleCommands()
{
return [
new CreatePluginCommand()
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider;

class LegacyOptionFileProviderLoader implements FileProviderLoaderInterface
{



private $isLegacy;





public function __construct($isLegacy)
{
if (!is_bool($isLegacy)) {
throw new \Exception('Boolean expected, got ' . gettype($isLegacy));
}

$this->isLegacy = $isLegacy;
}






public function load()
{
if ($this->isLegacy) {
return $this->getLegacyProvider();
}
return $this->getCurrentProvider();
}




private function getLegacyProvider()
{
return [
new Legacy\ApiFileProvider(),
new Legacy\BackendControllerFileProvider(),
new Legacy\BackendFileProvider(),
new Legacy\CommandFileProvider(),
new Legacy\ControllerPathFileProvider(),
new Legacy\DefaultFileProvider(),
new Legacy\FilterFileProvider(),
new Legacy\FrontendFileProvider(),
new Legacy\ModelFileProvider(),
new Legacy\WidgetFileProvider(),
new Legacy\ElasticSearchProvider()
];
}




private function getCurrentProvider()
{
return [
new Current\ApiFileProvider(),
new Current\BackendControllerFileProvider(),
new Current\BackendFileProvider(),
new Current\CommandFileProvider(),
new Current\ControllerPathFileProvider(),
new Current\DefaultFileProvider(),
new Current\FilterFileProvider(),
new Current\FrontendFileProvider(),
new Current\ModelFileProvider(),
new Current\WidgetFileProvider(),
new Current\ElasticSearchProvider()
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class ApiFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasApi) {
return [];
}

return [
self::LEGACY_DIR . 'Components/Api/Resource/Resource.tpl' => "Components/Api/Resource/{$nameGenerator->camelCaseModel}.php",
self::LEGACY_DIR . 'Controllers/Api.tpl' => "Controllers/Api/{$nameGenerator->camelCaseModel}.php",
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\DataGenerator\Struct\Config;
use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class BackendControllerFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasBackend && !$configuration->hasWidget) {
return [];
}

return [
self::LEGACY_DIR . 'Controllers/Backend.tpl' => "Controllers/Backend/{$configuration->name}.php"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;

class ElasticSearchProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasElasticSearch) {
return [];
}

return [
self::LEGACY_DIR . 'Components/ESIndexingBundle/DataIndexer.tpl' => 'Components/ESIndexingBundle/DataIndexer.php',
self::LEGACY_DIR . 'Components/ESIndexingBundle/Mapping.tpl' => 'Components/ESIndexingBundle/Mapping.php',
self::LEGACY_DIR . 'Components/ESIndexingBundle/Provider.tpl' => 'Components/ESIndexingBundle/Provider.php',
self::LEGACY_DIR . 'Components/ESIndexingBundle/Settings.tpl' => 'Components/ESIndexingBundle/Settings.php',
self::LEGACY_DIR . 'Components/ESIndexingBundle/Synchronizer.tpl' => 'Components/ESIndexingBundle/Synchronizer.php',
self::LEGACY_DIR . 'Components/SearchBundleES/Search.tpl' => 'Components/SearchBundleES/Search.php'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class ControllerPathFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasBackend
&& !$configuration->hasFrontend
&& !$configuration->hasWidget
&& !$configuration->hasApi
) {
return [];
}

return [
self::LEGACY_DIR . 'Subscriber/ControllerPath.tpl' => 'Subscriber/ControllerPath.php',
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class CommandFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasCommands) {
return [];
}

return [
self::LEGACY_DIR . 'Commands/Command.tpl' => "Commands/{$nameGenerator->camelCaseModel}.php"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class WidgetFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasWidget) {
return [];
}

return [
self::LEGACY_DIR . 'Views/backend/widget/main.tpl' => "Views/backend/{$nameGenerator->under_score_js}/widgets/{$nameGenerator->under_score_js}.js",
self::LEGACY_DIR . 'Snippets/backend/widget/labels.tpl' => 'Snippets/backend/widget/labels.ini'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class BackendFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasBackend) {
return [];
}

return [
self::LEGACY_DIR . 'Views/backend/application/app.tpl' => "Views/backend/{$nameGenerator->under_score_js}/app.js",
self::LEGACY_DIR . 'Views/backend/application/controller/main.tpl' => "Views/backend/{$nameGenerator->under_score_js}/controller/main.js",
self::LEGACY_DIR . 'Views/backend/application/model/main.tpl' => "Views/backend/{$nameGenerator->under_score_js}/model/main.js",
self::LEGACY_DIR . 'Views/backend/application/store/main.tpl' => "Views/backend/{$nameGenerator->under_score_js}/store/main.js",
self::LEGACY_DIR . 'Views/backend/application/view/detail/container.tpl' => "Views/backend/{$nameGenerator->under_score_js}/view/detail/container.js",
self::LEGACY_DIR . 'Views/backend/application/view/detail/window.tpl' => "Views/backend/{$nameGenerator->under_score_js}/view/detail/window.js",
self::LEGACY_DIR . 'Views/backend/application/view/list/list.tpl' => "Views/backend/{$nameGenerator->under_score_js}/view/list/list.js",
self::LEGACY_DIR . 'Views/backend/application/view/list/window.tpl' => "Views/backend/{$nameGenerator->under_score_js}/view/list/window.js",
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class FilterFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasFilter) {
return [];
}

return [
self::LEGACY_DIR . 'Components/SearchBundleDBAL/Condition/Condition.tpl' => "Components/SearchBundleDBAL/Condition/{$configuration->name}Condition.php",
self::LEGACY_DIR . 'Components/SearchBundleDBAL/Condition/ConditionHandler.tpl' => "Components/SearchBundleDBAL/Condition/{$configuration->name}ConditionHandler.php",
self::LEGACY_DIR . 'Components/SearchBundleDBAL/Facet/Facet.tpl' => "Components/SearchBundleDBAL/Facet/{$configuration->name}Facet.php",
self::LEGACY_DIR . 'Components/SearchBundleDBAL/Facet/FacetHandler.tpl' => "Components/SearchBundleDBAL/Facet/{$configuration->name}FacetHandler.php",
self::LEGACY_DIR . 'Components/SearchBundleDBAL/CriteriaRequestHandler.tpl' => "Components/SearchBundleDBAL/{$configuration->name}CriteriaRequestHandler.php",
self::LEGACY_DIR . 'Subscriber/SearchBundle.tpl' => 'Subscriber/SearchBundle.php'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class DefaultFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
return [
self::LEGACY_DIR . 'Readme.tpl' => 'Readme.md',
self::LEGACY_DIR . 'LICENSE' => 'LICENSE',
self::LEGACY_DIR . 'Subscriber/Frontend.tpl' => 'Subscriber/Frontend.php',
self::LEGACY_DIR . 'phpunit.xml.dist.tpl' => 'phpunit.xml.dist',
self::LEGACY_DIR . 'Bootstrap.tpl' => 'Bootstrap.php',
self::LEGACY_DIR . 'plugin.tpl' => 'plugin.json',
self::LEGACY_DIR . 'tests/LegacyPluginTest.tpl' => 'tests/Test.php',
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class ModelFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasModels) {
return [];
}

return [
self::LEGACY_DIR . 'Models/Model.tpl' => "Models/{$configuration->name}/{$nameGenerator->camelCaseModel}.php",
self::LEGACY_DIR . 'Models/Repository.tpl' => "Models/{$configuration->name}/Repository.php"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Legacy;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class FrontendFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasFrontend) {
return [];
}

return [
self::LEGACY_DIR . 'Controllers/Frontend.tpl' => "Controllers/Frontend/{$configuration->name}.php",
self::LEGACY_DIR . 'Views/frontend/plugin_name/index.tpl' => "Views/frontend/{$nameGenerator->under_score_js}/index.tpl"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider;

interface FileProviderLoaderInterface
{





public function load();
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Struct\Configuration;








interface FileProviderInterface
{



const CURRENT_DIR = 'current/';




const LEGACY_DIR = 'legacy/';







public function getFiles(Configuration $configuration, NameGenerator $nameGenerator);
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class ApiFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasApi) {
return [];
}

return [
self::CURRENT_DIR . 'Components/Api/Resource/Resource.tpl' => "Components/Api/Resource/{$nameGenerator->camelCaseModel}.php",
self::CURRENT_DIR . 'Controllers/Api.tpl' => "Controllers/Api/{$nameGenerator->camelCaseModel}.php",
self::CURRENT_DIR . 'Subscriber/ApiSubscriber.tpl' => 'Subscriber/ApiSubscriber.php'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\DataGenerator\Struct\Config;
use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class BackendControllerFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasBackend && !$configuration->hasWidget) {
return [];
}

return [
self::CURRENT_DIR . 'Controllers/Backend.tpl' => "Controllers/Backend/{$configuration->name}.php"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;

class ElasticSearchProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasElasticSearch) {
return [];
}

return [
self::CURRENT_DIR . 'Components/ESIndexingBundle/DataIndexer.tpl' => 'Components/ESIndexingBundle/DataIndexer.php',
self::CURRENT_DIR . 'Components/ESIndexingBundle/Mapping.tpl' => 'Components/ESIndexingBundle/Mapping.php',
self::CURRENT_DIR . 'Components/ESIndexingBundle/Provider.tpl' => 'Components/ESIndexingBundle/Provider.php',
self::CURRENT_DIR . 'Components/ESIndexingBundle/Settings.tpl' => 'Components/ESIndexingBundle/Settings.php',
self::CURRENT_DIR . 'Components/ESIndexingBundle/Synchronizer.tpl' => 'Components/ESIndexingBundle/Synchronizer.php',
self::CURRENT_DIR . 'Components/SearchBundleES/Search.tpl' => 'Components/SearchBundleES/Search.php'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class ControllerPathFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasBackend
&& !$configuration->hasFrontend
&& !$configuration->hasWidget
&& !$configuration->hasApi
) {
return [];
}

return [
self::CURRENT_DIR . 'Subscriber/ControllerPath.tpl' => 'Subscriber/ControllerPath.php',
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class CommandFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasCommands) {
return [];
}

return [
self::CURRENT_DIR . 'Commands/Command.tpl' => "Commands/{$nameGenerator->camelCaseModel}.php"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class WidgetFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasWidget) {
return [];
}

return [
self::CURRENT_DIR . 'Resources/views/backend/widget/main.tpl' => "Resources/views/backend/widgets/{$nameGenerator->under_score_js}.js",
self::CURRENT_DIR . 'Subscriber/BackendWidget.tpl' => 'Subscriber/BackendWidget.php',
self::CURRENT_DIR . 'Resources/snippets/backend/widget/labels.tpl' => 'Resources/snippets/backend/widget/labels.ini',
self::CURRENT_DIR . 'Controllers/BackendWidget.tpl' => "Controllers/Backend/{$nameGenerator->backendWidgetController}.php"
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class BackendFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasBackend) {
return [];
}

return [
self::CURRENT_DIR . 'Resources/views/backend/application/app.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/app.js",
self::CURRENT_DIR . 'Resources/views/backend/application/controller/main.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/controller/main.js",
self::CURRENT_DIR . 'Resources/views/backend/application/model/main.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/model/main.js",
self::CURRENT_DIR . 'Resources/views/backend/application/store/main.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/store/main.js",
self::CURRENT_DIR . 'Resources/views/backend/application/view/detail/container.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/view/detail/container.js",
self::CURRENT_DIR . 'Resources/views/backend/application/view/detail/window.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/view/detail/window.js",
self::CURRENT_DIR . 'Resources/views/backend/application/view/list/list.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/view/list/list.js",
self::CURRENT_DIR . 'Resources/views/backend/application/view/list/window.tpl' => "Resources/views/backend/{$nameGenerator->under_score_js}/view/list/window.js",
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class FilterFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasFilter) {
return [];
}

return [
self::CURRENT_DIR . 'Components/SearchBundleDBAL/Condition/Condition.tpl' => "Components/SearchBundleDBAL/Condition/{$configuration->name}Condition.php",
self::CURRENT_DIR . 'Components/SearchBundleDBAL/Condition/ConditionHandler.tpl' => "Components/SearchBundleDBAL/Condition/{$configuration->name}ConditionHandler.php",
self::CURRENT_DIR . 'Components/SearchBundleDBAL/Facet/Facet.tpl' => "Components/SearchBundleDBAL/Facet/{$configuration->name}Facet.php",
self::CURRENT_DIR . 'Components/SearchBundleDBAL/Facet/FacetHandler.tpl' => "Components/SearchBundleDBAL/Facet/{$configuration->name}FacetHandler.php",
self::CURRENT_DIR . 'Components/SearchBundleDBAL/Sorting/Sorting.tpl' => 'Components/SearchBundleDBAL/Sorting/Sorting.php',
self::CURRENT_DIR . 'Components/SearchBundleDBAL/Sorting/SortingHandler.tpl' => 'Components/SearchBundleDBAL/Sorting/SortingHandler.php',
self::CURRENT_DIR . 'Components/SearchBundle/CriteriaRequestHandler.tpl' => "Components/SearchBundle/{$configuration->name}CriteriaRequestHandler.php",
self::CURRENT_DIR . 'Subscriber/SearchBundle.tpl' => 'Subscriber/SearchBundle.php',
self::CURRENT_DIR . 'Resources/views/frontend/listing/actions/action-sorting.tpl' => 'Resources/views/frontend/listing/actions/action-sorting.tpl'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class DefaultFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
$pluginClassName = "{$configuration->name}.php";

return [
self::CURRENT_DIR . 'PluginClass.tpl' => $pluginClassName,
self::CURRENT_DIR . 'plugin.xml.tpl' => 'plugin.xml',
self::CURRENT_DIR . 'Readme.tpl' => 'Readme.md',
self::CURRENT_DIR . 'LICENSE' => 'LICENSE',
self::CURRENT_DIR . 'Subscriber/Frontend.tpl' => 'Subscriber/Frontend.php',
self::CURRENT_DIR . 'phpunit.xml.dist.tpl' => 'phpunit.xml.dist',
self::CURRENT_DIR . 'tests/PluginTest.tpl' => 'tests/PluginTest.php',
self::CURRENT_DIR . 'Resources/services.xml.tpl' => 'Resources/services.xml',
self::CURRENT_DIR . 'Resources/config.xml.tpl' => 'Resources/config.xml',
self::CURRENT_DIR . 'Resources/menu.xml.tpl' => 'Resources/menu.xml'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class ModelFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasModels) {
return [];
}

return [
self::CURRENT_DIR . 'Models/Model.tpl' => "Models/{$nameGenerator->camelCaseModel}.php",
self::CURRENT_DIR . 'Models/Repository.tpl' => 'Models/Repository.php'
];
}
}
<?php

namespace Shopware\PluginCreator\Services\TemplateFileProvider\Current;

use Shopware\PluginCreator\Services\NameGenerator;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;





class FrontendFileProvider implements FileProviderInterface
{



public function getFiles(Configuration $configuration, NameGenerator $nameGenerator)
{
if (!$configuration->hasFrontend) {
return [];
}

return [
self::CURRENT_DIR . 'Controllers/Frontend.tpl' => "Controllers/Frontend/{$configuration->name}.php",
self::CURRENT_DIR . 'Resources/views/frontend/plugin_name/index.tpl' => "Resources/views/frontend/{$nameGenerator->under_score_js}/index.tpl"
];
}
}
<?php


namespace Shopware\PluginCreator\Services\IoAdapter;







interface IoAdapter
{




public function exists($path);





public function createDirectory($dir);






public function createFile($file, $content);
}
<?php

namespace Shopware\PluginCreator\Services\IoAdapter;







class Dummy implements IoAdapter
{
protected $files = [];





public function exists($path)
{
return false;
}

public function createDirectory($dir)
{
return true;
}

public function createFile($file, $content)
{
$this->files[$file] = $content;
}




public function getFiles()
{
return $this->files;
}
}
<?php

namespace Shopware\PluginCreator\Services\IoAdapter;







class HardDrive implements IoAdapter
{




public function exists($path)
{
return file_exists($path);
}

public function createDirectory($path)
{
if ($this->exists($path)) {
return;
}

$success = mkdir($path, 0777, true);

if (!$success) {
throw new \RuntimeException("Could not create »{$path}«. Check your directory permission");
}
}

public function createFile($file, $content)
{
file_put_contents($file, $content);
}
}
<?php

namespace Shopware\PluginCreator\Services\WorkingDirectoryProvider;

interface OutputDirectoryProviderInterface
{



public function getPath();
}
<?php

namespace Shopware\PluginCreator\Services\WorkingDirectoryProvider\RootDetector;

class ShopwareRootDetector implements RootDetectorInterface
{



public static function getDirectories()
{
return [
'/engine',
'/var',
'/bin',
'/vendor',
'/files'
];
}




public static function getFiles()
{
return [
'/shopware.php'
];
}





public function isRoot($path)
{
if ($this->validateDirectories($path) && $this->validateFiles($path)) {
return true;
}

return false;
}





private function validateDirectories($path)
{
foreach (self::getDirectories() as $directory) {
if (!is_dir($path . $directory)) {
return false;
}
}

return true;
}





private function validateFiles($path)
{
foreach (self::getFiles() as $file) {
if (!file_exists($path . $file)) {
return false;
}
}

return true;
}
}
<?php

namespace Shopware\PluginCreator\Services\WorkingDirectoryProvider\RootDetector;

interface RootDetectorInterface
{




public function isRoot($path);
}
<?php

namespace Shopware\PluginCreator\Services\WorkingDirectoryProvider;

use Shopware\PluginCreator\Services\WorkingDirectoryProvider\RootDetector\RootDetectorInterface;

class CurrentOutputDirectoryProvider implements OutputDirectoryProviderInterface
{
const CURRENT_PLUGIN_DIR = 'custom/plugins';




private $rootDetector;




private $name;





public function __construct(RootDetectorInterface $rootDetector, $name)
{
$this->rootDetector = $rootDetector;
$this->name = $name;
}




public function getPath()
{
if ($this->rootDetector->isRoot($this->getCwd())) {
return $this->getCwd() . '/' . self::CURRENT_PLUGIN_DIR . '/' . $this->name . '/';
}
return $this->getCwd() . '/' . $this->name . '/';
}




private function getCwd()
{
return getcwd();
}
}
<?php

namespace Shopware\PluginCreator\Services\WorkingDirectoryProvider;

use Shopware\PluginCreator\Services\WorkingDirectoryProvider\RootDetector\RootDetectorInterface;

class LegacyOutputDirectoryProvider implements OutputDirectoryProviderInterface
{
const LEGACY_PLUGIN_DIR = 'engine/Shopware/Plugins/Local';

const FRONTEND_NAMESPACE = 'Frontend';
const BACKEND_NAMESPACE = 'Backend';
const CORE_NAMESPACE = 'Core';




private $namespace;




private $rootDetector;




private $name;







public function __construct(RootDetectorInterface $rootDetector, $name, $namespace)
{
if (!$this->isValidNamespace($namespace) && strlen($namespace)) {
throw new \Exception(
sprintf('Invalid namespace given: %s', $namespace)
);
}

$this->namespace = $namespace;
$this->rootDetector = $rootDetector;
$this->name = $name;
}




public function getPath()
{
if ($this->rootDetector->isRoot($this->getCwd())) {
return $this->getCwd() . '/' . self::LEGACY_PLUGIN_DIR . '/' . $this->namespace . '/' . $this->name . '/';
}

return $this->getCwd() . '/' . $this->name . '/';
}





private function isValidNamespace($namespace)
{
return self::FRONTEND_NAMESPACE == $namespace || self::BACKEND_NAMESPACE == $namespace || self::CORE_NAMESPACE == $namespace;
}




private function getCwd()
{
return getcwd();
}
}
<?php

namespace Shopware\PluginCreator\Services;

use Shopware\PluginCreator\Struct\Configuration;







class NameGenerator
{

 public $developerPrefix;

 public $dash_js;

 public $under_score_js;

 public $under_score_model;

 public $camelCaseModel;

 public $backendModelAlias;

 public $backendWidgetController;




private $configuration;

public function __construct(Configuration $configuration)
{
$this->configuration = $configuration;

$this->generateNames();
}




public function generateNames()
{
$parts = $this->upperToArray($this->configuration->name);

$backendModelParts = $this->upperToArray($this->getModelName());

$this->backendModelAlias = $this->getBackendModelAlias();
$this->camelCaseModel = implode('', $backendModelParts);
$this->under_score_model = strtolower(implode('_', $backendModelParts));
$this->under_score_js = strtolower(implode('_', $parts));
$this->dash_js = strtolower(implode('-', $parts));
$this->developerPrefix = $parts[0];
$this->backendWidgetController = $this->configuration->name . 'Widget';
}






public function getModelName()
{
if (!$this->configuration->backendModel) {
return implode('', array_slice($this->upperToArray($this->configuration->name), 1));
}

$parts = explode('\\', $this->configuration->backendModel);

return array_pop($parts);
}






public function getBackendModelAlias()
{
if (!$this->configuration->backendModel) {
return 'alias';
}

$parts = explode('\\', $this->configuration->backendModel);

return strtolower(array_pop($parts));
}







public function upperToArray($input)
{
return preg_split('/(?=[A-Z])/', $input, -1, PREG_SPLIT_NO_EMPTY);
}
}
<?php

namespace Shopware\PluginCreator\Services;







class Template
{
private $_templateVars = [];

private $_path = '';






public function setTemplatePath($path)
{
$this->_path = rtrim($path, '/') . '/';
}







public function assign($name, $value)
{
$this->_templateVars[$name] = $value;
}







public function fetch($_template)
{
return $this->doRender($_template, true);
}






public function display($_template)
{
$this->doRender($_template);
}











private function doRender($_template, $return = false)
{

 if ($this->_templateVars) {
extract($this->_templateVars, EXTR_SKIP);
}

if ($return) {
ob_start();
}
$old = set_error_handler([$this, 'errorReporter']);
include $this->_path . $_template;
set_error_handler($old);
if ($return) {
return ob_get_clean();
}
}

public function errorReporter($severity, $message, $filename, $lineno)
{
ob_clean();
throw new \ErrorException($message . ': ' . $filename . ', line ' . $lineno, 0, $severity, $filename, $lineno);
}
}
<?php

namespace Shopware\PluginCreator\Services;

use Shopware\PluginCreator\Services\IoAdapter\HardDrive;
use Shopware\PluginCreator\Services\TemplateFileProvider\LegacyOptionFileProviderLoader;
use Shopware\PluginCreator\Services\WorkingDirectoryProvider\CurrentOutputDirectoryProvider;
use Shopware\PluginCreator\Services\WorkingDirectoryProvider\LegacyOutputDirectoryProvider;
use Shopware\PluginCreator\Services\WorkingDirectoryProvider\RootDetector\ShopwareRootDetector;
use Shopware\PluginCreator\Struct\Configuration;





class GeneratorFactory
{




public function create(Configuration $configuration)
{
$legacyOptionFileProvider = new LegacyOptionFileProviderLoader($configuration->isLegacyPlugin);
$outputDirectoryProvider = $this->getOutputDirectoryProvider($configuration);

return new Generator(
new HardDrive(),
$configuration,
new NameGenerator($configuration),
new Template(),
$legacyOptionFileProvider,
$outputDirectoryProvider
);
}





private function getOutputDirectoryProvider(Configuration $configuration)
{
$outputDirectoryProvider = new CurrentOutputDirectoryProvider(
new ShopwareRootDetector(),
$configuration->name
);

if ($configuration->isLegacyPlugin) {
return new LegacyOutputDirectoryProvider(
new ShopwareRootDetector(),
$configuration->name,
$configuration->namespace
);
}
return $outputDirectoryProvider;
}
}
<?php

namespace Shopware\PluginCreator\Services;

use Shopware\PluginCreator\Services\IoAdapter\IoAdapter;
use Shopware\PluginCreator\Services\TemplateFileProvider\FileProviderLoaderInterface;
use Shopware\PluginCreator\Services\WorkingDirectoryProvider\OutputDirectoryProviderInterface;
use Shopware\PluginCreator\Struct\Configuration;

class Generator
{
const TEMPLATE_DIRECTORY = 'template';




private $configuration;




private $template;




private $nameGenerator;




private $ioAdapter;




private $fileProviderLoader;




private $outputDirectoryProvider;









public function __construct(
IoAdapter $ioAdapter,
Configuration $configuration,
NameGenerator $nameGenerator,
Template $template,
FileProviderLoaderInterface $fileProviderLoader,
OutputDirectoryProviderInterface $outputDirectoryProvider
) {
$this->configuration = $configuration;
$this->template = $template;
$this->nameGenerator = $nameGenerator;
$this->ioAdapter = $ioAdapter;
$this->fileProviderLoader = $fileProviderLoader;
$this->outputDirectoryProvider = $outputDirectoryProvider;
}




public function run()
{
$this->configureTemplate();

$path = $this->outputDirectoryProvider->getPath();
if ($this->ioAdapter->exists($path)) {
throw new \RuntimeException("Could not create »{$path}«. Directory already exists");
}
$this->ioAdapter->createDirectory($path);

$this->processTemplateFiles();
}






private function createFilesFromTemplate($files)
{
foreach ($files as $from => $to) {
$fileContent = $this->template->fetch($from);

$path = $this->outputDirectoryProvider->getPath();
$this->ioAdapter->createDirectory(dirname($path . $to));

$this->ioAdapter->createFile($path . $to, $fileContent);
}
}




private function configureTemplate()
{
$this->template->assign('configuration', $this->configuration);
$this->template->assign('names', $this->nameGenerator);
$this->template->setTemplatePath(dirname(__DIR__) . '/' . self::TEMPLATE_DIRECTORY);
}




private function processTemplateFiles()
{
foreach ($this->fileProviderLoader->load() as $provider) {
$this->createFilesFromTemplate(
$provider->getFiles($this->configuration, $this->nameGenerator)
);
}
}
}
<?php

namespace Shopware\PluginCreator\Command;

use Shopware\PluginCreator\Services\GeneratorFactory;
use Shopware\PluginCreator\Struct\Configuration;
use ShopwareCli\Command\BaseCommand;
use ShopwareCli\Config;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;

class CreatePluginCommand extends BaseCommand
{
const LEGACY_OPTION = 'legacy';




protected function getConfig()
{
return $this->container->get('config');
}




protected function configure()
{
$this->setName('plugin:create')->setDescription('Creates a new plugin.')
->addArgument(
'name',
InputArgument::REQUIRED,
'Prefixed name of the plugin to create. E.g: SwagAdvancedBasket'
)
->addOption(
self::LEGACY_OPTION,
null,
InputOption::VALUE_NONE,
'Create a legacy Plugin for Shopware versions lower than 5.2'
)
->addOption(
'namespace',
null,
InputOption::VALUE_OPTIONAL,
'Namespace to create the plugin in. One of Frontend, Core or Backend',
'Frontend'
)
->addOption(
'haveBackend',
'b',
InputOption::VALUE_NONE,
'Do you want a backend application to be created? This will create the ExtJS structure and connect it to an existing or new model'
)
->addOption(
'haveFilter',
null,
InputOption::VALUE_NONE,
'Do you want to generate front filters / facets / conditions?'
)
->addOption(
'haveFrontend',
'f',
InputOption::VALUE_NONE,
'Do you need a frontend controller?'
)
->addOption(
'backendModel',
null,
InputOption::VALUE_OPTIONAL,
'If you need a backend application: What\'s the name of its main model?'
)
->addOption(
'haveModels',
'm',
InputOption::VALUE_NONE,
'Do you want custom models to be created and registered?'
)
->addOption(
'haveCommands',
'c',
InputOption::VALUE_NONE,
'Do you want your plugin to be prepared for commands?'
)
->addOption(
'haveWidget',
'w',
InputOption::VALUE_NONE,
'Do you want your plugin to have a widget?'
)
->addOption(
'haveApi',
'a',
InputOption::VALUE_NONE,
'Do you want your plugin to have an api resource?'
)
->addOption(
'haveElasticSearch',
'e',
InputOption::VALUE_NONE,
'Do you want your plugin to have an elastic search integration?'
)
->addOption(
'licenseHeader',
null,
InputOption::VALUE_OPTIONAL,
'File with your desired license header',
''
)
->setHelp(<<<EOF
The <info>%command.name%</info> creates a new plugin.
EOF
);
}

public function interact(InputInterface $input, OutputInterface $output)
{

$helper = $this->getHelperSet()->get('question');

$name = $input->getArgument('name');
$modelName = implode('', array_slice($this->upperToArray($name), 1));

if ($input->getOption(self::LEGACY_OPTION)) {
$defaultModel = sprintf('Shopware\CustomModels\%s\%s', $name, $modelName);
} else {
$defaultModel = sprintf('%s\Models\%s', $name, $modelName);
}

$this->normalizeBooleanFields($input);

$backendModel = $input->getOption('backendModel');


 if (($input->getOption('haveBackend') || $input->getOption('haveApi')) && empty($backendModel)) {
$question = new Question('<question>Please specify the main model for your backend application:</question> <comment>' . $defaultModel . '</comment>: ', $defaultModel);
$question->setValidator($this->validateModel());
$modelName = $helper->ask($input, $output, $question);
$input->setOption('backendModel', $modelName);
}


 if ($input->getOption('haveBackend')
&& strpos($input->getOption('backendModel'), 'Shopware\Models') === false
) {
$input->setOption('haveModels', true);
}
}






public function normalizeBooleanFields(InputInterface $input)
{
$inputOptions = [
'haveBackend',
'haveFrontend',
'haveModels',
'haveCommands',
'haveWidget',
'haveApi',
'haveFilter',
self::LEGACY_OPTION
];

foreach ($inputOptions as $key) {
switch (strtolower($input->getOption($key))) {
case 'false':
case '0':
$input->setOption($key, false);
break;
case 'true':
case '1':
$input->setOption($key, true);
break;
}
}
}




protected function execute(InputInterface $input, OutputInterface $output)
{
$this->validateName($input->getArgument('name'));

if ($input->getOption(self::LEGACY_OPTION)) {
$this->validateNamespace($input->getOption('namespace'));
}

$configuration = $this->getConfigurationObject($input);
$configuration->pluginConfig = $this->getConfig()->offsetGet('PluginConfig');

$generator = (new GeneratorFactory())->create($configuration);

$generator->run();
}







protected function validateName($name)
{
$parts = $this->upperToArray($name);
if (count($parts) <= 1) {
throw new \InvalidArgumentException('Name must be in CamelCase and have at least two components. Don\'t forget you developer-prefix');
}
}







public function upperToArray($input)
{
return preg_split('/(?=[A-Z])/', $input, -1, PREG_SPLIT_NO_EMPTY);
}








public function validateNamespace($input)
{
if (!in_array(strtolower($input), ['frontend', 'core', 'backend'])) {
throw new \InvalidArgumentException('Namespace mus be one of FRONTEND, BACKEND or CORE');
}

return $input;
}






public function validateModel()
{
return function ($input) {
if (empty($input)) {
throw new \InvalidArgumentException('You need to enter a model name like »Shopware\Models\Article\Article«');
}

return $input;
};
}







protected function getConfigurationObject(InputInterface $input)
{
$configuration = new Configuration();
$configuration->name = $input->getArgument('name');
$configuration->namespace = $input->getOption('namespace');
$configuration->hasFrontend = $input->getOption('haveFrontend');
$configuration->hasFilter = $input->getOption('haveFilter');
$configuration->hasBackend = $input->getOption('haveBackend');
$configuration->hasWidget = $input->getOption('haveWidget');
$configuration->hasApi = $input->getOption('haveApi');
$configuration->hasModels = $input->getOption('haveModels');
$configuration->hasCommands = $input->getOption('haveCommands');
$configuration->backendModel = $input->getOption('backendModel');
$configuration->hasElasticSearch = $input->getOption('haveElasticSearch');
$configuration->isLegacyPlugin = $input->getOption(self::LEGACY_OPTION);

$licenseHeader = $input->getOption('licenseHeader');
if (!empty($licenseHeader) && file_exists($licenseHeader)) {
$configuration->licenseHeaderPlain = file_get_contents($licenseHeader);
$configuration->licenseHeader = $this->prepareLicenseHeader($configuration->licenseHeaderPlain);
} else {
$configuration->licenseHeaderPlain = null;
$configuration->licenseHeader = null;
}

return $configuration;
}

private function prepareLicenseHeader($license)
{
$license = str_replace("\n", "\n * ", trim($license));

return "/**\n * " . $license . "\n */\n";
}
}
<?php
namespace ShopwareCli;

use ShopwareCli\Services\PathProvider\PathProvider;

class ConfigFileCollector
{



private $pathProvider;




public function __construct(PathProvider $pathProvider)
{
$this->pathProvider = $pathProvider;
}






public function collectConfigFiles()
{
$files = [];


 $files[] = $this->pathProvider->getCliToolPath() . '/config.yaml.dist';

$extensionPath = $this->pathProvider->getExtensionPath();
$files = array_merge($files, $this->iterateVendors($extensionPath));
$files = array_merge($files, $this->iterateVendors(__DIR__ . '/Extensions'));


 $userConfig = $this->pathProvider->getConfigPath() . '/config.yaml';
if (file_exists($userConfig)) {
$files[] = $userConfig;
}

return $files;
}





private function iterateVendors($extensionPath)
{
$files = [];

if (!is_dir($extensionPath)) {
return [];
}

$iter = new DirectoryFilterIterator(new \DirectoryIterator($extensionPath));
foreach ($iter as $vendorFileInfo) {
$file = $vendorFileInfo->getPathname() . '/config.yaml';
if (file_exists($file)) {
$files[] = $file;
}

$files = array_merge(
$files,
$this->iterateExtensions($vendorFileInfo->getPathname())
);
}

return $files;
}





private function iterateExtensions($vendorPath)
{
$files = [];

$iter = new DirectoryFilterIterator(new \DirectoryIterator($vendorPath));
foreach ($iter as $extensionFileInfo) {
$file = $extensionFileInfo->getPathname() . '/config.yaml';
if (file_exists($file)) {
$files[] = $file;
}
}

return $files;
}
}
<?php

namespace ShopwareCli;

use Composer\Autoload\ClassLoader;
use ShopwareCli\Application\DependencyInjection;
use ShopwareCli\Services\PathProvider\PathProvider;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;







class Application extends \Symfony\Component\Console\Application
{
const NAME = 'sw-cli-tools';
const VERSION = '0.1.0-2-gc43db38';




private $loader;




private $container;




public function __construct(ClassLoader $loader)
{
$this->loader = $loader;

parent::__construct(static::NAME, static::VERSION);

$this->container = DependencyInjection::createContainer(dirname(__DIR__));
}




public function doRun(InputInterface $input, OutputInterface $output)
{
$this->createContainer($input, $output);
$this->checkDirectories();

$noExtensions = $input->hasParameterOption('--no-extensions');
$this->loadExtensions($noExtensions);


 $this->container->compile();

$this->addCommands($this->container->get('command_manager')->getCommands());

$this->container->get('plugin_provider')->setRepositories($this->container->get('repository_manager')->getRepositories());

return parent::doRun($input, $output);
}






protected function getDefaultInputDefinition()
{
$inputDefinitions = parent::getDefaultInputDefinition();
$inputDefinitions->addOption(
new InputOption('--no-extensions', null, InputOption::VALUE_NONE, 'Don\'t load 3rd party extensions.')
);

return $inputDefinitions;
}








protected function createContainer(InputInterface $input, OutputInterface $output)
{
$questionHelper = $this->getHelperSet()->get('question');

$this->container->set('output_interface', $output);
$this->container->set('input_interface', $input);
$this->container->set('question_helper', $questionHelper);
$this->container->set('helper_set', $this->getHelperSet());
$this->container->set('autoloader', $this->loader);

return $this->container;
}






protected function checkDirectories()
{

$pathProvider = $this->container->get('path_provider');

foreach ([
$pathProvider->getAssetsPath(),
$pathProvider->getCachePath(),
$pathProvider->getExtensionPath(),
$pathProvider->getConfigPath()
] as $dir) {
if (is_dir($dir)) {
continue;
}

if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException("Could not find / create $dir");
}
}
}









protected function loadExtensions($noExtensions)
{
$paths = [$this->container->get('path_provider')->getCliToolPath() . '/src/Extensions'];

if (!$noExtensions) {
$paths[] = $this->container->get('path_provider')->getExtensionPath();
}

$this->container->get('extension_manager')->discoverExtensions($paths);
$this->container->get('extension_manager')->injectContainer($this->container);
}




public function getContainer()
{
return $this->container;
}
}
<?php

namespace ShopwareCli;

use ShopwareCli\Services\IoService;

class Utilities
{



private $ioService;

public function __construct(IoService $ioService)
{
$this->ioService = $ioService;
}








public function isShopwareInstallation($path)
{
return is_readable($path.'/shopware.php');
}







public function getValidShopwarePath($shopwarePath = null)
{
if (!$shopwarePath) {
$shopwarePath = realpath(getcwd());
}

if ($this->isShopwareInstallation($shopwarePath)) {
return $shopwarePath;
}

return $this->ioService->askAndValidate(
'Path to your Shopware installation: ',
[$this, 'validateShopwarePath']
);
}








public function validateShopwarePath($shopwarePath)
{
$shopwarePathReal = realpath($shopwarePath);

if (!$this->isShopwareInstallation($shopwarePathReal)) {
throw new \RuntimeException(
"{$shopwarePathReal} is not a valid shopware path"
);
}

return $shopwarePathReal;
}







public function changeDir($path)
{
if (!chdir($path)) {
throw new \RuntimeException("Could not cd into '$path''");
}
}
}
<?php

namespace ShopwareCli\Cache;

use ShopwareCli\Services\PathProvider\PathProvider;

class File implements CacheInterface
{
protected $path;
protected $info;



private $pathProvider;

public function __construct(PathProvider $pathProvider)
{
$this->pathProvider = $pathProvider;
$this->path = $pathProvider->getCachePath() . DIRECTORY_SEPARATOR;

$this->info = $this->readTable();
}

public function write($key, $data, $valid)
{
$file = $this->path . $key;
$success = file_put_contents($file, $data);

$this->info[$key] = ['valid' => $valid];
$this->writeTable($key, $valid);

return $success !== false;
}

public function read($key)
{
if ($this->exists($key)) {
$content = file_get_contents($this->path . $key);

return $content ?: false;
}

return false;
}

public function delete($key)
{
unlink($this->path . $key);
$this->writeTable();
}





public function exists($key)
{
$file = $this->path . $key;

if (!file_exists($file)) {
return false;
}

$validTime = @$this->info[$key]['valid'];

return time() - filectime($file) < $validTime;
}

public function clear()
{
foreach ($this->getKeys() as $key) {
unlink($this->path . $key);
unset($this->info[$key]);
}
$this->writeTable();
}

public function getKeys()
{
return array_keys($this->info);
}

private function getInfoFile()
{
return $this->path . 'info.json';
}

private function readTable()
{
$file = $this->getInfoFile();
$content = null;

if (file_exists($file)) {
$content = file_get_contents($file);
}

if (!$content) {
$content = [];
} else {
$content = json_decode($content, true);
}

return $content;
}

private function writeTable()
{
$file = $this->getInfoFile();

file_put_contents($file, json_encode($this->info));
}
}
<?php

namespace ShopwareCli\Cache;

interface CacheInterface
{







public function write($key, $data, $valid);






public function read($key);


public function delete($key);





public function exists($key);


public function clear();

public function getKeys();
}
<?php
namespace ShopwareCli;







abstract class Struct
{



public function __construct(array $values = [])
{
foreach ($values as $name => $value) {
$this->$name = $value;
}
}






public function __get($name)
{
throw new \OutOfRangeException("Unknown property \${$name} in " . get_class($this) . '.');
}







public function __set($name, $value)
{
throw new \OutOfRangeException("Unknown property \${$name} in " . get_class($this) . '.');
}






public function __unset($name)
{
throw new \OutOfRangeException("Unknown property \${$name} in " . get_class($this) . '.');
}
}
<?php
namespace ShopwareCli\Services;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

class ProcessExecutor
{






private $timeout;




private $output;





public function __construct(OutputInterface $output, $timeout)
{
$this->timeout = $timeout;
$this->output = $output;
}








public function execute($commandline, $cwd = null, $allowFailure = false, $timeout = null)
{
$process = new Process($commandline, $cwd);
$process->setTimeout($timeout ?: $this->timeout);

$output = $this->output; 
 $process->run(function ($type, $buffer) use ($output) {
$output->write($buffer);
});

if (!$allowFailure && !$process->isSuccessful()) {
throw new \RuntimeException("Command failed. Error Output:\n\n" . $process->getErrorOutput(), $process->getExitCode());
}

return $process->getExitCode();
}
}
<?php

namespace ShopwareCli\Services\Rest\Curl;

use ShopwareCli\Services\Rest\RestInterface;







class RestClient implements RestInterface
{
const METHOD_GET = 'GET';
const METHOD_PUT = 'PUT';
const METHOD_POST = 'POST';
const METHOD_DELETE = 'DELETE';

const USER_AGENT = 'sw-cli-tools/1.0';




protected $validMethods = [
self::METHOD_GET,
self::METHOD_PUT,
self::METHOD_POST,
self::METHOD_DELETE
];




protected $apiUrl;




protected $cURL;








public function __construct($apiUrl, $username = '', $apiKey = '', $curlOptions = [])
{
if (!filter_var($apiUrl, FILTER_VALIDATE_URL)) {
throw new \Exception('Invalid URL given');
}

$this->apiUrl = rtrim($apiUrl, '/') . '/';


 $this->cURL = curl_init();
curl_setopt($this->cURL, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->cURL, CURLOPT_FOLLOWLOCATION, false);
if ($username != '' && $apiKey != '') {
curl_setopt($this->cURL, CURLOPT_USERPWD, $username . ':' . $apiKey);
}
curl_setopt($this->cURL, CURLOPT_USERAGENT, self::USER_AGENT);

curl_setopt_array($this->cURL, $curlOptions);
}











public function call($url, $method = self::METHOD_GET, $parameters = [], $headers = [])
{
if (!in_array($method, $this->validMethods)) {
throw new \Exception('Invalid HTTP method: ' . $method);
}
$url = $this->apiUrl . $url;

$dataString = json_encode($parameters);
curl_setopt($this->cURL, CURLOPT_URL, $url);
curl_setopt($this->cURL, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($this->cURL, CURLOPT_POSTFIELDS, $dataString);

$headers = array_merge(
[
'Content-Type: application/json; charset=utf-8',
],
$headers
);

curl_setopt($this->cURL, CURLOPT_HTTPHEADER, $headers);
$body = curl_exec($this->cURL);

return new Response($body, $this->cURL);
}




public function get($url, $parameters = [], $headers = [])
{
return $this->call($url, self::METHOD_GET, $parameters, $headers);
}




public function post($url, $parameters = [], $headers = [])
{
return $this->call($url, self::METHOD_POST, $parameters, $headers);
}




public function put($url, $parameters = [], $headers = [])
{
return $this->call($url, self::METHOD_PUT, $parameters, $headers);
}




public function delete($url, $parameters = [], $headers = [])
{
return $this->call($url, self::METHOD_DELETE, $parameters, $headers);
}
}
<?php

namespace ShopwareCli\Services\Rest\Curl;

use ShopwareCli\Services\Rest\ResponseInterface;









class Response implements ResponseInterface
{



protected $rawBody;




protected $body;




protected $code;




protected $errorMessage = null;




protected $success = false;





public function __construct($body, $curlHandle)
{
$this->rawBody = $body;

if ($body === false) {
$this->errorMessage = curl_error($curlHandle);

return;
}

$this->code = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);

if (null === $decodedResult = json_decode($this->rawBody, true)) {
$jsonError = json_last_error_msg();
$rawErrorBody = print_r($body, true);

$this->errorMessage = <<<error
<h2>Could not decode json</h2>
json_last_error: $jsonError;
<br>Raw:<br>
<pre>$rawErrorBody"</pre>";
error;

return;
}

$this->body = $decodedResult;
}




public function getErrorMessage()
{
return $this->errorMessage;
}




public function getCode()
{
return $this->code;
}




public function getRawBody()
{
return $this->rawBody;
}




public function getResult()
{
return $this->body;
}
}
<?php

namespace ShopwareCli\Services\Rest;

interface ResponseInterface
{






public function getErrorMessage();






public function getCode();






public function getRawBody();






public function getResult();
}
<?php

namespace ShopwareCli\Services\Rest;

use ShopwareCli\Services\Rest\Curl\RestClient;
use Symfony\Component\DependencyInjection\ContainerInterface;







class RestServiceFactory
{



protected $container;




public function __construct($container)
{
$this->container = $container;
}








public function factory($baseUrl, $username = null, $password = null, $cacheTime = 3600)
{
return new CacheDecorator(new RestClient($baseUrl, $username, $password), $this->container->get('cache'), $cacheTime);
}
}
<?php

namespace ShopwareCli\Services\Rest;







interface RestInterface
{








public function get($url, $parameters = [], $headers = []);









public function post($url, $parameters = [], $headers = []);









public function put($url, $parameters = [], $headers = []);









public function delete($url, $parameters = [], $headers = []);
}
<?php

namespace ShopwareCli\Services\Rest;

use ShopwareCli\Cache\CacheInterface;







class CacheDecorator implements RestInterface
{



protected $decorate;




protected $cacheProvider;




protected $cacheTime;






public function __construct(RestInterface $restService, CacheInterface $cacheProvider, $cacheTime = 1)
{
$this->decorate = $restService;
$this->cacheProvider = $cacheProvider;
$this->cacheTime = $cacheTime;
}




public function get($url, $parameters = [], $headers = [])
{
$cacheKey = $url . json_encode($parameters) . json_encode($headers);

return $this->callCached('get', sha1($cacheKey), $url, $parameters = [], $headers = []);
}




public function post($url, $parameters = [], $headers = [])
{
return $this->decorate->post($url, $parameters, $headers);
}




public function put($url, $parameters = [], $headers = [])
{
return $this->decorate->put($url, $parameters, $headers);
}




public function delete($url, $parameters = [], $headers = [])
{
return $this->decorate->delete($url, $parameters, $headers);
}









public function callCached($call, $key, $url, $parameters = [], $headers = [])
{

if (!$this->cacheProvider || $this->cacheTime == 0) {
$response = call_user_func([$this->decorate, $call], $url, $parameters, $headers);
} else {
$response = $this->cacheProvider->read($key);
if ($response === false) {
$response = call_user_func([$this->decorate, $call], $url, $parameters, $headers);
if ($response === false) {
return false;
}

 if (!$response->getErrorMessage()) {
$this->cacheProvider->write($key, serialize($response), $this->cacheTime);
}
} else {
$response = unserialize($response);
}
}

return $response;
}
}
<?php
namespace ShopwareCli\Services;





class StreamFileDownloader implements FileDownloader
{
const BLOCKSIZE = 8192;




private $ioService;




public function __construct(IoService $ioService)
{
$this->ioService = $ioService;
}






public function download($sourceUrl, $destination)
{
if (false === $readHandle = fopen($sourceUrl, 'rb')) {
throw new \RuntimeException(sprintf("Could not open URL '%s'.", $sourceUrl));
}

if (false === $writeHandle = fopen($destination, 'wb')) {
throw new \RuntimeException(sprintf('Could not write file: %s.', $destination));
}

$length = $this->getContentLengthFromStream($readHandle);

$progress = $this->ioService->createProgressBar($length/1024);
$progress->start();


 $progress->setRedrawFrequency(524288/1024);

$currentSize = 0;

while (!feof($readHandle)) {
$currentSize += fwrite($writeHandle, fread($readHandle, self::BLOCKSIZE));
$progress->setCurrent($currentSize/1024);
}
$progress->finish();

$this->ioService->writeln("\n Download finished");

fclose($readHandle);
fclose($writeHandle);
}





private function getContentLengthFromStream($readHandle)
{
$info = stream_get_meta_data($readHandle);

$size = 0;
foreach ($info['wrapper_data'] as $field) {
if (stripos($field, 'content-length') !== false) {
list($header, $size) = explode(':', $field);
}
}

return $size;
}
}
<?php

namespace ShopwareCli\Services;

use ShopwareCli\Config;
use ShopwareCli\Services\PathProvider\PathProvider;







class GitIdentityEnvironment
{
protected $wrapperFileName = 'ssh-as.sh';
protected $keyFileName = 'ssh.key';

protected $sshAliasTemplate = <<<'EOF'
#!/bin/bash
set -e
set -u

ssh -i $SSH_KEYFILE $@
EOF;



private $pathProvider;



private $config;

public function __construct(PathProvider $pathProvider, Config $config)
{
$this->pathProvider = $pathProvider;
$this->config = $config;
}








private function getCustomKey()
{
if (isset($this->config['sshKey'])) {
$keyPath = $this->config['sshKey'];
if (!file_exists($keyPath)) {
throw new \RuntimeException("Could not find ssh key $keyPath");
}

return $keyPath;
}

$packageKey = $this->pathProvider->getCliToolPath() . '/assets/ssh.key';

if (!file_exists($packageKey)) {
return false;
}

$dir = $this->pathProvider->getRuntimeDir() . '/sw-cli-tools/';
$sshKeyFile = $dir . $this->keyFileName;

if (file_exists($sshKeyFile) || $this->writeSshKey($dir, $packageKey)) {
return $sshKeyFile;
}

return null;
}






private function writeSshKey($dir, $sshKeyFile)
{
if (!is_dir($dir) && !mkdir($dir, 0700, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
}

$filename = $dir . $this->keyFileName;
copy($sshKeyFile, $filename);
chmod($filename, 0700);

return file_exists($filename);
}







private function getGitWrapper()
{
$dir = $this->pathProvider->getRuntimeDir() . '/sw-cli-tools/';

$wrapperFile = $dir . $this->wrapperFileName;

if (file_exists($wrapperFile) || $this->writeGitSshWrapper($dir)) {
return $wrapperFile;
}

throw new \RuntimeException("Could not create git wrapper file $wrapperFile");
}







private function writeGitSshWrapper($dir)
{
if (!is_dir($dir) && !mkdir($dir, 0700, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
}

$filename = $dir . $this->wrapperFileName;
file_put_contents($filename, $this->sshAliasTemplate);
chmod($filename, 0700);

return file_exists($filename);
}







public function getGitEnv()
{
if (!$this->getCustomKey()) {
return null;
}

return [
'SSH_KEYFILE' => $this->getCustomKey(),
'GIT_SSH' => $this->getGitWrapper()
];
}
}
<?php

namespace ShopwareCli\Services\ZipUtil;

use Countable;
use SeekableIterator;





abstract class Adapter implements SeekableIterator, Countable
{



protected $position;




protected $count;




public function seek($position)
{
$this->position = (int) $position;
}




public function count()
{
return $this->count;
}

public function rewind()
{
$this->position = 0;
}




public function key()
{
return $this->position;
}

public function next()
{
++$this->position;
}




public function valid()
{
return $this->count > $this->position;
}




public function each()
{
if (!$this->valid()) {
return false;
}
$result = [$this->key(), $this->current()];
$this->next();

return $result;
}
}
<?php

namespace ShopwareCli\Services\ZipUtil;

use ZipArchive;





class Zip extends Adapter
{



protected $stream;






public function __construct($fileName = null, $flags = null)
{
if (!extension_loaded('zip')) {
throw new \Exception('The PHP extension "zip" is not loaded.');
}

$this->stream = new ZipArchive();

if ($fileName != null) {
if (true !== ($retval = $this->stream->open($fileName, $flags))) {
throw new \RuntimeException($this->getErrorMessage($retval, $fileName), $retval);
}
$this->position = 0;
$this->count = $this->stream->numFiles;
}
}




public function current()
{
return new Entry\Zip($this->stream, $this->position);
}





public function getStream($name)
{
return $this->stream->getStream($name);
}





public function getContents($name)
{
return $this->stream->getFromName($name);
}





public function getEntry($position)
{
return $this->stream->statIndex($position);
}




public function close()
{
return $this->stream->close();
}








protected function getErrorMessage($retval, $file)
{
switch ($retval) {
case ZipArchive::ER_EXISTS:
return sprintf("File '%s' already exists.", $file);
case ZipArchive::ER_INCONS:
return sprintf("Zip archive '%s' is inconsistent.", $file);
case ZipArchive::ER_INVAL:
return sprintf('Invalid argument (%s)', $file);
case ZipArchive::ER_MEMORY:
return sprintf('Malloc failure (%s)', $file);
case ZipArchive::ER_NOENT:
return sprintf("No such zip file: '%s'", $file);
case ZipArchive::ER_NOZIP:
return sprintf("'%s' is not a zip archive.", $file);
case ZipArchive::ER_OPEN:
return sprintf("Can't open zip file: %s", $file);
case ZipArchive::ER_READ:
return sprintf('Zip read error (%s)', $file);
case ZipArchive::ER_SEEK:
return sprintf('Zip seek error (%s)', $file);
default:
return sprintf("'%s' is not a valid zip archive, got error code: %s", $file, $retval);
}
}
}
<?php

namespace ShopwareCli\Services\ZipUtil\Entry;

use ZipArchive;





class Zip
{



protected $position;




protected $stream;




protected $name;





public function __construct($stream, $position)
{
$this->position = $position;
$this->stream = $stream;
$this->name = $stream->getNameIndex($position);
}




public function getStream()
{
return $this->stream->getStream($this->name);
}




public function getContents()
{
return $this->stream->getFromIndex($this->position);
}




public function isDir()
{
return substr($this->name, -1) === '/';
}




public function isFile()
{
return substr($this->name, -1) !== '/';
}




public function getName()
{
$name = $this->name;
if (strpos($name, './') === 0) {
$name = substr($name, 2);
}

return $name;
}
}
<?php

namespace ShopwareCli\Services;









class ShopwareInfo
{
public function getCacheDir($path)
{
$path = $this->normalizePath($path);

if (file_exists($path . 'cache/clear_cache.sh')) {
return $path . 'cache';
}

if (file_exists($path . 'var/cache/clear_cache.sh')) {
return $path . 'var/cache';
}

throw new \RuntimeException('Cache path not found');
}

public function getLogDir($path)
{
$path = $this->normalizePath($path);

if (file_exists($path . 'logs/.htaccess')) {
return $path . 'logs';
}

if (file_exists($path . 'var/log/.htaccess')) {
return $path . 'var/log';
}

throw new \RuntimeException('Log path not found');
}

public function getMediaDir($path)
{
return $this->normalizePath($path) . 'media';
}

public function getFilesDir($path)
{
return $this->normalizePath($path) . 'files';
}





private function normalizePath($path)
{
return rtrim($path, '/\\') . '/';
}
}
<?php

namespace ShopwareCli\Services;

use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;





class IoService
{



private $input;




private $output;




private $questionHelper;






public function __construct(
InputInterface $input,
OutputInterface $output,
QuestionHelper $questionHelper
) {
$this->input = $input;
$this->output = $output;
$this->questionHelper = $questionHelper;
}






public function isInteractive()
{
return $this->input->isInteractive();
}






public function isQuiet()
{
return $this->output->getVerbosity() === OutputInterface::VERBOSITY_QUIET;
}






public function isVerbose()
{
return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE;
}





public function isVeryVerbose()
{
return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE;
}






public function isDebug()
{
return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG;
}






public function write($message)
{
$this->output->write($message);
}






public function writeln($message)
{
$this->output->write($message, true);
}








public function ask($question, $default = null, $hidden = false)
{
$question = $question instanceof Question ? $question : new Question($question, $default);

if ($hidden) {
$question->setHidden(true);
$question->setHiddenFallback(false);
}

return $this->questionHelper->ask($this->input, $this->output, $question);
}








public function createTable($headers = null, $results = null)
{
$tableObject = new Table($this->output);

if ($headers) {
$tableObject->setHeaders($headers);
}

if ($results) {
$tableObject->setRows($results);
}

return $tableObject;
}








public function askConfirmation($question, $default = null)
{
$question = $question instanceof ConfirmationQuestion
? $question
: new ConfirmationQuestion($question, $default);

return $this->questionHelper->ask($this->input, $this->output, $question);
}











public function askAndValidate($question, $validator = false, $attempts = false, $default = null, $hidden = false)
{
$question = $question instanceof Question ? $question : new Question($question, $default);

if ($attempts) {
$question->setMaxAttempts($attempts);
}

if ($validator) {
$question->setValidator($validator);
}

if ($hidden) {
$question->setHidden(true);
$question->setHiddenFallback(false);
}

return $this->questionHelper->ask($this->input, $this->output, $question);
}





public function createProgressBar($max = 0)
{
return new ProgressBar($this->output, $max);
}




public function cls()
{
if (!$this->input->isInteractive()) {
return;
}


 $this->output->write(chr(27) . '[2J'); 
 $this->output->write(chr(27) . '[1;1H'); 
 }
}
<?php

namespace ShopwareCli\Services\PathProvider;

use ShopwareCli\Services\PathProvider\DirectoryGateway\DirectoryGatewayInterface;

class PathProvider
{



private $directoryGateway;

public function __construct(DirectoryGatewayInterface $directoryGateway)
{
$this->directoryGateway = $directoryGateway;
}




public function getCliToolPath()
{
return dirname(dirname(dirname(__DIR__)));
}

public function getCachePath()
{
return $this->directoryGateway->getCacheDir();
}

public function getAssetsPath()
{
return $this->directoryGateway->getAssetsDir();
}

public function getExtensionPath()
{
return $this->directoryGateway->getExtensionDir();
}

public function getConfigPath()
{
return $this->directoryGateway->getConfigDir();
}

public function getRuntimeDir()
{

 return '/tmp';

 }
}
<?php

namespace ShopwareCli\Services\PathProvider\DirectoryGateway;

interface DirectoryGatewayInterface
{



public function getAssetsDir();




public function getExtensionDir();




public function getCacheDir();




public function getConfigDir();




public function getRuntimeDir();
}
<?php

namespace ShopwareCli\Services\PathProvider\DirectoryGateway;

class CliToolGateway implements DirectoryGatewayInterface
{



private $basePath;




public function __construct($basePath)
{
$this->basePath = rtrim($basePath, '/');
}




public function getBasePath()
{
return $this->basePath;
}




public function getCacheDir()
{
return $this->getBasePath() . '/cache';
}




public function getAssetsDir()
{
return $this->getBasePath() . '/assets';
}




public function getExtensionDir()
{
return $this->getBasePath() . '/extensions';
}




public function getConfigDir()
{
return $this->getBasePath();
}




public function getRuntimeDir()
{
throw new \RuntimeException('not implemented');
}
}
<?php

namespace ShopwareCli\Services\PathProvider\DirectoryGateway;

use XdgBaseDir\Xdg;

class XdgGateway implements DirectoryGatewayInterface
{



private $xdg;




public function __construct(Xdg $xdg)
{
$this->xdg = $xdg;
}




public function getAssetsDir()
{
return $this->xdg->getHomeDataDir() . '/sw-cli-tools/assets';
}




public function getExtensionDir()
{
return $this->xdg->getHomeConfigDir() . '/sw-cli-tools/extensions';
}




public function getCacheDir()
{
return $this->xdg->getHomeCacheDir() . '/sw-cli-tools';
}




public function getConfigDir()
{
return $this->xdg->getHomeConfigDir() . '/sw-cli-tools';
}




public function getRuntimeDir()
{
return $this->xdg->getRuntimeDir(false);
}
}
<?php

namespace ShopwareCli\Services;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

class GitUtil
{






private $timeout;




private $output;



private $gitEnv;






public function __construct(OutputInterface $output, GitIdentityEnvironment $gitEnv, $timeout)
{
$this->timeout = $timeout;
$this->output = $output;
$this->gitEnv = $gitEnv;
}







public function run($commandline, $timeout = null)
{
$commandline = 'git ' . $commandline;

$process = new Process($commandline, null, $this->gitEnv->getGitEnv());
$process->setTimeout($timeout ?: $this->timeout);

$output = $this->output; 
 $process->run(function ($type, $buffer) use ($output) {
$output->write($buffer);
});

if (!$process->isSuccessful()) {
throw new \RuntimeException("Command failed. Error Output:\n\n" . $process->getErrorOutput(), $process->getExitCode());
}

return $process->getOutput();
}
}
<?php

namespace ShopwareCli\Services;





interface FileDownloader
{




public function download($sourceUrl, $destination);
}
<?php

namespace ShopwareCli\Services;

class OpenSSLVerifier
{
private $publicKey;




public function __construct($publicKey)
{
if (!is_readable($publicKey)) {
throw new \InvalidArgumentException(sprintf(
'Public keyfile (%s) not readable',
$publicKey
));
}

$this->publicKey = $publicKey;
}




public function isSystemSupported()
{
return function_exists('openssl_verify');
}







public function isValid($message, $signature)
{
$publicKey = trim(file_get_contents($this->publicKey));

if (false === $pubkeyid = openssl_pkey_get_public($publicKey)) {
while ($errors[] = openssl_error_string());
throw new \RuntimeException(sprintf("Error during public key read: \n%s", implode("\n", $errors)));
}

$signature = base64_decode($signature);


 $ok = openssl_verify($message, $signature, $pubkeyid);


 openssl_free_key($pubkeyid);

if ($ok == 1) {
return true;
} elseif ($ok == 0) {
return false;
} else {
while ($errors[] = openssl_error_string());
throw new \RuntimeException(sprintf("Error during private key read: \n%s", implode("\n", $errors)));
}
}
}
<?php

namespace ShopwareCli\Command;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;







class CacheGetCommand extends BaseCommand
{
protected $utilities;
protected $zipDir;

protected function configure()
{
$this->setName('cli:cache:get')
->setDescription('Read the cache')
->addArgument(
'keys',
InputArgument::IS_ARRAY,
'One or more cache keys to read'
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$keys = $input->getArgument('keys');

if (empty($keys)) {
foreach ($this->container->get('cache')->getKeys() as $key) {
$output->writeln($key);
}

return;
}

foreach ($keys as $key) {
$output->writeln("<question>{$key}</question>");
$output->writeln($this->container->get('cache')->read($key));
}
}
}
<?php

namespace ShopwareCli\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;







abstract class BaseCommand extends Command implements ContainerAwareInterface
{

protected $container;








public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
<?php

namespace ShopwareCli\Command;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;







class CacheCommand extends BaseCommand
{
protected $utilities;
protected $zipDir;

protected function configure()
{
$this->setName('cli:cache:clear')
->setDescription('Clear the repository cache');
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->container->get('cache')->clear();
}
}
<?php

namespace ShopwareCli;

use Symfony\Component\Yaml\Yaml;







class Config implements \ArrayAccess
{



protected $configArray;




public function __construct(ConfigFileCollector $fileCollector)
{
$config = [];
foreach ($fileCollector->collectConfigFiles() as $configFile) {
$config = array_replace_recursive($config, Yaml::parse(file_get_contents($configFile), true));
}

$this->configArray = $config;

$this->validateConfig();
}




public function getRepositories()
{
return (array) $this->configArray['repositories'];
}






public function offsetExists($offset)
{
return isset($this->configArray[$offset]);
}






public function offsetGet($offset)
{
if (array_key_exists($offset, $this->configArray)) {
return $this->configArray[$offset];
}

return null;
}





public function offsetSet($offset, $value)
{
$this->configArray[$offset] = $value;
}




public function offsetUnset($offset)
{
unset($this->configArray[$offset]);
}

private function validateConfig()
{
if (isset($this->configArray['ShopwareInstallConfig'])) {
throw new \RuntimeException("The config format changed, 'ShopwareInstallConfig' is not used anymore. Its former options are now distinct options 'ShopConfig', 'DatabaseConfig' and 'ShopwareInstallRepos'. Have a look at config.yaml.dist for more info.");
}
}
}
# PluginCreator
The PluginCreator allows you to generate boilerplate code for shopware plugins. This way you get new, state of the art
and best practice plugins within seconds.

# Features
Depending on your configuration, you can generate:

 * backend and frontend controllers
 * backend applications using the new shopware backend components
 * widgets
 * API resources and controllers
 * models
 * subscriber
 * unit tests
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Commands;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Commands;
<?php } ?>

use Shopware\Components\Model\ModelManager;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Shopware\Commands\ShopwareCommand;

class <?= $names->camelCaseModel; ?> extends ShopwareCommand
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('<?= $names->developerPrefix; ?>:GROUP:OPERATION')
            ->setDescription('Description of this command')
            ->addArgument(
                'my-argument',
                InputArgument::REQUIRED,
                'An required argument (positional)'
            )
            ->addOption(
                'my-option',
                null,
                InputOption::VALUE_OPTIONAL,
                'An optional *option*',
                'My-Default-Value'
            )
            ->setHelp(<<<EOF
The <info>%command.name%</info> implements a command.
EOF
            );
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln($input->getOption('my-option'));
        $output->writeln($input->getArgument('my-argument'));

    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet;
<?php } ?>

use Shopware\Bundle\SearchBundle\Criteria;
use Shopware\Bundle\SearchBundle\FacetInterface;
use Shopware\Bundle\SearchBundle\FacetResult\BooleanFacetResult;
use Shopware\Bundle\SearchBundleDBAL\FacetHandlerInterface;
use Shopware\Bundle\SearchBundleDBAL\QueryBuilderFactory;
use Shopware\Bundle\StoreFrontBundle\Struct;

class <?= $configuration->name; ?>FacetHandler implements FacetHandlerInterface
{
    /**
     * @var QueryBuilderFactory
     */
    private $queryBuilderFactory;

    /**
     * @var \Shopware_Components_Snippet_Manager
     */
    private $snippetManager;

    /**
     * @param QueryBuilderFactory $queryBuilderFactory
     * @param \Shopware_Components_Snippet_Manager $snippetManager
     */
    public function __construct(
        QueryBuilderFactory $queryBuilderFactory,
        \Shopware_Components_Snippet_Manager $snippetManager
    ) {
        $this->queryBuilderFactory = $queryBuilderFactory;
        $this->snippetManager = $snippetManager;
    }

    /**
     * @inheritdoc
     */
    public function supportsFacet(FacetInterface $facet)
    {
        return ($facet instanceof <?= $configuration->name; ?>Facet);
    }

    /**
     * @inheritdoc
     */
    public function generateFacet(
        FacetInterface $facet,
        Criteria $criteria,
        Struct\ShopContextInterface $context
    ) {

        // This will add a new boolean filter. There are plenty of additional filter
        // https://developers.shopware.com/developers-guide/shopware-5-search-bundle/#facetresult
        return new BooleanFacetResult(
            $facet->getName(),
            '<?= $names->under_score_js; ?>_condition',
            $criteria->hasCondition($facet->getName()),
            'Example condition' // use $this->snippetManager for translatable snippets
        );
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet;
<?php } ?>

use Shopware\Bundle\SearchBundle\FacetInterface;

class <?= $configuration->name; ?>Facet implements FacetInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return '<?= $names->under_score_js; ?>';
    }

    /**
     * @inheritdoc
     */
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Components\SearchBundleDBAL;

use Enlight_Controller_Request_RequestHttp as Request;
use Shopware\Bundle\SearchBundle\Criteria;
use Shopware\Bundle\SearchBundle\CriteriaRequestHandlerInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;

class <?= $configuration->name; ?>CriteriaRequestHandler implements CriteriaRequestHandlerInterface
{
    /**
     * @inheritdoc
     */
    public function handleRequest(
        Request $request,
        Criteria $criteria,
        ShopContextInterface $context
    ) {
        if ($request->has('<?= $names->under_score_js; ?>_condition')) {
            $criteria->addCondition(new Condition\<?= $configuration->name; ?>Condition());
        }

        $criteria->addFacet(new Facet\<?= $configuration->name; ?>Facet());
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition;
<?php } ?>

use Shopware\Bundle\SearchBundle\ConditionInterface;

class <?= $configuration->name; ?>Condition implements ConditionInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return '<?= $names->under_score_js; ?>';
    }

    /**
     * @inheritdoc
     */
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition;
<?php } ?>

use Shopware\Bundle\SearchBundle\ConditionInterface;
use Shopware\Bundle\SearchBundleDBAL\ConditionHandlerInterface;
use Shopware\Bundle\SearchBundleDBAL\QueryBuilder;
use Shopware\Bundle\StoreFrontBundle\Struct;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;

class <?= $configuration->name; ?>ConditionHandler implements ConditionHandlerInterface
{
    const STATE_INCLUDED = '<?= $names->under_score_js; ?>_included';

    /**
     * @inheritdoc
     */
    public function supportsCondition(ConditionInterface $condition)
    {
        return ($condition instanceof <?= $configuration->name; ?>Condition);
    }

    /**
     * @inheritdoc
     */
    public function generateCondition(
        ConditionInterface $condition,
        QueryBuilder $query,
        ShopContextInterface $context
    ) {

        if (!$query->hasState(self::STATE_INCLUDED)) {
            // implement your condition here.

            // e.g. limit to product.ids <= 100
            $query->andWhere('product.id <= 100');

            // e.g. join another table and only include products,
            // that are referenced in that table.
            // $query->innerJoin(
            //     'product',
            //     's_bundle_articles',
            //     'bundle',
            //     'bundle.article_id = product.id'
            // );
            $query->addState(self::STATE_INCLUDED);
        }
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\SearchBundleES;

use Elasticsearch\Client;
use Shopware\Bundle\ESIndexingBundle\IndexFactoryInterface;
use Shopware\Bundle\SearchBundle\Criteria;
use Shopware\Bundle\SearchBundle\ProductSearchInterface;
use Shopware\Bundle\StoreFrontBundle\Struct;

class Search implements ProductSearchInterface
{
    /**
     * @var ProductSearchInterface
     */
    private $coreService;

    /**
     * @var Client
     */
    private $client;

    /**
     * @var IndexFactoryInterface
     */
    private $indexFactory;

    /**
     * @param Client $client
     * @param ProductSearchInterface $coreService
     * @param IndexFactoryInterface $indexFactory
     */
    public function __construct(
        Client $client,
        ProductSearchInterface $coreService,
        IndexFactoryInterface $indexFactory
    ) {
        $this->coreService = $coreService;
        $this->client = $client;
        $this->indexFactory = $indexFactory;
    }

    public function search(Criteria $criteria, Struct\ProductContextInterface $context)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle;

use Shopware\Bundle\ESIndexingBundle\FieldMappingInterface;
use Shopware\Bundle\ESIndexingBundle\MappingInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\Shop;

class Mapping implements MappingInterface
{
    /**
     * @var FieldMappingInterface
     */
    private $fieldMapping;

    /**
     * @param FieldMappingInterface $fieldMapping
     */
    public function __construct(FieldMappingInterface $fieldMapping)
    {
        $this->fieldMapping = $fieldMapping;
    }

    /**
     * @return string
     */
    public function getType()
    {
    }

    /**
     * @param Shop $shop
     * @return array
     */
    public function get(Shop $shop)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle;

use Doctrine\DBAL\Connection;
use Elasticsearch\Client;
use Shopware\Bundle\ESIndexingBundle\Console\ProgressHelperInterface;
use Shopware\Bundle\ESIndexingBundle\DataIndexerInterface;
use Shopware\Bundle\ESIndexingBundle\Struct\ShopIndex;

class DataIndexer implements DataIndexerInterface
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * @var Client
     */
    private $client;

    /**
     * @var Provider
     */
    private $provider;

    /**
     * @param Connection $connection
     * @param Client $client
     * @param Provider $provider
     */
    public function __construct(
        Connection $connection,
        Client $client,
        Provider $provider
    ) {
        $this->connection = $connection;
        $this->client = $client;
        $this->provider = $provider;
    }

    /**
     * @param ShopIndex $index
     * @param ProgressHelperInterface $progress
     */
    public function populate(ShopIndex $index, ProgressHelperInterface $progress)
    {
    }

    /**
     * @param ShopIndex $index
     * @param int[] $ids
     */
    public function index(ShopIndex $index, $ids)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle;

use Doctrine\DBAL\Connection;
use Shopware\Bundle\ESIndexingBundle\Struct\ShopIndex;
use Shopware\Bundle\ESIndexingBundle\SynchronizerInterface;

class Synchronizer implements SynchronizerInterface
{
    /**
     * @var DataIndexer
     */
    private $indexer;

    /**
     * @var Connection
     */
    private $connection;

    /**
     * @param DataIndexer $indexer
     * @param Connection $connection
     */
    public function __construct(DataIndexer $indexer, Connection $connection)
    {
        $this->indexer = $indexer;
        $this->connection = $connection;
    }

    public function synchronize(ShopIndex $shopIndex, $backlogs)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle;

use Doctrine\DBAL\Connection;

class Provider
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * @param Connection $connection
     */
    public function __construct(Connection $connection)
    {
        $this->connection = $connection;
    }

    /**
     * @param int[] $ids
     * @return []
     */
    public function get($ids)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle;

use Shopware\Bundle\ESIndexingBundle\SettingsInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\Shop;

class Settings implements SettingsInterface
{
    /**
     * @param Shop $shop
     * @return array|null
     */
    public function get(Shop $shop)
    {
    }
}
<?= $configuration->phpFileHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\Components\Api\Resource;

use Doctrine\ORM\Tools\Pagination\Paginator;
use Shopware\Components\Api\Exception as ApiException;
use Shopware\Components\Model\QueryBuilder;
use Shopware\Components\Api\Resource\Resource;

class <?= $names->camelCaseModel; ?> extends Resource
{
    /**
     * Return a list of entities
     *
     * @param $offset
     * @param $limit
     * @param $filter
     * @param $sort
     *
     * @return array
     */
    public function getList($offset, $limit, $filter, $sort)
    {
        $builder = $this->getBaseQuery();
        $builder = $this->addQueryLimit($builder, $offset, $limit);

        if (!empty($filter)) {
            $builder->addFilter($filter);
        }
        if (!empty($sort)) {
            $builder->addOrderBy($sort);
        }

        $query = $builder->getQuery();

        $query->setHydrationMode($this->getResultMode());

        $paginator = new Paginator($query);

        $totalResult = $paginator->count();

        $result = $paginator->getIterator()->getArrayCopy();

        return array('data' => $result, 'total' => $totalResult);
    }


    /**
     * Read the given entity $id
     *
     * @param $id
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function getOne($id)
    {
        $builder = $this->getBaseQuery();

        $builder->where('<?= $names->backendModelAlias; ?>.id = :id')
            ->setParameter('id', $id);

        /** @var $model \<?= $configuration->backendModel; ?> */
        $model = $builder->getQuery()->getOneOrNullResult($this->getResultMode());

        if (!$model) {
            throw new ApiException\NotFoundException("<?= $names->camelCaseModel; ?> by id $id not found");
        }

        return $model;
    }

    /**
     * Create a new entity with $data
     *
     * @param $data
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws ApiException\OrmException
     * @throws ApiException\ParameterMissingException
     * @throws ApiException\ValidationException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\ORM\TransactionRequiredException
     */
    public function create($data)
    {
        $data = $this->prepareData($data);
        $model = new \<?= $configuration->backendModel; ?>();
        $model->fromArray($data);

        $violations = $this->getManager()->validate($model);

        if ($violations->count() > 0) {
            throw new ApiException\ValidationException($violations);
        }

        $this->getManager()->persist($model);
        $this->flush();

        return $model;
    }

    /**
     * Update a given entity $id with $data
     *
     * @param $id
     * @param $data
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws ApiException\OrmException
     * @throws ApiException\ParameterMissingException
     * @throws ApiException\ValidationException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\ORM\TransactionRequiredException
     */
    public function update($id, $data)
    {
        if (empty($id)) {
            throw new ApiException\ParameterMissingException();
        }

        /** @var $model \<?= $configuration->backendModel; ?> */
        $model = $this->getManager()->find('<?= $configuration->backendModel; ?>', $id);

        if (!$model) {
            throw new ApiException\NotFoundException("<?= $names->backendModelAlias; ?> by id $id not found");
        }

        $data = $this->prepareData($data);

        $model->fromArray($data);

        $violations = $this->getManager()->validate($model);
        if ($violations->count() > 0) {
            throw new ApiException\ValidationException($violations);
        }

        $this->flush();

        return $model;
    }

    /**
     * Delete the given entity
     *
     * @param $id
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws ApiException\OrmException
     * @throws ApiException\ParameterMissingException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\ORM\TransactionRequiredException
     */
    public function delete($id)
    {
        if (empty($id)) {
            throw new ApiException\ParameterMissingException();
        }

        /** @var $model \<?= $configuration->backendModel; ?> */
        $model = $this->getManager()->find('<?= $configuration->backendModel; ?>', $id);

        if (!$model) {
            throw new ApiException\NotFoundException("<?= $names->backendModelAlias; ?> by id $id not found");
        }

        $this->getManager()->remove($model);
        $this->flush();

        return $model;
    }


    /**
     * Here the data is prepared for automatic setting
     */
    protected function prepareData($data)
    {
        return $data;
    }

    /**
     * @param QueryBuilder $builder
     * @param              $offset
     * @param null         $limit
     *
     * @return QueryBuilder
     */
    protected function addQueryLimit(QueryBuilder $builder, $offset, $limit = null)
    {
        $builder->setFirstResult($offset)
            ->setMaxResults($limit);

        return $builder;
    }

    /**
     * @return \Doctrine\ORM\QueryBuilder|QueryBuilder
     */
    protected function getBaseQuery()
    {
        $builder = $this->getManager()->createQueryBuilder();
        $builder->select(array('<?= $names->backendModelAlias; ?>'))
            ->from('<?= $configuration->backendModel; ?>', '<?= $names->backendModelAlias; ?>');

        return $builder;
    }
}
The MIT License (MIT)

Copyright (c) shopware AG

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.
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->hasElasticSearch) { ?>
use Shopware\Components\Model\ModelManager;
use <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle\DataIndexer;
use <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle\Mapping;
use <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle\Provider;
use <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle\Settings;
use <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\ESIndexingBundle\Synchronizer;
use <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\SearchBundleES\Search;
<?php } ?>

/**
 * The Bootstrap class is the main entry point of any shopware plugin.
 *
 * Short function reference
 * - install: Called a single time during (re)installation. Here you can trigger install-time actions like
 *   - creating the menu
 *   - creating attributes
 *   - creating database tables
 *   You need to return "true" or array('success' => true, 'invalidateCache' => array()) in order to let the installation
 *   be successful
 *
 * - update: Triggered when the user updates the plugin. You will get passes the former version of the plugin as param
 *   In order to let the update be successful, return "true"
 *
 * - uninstall: Triggered when the plugin is reinstalled or uninstalled. Clean up your tables here.
 */
class Shopware_Plugins_<?= $configuration->namespace; ?>_<?= $configuration->name; ?>_Bootstrap extends Shopware_Components_Plugin_Bootstrap
{
    public function getVersion() {
        $info = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR .'plugin.json'), true);
        if ($info) {
            return $info['currentVersion'];
        } else {
            throw new Exception('The plugin has an invalid version file.');
        }
    }

    public function getLabel()
    {
        return '<?= $configuration->name; ?>';
    }

    public function uninstall()
    {
<?php if ($configuration->hasModels) { ?>
        $this->registerCustomModels();

        $em = $this->Application()->Models();
        $tool = new \Doctrine\ORM\Tools\SchemaTool($em);

        $classes = array(
            $em->getClassMetadata('Shopware\CustomModels\<?= $configuration->name; ?>\<?= $names->camelCaseModel; ?>')
        );
        $tool->dropSchema($classes);

<?php } ?>
        return true;
    }

    public function update($oldVersion)
    {
        return true;
    }

    public function install()
    {
        if (!$this->assertMinimumVersion('<?= $configuration->pluginConfig['minimumVersion']; ?>')) {
            throw new \RuntimeException('At least Shopware <?= $configuration->pluginConfig['minimumVersion']; ?> is required');
        }
<?php if ($configuration->hasWidget) { ?>

        $this->createWidget('<?= $names->under_score_js; ?>');
<?php } ?>

<?php if ($configuration->hasBackend) { ?>

        $this->createMenuItem(array(
            'label' => '<?= $configuration->name; ?>',
            'controller' => '<?= $configuration->name; ?>',
            'class' => 'sprite-application-block',
            'action' => 'Index',
            'active' => 1,
            'parent' => $this->Menu()->findOneBy(array('label' => 'Marketing'))
        ));
<?php } ?>

        $this->subscribeEvent(
            'Enlight_Controller_Front_DispatchLoopStartup',
            'onStartDispatch'
        );

<?php if ($configuration->hasCommands) { ?>

        $this->subscribeEvent(
            'Shopware_Console_Add_Command',
            'onAddConsoleCommand'
        );
<?php } ?>
<?php if ($configuration->hasModels) { ?>

<?php if ($configuration->hasElasticSearch) { ?>
        $this->subscribeElasticSearchEvents();
<?php } ?>

        $this->updateSchema();
<?php } ?>
<?php if ($configuration->hasFrontend || $configuration->hasBackend) { ?>
        return array('success' => true, 'invalidateCache' => array('frontend', 'backend'));
<?php } else { ?>
        return true;
<?php } ?>
    }

<?php if ($configuration->hasCommands) { ?>
    /**
     * Callback function of the console event subscriber. Register your console commands here.
     */
    public function onAddConsoleCommand(Enlight_Event_EventArgs $args)
    {
        $this->registerMyComponents();

        // You can easily add more commands here
        return new \Doctrine\Common\Collections\ArrayCollection(array(
            new \<?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Commands\<?= $names->camelCaseModel; ?>()
        ));
    }
<?php } ?>
<?php if ($configuration->hasModels) { ?>

    /**
     * Creates the database scheme from an existing doctrine model.
     *
     * Will remove the table first, so handle with care.
     */
    protected function updateSchema()
    {
        $this->registerCustomModels();

        $em = $this->Application()->Models();
        $tool = new \Doctrine\ORM\Tools\SchemaTool($em);

        $classes = array(
            $em->getClassMetadata('Shopware\CustomModels\<?= $configuration->name; ?>\<?= $names->camelCaseModel; ?>')
        );

        try {
            $tool->dropSchema($classes);
        } catch (Exception $e) {
            //ignore
        }
        $tool->createSchema($classes);
    }
<?php } ?>

    /**
     * This callback function is triggered at the very beginning of the dispatch process and allows
     * us to register additional events on the fly. This way you won't ever need to reinstall you
     * plugin for new events - any event and hook can simply be registered in the event subscribers
     */
    public function onStartDispatch(Enlight_Event_EventArgs $args)
    {
        $this->registerMyComponents();
<?php if ($configuration->hasModels) { ?>
        $this->registerCustomModels();<?php } ?>
<?php if ($configuration->hasApi) { ?>$this->registerApiComponent();<?php } ?>
<?php if ($configuration->hasFrontend || $configuration->hasBackend || $configuration->hasWidget) { ?>
        $this->registerMyTemplateDir();
        $this->registerMySnippets();
<?php } ?>


        $subscribers = array(
<?php if ($configuration->hasFrontend || $configuration->hasBackend || $configuration->hasWidget || $configuration->hasApi) { ?>
            new \<?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Subscriber\ControllerPath(),
<?php } ?><?php if ($configuration->hasFilter) { ?>
            new \<?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Subscriber\SearchBundle(),
<?php } ?>
            new \<?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Subscriber\Frontend()
        );

        foreach ($subscribers as $subscriber) {
            $this->Application()->Events()->addSubscriber($subscriber);
        }
    }
<?php if ($configuration->hasFrontend || $configuration->hasBackend || $configuration->hasWidget) { ?>

    /**
     * Registers the template directory, needed for templates in frontend an backend
     */
    public function registerMyTemplateDir()
    {
        Shopware()->Template()->addTemplateDir($this->Path() . 'Views');
    }

    /**
     * Registers the snippet directory, needed for backend snippets
     */
    public function registerMySnippets()
    {
        $this->Application()->Snippets()->addConfigDir(
            $this->Path() . 'Snippets/'
        );
    }
<?php } ?>
<?php if ($configuration->hasApi) { ?>

    public function registerApiComponent()
    {
        $this->Application()->Loader()->registerNamespace(
            '<?= $configuration->pluginConfig['namespace']; ?>\Components',
            $this->Path() . 'Components/'
        );
    }
<?php } ?>

    public function registerMyComponents()
    {
        $this->Application()->Loader()->registerNamespace(
            '<?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>',
            $this->Path()
        );
    }

<?php if ($configuration->hasElasticSearch) { ?>
    private function subscribeElasticSearchEvents()
    {
        $this->subscribeEvent('Enlight_Bootstrap_InitResource_<?= $names->under_score_js ?>_search.indexer', 'registerIndexerService');
        $this->subscribeEvent('Shopware_ESIndexingBundle_Collect_Indexer', 'addIndexer');
        $this->subscribeEvent('Shopware_ESIndexingBundle_Collect_Mapping', 'addMapping');
        $this->subscribeEvent('Shopware_ESIndexingBundle_Collect_Synchronizer', 'addSynchronizer');
        $this->subscribeEvent('Enlight_Bootstrap_AfterInitResource_shopware_search.product_search', 'decorateProductSearch');
        $this->subscribeEvent('Shopware_ESIndexingBundle_Collect_Settings', 'addSettings');
    }

    public function addSettings()
    {
        return new Settings();
    }

    public function registerIndexerService()
    {
        return new DataIndexer(
            $this->get('dbal_connection'),
            $this->get('shopware_elastic_search.client'),
            new Provider($this->get('dbal_connection'))
        );
    }

    public function addIndexer()
    {
        return $this->get('<?= $names->under_score_js ?>_search.indexer');
    }

    public function addMapping()
    {
        return new Mapping($this->get('shopware_elastic_search.field_mapping'));
    }

    public function addSynchronizer()
    {
        return new Synchronizer(
            $this->get('<?= $names->under_score_js ?>_search.indexer'),
            $this->get('dbal_connection')
        );
    }

    public function decorateProductSearch()
    {
        $service = new Search(
            $this->get('shopware_elastic_search.client'),
            $this->get('shopware_search.product_search'),
            $this->get('shopware_elastic_search.index_factory')
        );
        Shopware()->Container()->set('shopware_search.product_search', $service);
    }
<?php } ?>



}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Subscriber;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Subscriber;
<?php } ?>

use <?= $configuration->name; ?>\Components\SearchBundleDBAL;
use Enlight\Event\SubscriberInterface;

class SearchBundle implements SubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            'Shopware_SearchBundleDBAL_Collect_Facet_Handlers' => 'registerFacetHandlers',
            'Shopware_SearchBundleDBAL_Collect_Condition_Handlers' => 'registerConditionHandlers',
            'Shopware_SearchBundle_Collect_Criteria_Request_Handlers' => 'registerRequestHandlers',
        );
    }

    public function registerFacetHandlers()
    {
        return new \Shopware\<?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet\<?= $configuration->name; ?>FacetHandler(
            Shopware()->Container()->get('shopware_searchdbal.dbal_query_builder_factory'),
            Shopware()->Container()->get('snippets')
        );
    }

    public function registerConditionHandlers()
    {
        return new \Shopware\<?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition\<?= $configuration->name; ?>ConditionHandler();
    }

    public function registerRequestHandlers()
    {
        return new \Shopware\<?= $configuration->name; ?>\Components\SearchBundleDBAL\<?= $configuration->name; ?>CriteriaRequestHandler();
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Subscriber;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Subscriber;
<?php } ?>

use Enlight\Event\SubscriberInterface;

class ControllerPath implements SubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            <?php if ($configuration->hasBackend || $configuration->hasWidget) { ?>
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_<?= $configuration->name; ?>' => 'onGetControllerPathBackend',<?php } ?><?php if ($configuration->hasFrontend) { ?>
            'Enlight_Controller_Dispatcher_ControllerPath_Frontend_<?= $configuration->name; ?>' => 'onGetControllerPathFrontend',<?php } ?><?php if ($configuration->hasWidget) { ?>
            'Enlight_Controller_Action_PostDispatch_Backend_Index' => 'extendsBackendWidget',<?php } ?><?php if ($configuration->hasApi) { ?>
            'Enlight_Controller_Dispatcher_ControllerPath_Api_<?= $names->camelCaseModel; ?>' => 'getApiController<?= $names->camelCaseModel; ?>'<?php } ?>
        );
    }

<?php if ($configuration->hasApi) { ?>

    public function getApiController<?= $names->camelCaseModel; ?>(\Enlight_Event_EventArgs $args)
    {
        return __DIR__ . '/../Controllers/Api/<?= $names->camelCaseModel; ?>.php';
    }
<?php } ?>

<?php if ($configuration->hasBackend || $configuration->hasWidget) { ?>
    /**
     * Register the backend controller
     *
     * @param   \Enlight_Event_EventArgs $args
     * @return  string
     * @Enlight\Event Enlight_Controller_Dispatcher_ControllerPath_Backend_<?= $configuration->name; ?>
     */
    public function onGetControllerPathBackend(\Enlight_Event_EventArgs $args)
    {
        return __DIR__ . '/../Controllers/Backend/<?= $configuration->name; ?>.php';
    }
<?php } ?>

<?php if ($configuration->hasWidget) { ?>
    public function extendsBackendWidget(\Enlight_Event_EventArgs $args)
    {
        /** @var \Enlight_Controller_Action $controller */
        $controller = $args->getSubject();

        if ($controller->Request()->getActionName() !== 'index') {
            return;
        }


        $controller->View()->extendsTemplate('backend/<?= $names->under_score_js; ?>/widgets/<?= $names->under_score_js; ?>.js');
    }
<?php } ?>

<?php if ($configuration->hasFrontend) { ?>
    /**
     * Register the frontend controller
     *
     * @param   \Enlight_Event_EventArgs $args
     * @return  string
     * @Enlight\Event Enlight_Controller_Dispatcher_ControllerPath_Frontend_<?= $configuration->name; ?>
     */
    public function onGetControllerPathFrontend(\Enlight_Event_EventArgs $args)
    {
        return __DIR__ . '/../Controllers/Frontend/<?= $configuration->name; ?>.php';
    }
<?php } ?>
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace <?= $configuration->pluginConfig['namespace']; ?>\<?= $configuration->name; ?>\Subscriber;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Subscriber;
<?php } ?>

use Enlight\Event\SubscriberInterface;

class Frontend implements SubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            'Enlight_Controller_Action_PostDispatchSecure_Frontend' => 'onFrontendPostDispatch'
        );
    }

    public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
    {
        /** @var $controller \Enlight_Controller_Action */
        $controller = $args->getSubject();
        $view = $controller->View();
    }
}
<?= $configuration->licenseHeaderPlain; ?><?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

/**
 * Frontend controller
 */
class Shopware_Controllers_Frontend_<?= $configuration->name; ?> extends Enlight_Controller_Action
{
    public function indexAction()
    {
        // Assign a template variable
        $this->View()->assign('name', '<?= $configuration->name; ?>');
    }
}
<?= $configuration->phpFileHeader; ?>

class Shopware_Controllers_Api_<?= $names->camelCaseModel; ?> extends Shopware_Controllers_Api_Rest
{
    /**
     * @var \<?= $configuration->pluginConfig['namespace']; ?>\Components\Api\Resource\<?= $names->camelCaseModel; ?>
     */
    protected $resource = null;

    public function init()
    {
        $this->resource = \Shopware\Components\Api\Manager::getResource('<?= $names->camelCaseModel; ?>');
    }

    /**
     * Get list of entities
     *
     * GET /api/<?= strtolower($names->camelCaseModel); ?>/
     */
    public function indexAction()
    {
        $limit  = $this->Request()->getParam('limit', 1000);
        $offset = $this->Request()->getParam('start', 0);
        $sort   = $this->Request()->getParam('sort', array());
        $filter = $this->Request()->getParam('filter', array());

        $result = $this->resource->getList($offset, $limit, $filter, $sort);

        $this->View()->assign($result);
        $this->View()->assign('success', true);
    }

    /**
     * Get one entity
     *
     * GET /api/<?= strtolower($names->camelCaseModel); ?>/{id}
     */
    public function getAction()
    {
        $id = $this->Request()->getParam('id');

        $entity = $this->resource->getOne($id);

        $this->View()->assign('data', $entity);
        $this->View()->assign('success', true);
    }

    /**
     * Create new entity
     *
     * POST /api/<?= strtolower($names->camelCaseModel); ?>}
     */
    public function postAction()
    {
        $entity = $this->resource->create($this->Request()->getPost());

        $location = $this->apiBaseUrl . '<?= strtolower($names->camelCaseModel); ?>/' . $entity->getId();
        $data = array(
            'id'       => $entity->getId(),
            'location' => $location
        );

        $this->View()->assign(array('success' => true, 'data' => $data));
        $this->Response()->setHeader('Location', $location);
    }

    /**
     * Update entity
     *
     * PUT /api/<?= strtolower($names->camelCaseModel); ?>/{id}
     */
    public function putAction()
    {
        $id = $this->Request()->getParam('id');
        $params = $this->Request()->getPost();


        $entity = $this->resource->update($id, $params);

        $location = $this->apiBaseUrl . '<?= strtolower($names->camelCaseModel); ?>/' . $entity->getId();
        $data = array(
            'id'       => $entity->getId(),
            'location' => $location
        );

        $this->View()->assign(array('success' => true, 'data' => $data));
        $this->Response()->setHeader('Location', $location);
    }

    /**
     * Delete entity
     *
     * DELETE /api/<?= strtolower($names->camelCaseModel); ?>/{id}
     */
    public function deleteAction()
    {
        $id = $this->Request()->getParam('id');

        $this->resource->delete($id);

        $this->View()->assign(array('success' => true));
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->backendModel) { ?>
/**
 * Backend controllers extending from Shopware_Controllers_Backend_Application do support the new backend components
 */
class Shopware_Controllers_Backend_<?= $configuration->name; ?> extends Shopware_Controllers_Backend_Application
{
    protected $model = '<?= $configuration->backendModel; ?>';
    protected $alias = '<?= $names->under_score_model; ?>';
<?php } else { ?>
class Shopware_Controllers_Backend_<?= $configuration->name; ?> extends Shopware_Controllers_Backend_ExtJs
{
<?php } ?>


<?php if ($configuration->hasWidget) { ?>
    /**
     * Loads data for the backend widget
     */
    public function loadBackendWidgetAction()
    {
        $data = array(
            array('id' => 1, 'name' => 'Shopware'),
            array('id' => 2, 'name' => 'Shopman'),
        );

        $this->View()->assign(array(
            'success' => true,
            'data' => $data
        ));
    }
<?php } ?>
}
# <?= $configuration->name; ?>

## About <?= $configuration->name; ?>

This skeleton contains a License file, fileheader and a basic README.

## License

Please see [License File](LICENSE) for more information.<?= $configuration->phpFileHeader; ?>

class PluginTest extends Shopware\Components\Test\Plugin\TestCase
{
    protected static $ensureLoadedPlugins = array(
        '<?= $configuration->name; ?>' => array(
        )
    );

    public function setUp()
    {
        parent::setUp();

        $helper = \TestHelper::Instance();
        $loader = $helper->Loader();


        $pluginDir = getcwd() . '/../';

        $loader->registerNamespace(
            'Shopware\\<?= $configuration->name; ?>',
            $pluginDir
        );
    }

    public function testCanCreateInstance()
    {
        /** @var Shopware_Plugins_<?= $configuration->namespace; ?>_<?= $configuration->name; ?>_Bootstrap $plugin */
        $plugin = Shopware()->Plugins()-><?= $configuration->namespace; ?>()-><?= $configuration->name; ?>();

        $this->assertInstanceOf('Shopware_Plugins_<?= $configuration->namespace; ?>_<?= $configuration->name; ?>_Bootstrap', $plugin);
    }
}<?= '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL; ?>
<?php if ($configuration->isLegacyPlugin) { ?>
<phpunit bootstrap="../../../../../../tests/Shopware/TestHelper.php">
<?php } else { ?>
<phpunit bootstrap="../../../tests/Functional/bootstrap.php">
<?php } ?>
<testsuite name="<?= $configuration->name; ?> Test Suite">
    <directory>tests</directory>
</testsuite>
</phpunit>
<?= $configuration->licenseHeader; ?>

//{block name="backend/index/application" append}
Ext.define('Shopware.apps.<?= $configuration->name; ?>.widgets.<?= $configuration->name; ?>', {
    extend: 'Shopware.apps.Index.view.widgets.Base',

    alias: 'widget.<?= $names->under_score_js; ?>',

    layout: 'fit',

    initComponent: function () {
        var me = this;

        me.items = me.getItems();

        me.callParent(arguments);
    },

    getItems: function () {
        var me = this;

        return [
            {
                xtype: 'grid',
                store: me.getWidgetStore(),
                viewConfig: {
                    hideLoadingMsg: true
                },
                border: 0,
                columns: [
                    {
                        dataIndex: 'id',
                        header: 'ID',
                        flex: 1
                    },
                    {
                        dataIndex: 'name',
                        header: 'Name',
                        flex: 1
                    }
                ]
            }
        ];
    },

    getWidgetStore: function () {
        var me = this;

        return Ext.create('Ext.data.Store', {
            fields: [
                { name: 'id', type: 'integer' },
                { name: 'name', type: 'string' }
            ],
            proxy: {
                type: 'ajax',
                url: '{url controller=<?= $names->backendWidgetController; ?> action=loadBackendWidget}',
                reader: {
                    type: 'json',
                    root: 'data'
                }
            },
            autoLoad: true
        });
    }



});
//{/block}<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.model.Main', {
    extend: 'Shopware.data.Model',

    configure: function() {
        return {
            controller: '<?= $configuration->name; ?>',
            detail: 'Shopware.apps.<?= $configuration->name; ?>.view.detail.Container'
        };
    },


    fields: [
        { name : 'id', type: 'int', useNull: true },
        { name : 'name', type: 'string', useNull: false }
    ]
});

<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.store.Main', {
    extend:'Shopware.store.Listing',

    configure: function() {
        return {
            controller: '<?= $configuration->name; ?>'
        };
    },
    model: 'Shopware.apps.<?= $configuration->name; ?>.model.Main'
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.detail.Window', {
    extend: 'Shopware.window.Detail',
    alias: 'widget.<?= $names->dash_js; ?>-detail-window',

    title : '{s name=title}<?= $configuration->name; ?> details{/s}',
    height: 420,
    width: 900
});
<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.detail.Container', {
    extend: 'Shopware.model.Container',
    padding: 20,

    configure: function() {
        return {
            controller: '<?= $configuration->name; ?>'
        };
    }
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.list.Window', {
    extend: 'Shopware.window.Listing',
    alias: 'widget.<?= $names->dash_js; ?>-list-window',
    height: 450,
    title : '{s name=window_title}<?= $configuration->name; ?> listing{/s}',

    configure: function() {
        return {
            listingGrid: 'Shopware.apps.<?= $configuration->name; ?>.view.list.List',
            listingStore: 'Shopware.apps.<?= $configuration->name; ?>.store.Main'
        };
    }
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.list.List', {
    extend: 'Shopware.grid.Panel',
    alias:  'widget.<?= $names->dash_js; ?>-listing-grid',
    region: 'center',

    configure: function() {
        return {
            detailWindow: 'Shopware.apps.<?= $configuration->name; ?>.view.detail.Window'
        };
    }
});
<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.controller.Main', {
    extend: 'Enlight.app.Controller',

    init: function() {
        var me = this;
        me.mainWindow = me.getView('list.Window').create({ }).show();
    }
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>', {
    extend: 'Enlight.app.SubApplication',

    name:'Shopware.apps.<?= $configuration->name; ?>',

    loadPath: '{url action=load}',
    bulkLoad: true,

    controllers: [ 'Main' ],

    views: [
        'list.Window',
        'list.List',

        'detail.Container',
        'detail.Window'
    ],

    models: [ 'Main' ],
    stores: [ 'Main' ],

    launch: function() {
        return this.getController('Main').mainWindow;
    }
});<?= $configuration->licenseHeader; ?>

{extends file='frontend/index/index.tpl'}

{block name="frontend_index_content"}
    <h1>Hello world, this plugin is called <?= $configuration->name; ?> :)</h1>
{/block}[en_GB]
<?= $names->under_score_js; ?> = <?= $configuration->name; ?>

[de_DE]
<?= $names->under_score_js; ?> = <?= $configuration->name; ?>
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace Shopware\CustomModels\<?= $configuration->name; ?>;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Models;
<?php } ?>

use Shopware\Components\Model\ModelEntity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="s_plugin_<?= $names->under_score_model; ?>")
 * @ORM\Entity(repositoryClass="Repository")
 */
class <?= $names->camelCaseModel; ?> extends ModelEntity
{
    /**
     * Primary Key - autoincrement value
     *
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $name
     *
     * @ORM\Column(name="name", type="string", nullable=false)
     */
    private $name;

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param $name string
     */
    public function setName($name)
    {
        $this->name = $name;
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->isLegacyPlugin) { ?>
namespace Shopware\CustomModels\<?= $configuration->name; ?>;
<?php } else { ?>
namespace <?= $configuration->name; ?>\Models;
<?php } ?>

use Shopware\Components\Model\ModelRepository;

class Repository extends ModelRepository
{

    /**
     * Returns an instance of the \Doctrine\ORM\Query object which selects a list of <?= $names->camelCaseModel; ?>

     *
     * @param null $filter
     * @param null $orderBy
     * @param      $offset
     * @param      $limit
     * @return \Doctrine\ORM\Query
     */
    public function getListQuery($filter = null, $orderBy = null, $offset, $limit)
    {
        $builder = $this->getListQueryBuilder($filter, $orderBy);
        $builder->setFirstResult($offset)
            ->setMaxResults($limit);
        return $builder->getQuery();
    }

    /**
     * Helper function to create the query builder for the "getListQuery" function.
     * This function can be hooked to modify the query builder of the query object.
     *
     * @param null $filter
     * @param null $orderBy
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function getListQueryBuilder($filter = null, $orderBy = null)
    {
        $builder = $this->getEntityManager()->createQueryBuilder();

        $builder->select(array('<?= $names->under_score_model; ?>'))
            ->from($this->getEntityName(), '<?= $names->under_score_model; ?>');

        $this->addFilter($builder, $filter);
        $this->addOrderBy($builder, $orderBy);

        return $builder;
    }
}
{
    "label": {
        "de": "<?= $configuration->name; ?>",
        "en": "<?= $configuration->name; ?>"
    },
    "copyright": "<?= $configuration->pluginConfig['copyright']; ?>",
    "license": "<?= $configuration->pluginConfig['license']; ?>",
    "link": "<?= $configuration->pluginConfig['link']; ?>",
    "author": "<?= $configuration->pluginConfig['author']; ?>",

    "currentVersion": "1.0.0",

    "changelog": {
        "de": {
            "1.0.0": "Erstveröffentlichung"
        },
        "en": {
            "1.0.0": "First release"
        }
    },

    "compatibility": {
        "minimumVersion": "<?= $configuration->pluginConfig['minimumVersion']; ?>",
        "maximumVersion": null,
        "blacklist": [
        ]
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Commands;

use Shopware\Components\Model\ModelManager;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Shopware\Commands\ShopwareCommand;

class <?= $names->camelCaseModel; ?> extends ShopwareCommand
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('<?= $names->developerPrefix; ?>:GROUP:OPERATION')
            ->setDescription('Description of this command')
            ->addArgument(
                'my-argument',
                InputArgument::REQUIRED,
                'An required argument (positional)'
            )
            ->addOption(
                'my-option',
                null,
                InputOption::VALUE_OPTIONAL,
                'An optional *option*',
                'My-Default-Value'
            )
            ->setHelp(<<<EOF
The <info>%command.name%</info> implements a command.
EOF
            );
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln($input->getOption('my-option'));
        $output->writeln($input->getArgument('my-argument'));

    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Sorting;

use Shopware\Bundle\SearchBundle\SortingInterface;

class Sorting implements SortingInterface
{
    /**
     * @inheritdoc
     */
    public function getName()
    {
    }

    /**
     * @inheritdoc
     */
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Sorting;

use Shopware\Bundle\SearchBundle\SortingInterface;
use Shopware\Bundle\SearchBundleDBAL\QueryBuilder;
use Shopware\Bundle\SearchBundleDBAL\SortingHandlerInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;

class SortingHandler implements SortingHandlerInterface
{
    /**
     * @inheritdoc
     */
    public function supportsSorting(SortingInterface $sorting)
    {
    }

    /**
     * @inheritdoc
     */
    public function generateSorting(
        SortingInterface $sorting,
        QueryBuilder $query,
        ShopContextInterface $context
    ) {
    }
}<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet;

use Shopware\Bundle\SearchBundle\Criteria;
use Shopware\Bundle\SearchBundle\FacetInterface;
use Shopware\Bundle\SearchBundle\FacetResult\BooleanFacetResult;
use Shopware\Bundle\SearchBundleDBAL\FacetHandlerInterface;
use Shopware\Bundle\SearchBundleDBAL\QueryBuilderFactory;
use Shopware\Bundle\StoreFrontBundle\Struct;

class <?= $configuration->name; ?>FacetHandler implements FacetHandlerInterface
{
    /**
     * @var QueryBuilderFactory
     */
    private $queryBuilderFactory;

    /**
     * @var \Shopware_Components_Snippet_Manager
     */
    private $snippetManager;

    /**
     * @param QueryBuilderFactory $queryBuilderFactory
     * @param \Shopware_Components_Snippet_Manager $snippetManager
     */
    public function __construct(
        QueryBuilderFactory $queryBuilderFactory,
        \Shopware_Components_Snippet_Manager $snippetManager
    ) {
        $this->queryBuilderFactory = $queryBuilderFactory;
        $this->snippetManager = $snippetManager;
    }

    /**
     * @inheritdoc
     */
    public function supportsFacet(FacetInterface $facet)
    {
        return ($facet instanceof <?= $configuration->name; ?>Facet);
    }

    /**
     * @inheritdoc
     */
    public function generateFacet(
        FacetInterface $facet,
        Criteria $criteria,
        Struct\ShopContextInterface $context
    ) {

        // This will add a new boolean filter. There are plenty of additional filter
        // https://developers.shopware.com/developers-guide/shopware-5-search-bundle/#facetresult
        return new BooleanFacetResult(
            $facet->getName(),
            '<?= $names->under_score_js; ?>_condition',
            $criteria->hasCondition($facet->getName()),
            'Example condition' // use $this->snippetManager for translatable snippets
        );
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet;

use Shopware\Bundle\SearchBundle\FacetInterface;

class <?= $configuration->name; ?>Facet implements FacetInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return '<?= $names->under_score_js; ?>';
    }

    /**
     * @inheritdoc
     */
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition;

use Shopware\Bundle\SearchBundle\ConditionInterface;

class <?= $configuration->name; ?>Condition implements ConditionInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return '<?= $names->under_score_js; ?>';
    }

    /**
     * @inheritdoc
     */
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition;

use Shopware\Bundle\SearchBundle\ConditionInterface;
use Shopware\Bundle\SearchBundleDBAL\ConditionHandlerInterface;
use Shopware\Bundle\SearchBundleDBAL\QueryBuilder;
use Shopware\Bundle\StoreFrontBundle\Struct;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;

class <?= $configuration->name; ?>ConditionHandler implements ConditionHandlerInterface
{
    const STATE_INCLUDED = '<?= $names->under_score_js; ?>_included';

    /**
     * @inheritdoc
     */
    public function supportsCondition(ConditionInterface $condition)
    {
        return ($condition instanceof <?= $configuration->name; ?>Condition);
    }

    /**
     * @inheritdoc
     */
    public function generateCondition(
        ConditionInterface $condition,
        QueryBuilder $query,
        ShopContextInterface $context
    ) {

        if (!$query->hasState(self::STATE_INCLUDED)) {
            // implement your condition here.

            // e.g. limit to product.ids <= 100
            $query->andWhere('product.id <= 100');

            // e.g. join another table and only include products,
            // that are referenced in that table.
            // $query->innerJoin(
            //     'product',
            //     's_bundle_articles',
            //     'bundle',
            //     'bundle.article_id = product.id'
            // );
            $query->addState(self::STATE_INCLUDED);
        }
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

use Elasticsearch\Client;
use Shopware\Bundle\ESIndexingBundle\IndexFactoryInterface;
use Shopware\Bundle\SearchBundle\Criteria;
use Shopware\Bundle\SearchBundle\ProductSearchInterface;
use Shopware\Bundle\StoreFrontBundle\Struct;

class Search implements ProductSearchInterface
{
    /**
     * @var ProductSearchInterface
     */
    private $coreService;

    /**
     * @var Client
     */
    private $client;

    /**
     * @var IndexFactoryInterface
     */
    private $indexFactory;

    /**
     * @param Client $client
     * @param ProductSearchInterface $coreService
     * @param IndexFactoryInterface $indexFactory
     */
    public function __construct(
        Client $client,
        ProductSearchInterface $coreService,
        IndexFactoryInterface $indexFactory
    ) {
        $this->coreService = $coreService;
        $this->client = $client;
        $this->indexFactory = $indexFactory;
    }

    public function search(Criteria $criteria, Struct\ProductContextInterface $context)
    {
        $result = $this->coreService->search($criteria, $context);

        return $result;
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Components\SearchBundle;

use <?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition\<?= $configuration->name; ?>Condition;
use <?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet\<?= $configuration->name; ?>Facet;
use <?= $configuration->name; ?>\Components\SearchBundleDBAL\Sorting\Sorting;
use Enlight_Controller_Request_RequestHttp as Request;
use Shopware\Bundle\SearchBundle\Criteria;
use Shopware\Bundle\SearchBundle\CriteriaRequestHandlerInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\ShopContextInterface;

class <?= $configuration->name; ?>CriteriaRequestHandler implements CriteriaRequestHandlerInterface
{
    /**
     * @inheritdoc
     */
    public function handleRequest(
        Request $request,
        Criteria $criteria,
        ShopContextInterface $context
    ) {
        if ($request->has('<?= $names->under_score_js; ?>_condition')) {
            $criteria->addCondition(new <?= $configuration->name; ?>Condition());
        }

        if ($request->get('sSort') == '<?= $names->under_score_js; ?>_random') {
            $criteria->addSorting(new Sorting());
        }

        $criteria->addFacet(new <?= $configuration->name; ?>Facet());
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name ?>\Components\ESIndexingBundle;

use Shopware\Bundle\ESIndexingBundle\FieldMappingInterface;
use Shopware\Bundle\ESIndexingBundle\MappingInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\Shop;

class Mapping implements MappingInterface
{
    /**
     * @var FieldMappingInterface
     */
    private $fieldMapping;

    /**
     * @param FieldMappingInterface $fieldMapping
     */
    public function __construct(FieldMappingInterface $fieldMapping)
    {
        $this->fieldMapping = $fieldMapping;
    }

    /**
     * @return string
     */
    public function getType()
    {
    }

    /**
     * @param Shop $shop
     * @return array
     */
    public function get(Shop $shop)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name ?>\Components\ESIndexingBundle;

use Doctrine\DBAL\Connection;
use Elasticsearch\Client;
use Shopware\Bundle\ESIndexingBundle\Console\ProgressHelperInterface;
use Shopware\Bundle\ESIndexingBundle\DataIndexerInterface;
use Shopware\Bundle\ESIndexingBundle\Struct\ShopIndex;
use Shopware\Bundle\StoreFrontBundle\Struct\Shop;

class DataIndexer implements DataIndexerInterface
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * @var Client
     */
    private $client;

    /**
     * @var Provider
     */
    private $provider;

    /**
     * @param Connection $connection
     * @param Client $client
     * @param Provider $provider
     */
    public function __construct(
        Connection $connection,
        Client $client,
        Provider $provider
    ) {
        $this->connection = $connection;
        $this->client = $client;
        $this->provider = $provider;
    }

    /**
     * @param ShopIndex $index
     * @param ProgressHelperInterface $progress
     */
    public function populate(ShopIndex $index, ProgressHelperInterface $progress)
    {
    }

    /**
     * @param ShopIndex $index
     * @param int[] $ids
     */
    public function index(ShopIndex $index, $ids)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name ?>\Components\ESIndexingBundle;

use Doctrine\DBAL\Connection;
use Shopware\Bundle\ESIndexingBundle\Struct\ShopIndex;
use Shopware\Bundle\ESIndexingBundle\SynchronizerInterface;

class Synchronizer implements SynchronizerInterface
{
    /**
     * @var DataIndexer
     */
    private $indexer;

    /**
     * @var Connection
     */
    private $connection;

    /**
     * @param DataIndexer $indexer
     * @param Connection $connection
     */
    public function __construct(DataIndexer $indexer, Connection $connection)
    {
        $this->indexer = $indexer;
        $this->connection = $connection;
    }

    public function synchronize(ShopIndex $shopIndex, $backlogs)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name ?>\Components\ESIndexingBundle;

use Doctrine\DBAL\Connection;

class Provider
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * @param Connection $connection
     */
    public function __construct(Connection $connection)
    {
        $this->connection = $connection;
    }

    /**
     * @param int[] $ids
     * @return []
     */
    public function get($ids)
    {
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name ?>\Components\ESIndexingBundle;

use Shopware\Bundle\ESIndexingBundle\SettingsInterface;
use Shopware\Bundle\StoreFrontBundle\Struct\Shop;

class Settings implements SettingsInterface
{
    /**
     * @param Shop $shop
     * @return array|null
     */
    public function get(Shop $shop)
    {
    }
}
<?= $configuration->phpFileHeader; ?>

namespace <?= $configuration->pluginConfig['namespace']; ?>\Components\Api\Resource;

use Doctrine\ORM\Tools\Pagination\Paginator;
use Shopware\Components\Api\Exception as ApiException;
use Shopware\Components\Model\QueryBuilder;
use Shopware\Components\Api\Resource\Resource;

class <?= $names->camelCaseModel; ?> extends Resource
{
    /**
     * Return a list of entities
     *
     * @param $offset
     * @param $limit
     * @param $filter
     * @param $sort
     *
     * @return array
     */
    public function getList($offset, $limit, $filter, $sort)
    {
        $builder = $this->getBaseQuery();
        $builder = $this->addQueryLimit($builder, $offset, $limit);

        if (!empty($filter)) {
            $builder->addFilter($filter);
        }
        if (!empty($sort)) {
            $builder->addOrderBy($sort);
        }

        $query = $builder->getQuery();

        $query->setHydrationMode($this->getResultMode());

        $paginator = new Paginator($query);

        $totalResult = $paginator->count();

        $result = $paginator->getIterator()->getArrayCopy();

        return array('data' => $result, 'total' => $totalResult);
    }


    /**
     * Read the given entity $id
     *
     * @param $id
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function getOne($id)
    {
        $builder = $this->getBaseQuery();

        $builder->where('<?= $names->backendModelAlias; ?>.id = :id')
            ->setParameter('id', $id);

        /** @var $model \<?= $configuration->backendModel; ?> */
        $model = $builder->getQuery()->getOneOrNullResult($this->getResultMode());

        if (!$model) {
            throw new ApiException\NotFoundException("<?= $names->camelCaseModel; ?> by id $id not found");
        }

        return $model;
    }

    /**
     * Create a new entity with $data
     *
     * @param $data
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws ApiException\OrmException
     * @throws ApiException\ParameterMissingException
     * @throws ApiException\ValidationException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\ORM\TransactionRequiredException
     */
    public function create($data)
    {
        $data = $this->prepareData($data);
        $model = new \<?= $configuration->backendModel; ?>();
        $model->fromArray($data);

        $violations = $this->getManager()->validate($model);

        if ($violations->count() > 0) {
            throw new ApiException\ValidationException($violations);
        }

        $this->getManager()->persist($model);
        $this->flush();

        return $model;
    }

    /**
     * Update a given entity $id with $data
     *
     * @param $id
     * @param $data
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws ApiException\OrmException
     * @throws ApiException\ParameterMissingException
     * @throws ApiException\ValidationException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\ORM\TransactionRequiredException
     */
    public function update($id, $data)
    {
        if (empty($id)) {
            throw new ApiException\ParameterMissingException();
        }

        /** @var $model \<?= $configuration->backendModel; ?> */
        $model = $this->getManager()->find('<?= $configuration->backendModel; ?>', $id);

        if (!$model) {
            throw new ApiException\NotFoundException("<?= $names->backendModelAlias; ?> by id $id not found");
        }

        $data = $this->prepareData($data);

        $model->fromArray($data);

        $violations = $this->getManager()->validate($model);
        if ($violations->count() > 0) {
            throw new ApiException\ValidationException($violations);
        }

        $this->flush();

        return $model;
    }

    /**
     * Delete the given entity
     *
     * @param $id
     *
     * @return \<?= $configuration->backendModel; ?>

     *
     * @throws ApiException\NotFoundException
     * @throws ApiException\OrmException
     * @throws ApiException\ParameterMissingException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \Doctrine\ORM\TransactionRequiredException
     */
    public function delete($id)
    {
        if (empty($id)) {
            throw new ApiException\ParameterMissingException();
        }

        /** @var $model \<?= $configuration->backendModel; ?> */
        $model = $this->getManager()->find('<?= $configuration->backendModel; ?>', $id);

        if (!$model) {
            throw new ApiException\NotFoundException("<?= $names->backendModelAlias; ?> by id $id not found");
        }

        $this->getManager()->remove($model);
        $this->flush();

        return $model;
    }


    /**
     * Here the data is prepared for automatic setting
     */
    protected function prepareData($data)
    {
        return $data;
    }

    /**
     * @param QueryBuilder $builder
     * @param              $offset
     * @param null         $limit
     *
     * @return QueryBuilder
     */
    protected function addQueryLimit(QueryBuilder $builder, $offset, $limit = null)
    {
        $builder->setFirstResult($offset)
            ->setMaxResults($limit);

        return $builder;
    }

    /**
     * @return \Doctrine\ORM\QueryBuilder|QueryBuilder
     */
    protected function getBaseQuery()
    {
        $builder = $this->getManager()->createQueryBuilder();
        $builder->select(array('<?= $names->backendModelAlias; ?>'))
            ->from('<?= $configuration->name; ?>\Models\<?= $configuration->backendModel; ?>', '<?= $names->backendModelAlias; ?>');

        return $builder;
    }
}
The MIT License (MIT)

Copyright (c) shopware AG

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.
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Subscriber;

use Symfony\Component\DependencyInjection\ContainerInterface;
use <?= $configuration->name; ?>\Components\SearchBundleDBAL;
use Enlight\Event\SubscriberInterface;

class SearchBundle implements SubscriberInterface
{
    /**
    * @var ContainerInterface
    */
    private $container;

    /**
    * @param ContainerInterface $container
    */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public static function getSubscribedEvents()
    {
        return array(
            'Shopware_SearchBundleDBAL_Collect_Facet_Handlers' => 'registerFacetHandlers',
            'Shopware_SearchBundleDBAL_Collect_Condition_Handlers' => 'registerConditionHandlers',
            'Shopware_SearchBundle_Collect_Criteria_Request_Handlers' => 'registerRequestHandlers',
            'Enlight_Controller_Action_PostDispatchSecure_Frontend_Listing' => 'extendListingTemplate'
        );
    }

    public function registerFacetHandlers()
    {
        return new \<?= $configuration->name; ?>\Components\SearchBundleDBAL\Facet\<?= $configuration->name; ?>FacetHandler(
            Shopware()->Container()->get('shopware_searchdbal.dbal_query_builder_factory'),
            Shopware()->Container()->get('snippets')
        );
    }

    public function registerConditionHandlers()
    {
        return new \<?= $configuration->name; ?>\Components\SearchBundleDBAL\Condition\<?= $configuration->name; ?>ConditionHandler();
    }

    public function registerRequestHandlers()
    {
        return new \<?= $configuration->name; ?>\Components\SearchBundle\<?= $configuration->name; ?>CriteriaRequestHandler();
    }

    /**
     * Adds the sorting option in the frontend.
     */
    public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
    {
        /** @var $controller \Enlight_Controller_Action */
        $controller = $args->getSubject();
    }


    /**
    * Adds the sorting option in the frontend.
    */
    public function extendListingTemplate(\Enlight_Event_EventArgs $args)
    {
        /** @var $controller \Enlight_Controller_Action */
        $controller = $args->getSubject();
        $view = $controller->View();

        $view->addTemplateDir(
            $this->container->getParameter('<?= $names->under_score_js ?>.plugin_dir') . '/Resources/views/'
        );
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Subscriber;

use Enlight\Event\SubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class ControllerPath implements SubscriberInterface
{
    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public static function getSubscribedEvents()
    {
        return array(
            <?php if ($configuration->hasBackend) { ?>
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_<?= $configuration->name; ?>' => 'onGetControllerPathBackend',<?php } ?><?php if ($configuration->hasFrontend) { ?>
            'Enlight_Controller_Dispatcher_ControllerPath_Frontend_<?= $configuration->name; ?>' => 'onGetControllerPathFrontend',<?php } ?><?php if ($configuration->hasApi) { ?>
            'Enlight_Controller_Dispatcher_ControllerPath_Api_<?= $names->camelCaseModel; ?>' => 'getApiController<?= $names->camelCaseModel; ?>'<?php } ?>
        );
    }

<?php if ($configuration->hasApi) { ?>

    public function getApiController<?= $names->camelCaseModel; ?>(\Enlight_Event_EventArgs $args)
    {
        return __DIR__ . '/../Controllers/Api/<?= $names->camelCaseModel; ?>.php';
    }
<?php } ?>

<?php if ($configuration->hasBackend || $configuration->hasWidget) { ?>
    /**
     * Register the backend controller
     *
     * @param   \Enlight_Event_EventArgs $args
     * @return  string
     * @Enlight\Event Enlight_Controller_Dispatcher_ControllerPath_Backend_<?= $configuration->name; ?>
     */
    public function onGetControllerPathBackend(\Enlight_Event_EventArgs $args)
    {
        $this->container->get('template')->addTemplateDir(__DIR__ . '/../Resources/views/');
        return __DIR__ . '/../Controllers/Backend/<?= $configuration->name; ?>.php';
    }
<?php } ?>

<?php if ($configuration->hasFrontend) { ?>
    /**
     * Register the frontend controller
     *
     * @param   \Enlight_Event_EventArgs $args
     * @return  string
     * @Enlight\Event Enlight_Controller_Dispatcher_ControllerPath_Frontend_<?= $configuration->name; ?>
     */
    public function onGetControllerPathFrontend(\Enlight_Event_EventArgs $args)
    {
        $this->container->get('template')->addTemplateDir(__DIR__ . '/../Resources/views/');
        return __DIR__ . '/../Controllers/Frontend/<?= $configuration->name; ?>.php';
    }
<?php } ?>
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Subscriber;

use Enlight\Event\SubscriberInterface;

class Frontend implements SubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            'Enlight_Controller_Action_PostDispatchSecure_Frontend' => 'onFrontendPostDispatch'
        );
    }

    public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
    {
        /** @var $controller \Enlight_Controller_Action */
        $controller = $args->getSubject();
        $view = $controller->View();
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace  <?= $configuration->name; ?>\Subscriber;

use Enlight\Event\SubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class ApiSubscriber implements SubscriberInterface
{
    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return [
            'Enlight_Controller_Front_DispatchLoopStartup' => 'onStartDispatch'
        ];
    }

    /**
     * This callback function is triggered at the very beginning of the dispatch process and allows
     * us to register additional events on the fly. This way you won't ever need to reinstall you
     * plugin for new events - any event and hook can simply be registered in the event subscribers
     */
    public function onStartDispatch(\Enlight_Event_EventArgs $args)
    {
        $this->container->get('Loader')->registerNamespace(
            'Shopware\Components\Api',
            $this->container->getParameter('<?= $names->under_score_js ?>.plugin_dir') . '/Components/Api/'
        );
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Subscriber;

use Enlight\Event\SubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class BackendWidget implements SubscriberInterface
{
    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
    * @return array
    */
    public static function getSubscribedEvents()
    {
        return array(
            'Enlight_Controller_Action_PostDispatch_Backend_Index' => 'extendsBackendWidget',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_<?= $names->backendWidgetController; ?>' => 'getBackendWidgetController'
        );
    }

    public function extendsBackendWidget(\Enlight_Event_EventArgs $args)
    {
        /** @var \Enlight_Controller_Action $controller */
        $controller = $args->getSubject();

        if ($controller->Request()->getActionName() !== 'index') {
            return;
        }

        $dir = $this->container->getParameter('<?= $names->under_score_js ?>.plugin_dir');
        $controller->View()->addTemplateDir($dir . '/Resources/views/');
        $controller->View()->extendsTemplate('backend/widgets/<?= $names->under_score_js; ?>.js');
    }

    /**
    * Register the backend widget controller
    *
    * @param   \Enlight_Event_EventArgs $args
    * @return  string
    */
    public function getBackendWidgetController(\Enlight_Event_EventArgs $args)
    {
        return __DIR__ . '/../Controllers/Backend/<?= $names->backendWidgetController; ?>.php';
    }
}
<?= $configuration->licenseHeaderPlain; ?><?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

/**
 * Frontend controller
 */
class Shopware_Controllers_Frontend_<?= $configuration->name; ?> extends Enlight_Controller_Action
{
    public function indexAction()
    {
        // Assign a template variable
        $this->View()->assign('name', '<?= $configuration->name; ?>');
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

class Shopware_Controllers_Backend_<?= $names->backendWidgetController; ?> extends Shopware_Controllers_Backend_ExtJs
{
    /**
    * Loads data for the backend widget
    */
    public function loadBackendWidgetAction()
    {
        $data = array(
            array('id' => 1, 'name' => 'Shopware'),
            array('id' => 2, 'name' => 'Shopman'),
        );

    $this->View()->assign(array(
            'success' => true,
            'data' => $data
        ));
    }
}
<?= $configuration->phpFileHeader; ?>

class Shopware_Controllers_Api_<?= $names->camelCaseModel; ?> extends Shopware_Controllers_Api_Rest
{
    /**
     * @var \<?= $configuration->pluginConfig['namespace']; ?>\Components\Api\Resource\<?= $names->camelCaseModel; ?>
     */
    protected $resource = null;

    public function init()
    {
        $this->resource = \Shopware\Components\Api\Manager::getResource('<?= $names->camelCaseModel; ?>');
    }

    /**
     * Get list of entities
     *
     * GET /api/<?= strtolower($names->camelCaseModel); ?>/
     */
    public function indexAction()
    {
        $limit  = $this->Request()->getParam('limit', 1000);
        $offset = $this->Request()->getParam('start', 0);
        $sort   = $this->Request()->getParam('sort', array());
        $filter = $this->Request()->getParam('filter', array());

        $result = $this->resource->getList($offset, $limit, $filter, $sort);

        $this->View()->assign($result);
        $this->View()->assign('success', true);
    }

    /**
     * Get one entity
     *
     * GET /api/<?= strtolower($names->camelCaseModel); ?>/{id}
     */
    public function getAction()
    {
        $id = $this->Request()->getParam('id');

        $entity = $this->resource->getOne($id);

        $this->View()->assign('data', $entity);
        $this->View()->assign('success', true);
    }

    /**
     * Create new entity
     *
     * POST /api/<?= strtolower($names->camelCaseModel); ?>}
     */
    public function postAction()
    {
        $entity = $this->resource->create($this->Request()->getPost());

        $location = $this->apiBaseUrl . '<?= strtolower($names->camelCaseModel); ?>/' . $entity->getId();
        $data = array(
            'id'       => $entity->getId(),
            'location' => $location
        );

        $this->View()->assign(array('success' => true, 'data' => $data));
        $this->Response()->setHeader('Location', $location);
    }

    /**
     * Update entity
     *
     * PUT /api/<?= strtolower($names->camelCaseModel); ?>/{id}
     */
    public function putAction()
    {
        $id = $this->Request()->getParam('id');
        $params = $this->Request()->getPost();


        $entity = $this->resource->update($id, $params);

        $location = $this->apiBaseUrl . '<?= strtolower($names->camelCaseModel); ?>/' . $entity->getId();
        $data = array(
            'id'       => $entity->getId(),
            'location' => $location
        );

        $this->View()->assign(array('success' => true, 'data' => $data));
        $this->Response()->setHeader('Location', $location);
    }

    /**
     * Delete entity
     *
     * DELETE /api/<?= strtolower($names->camelCaseModel); ?>/{id}
     */
    public function deleteAction()
    {
        $id = $this->Request()->getParam('id');

        $this->resource->delete($id);

        $this->View()->assign(array('success' => true));
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

<?php if ($configuration->backendModel) { ?>
/**
 * Backend controllers extending from Shopware_Controllers_Backend_Application do support the new backend components
 */
class Shopware_Controllers_Backend_<?= $configuration->name; ?> extends Shopware_Controllers_Backend_Application
{
    protected $model = \<?= $configuration->backendModel; ?>::class;

    protected $alias = '<?= $names->under_score_model; ?>';
<?php } else { ?>
class Shopware_Controllers_Backend_<?= $configuration->name; ?> extends Shopware_Controllers_Backend_ExtJs
{
<?php } ?>
<?php if ($configuration->hasWidget) { ?>
    /**
     * Loads data for the backend widget
     */
    public function loadBackendWidgetAction()
    {
        $data = array(
            array('id' => 1, 'name' => 'Shopware'),
            array('id' => 2, 'name' => 'Shopman'),
        );

        $this->View()->assign(array(
            'success' => true,
            'data' => $data
        ));
    }
<?php } ?>
}
<?= '<?xml version="1.0" encoding="utf-8"?>'.PHP_EOL; ?>
<plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../../../engine/Shopware/Components/Plugin/schema/plugin.xsd">
    <label lang="de"><?= $configuration->name; ?></label>
    <label lang="en"><?= $configuration->name; ?></label>
    <version>1.0.0</version>
    <copyright><?= $configuration->pluginConfig['copyright']; ?></copyright>
    <license><?= $configuration->pluginConfig['license']; ?></license>
    <link><?= $configuration->pluginConfig['link']; ?></link>
    <author><?= $configuration->pluginConfig['author']; ?></author>

    <compatibility minVersion="5.2.0" />

    <changelog version="1.0.0">
        <changes lang="de">Erste Veröffentlichung</changes>
        <changes lang="en">Initial Release</changes>
    </changelog>
</plugin># <?= $configuration->name; ?>

## About <?= $configuration->name; ?>

This skeleton contains a License file, fileheader and a basic README.

## License

Please see [License File](LICENSE) for more information.<?= $configuration->phpFileHeader; ?>

namespace <?= $configuration->name; ?>\Tests;

use <?= $configuration->name; ?>\<?= $configuration->name; ?> as Plugin;
use Shopware\Components\Test\Plugin\TestCase;

class PluginTest extends TestCase
{
    protected static $ensureLoadedPlugins = [
        '<?= $configuration->name; ?>' => []
    ];

    public function testCanCreateInstance()
    {
        /** @var Plugin $plugin */
        $plugin = Shopware()->Container()->get('kernel')->getPlugins()['<?= $configuration->name; ?>'];

        $this->assertInstanceOf(Plugin::class, $plugin);
    }
}
<?= '<?xml version="1.0" encoding="utf-8"?>'.PHP_EOL; ?>
<phpunit bootstrap="../../../tests/Functional/bootstrap.php">
<testsuite name="<?= $configuration->name; ?> Test Suite">
    <directory>tests</directory>
</testsuite>
</phpunit>
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>;

use Shopware\Components\Plugin;
<?php if ($configuration->hasCommands) { ?>
use Shopware\Components\Console\Application;
use <?= $configuration->name; ?>\Commands\<?= $names->camelCaseModel; ?>;
<?php } ?>
use Symfony\Component\DependencyInjection\ContainerBuilder;
<?php if ($configuration->hasWidget) { ?>
use Shopware\Models\Widget\Widget;
<?php } ?>
<?php if ($configuration->hasModels) { ?>
use Doctrine\ORM\Tools\SchemaTool;
<?php } ?>

/**
 * Shopware-Plugin <?= $configuration->name; ?>.
 */
class <?= $configuration->name; ?> extends Plugin
{
<?php if ($configuration->hasModels || $configuration->hasWidget) { ?>
    /**
     * Adds the widget to the database and creates the database schema.
     *
     * @param Plugin\Context\InstallContext $installContext
     */
    public function install(Plugin\Context\InstallContext $installContext)
    {
        parent::install($installContext);
<?php if ($configuration->hasWidget) { ?>
        $repo = $this->container->get('models')->getRepository(\Shopware\Models\Plugin\Plugin::class);
        /** @var \Shopware\Models\Plugin\Plugin $plugin */
        $plugin = $repo->findOneBy([ 'name' => '<?= $configuration->name ?>' ]);

        $widget = new Widget();
        $widget->setName('<?= $names->under_score_js ?>');
        $widget->setPlugin($plugin);

        $plugin->getWidgets()->add($widget);
<?php } ?>

<?php if ($configuration->hasModels) { ?>
        $this->createSchema();
<?php } ?>

    }

    /**
     * Remove widget and remove database schema.
     *
     * @param Plugin\Context\UninstallContext $uninstallContext
     */
    public function uninstall(Plugin\Context\UninstallContext $uninstallContext)
    {
        parent::uninstall($uninstallContext);
<?php if ($configuration->hasWidget) { ?>
        $modelManager = $this->container->get('models');
        $repo = $modelManager->getRepository(Widget::class);

        $widget = $repo->findOneBy([ 'name' => '<?= $names->under_score_js ?>' ]);
        $modelManager->remove($widget);
        $modelManager->flush();
<?php } ?>

<?php if ($configuration->hasModels) { ?>
        $this->removeSchema();
<?php } ?>
    }
<?php } ?>

    /**
    * @param ContainerBuilder $container
    */
    public function build(ContainerBuilder $container)
    {
        $container->setParameter('<?= $names->under_score_js ?>.plugin_dir', $this->getPath());
        parent::build($container);
    }

<?php if ($configuration->hasModels) { ?>
    /**
     * creates database tables on base of doctrine models
     */
    private function createSchema()
    {
        $tool = new SchemaTool($this->container->get('models'));
        $classes = [
            $this->container->get('models')->getClassMetadata(\<?= $configuration->name ?>\Models\<?= $names->camelCaseModel ?>::class)
        ];
        $tool->createSchema($classes);
    }

    private function removeSchema()
    {
        $tool = new SchemaTool($this->container->get('models'));
        $classes = [
            $this->container->get('models')->getClassMetadata(\<?= $configuration->name ?>\Models\<?= $names->camelCaseModel ?>::class)
        ];
        $tool->dropSchema($classes);
    }
<?php } ?>
}
<?= '<?xml version="1.0" encoding="utf-8"?>'.PHP_EOL; ?>
<menu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/shopware/5.2/engine/Shopware/Components/Plugin/schema/menu.xsd">
    <entries>
        <entry>
            <name><?= $configuration->name ?></name>
            <label lang="en"><?= $configuration->name ?></label>
            <label lang="de"><?= $configuration->name ?></label>
            <controller><?= $configuration->name ?></controller>
            <action>index</action>
            <class>sprite-application-block</class>
            <parent identifiedBy="controller">Marketing</parent>
        </entry>
    </entries>
</menu><?= '<?xml version="1.0" encoding="utf-8"?>'.PHP_EOL; ?>
<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
<?php if ($configuration->hasFrontend) { ?>
        <!-- @todo Add your services here -->
        <service id="<?= $names->under_score_js ?>.subscriber.frontend" class="<?= $configuration->name; ?>\Subscriber\Frontend">
            <tag name="shopware.event_subscriber" />
        </service>
<?php } ?>

<?php if ($configuration->hasBackend || $configuration->hasFrontend || $configuration->hasApi) { ?>
        <service id="<?= $names->under_score_js ?>.subscriber.controller_path" class="<?= $configuration->name; ?>\Subscriber\ControllerPath">
            <argument type="service" id="service_container" />
            <tag name="shopware.event_subscriber" />
        </service>
<?php } ?>

<?php if ($configuration->hasWidget) { ?>
        <service id="<?= $names->under_score_js ?>.subscriber.backend_widget" class="<?= $configuration->name; ?>\Subscriber\BackendWidget">
            <argument type="service" id="service_container" />
            <tag name="shopware.event_subscriber" />
        </service>
<?php } ?>

<?php if ($configuration->hasFilter) { ?>
        <service id="<?= $names->under_score_js ?>.subscriber.search_bundle" class="<?= $configuration->name; ?>\Subscriber\SearchBundle">
            <tag name="shopware.event_subscriber" />
            <argument type="service" id="service_container"></argument>
        </service>

        <service id="<?= $names->under_score_js; ?>.random_sorting.random_sorting" class="<?= $configuration->name; ?>\Components\SearchBundleDBAL\Sorting\SortingHandler">
            <tag name="sorting_handler_dbal"></tag>
        </service>
<?php } ?>


<?php if ($configuration->hasApi) { ?>
        <service id="<?= $names->under_score_js ?>.subscriber.api_subscriber" class="<?= $configuration->name; ?>\Subscriber\ApiSubscriber">
            <argument id="service_container" type="service" />
            <tag name="shopware.event_subscriber" />
        </service>
<?php } ?>

<?php if ($configuration->hasCommands) { ?>
        <service id="<?= $names->under_score_js ?>.commands.<?= $names->under_score_model ?>" class="<?= $configuration->name; ?>\Commands\<?= $names->camelCaseModel; ?>">
            <tag name="console.command" />
        </service>
<?php } ?>

<?php if($configuration->hasElasticSearch) { ?>
        <service id="<?= $names->under_score_js ?>.search.provider" class="<?= $configuration->name; ?>\Components\ESIndexingBundle\Provider">
            <argument id="dbal_connection" type="service" />
        </service>

        <service id="<?= $names->under_score_js ?>.data_indexer.data_indexer" class="<?= $configuration->name; ?>\Components\ESIndexingBundle\DataIndexer">
            <tag name="shopware_elastic_search.data_indexer" />
            <argument id="dbal_connection" type="service"/>
            <argument id="shopware_elastic_search.client" type="service"/>
            <argument id="<?= $names->under_score_js ?>.search.provider" type="service"/>
        </service>

        <service id="<?= $names->under_score_js ?>.mapping.mapping" class="<?= $configuration->name; ?>\Components\ESIndexingBundle\Mapping">
            <tag name="shopware_elastic_search.mapping" />
            <argument type="service" id="shopware_elastic_search.field_mapping" />
        </service>

        <service id="<?= $names->under_score_js ?>.synchronizer.synchronizer" class="<?= $configuration->name; ?>\Components\ESIndexingBundle\Synchronizer">
            <tag name="shopware_elastic_search.synchronizer"/>
            <argument type="service" id="<?= $names->under_score_js ?>.data_indexer.data_indexer" />
            <argument type="service" id="dbal_connection" />
        </service>

        <service id="<?= $names->under_score_js ?>.settings.settings" class="<?= $configuration->name; ?>\Components\ESIndexingBundle\Settings">
            <tag name="shopware_elastic_search.settings" />
        </service>

        <service
                id="shopware_search.<?= $names->under_score_js ?>.product_search_decorator"
                class="<?= $configuration->name; ?>\Components\SearchBundleES\Search"
                decorates="shopware_search.product_search"
                public="false"
        >
            <argument type="service" id="shopware_search.<?= $names->under_score_js ?>.product_search_decorator.inner" />
            <argument type="service" id="shopware_elastic_search.client" />
            <argument type="service" id="shopware_elastic_search.index_factory" />
        </service>
<?php } ?>

    </services>
</container>
<?= $configuration->licenseHeader; ?>

//{block name="backend/index/application" append}
Ext.define('Shopware.apps.<?= $configuration->name; ?>.widgets.<?= $configuration->name; ?>', {
    extend: 'Shopware.apps.Index.view.widgets.Base',

    alias: 'widget.<?= $names->under_score_js; ?>',

    layout: 'fit',

    initComponent: function () {
        var me = this;

        me.items = me.getItems();

        me.callParent(arguments);
    },

    getItems: function () {
        var me = this;

        return [
            {
                xtype: 'grid',
                store: me.getWidgetStore(),
                viewConfig: {
                    hideLoadingMsg: true
                },
                border: 0,
                columns: [
                    {
                        dataIndex: 'id',
                        header: 'ID',
                        flex: 1
                    },
                    {
                        dataIndex: 'name',
                        header: 'Name',
                        flex: 1
                    }
                ]
            }
        ];
    },

    getWidgetStore: function () {
        var me = this;

        return Ext.create('Ext.data.Store', {
            fields: [
                { name: 'id', type: 'integer' },
                { name: 'name', type: 'string' }
            ],
            proxy: {
                type: 'ajax',
                url: '{url controller=<?= $configuration->name; ?>Widget action=loadBackendWidget}',
                reader: {
                    type: 'json',
                    root: 'data'
                }
            },
            autoLoad: true
        });
    }



});
//{/block}<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.model.Main', {
    extend: 'Shopware.data.Model',

    configure: function() {
        return {
            controller: '<?= $configuration->name; ?>',
            detail: 'Shopware.apps.<?= $configuration->name; ?>.view.detail.Container'
        };
    },


    fields: [
        { name : 'id', type: 'int', useNull: true },
        { name : 'name', type: 'string', useNull: false }
    ]
});

<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.store.Main', {
    extend:'Shopware.store.Listing',

    configure: function() {
        return {
            controller: '<?= $configuration->name; ?>'
        };
    },
    model: 'Shopware.apps.<?= $configuration->name; ?>.model.Main'
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.detail.Window', {
    extend: 'Shopware.window.Detail',
    alias: 'widget.<?= $names->dash_js; ?>-detail-window',

    title : '{s name=title}<?= $configuration->name; ?> details{/s}',
    height: 420,
    width: 900
});
<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.detail.Container', {
    extend: 'Shopware.model.Container',
    padding: 20,

    configure: function() {
        return {
            controller: '<?= $configuration->name; ?>'
        };
    }
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.list.Window', {
    extend: 'Shopware.window.Listing',
    alias: 'widget.<?= $names->dash_js; ?>-list-window',
    height: 450,
    title : '{s name=window_title}<?= $configuration->name; ?> listing{/s}',

    configure: function() {
        return {
            listingGrid: 'Shopware.apps.<?= $configuration->name; ?>.view.list.List',
            listingStore: 'Shopware.apps.<?= $configuration->name; ?>.store.Main'
        };
    }
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.view.list.List', {
    extend: 'Shopware.grid.Panel',
    alias:  'widget.<?= $names->dash_js; ?>-listing-grid',
    region: 'center',

    configure: function() {
        return {
            detailWindow: 'Shopware.apps.<?= $configuration->name; ?>.view.detail.Window'
        };
    }
});
<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>.controller.Main', {
    extend: 'Enlight.app.Controller',

    init: function() {
        var me = this;
        me.mainWindow = me.getView('list.Window').create({ }).show();
    }
});<?= $configuration->licenseHeader; ?>

Ext.define('Shopware.apps.<?= $configuration->name; ?>', {
    extend: 'Enlight.app.SubApplication',

    name:'Shopware.apps.<?= $configuration->name; ?>',

    loadPath: '{url action=load}',
    bulkLoad: true,

    controllers: [ 'Main' ],

    views: [
        'list.Window',
        'list.List',

        'detail.Container',
        'detail.Window'
    ],

    models: [ 'Main' ],
    stores: [ 'Main' ],

    launch: function() {
        return this.getController('Main').mainWindow;
    }
});<?= $configuration->licenseHeader; ?>

{extends file='frontend/index/index.tpl'}

{block name="frontend_index_content"}
    <h1>Hello world, this plugin is called <?= $configuration->name; ?> :)</h1>
{/block}<?= $configuration->licenseHeader; ?>

{extends file="parent:frontend/listing/actions/action-sorting.tpl"}

{block name='frontend_listing_actions_sort_values'}
    <option value="<?= $names->under_score_js ?>_random"{if $sSort eq "<?= $names->under_score_js ?>_random"} selected="selected"{/if}>Example random sorting</option>
{/block}[en_GB]
<?= $names->under_score_js; ?> = <?= $configuration->name; ?>

[de_DE]
<?= $names->under_score_js; ?> = <?= $configuration->name; ?>
<?= '<?xml version="1.0" encoding="utf-8"?>'.PHP_EOL; ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../../../../engine/Shopware/Components/Plugin/schema/config.xsd">

    <elements>
        <element type="text">
            <name>demoConfig</name>
            <label lang="de">Demo Konfiguration</label>
            <label lang="en">Demo configuration</label>
            <value>Just a demo configuration, without any effects.</value>
            <description lang="de">Nur ein hoffentlich hilfreicher Text.</description>
            <description lang="en">Hopefully this text will help you.</description>
        </element>
    </elements>

</config><?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Models;

use Shopware\Components\Model\ModelEntity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="s_plugin_<?= $names->under_score_model; ?>")
 * @ORM\Entity(repositoryClass="Repository")
 */
class <?= $names->camelCaseModel; ?> extends ModelEntity
{
    /**
     * Primary Key - autoincrement value
     *
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $name
     *
     * @ORM\Column(name="name", type="string", nullable=false)
     */
    private $name;

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param $name string
     */
    public function setName($name)
    {
        $this->name = $name;
    }
}
<?= $configuration->phpFileHeader; ?>
<?= $configuration->licenseHeader; ?>

namespace <?= $configuration->name; ?>\Models;

use Shopware\Components\Model\ModelRepository;

class Repository extends ModelRepository
{

    /**
     * Returns an instance of the \Doctrine\ORM\Query object which selects a list of <?= $names->camelCaseModel; ?>

     *
     * @param null $filter
     * @param null $orderBy
     * @param      $offset
     * @param      $limit
     * @return \Doctrine\ORM\Query
     */
    public function getListQuery($filter = null, $orderBy = null, $offset, $limit)
    {
        $builder = $this->getListQueryBuilder($filter, $orderBy);
        $builder->setFirstResult($offset)
            ->setMaxResults($limit);
        return $builder->getQuery();
    }

    /**
     * Helper function to create the query builder for the "getListQuery" function.
     * This function can be hooked to modify the query builder of the query object.
     *
     * @param null $filter
     * @param null $orderBy
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function getListQueryBuilder($filter = null, $orderBy = null)
    {
        $builder = $this->getEntityManager()->createQueryBuilder();

        $builder->select(array('<?= $names->under_score_model; ?>'))
            ->from($this->getEntityName(), '<?= $names->under_score_model; ?>');

        $this->addFilter($builder, $filter);
        $this->addOrderBy($builder, $orderBy);

        return $builder;
    }
}
# Assets
Here you can copy files you want to include in your box releaseThe MIT License (MIT)

Copyright (c) 2014 shopware AG

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.

# Shopware CLI Tools

[![Build Status](https://img.shields.io/travis/shopwareLabs/sw-cli-tools/master.svg?style=flat-square)](https://travis-ci.org/shopwareLabs/sw-cli-tools)
[![Scrutinizer Score](https://img.shields.io/scrutinizer/g/shopwareLabs/sw-cli-tools.svg?style=flat-square)](https://scrutinizer-ci.com/g/shopwareLabs/sw-cli-tools)
[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)

The shopware CLI tools are your console helpers for all kind of Shopware tasks. They will allow you to:

 * setup Shopware from VCS
 * setup Shopware from a release tag
 * create Shopware plugins
 * define a bunch of plugin repositories you use
 * install plugins from the repositories and activate them in shopware
 * zip plugins in the way the Shopware store or the Shopware plugin manager expect it to be

The shopware CLI tools come with a slim extension interface, so you can extend it for your needs.

This is an **early development preview** - so don't expect it to be stable. Please wait for a 1.0.0 stable release before using this tools for production deployments

 Pull requests are very welcome as well as ideas for possible extensions.

# Support

Use at your own risk, there is no support for this tools.

# Install

Generally we recommend to use the sw.phar release files, you can download them to e.g. ~/bin/sw and add this directory to the $PATH of your local user (download current build from http://shopwarelabs.github.io/sw-cli-tools/).

If you want to use the development version of sw-cli-tools, you should checkout the repository and run `composer install` to download all dependencies

## Requirements ###
On your system at least the following packages needs to be available.

 * openjdk-7-jre-headless
 * ant
 * git
 * curl
 * php5-curl
 * If you want to use coloring you should enable php.posix in your php.ini

## Available commands
* sw cache:clear
* sw install:vcs
* sw install:release
* sw plugin:install
* sw plugin:zip:dir
* sw plugin:zip:vcs
* sw plugin:create
* sw generate

## Using the Commands
### sw plugin:install
Will install a plugin from one of the configured repos

Valid options/arguments are:

    --useHttp: use HTTP for checkout if possible (e.g. for VPN, SSH seems to be slow here sometimes)
    --small: Show 3 columns of plugins in a short form
    --shopware-root Shopware root directory
    --branch branch to checkout out
    names1…nameN - names of plugins to install

This command will automatically create a VCS mapping for phpstorm if `.idea/vcs.xml` can be found. You will need
to refresh you config with File->Sychronize (Control+Alt+Y)

### sw plugin:zip:vcs
Will checkout a plugin from VCS and zip it properly for the store

Valid options/arguments are:

    --useHttp: use HTTP for checkout if possible (e.g. for VPN, SSH seems to be slow here sometimes)
    --small: Show 3 columns of plugins in a short form
    --branch branch to checkout out
    names1…nameN - names of plugins to zip

If the plugins contains a file in its root named `.sw-zip-blacklist`, the files/directories described there, will be excluded from zipping

### sw plugin:zip:dir
Will zip the given plugin directory. DIRECTORY must point to the directory where the plugin bootstrap can be found.

### sw install:vcs
Checkout the latest shopware version from vcs (for development)

Valid options/arguments are:

    --branch: The branch to checkout
    --databaseName: Name of the database to use
    --installDir: Where to install shopware
    --user: Github user name. If provided, the checkout will be done via HTTP

The options will be read interactively, if not provided
The database credentials are configured in ~/.config/sw-cli-tools/config.yaml

### sw install:release
    --release=RELEASE                Release version. Default: Latest. Possible are all shopware release versions like "4.2.0"
    --install-dir[=INSTALL-DIR]      Install directory
    --unpack-only                    Only unpack the downloaded release
    --skip-download                  Skip release downloading
    --db-host=DB-HOST                Database host [default: "localhost"]
    --db-port=DB-PORT                Database port [default: "3306"]
    --db-socket=DB-SOCKET            Database socket
    --db-user=DB-USER                Database user
    --db-password=DB-PASSWORD        Database password
    --db-name=DB-NAME                Database name
    --shop-locale=SHOP-LOCALE        Shop locale [default: "de_DE"]
    --shop-host=SHOP-HOST            Shop host [default: "localhost"]
    --shop-path=SHOP-PATH            Shop path [default: "/"]
    --shop-name=SHOP-NAME            Shop name [default: "Demo shop"]
    --shop-email=SHOP-EMAIL          Shop email address [default: "your.email@shop.com"]
    --shop-currency=SHOP-CURRENCY    Shop currency [default: "EUR"]
    --admin-username=ADMIN-USERNAME  Administrator username [default: "demo"]
    --admin-password=ADMIN-PASSWORD  Administrator password [default: "demo"]
    --admin-email=ADMIN-EMAIL        Administrator email address [default: "demo@demo.demo"]
    --admin-locale=ADMIN-LOCALE      Administrator locale [default: "de_DE"]
    --admin-name=ADMIN-NAME          Administrator name [default: "Demo user"]

### sw plugin:create
Will create a Shopware plugin with all the boilerplate code. If the command will be executed from the shopware root folder the plugins will be placed in the plugin folder, otherwise it will be created in the same directory.

Valid options / arguments are:

    --legacy: Create a legacy Plugin for Shopware versions lower than 5.2
    --namespace[="..."]: Namespace of the plugin, default: Frontend
    --haveBackend: Generate a backend Controller + a simple ExtJS module
    --backendModel[="..."]: The name of the model for your backend application
    --haveFilter: Generate Condition/Facet/CriteriaRequestHandler in order to add a new filter in the frontend
    --haveFrontend | -f: Generate a frontend controller
    --haveModels | -m: Generate a simple doctrine model
    --haveCommands | -c: Generate a console command
    --haveWidget | -w: Generate a backend widget
    --haveApi | -a: Generate an API resource + REST controller
    --licenseHeader[="/home/user/license.txt"]: Include a license header file at the beginning of any file name: Name of your plugin. Must at least have a dev prefix + plugin name, e.g. "SwagBundle", "PrefixPluginName"; "SwagBrowserLanguageDetection"
    --haveElasticSearch | -e: Generate ElasticSearch blueprint classes and an example of a decorator for the product number search.

The options will be read interactively, if not provided.
The database credentials are configured in ~/.config/sw-cli-tools/config.yaml

### sw generate
Will generate data which can be used to fill the shop for e.g. load tests.

!Warning! this command is destructive

Valid options / arguments are:

     -a, --articles[=ARTICLES]                          Number of articles to create
         --articleFilterGroups[=ARTICLEFILTERGROUPS]    Number article filter option groups to create
         --articleFilterOptions[=ARTICLEFILTEROPTIONS]  Number article filter options to create
         --articleFilterValues[=ARTICLEFILTERVALUES]    Number article filter values to create per each filter option
     -o, --orders[=ORDERS]                              Number of orders to create
     -c, --categories[=CATEGORIES]                      Number of categories to create
         --categoriesPerArticle[=CATEGORIESPERARTICLE]  Number of categories to assign to each article
     -e, --newsletter[=NEWSLETTER]                      Number of newsletter to create
     -u, --customers[=CUSTOMERS]                        Number of customers to create
         --vouchers[=VOUCHERS]                          Number of vouchers to create
         --chunk-size[=CHUNK-SIZE]                      Chung size
     -s, --seed[=SEED]                                  Random seed
         --installDir[=INSTALLDIR]                      Your Shopware installation path. If provided, data will be automatically injected into the configured database. [default: ""]
     -n, --no-interaction                               Do not ask any interactive question

If executed from a Shopware installation, or if 'installDir' is provided, the data will
be automatically written into your Shopware database.
Otherwise, data will be exported to individual files in the '<current dir>\output' folder
You need to import the .sql files in the order in which they are generated (see the command output)

Requires 'local-infile=1' in your MySQL installation.

# Extending the cli tools

## New Extensions

Extensions are created in the `/home/USER/.config/sw-cli-tools/extensions` folder and consist of a vendor folder, the extension folder (with the extension's name) and a `Bootstrap.php` inside the extension folder. Additionally you can provide an own `config.yaml` inside the extension folder which will extend the default `config.yaml`.

The namespace of your extension bootstrap should be `VENDOR_FOLDER\EXTENSION_FOLDER\Bootstrap`.

### Bootstrap
The bootstrap is the main entry point of your extension. If it implements `ContainerAwareExtension`, it will get the container builder
 of the application injected via setContainer. This way the container can be extended by your extension.
Additionally the Bootstrap can implement `ConsoleAwareExtension`. If this is the case, the method "getConsoleCommands" will be
called after creation - please return an array of console command instances here.
Finally the extension will call the `getRepositories` method of extensions implementing `RepositoryAwareInterface`.

### Changing existing components

As you Bootstrap.php is instantiated after the container, you can replace any service of the container

# Paths
The SW cli tools make use of the XDG directory standard. Following directories are used:

    ~/.config/sw-cli-tools: Here the main configuration as well as the extensions are stored
    ~/.cache/sw-cli-tools: Here caches (like repo content) as well as release downloads are cached
    ~/.local/share/sw-cli-tools: Assets the demo data package are stored here

If you changed some of these directories via `XDG` environment variables, those directories are used instead

# Configuration
The configuration of the script is done in `~/.config/sw-cli-tools/config.yaml`. If the file does not exist on your system, it is created after the first usage of the script.

# Building sw.phar
For building the release package (`sw.phar`) [box](http://box-project.github.io/box2/) is used.
A new release is build automatically for every push on the master branch by Travis CI (See `bin/deploy.sh`).


# Coding standard
Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md).
Coding standard violations may be detected using php-cs-fixer:

    ./vendor/bin/php-cs-fixer fix -v --level=psr2 ./src
    ./vendor/bin/php-cs-fixer fix -v --level=psr2 ./tests

# General hints
## Timeouts
If you are having a slow internet connection and e.g. git checkouts or tasks related to the `ProcessExecutor` fail
with a timeout, you can increase the timeout by setting the environment variable `SW_TIMEOUT`:

    SW_TIMEOUT=500 sw install:vcs
PluginConfig:
    namespace: Shopware
    copyright: (c) by Shopware AG
    license: proprietary
    link: http://store.shopware.com
    author: Shopware AG
    minimumVersion: 4.3.0

repositories:
  ## Github API
#  GitHub:
#    ## General repo configuration
#    config:
#      ## API username
#      username: GITHUB_USER
#      ## API password
#      password: GITHUB_PASSWORD
#      ## API endpoint
#      endpoint: https://api.github.com
#    ## This defines the repos that are used with the GitHub repo type
#    repositories:
#      ## A user defined name for a repo
#      private:
#        ## How long should this be cached?
#        cache: 86400
#        ## URL which returns the branches of the repo
#        url: orgs/MyPluginRepos/repos
#        ## Plugins of this repo will be shown in this color within the repo listing
#        color: red


  ## Bitbucket API
#  BitBucket:
#    config:
#      username: BITBUCKET_USER
#      password: BITBUCKET_PASSWORD
#      endpoint: https://bitbucket.org/api/2.0
#    repositories:
#      all:
#        cache: 86400
#        url: repositories/BITBUCKET_REPO?pagelen=100
#        color: white



  ## Stash API
#  Stash:
#    config:
#      username: STASH_USER
#      password: STASH_PASSWORD
#      endpoint: http://you-stash-instande.tld/rest/api/1.0
#    repositories:
    ## You can also use your stash user space as repo. Public
    ## repos will be shown in the plugin list
#      stash.user:
#        cache: 86400
#        url: users/s.user/repos?limit=100
#      myrepo:
#       cache: 86400
#       url: projects/MYREPO/repos?limit=100
#       color: blue

  ## If you want to maintain a manual collection of repositories, you can use SimpleList
  ## Even here you can use colors and repos / collections of plugins
#  SimpleList:
#    repositories:
#      example1:
#        color: yellow
#        plugins:
#          Core_SwagJobQueue: ## Schema: MODULE_PLUGINNAME
#            ssh: git@github.com:bcremer/SwagJobQueue.git
#            http: https://github.com/bcremer/SwagJobQueue.git

general:
  # Allows you do determine how the plugin repositories should be sorted
  # Allowed values are:
  #   module          Sort by module and then by name
  #   name            Sort by name
  #   repository      Sort by repository - and then by name
  sortBy: repository

  # Do you want to use colors in your listing?
  enableRepositoryColors: true

update:
  pharUrl: https://shopwarelabs.github.io/sw-cli-tools/sw.phar
  vesionUrl: https://shopwarelabs.github.io/sw-cli-tools/sw.phar.version
  verifyPublicKey: false
  checkOnStartup: false

## the configured host will always be used
# username, password, mail and name only apply for "release" packages
ShopConfig:
  host:
  username: demo
  password: demo
  mail: test@example.org
  name: "Demo admin"

DatabaseConfig:
  host: localhost
  user: root
  pass: root

## If needed, you can change the owner of the shopware install dir
# ChangeOwner:
#  user: www-data
#  group: www-data

## A list of sql files you want to import after shopware was set up
# CustomDeltas:
#  - /home/USER/setup_mail_client.sql
#  - /home/USER/configure_shop.sql

## A list of shell commands to execute after shopware was set up
## CWD will be the shopware install dir
# CustomScripts:
# - ./bin/console sw:plugin:refresh
# - ./bin/console sw:plugin:install --activate AdvancedMenu

## Here you can specify a list of repositories to checkout.
# You can specify the destination path with the "destination" field
#
# Warning: The "core" repository is always required - it is the main
# shopware repo to checkout. If you want to, you can replace the ssh/http
# urls with urls to your own repository.
ShopwareInstallRepos:
  core:
    destination: /
    ssh: git@github.com:shopware/shopware.git
    http: https://github.com/shopware/shopware.git

## Here you can define a locale which is used for data generation.
## For available locales please refer to: https://github.com/fzaninotto/Faker/tree/master/src/Faker/Provider
#
# DataGenerator:
  # locale: de_DE

  ##
  # Here you could add own plugins and other stuff you want to include in any
  # installation you set up
  # e.g.
  # my-plugin:
  #   destination: /engine/Shopware/Plugins/Local/Core/SwagMyPlugin
  #    ssh: git@github.com:ShopwareAG/swag-my-plugin.git
  #    http: https://github.com/ShopwareAG/swag-my-plugin.git
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1qGj7WKeNt64jZK+jW1F
TbTm5DH80YqmJGt3jgFXKn3DNowRaJMExNs3QWddkvILzKI2BgkBRoAP5YYEpgal
R9H+5nRY3AboSrw7NmZMbg07/O1QMb1iq26LWYp5jQb+LL+tMWJYztRU+LHI+QWL
wlqIuul7+xItvmLORdwSwd7UsL9brTkE+ZNI36qxuZEwl9ETlZp1jnidnlL+zef0
TSsdmlOk+8OYyEJvo9Iil2n9oYh/6JofyTqHS4Clx2y+VcEWLx02Zzb7hSUC5z1V
EVtvqIt7V3J0I26DFC950dSlGImW5N/ciZJeCer+8tkc+eS8mF+2Q4vJCFEmMUCo
nQqWpqb5oTg4EpfeNlppGte0n42Vd8utyVF0uWHW95/Az9nyXRJQL17wSqp96Xtx
VigSmRP5OCaMYFRjGdG7M+oAOUJxiHgyyAz7O1i7cB3/Z/sbRsPxBJ/+NK73EttD
Wf3n/0feSi8tb/OGbxXfibmZ8LL3yWxlC/U6ZIPHPDKo75JS8pQUctRcWDol2Xv3
o47B48kRnYIcZm28nf91EFXSsPcjjp+ETaUEzelAgGQRbxrpwGorZmvQ/oPAJSCQ
ODb/K8prWXLjJHxH5JNsYYo16KyQrJ5K7201ntnxau6SDa5hT+esAPDNYXwLkMlL
JAh1jwyReZd6m8kJOwjDWLcCAwEAAQ==
-----END PUBLIC KEY-----
{"name":"Plugin info","type":"object","properties":{"label":{"type":"object","description":"Full name of the plugin","required":true},"copyright":{"type":"string","description":"Copyright notice","required":false},"license":{"type":"string","description":"License notice","required":false},"link":{"type":"string","description":"Link of the plugin","required":false},"author":{"type":"string","description":"Author of the plugin","required":false},"currentVersion":{"type":"string","description":"Plugin version string","required":false},"changelog":{"type":"object","description":"changelogs","required":true},"compatibility":{"type":"object","description":"Compatibility hints","required":false}}}<?php
error_reporting(-1);
ini_set('display_errors', 1);

function includeIfExists($file)
{
    return file_exists($file) ? include $file : false;
}

if ((!$loader = includeIfExists(__DIR__.'/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../autoload.php'))) {
    echo 'You must set up the project dependencies, run the following commands:'.PHP_EOL.
            'curl -sS https://getcomposer.org/installer | php'.PHP_EOL.
            'php composer.phar install'.PHP_EOL;
    exit(1);
}

$application = new ShopwareCli\Application($loader);
$application->run();
�]m�E@o��a���K��7�GBMB